summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2007-12-14 17:01:02 +0100
committerSebastien Helleu <flashcode@flashtux.org>2007-12-14 17:01:02 +0100
commite62ec5204c7061a83860fa6c6c8204414a2dd057 (patch)
tree122d8931668748e0bb445d7378be050ebcf22801
parent70e44d3c548c9c6856f0fd0d07c22df88817273b (diff)
downloadweechat-e62ec5204c7061a83860fa6c6c8204414a2dd057.zip
Improved main loop (less CPU usage), better precision for timers, use of one list by hook type (for fast search in hooks)
-rw-r--r--ChangeLog3
-rw-r--r--src/core/wee-command.c51
-rw-r--r--src/core/wee-config.c108
-rw-r--r--src/core/wee-hook.c565
-rw-r--r--src/core/wee-hook.h24
-rw-r--r--src/core/wee-util.c41
-rw-r--r--src/core/wee-util.h2
-rw-r--r--src/core/weechat.c1
-rw-r--r--src/gui/curses/gui-curses-infobar.c55
-rw-r--r--src/gui/curses/gui-curses-main.c140
-rw-r--r--src/gui/gtk/gui-gtk-infobar.c27
-rw-r--r--src/gui/gui-completion.c16
-rw-r--r--src/gui/gui-infobar.c10
-rw-r--r--src/gui/gui-infobar.h4
-rw-r--r--src/gui/gui-keyboard.c14
-rw-r--r--src/plugins/demo/demo.c28
-rw-r--r--src/plugins/plugin-api.c16
-rw-r--r--src/plugins/plugin-api.h2
-rw-r--r--src/plugins/weechat-plugin.h8
19 files changed, 729 insertions, 386 deletions
diff --git a/ChangeLog b/ChangeLog
index c1fc74db1..7b260dcf0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,11 @@
WeeChat - Wee Enhanced Environment for Chat
===========================================
-ChangeLog - 2007-12-13
+ChangeLog - 2007-12-14
Version 0.2.7 (under dev!):
+ * improved main loop: higher timout in select(), less CPU usage
* added /reload command to reload WeeChat and plugins config files
* new plugins: IRC, alias, demo, fifo, logger, trigger
* added hooks: command, timer, file descriptor, print, signal, config,
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index c2b9b9d78..77c70e3a8 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -494,10 +494,10 @@ command_help (void *data, void *buffer,
case 1:
gui_chat_printf (NULL, "");
gui_chat_printf (NULL, _("%s internal commands:"), PACKAGE_NAME);
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& !ptr_hook->plugin
&& HOOK_COMMAND(ptr_hook, command)
&& HOOK_COMMAND(ptr_hook, command)[0])
@@ -522,10 +522,10 @@ command_help (void *data, void *buffer,
}
gui_chat_printf (NULL, "");
gui_chat_printf (NULL, _("Other commands:"));
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& ptr_hook->plugin
&& HOOK_COMMAND(ptr_hook, command)
&& HOOK_COMMAND(ptr_hook, command)[0])
@@ -550,10 +550,10 @@ command_help (void *data, void *buffer,
}
break;
case 2:
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& HOOK_COMMAND(ptr_hook, command)
&& HOOK_COMMAND(ptr_hook, command)[0]
&& (HOOK_COMMAND(ptr_hook, level) == 0)
@@ -886,11 +886,10 @@ command_plugin_list (char *name, int full)
{
/* commands hooked */
hook_found = 0;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->plugin == ptr_plugin)
- && (ptr_hook->type == HOOK_TYPE_COMMAND))
+ if (!ptr_hook->deleted && (ptr_hook->plugin == ptr_plugin))
{
if (!hook_found)
gui_chat_printf (NULL, _(" commands hooked:"));
@@ -907,11 +906,10 @@ command_plugin_list (char *name, int full)
/* timers hooked */
hook_found = 0;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_TIMER]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->plugin == ptr_plugin)
- && (ptr_hook->type == HOOK_TYPE_TIMER))
+ if (!ptr_hook->deleted && (ptr_hook->plugin == ptr_plugin))
{
if (!hook_found)
gui_chat_printf (NULL, _(" timers hooked:"));
@@ -949,11 +947,10 @@ command_plugin_list (char *name, int full)
/* fd hooked */
hook_found = 0;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_FD]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->plugin == ptr_plugin)
- && (ptr_hook->type == HOOK_TYPE_FD))
+ if (!ptr_hook->deleted && (ptr_hook->plugin == ptr_plugin))
{
if (!hook_found)
gui_chat_printf (NULL,
@@ -968,11 +965,10 @@ command_plugin_list (char *name, int full)
/* prints hooked */
hook_found = 0;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_PRINT]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->plugin == ptr_plugin)
- && (ptr_hook->type == HOOK_TYPE_PRINT))
+ if (!ptr_hook->deleted && (ptr_hook->plugin == ptr_plugin))
{
if (!hook_found)
gui_chat_printf (NULL, _(" prints hooked:"));
@@ -994,11 +990,10 @@ command_plugin_list (char *name, int full)
/* signals hooked */
hook_found = 0;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_SIGNAL]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->plugin == ptr_plugin)
- && (ptr_hook->type == HOOK_TYPE_SIGNAL))
+ if (!ptr_hook->deleted && (ptr_hook->plugin == ptr_plugin))
{
if (!hook_found)
gui_chat_printf (NULL, _(" signals hooked:"));
@@ -1012,11 +1007,10 @@ command_plugin_list (char *name, int full)
/* config options hooked */
hook_found = 0;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_CONFIG]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->plugin == ptr_plugin)
- && (ptr_hook->type == HOOK_TYPE_CONFIG))
+ if (!ptr_hook->deleted && (ptr_hook->plugin == ptr_plugin))
{
if (!hook_found)
gui_chat_printf (NULL,
@@ -1034,11 +1028,10 @@ command_plugin_list (char *name, int full)
/* completion hooked */
hook_found = 0;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMPLETION]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->plugin == ptr_plugin)
- && (ptr_hook->type == HOOK_TYPE_COMPLETION))
+ if (!ptr_hook->deleted && (ptr_hook->plugin == ptr_plugin))
{
if (!hook_found)
gui_chat_printf (NULL,
@@ -2067,10 +2060,10 @@ command_print_stdout ()
{
struct t_hook *ptr_hook;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& HOOK_COMMAND(ptr_hook, command)
&& HOOK_COMMAND(ptr_hook, command)[0]
&& !ptr_hook->plugin)
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index d8dc7b43b..cc89254ae 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -36,15 +36,19 @@
#include "weechat.h"
#include "wee-config.h"
#include "wee-config-file.h"
+#include "wee-hook.h"
#include "wee-log.h"
#include "wee-util.h"
#include "wee-list.h"
+#include "wee-string.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-color.h"
#include "../gui/gui-hotlist.h"
+#include "../gui/gui-infobar.h"
#include "../gui/gui-keyboard.h"
#include "../gui/gui-status.h"
#include "../gui/gui-window.h"
+#include "../plugins/plugin.h"
struct t_config_file *weechat_config_file = NULL;
@@ -178,6 +182,10 @@ struct t_config_option *config_plugins_path;
struct t_config_option *config_plugins_autoload;
struct t_config_option *config_plugins_extension;
+/* hooks */
+
+struct t_hook *config_day_change_timer = NULL;
+
/*
* config_change_save_on_exit: called when "save_on_exit" flag is changed
@@ -318,6 +326,91 @@ config_change_nicks_colors ()
}
/*
+ * config_change_infobar_seconds: called when display of seconds in infobar changed
+ */
+
+void
+config_change_infobar_seconds ()
+{
+ int seconds;
+
+ if (gui_infobar_refresh_timer)
+ unhook (gui_infobar_refresh_timer);
+
+ seconds = (CONFIG_BOOLEAN(config_look_infobar_seconds)) ? 1 : 60;
+ gui_infobar_refresh_timer = hook_timer (NULL, seconds * 1000, seconds, 0,
+ gui_infobar_refresh_timer_cb, NULL);
+ (void) gui_infobar_refresh_timer_cb ("force");
+}
+
+/*
+ * config_day_change_timer_cb: timer callback for displaying
+ * "Day changed to xxx" message
+ */
+
+int
+config_day_change_timer_cb (void *data)
+{
+ struct timeval tv_time;
+ struct tm *local_time;
+ char text_time[1024], *text_time2;
+ struct t_gui_buffer *ptr_buffer;
+
+ /* make C compiler happy */
+ (void) data;
+
+ gettimeofday (&tv_time, NULL);
+ local_time = localtime (&tv_time.tv_sec);
+
+ strftime (text_time, sizeof (text_time),
+ CONFIG_STRING(config_look_day_change_time_format),
+ local_time);
+ text_time2 = string_iconv_to_internal (NULL, text_time);
+ gui_add_hotlist = 0;
+ for (ptr_buffer = gui_buffers; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
+ {
+ if (ptr_buffer->type == GUI_BUFFER_TYPE_FORMATED)
+ gui_chat_printf (ptr_buffer,
+ _("\t\tDay changed to %s"),
+ (text_time2) ?
+ text_time2 : text_time);
+ }
+ if (text_time2)
+ free (text_time2);
+ gui_add_hotlist = 1;
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * config_change_day_change: called when day_change option changed
+ */
+
+void
+config_change_day_change ()
+{
+ if (CONFIG_BOOLEAN(config_look_day_change))
+ {
+ if (!config_day_change_timer)
+ config_day_change_timer = hook_timer (NULL,
+ 24 * 3600 * 1000,
+ 24 * 3600,
+ 0,
+ &config_day_change_timer_cb,
+ NULL);
+ }
+ else
+ {
+ if (config_day_change_timer)
+ {
+ unhook (config_day_change_timer);
+ config_day_change_timer = NULL;
+ }
+ }
+}
+
+/*
* config_weechat_read_key: read a key in configuration file
*/
@@ -543,7 +636,7 @@ config_weechat_init ()
config_look_infobar_seconds = config_file_new_option (
ptr_section, "look_infobar_seconds", "boolean",
N_("display seconds in infobar time"),
- NULL, 0, 0, "on", &config_change_buffer_content);
+ NULL, 0, 0, "on", &config_change_infobar_seconds);
config_look_infobar_delay_highlight = config_file_new_option (
ptr_section, "look_infobar_delay_highlight", "integer",
N_("delay (in seconds) for highlight messages in "
@@ -576,7 +669,7 @@ config_weechat_init ()
config_look_day_change = config_file_new_option (
ptr_section, "look_day_change", "boolean",
N_("display special message when day changes"),
- NULL, 0, 0, "on", NULL);
+ NULL, 0, 0, "on", &config_change_day_change);
config_look_day_change_time_format = config_file_new_option (
ptr_section, "look_day_change_time_format", "string",
N_("time format for date displayed when day changed"),
@@ -1045,7 +1138,16 @@ config_weechat_init ()
int
config_weechat_read ()
{
- return config_file_read (weechat_config_file);
+ int rc;
+
+ rc = config_file_read (weechat_config_file);
+ if (rc == 0)
+ {
+ config_change_infobar_seconds ();
+ config_change_day_change ();
+ }
+
+ return rc;
}
/*
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index d5d7fcc38..31a782f18 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -38,12 +38,29 @@
#include "../plugins/plugin.h"
-struct t_hook *weechat_hooks = NULL;
-struct t_hook *last_weechat_hook = NULL;
+struct t_hook *weechat_hooks[HOOK_NUM_TYPES];
+struct t_hook *last_weechat_hook[HOOK_NUM_TYPES];
int hook_exec_recursion = 0;
+int real_delete_pending = 0;
/*
+ * hook_init: init hooks lists
+ */
+
+void
+hook_init ()
+{
+ int type;
+
+ for (type = 0; type < HOOK_NUM_TYPES; type++)
+ {
+ weechat_hooks[type] = NULL;
+ last_weechat_hook[type] = NULL;
+ }
+}
+
+/*
* hook_find_pos: find position for new hook (keeping command list sorted)
*/
@@ -57,10 +74,10 @@ hook_find_pos (struct t_hook *hook)
return NULL;
/* for command hook, keep list sorted */
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[hook->type]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& (string_strcasecmp (HOOK_COMMAND(hook, command),
HOOK_COMMAND(ptr_hook, command)) <= 0))
return ptr_hook;
@@ -79,7 +96,7 @@ hook_add_to_list (struct t_hook *new_hook)
{
struct t_hook *pos_hook;
- if (weechat_hooks)
+ if (weechat_hooks[new_hook->type])
{
pos_hook = hook_find_pos (new_hook);
if (pos_hook)
@@ -90,24 +107,24 @@ hook_add_to_list (struct t_hook *new_hook)
if (pos_hook->prev_hook)
(pos_hook->prev_hook)->next_hook = new_hook;
else
- weechat_hooks = new_hook;
+ weechat_hooks[new_hook->type] = new_hook;
pos_hook->prev_hook = new_hook;
}
else
{
/* add hook to end of list */
- new_hook->prev_hook = last_weechat_hook;
+ new_hook->prev_hook = last_weechat_hook[new_hook->type];
new_hook->next_hook = NULL;
- last_weechat_hook->next_hook = new_hook;
- last_weechat_hook = new_hook;
+ last_weechat_hook[new_hook->type]->next_hook = new_hook;
+ last_weechat_hook[new_hook->type] = new_hook;
}
}
else
{
new_hook->prev_hook = NULL;
new_hook->next_hook = NULL;
- weechat_hooks = new_hook;
- last_weechat_hook = new_hook;
+ weechat_hooks[new_hook->type] = new_hook;
+ last_weechat_hook[new_hook->type] = new_hook;
}
}
@@ -120,12 +137,12 @@ hook_remove_from_list (struct t_hook *hook)
{
struct t_hook *new_hooks;
- if (last_weechat_hook == hook)
- last_weechat_hook = hook->prev_hook;
+ if (last_weechat_hook[hook->type] == hook)
+ last_weechat_hook[hook->type] = hook->prev_hook;
if (hook->prev_hook)
{
hook->prev_hook->next_hook = hook->next_hook;
- new_hooks = weechat_hooks;
+ new_hooks = weechat_hooks[hook->type];
}
else
new_hooks = hook->next_hook;
@@ -134,7 +151,7 @@ hook_remove_from_list (struct t_hook *hook)
hook->next_hook->prev_hook = hook->prev_hook;
free (hook);
- weechat_hooks = new_hooks;
+ weechat_hooks[hook->type] = new_hooks;
}
/*
@@ -144,34 +161,41 @@ hook_remove_from_list (struct t_hook *hook)
void
hook_remove_deleted ()
{
+ int type;
struct t_hook *ptr_hook, *next_hook;
-
- ptr_hook = weechat_hooks;
- while (ptr_hook)
+
+ if (real_delete_pending)
{
- next_hook = ptr_hook->next_hook;
-
- if (ptr_hook->type == HOOK_TYPE_DELETED)
- hook_remove_from_list (ptr_hook);
-
- ptr_hook = next_hook;
+ for (type = 0; type < HOOK_NUM_TYPES; type++)
+ {
+ ptr_hook = weechat_hooks[type];
+ while (ptr_hook)
+ {
+ next_hook = ptr_hook->next_hook;
+
+ if (ptr_hook->deleted)
+ hook_remove_from_list (ptr_hook);
+
+ ptr_hook = next_hook;
+ }
+ }
+ real_delete_pending = 0;
}
}
/*
- * hook_init: init a new hook with default values
+ * hook_init_data: init data a new hook with default values
*/
void
-hook_init (struct t_hook *hook, void *plugin, int type, void *callback_data)
+hook_init_data (struct t_hook *hook, void *plugin, int type, void *callback_data)
{
hook->plugin = plugin;
hook->type = type;
+ hook->deleted = 0;
+ hook->running = 0;
hook->callback_data = callback_data;
-
hook->hook_data = NULL;
-
- hook->running = 0;
}
/*
@@ -183,13 +207,17 @@ hook_init (struct t_hook *hook, void *plugin, int type, void *callback_data)
int
hook_valid (struct t_hook *hook)
{
+ int type;
struct t_hook *ptr_hook;
-
- for (ptr_hook = weechat_hooks; ptr_hook;
- ptr_hook = ptr_hook->next_hook)
+
+ for (type = 0; type < HOOK_NUM_TYPES; type++)
{
- if (ptr_hook == hook)
- return 1;
+ for (ptr_hook = weechat_hooks[type]; ptr_hook;
+ ptr_hook = ptr_hook->next_hook)
+ {
+ if (!ptr_hook->deleted && (ptr_hook == hook))
+ return 1;
+ }
}
/* hook not found */
@@ -205,14 +233,18 @@ hook_valid (struct t_hook *hook)
int
hook_valid_for_plugin (void *plugin, struct t_hook *hook)
{
+ int type;
struct t_hook *ptr_hook;
-
- for (ptr_hook = weechat_hooks; ptr_hook;
- ptr_hook = ptr_hook->next_hook)
+
+ for (type = 0; type < HOOK_NUM_TYPES; type++)
{
- if ((ptr_hook == hook)
- && (ptr_hook->plugin == (struct t_weechat_plugin *)plugin))
- return 1;
+ for (ptr_hook = weechat_hooks[type]; ptr_hook;
+ ptr_hook = ptr_hook->next_hook)
+ {
+ if (!ptr_hook->deleted && (ptr_hook == hook)
+ && (ptr_hook->plugin == (struct t_weechat_plugin *)plugin))
+ return 1;
+ }
}
/* hook not found */
@@ -228,10 +260,10 @@ hook_search_command (char *command)
{
struct t_hook *ptr_hook;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& (string_strcasecmp (HOOK_COMMAND(ptr_hook, command), command) == 0))
return ptr_hook;
}
@@ -260,10 +292,10 @@ hook_command (void *plugin, char *command, char *description,
/* increase level for command hooks with same command name
so that these commands will not be used any more, until this
one is removed */
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& (string_strcasecmp (HOOK_COMMAND(ptr_hook, command), command) == 0))
{
HOOK_COMMAND(ptr_hook, level)++;
@@ -280,7 +312,7 @@ hook_command (void *plugin, char *command, char *description,
return NULL;
}
- hook_init (new_hook, plugin, HOOK_TYPE_COMMAND, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_COMMAND, callback_data);
new_hook->hook_data = new_hook_command;
new_hook_command->callback = callback;
@@ -328,14 +360,14 @@ hook_command_exec (void *buffer, char *string, int only_builtin)
hook_exec_recursion++;
- ptr_hook = weechat_hooks;
+ ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND];
while (ptr_hook)
{
next_hook = ptr_hook->next_hook;
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
+ && !ptr_hook->running
&& (HOOK_COMMAND(ptr_hook, level) == 0)
- && (!ptr_hook->running)
&& (!only_builtin || !ptr_hook->plugin)
&& (!ptr_hook->plugin
|| !((struct t_gui_buffer *)buffer)->plugin
@@ -346,8 +378,7 @@ hook_command_exec (void *buffer, char *string, int only_builtin)
ptr_hook->running = 1;
rc = (int) (HOOK_COMMAND(ptr_hook, callback))
(ptr_hook->callback_data, buffer, argc, argv, argv_eol);
- if (ptr_hook->type == HOOK_TYPE_COMMAND)
- ptr_hook->running = 0;
+ ptr_hook->running = 0;
if (hook_exec_recursion > 0)
hook_exec_recursion--;
if (hook_exec_recursion == 0)
@@ -379,11 +410,12 @@ hook_command_exec (void *buffer, char *string, int only_builtin)
*/
struct t_hook *
-hook_timer (void *plugin, long interval, int max_calls,
+hook_timer (void *plugin, long interval, int align_second, int max_calls,
t_hook_callback_timer *callback, void *callback_data)
{
struct t_hook *new_hook;
struct t_hook_timer *new_hook_timer;
+ struct timezone tz;
new_hook = (struct t_hook *)malloc (sizeof (struct t_hook));
if (!new_hook)
@@ -395,13 +427,28 @@ hook_timer (void *plugin, long interval, int max_calls,
return NULL;
}
- hook_init (new_hook, plugin, HOOK_TYPE_TIMER, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_TIMER, callback_data);
new_hook->hook_data = new_hook_timer;
new_hook_timer->callback = callback;
new_hook_timer->interval = interval;
new_hook_timer->remaining_calls = max_calls;
- gettimeofday (&new_hook_timer->last_exec, NULL);
+
+ tz.tz_minuteswest = 0;
+ gettimeofday (&new_hook_timer->last_exec, &tz);
+
+ if ((interval >= 1000) && (align_second > 0))
+ {
+ new_hook_timer->last_exec.tv_usec = 0;
+ new_hook_timer->last_exec.tv_sec =
+ new_hook_timer->last_exec.tv_sec -
+ ((new_hook_timer->last_exec.tv_sec - (tz.tz_minuteswest * 60)) %
+ align_second);
+ }
+
+ new_hook_timer->next_exec.tv_sec = new_hook_timer->last_exec.tv_sec;
+ new_hook_timer->next_exec.tv_usec = new_hook_timer->last_exec.tv_usec;
+ util_timeval_add (&new_hook_timer->next_exec, interval);
hook_add_to_list (new_hook);
@@ -409,43 +456,104 @@ hook_timer (void *plugin, long interval, int max_calls,
}
/*
+ * hook_timer_time_to_next: get time to next timeout
+ * return 1 if timeout is set with next timeout
+ * 0 if there's no timeout
+ */
+
+int
+hook_timer_time_to_next (struct timeval *tv_time)
+{
+ struct t_hook *ptr_hook;
+ int found;
+ struct timeval tv_now;
+ long diff_usec;
+
+ found = 0;
+ tv_time->tv_sec = 0;
+ tv_time->tv_usec = 0;
+
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_TIMER]; ptr_hook;
+ ptr_hook = ptr_hook->next_hook)
+ {
+ if (!ptr_hook->deleted
+ && (!found
+ || (util_timeval_cmp (&HOOK_TIMER(ptr_hook, next_exec), tv_time) < 0)))
+ {
+ found = 1;
+ tv_time->tv_sec = HOOK_TIMER(ptr_hook, next_exec).tv_sec;
+ tv_time->tv_usec = HOOK_TIMER(ptr_hook, next_exec).tv_usec;
+ }
+ }
+
+ /* no timeout found */
+ if (!found)
+ return 0;
+
+ gettimeofday (&tv_now, NULL);
+
+ /* next timeout is past date! */
+ if (util_timeval_cmp (tv_time, &tv_now) < 0)
+ {
+ tv_time->tv_sec = 0;
+ tv_time->tv_usec = 0;
+ return 1;
+ }
+
+ tv_time->tv_sec = tv_time->tv_sec - tv_now.tv_sec;
+ diff_usec = tv_time->tv_usec - tv_now.tv_usec;
+ if (diff_usec >= 0)
+ tv_time->tv_usec = diff_usec;
+ else
+ {
+ tv_time->tv_sec--;
+ tv_time->tv_usec = 1000000 + diff_usec;
+ }
+
+ return 1;
+}
+
+/*
* hook_timer_exec: execute timer hooks
*/
void
-hook_timer_exec (struct timeval *tv_time)
+hook_timer_exec ()
{
+ struct timeval tv_time;
struct t_hook *ptr_hook, *next_hook;
- long time_diff;
+
+ gettimeofday (&tv_time, NULL);
hook_exec_recursion++;
- ptr_hook = weechat_hooks;
+ ptr_hook = weechat_hooks[HOOK_TYPE_TIMER];
while (ptr_hook)
{
next_hook = ptr_hook->next_hook;
- if ((ptr_hook->type == HOOK_TYPE_TIMER)
- && (!ptr_hook->running))
+ if (!ptr_hook->deleted
+ && !ptr_hook->running
+ && (util_timeval_cmp (&HOOK_TIMER(ptr_hook, next_exec),
+ &tv_time) <= 0))
{
- time_diff = util_timeval_diff (&HOOK_TIMER(ptr_hook, last_exec),
- tv_time);
- if (time_diff >= HOOK_TIMER(ptr_hook, interval))
+ ptr_hook->running = 1;
+ (void) (HOOK_TIMER(ptr_hook, callback))
+ (ptr_hook->callback_data);
+ ptr_hook->running = 0;
+ if (!ptr_hook->deleted)
{
- ptr_hook->running = 1;
- (void) (HOOK_TIMER(ptr_hook, callback))
- (ptr_hook->callback_data);
- if (ptr_hook->type == HOOK_TYPE_TIMER)
+ HOOK_TIMER(ptr_hook, last_exec).tv_sec = tv_time.tv_sec;
+ HOOK_TIMER(ptr_hook, last_exec).tv_usec = tv_time.tv_usec;
+
+ util_timeval_add (&HOOK_TIMER(ptr_hook, next_exec),
+ HOOK_TIMER(ptr_hook, interval));
+
+ if (HOOK_TIMER(ptr_hook, remaining_calls) > 0)
{
- ptr_hook->running = 0;
- HOOK_TIMER(ptr_hook, last_exec).tv_sec = tv_time->tv_sec;
- HOOK_TIMER(ptr_hook, last_exec).tv_usec = tv_time->tv_usec;
- if (HOOK_TIMER(ptr_hook, remaining_calls) > 0)
- {
- HOOK_TIMER(ptr_hook, remaining_calls)--;
- if (HOOK_TIMER(ptr_hook, remaining_calls) == 0)
- unhook (ptr_hook);
- }
+ HOOK_TIMER(ptr_hook, remaining_calls)--;
+ if (HOOK_TIMER(ptr_hook, remaining_calls) == 0)
+ unhook (ptr_hook);
}
}
}
@@ -469,11 +577,10 @@ hook_search_fd (int fd)
{
struct t_hook *ptr_hook;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_FD]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_FD)
- && (HOOK_FD(ptr_hook, fd) == fd))
+ if (!ptr_hook->deleted && (HOOK_FD(ptr_hook, fd) == fd))
return ptr_hook;
}
@@ -505,7 +612,7 @@ hook_fd (void *plugin, int fd, int flags,
return NULL;
}
- hook_init (new_hook, plugin, HOOK_TYPE_FD, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_FD, callback_data);
new_hook->hook_data = new_hook_fd;
new_hook_fd->callback = callback;
@@ -530,10 +637,10 @@ hook_fd_set (fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
FD_ZERO (write_fds);
FD_ZERO (except_fds);
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_FD]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if (ptr_hook->type == HOOK_TYPE_FD)
+ if (!ptr_hook->deleted)
{
if (HOOK_FD(ptr_hook, flags) & HOOK_FD_FLAG_READ)
FD_SET (HOOK_FD(ptr_hook, fd), read_fds);
@@ -556,13 +663,13 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
hook_exec_recursion++;
- ptr_hook = weechat_hooks;
+ ptr_hook = weechat_hooks[HOOK_TYPE_FD];
while (ptr_hook)
{
next_hook = ptr_hook->next_hook;
- if ((ptr_hook->type == HOOK_TYPE_FD)
- && (!ptr_hook->running)
+ if (!ptr_hook->deleted
+ && !ptr_hook->running
&& (((HOOK_FD(ptr_hook, flags)& HOOK_FD_FLAG_READ)
&& (FD_ISSET(HOOK_FD(ptr_hook, fd), read_fds)))
|| ((HOOK_FD(ptr_hook, flags) & HOOK_FD_FLAG_WRITE)
@@ -572,8 +679,7 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
{
ptr_hook->running = 1;
(HOOK_FD(ptr_hook, callback)) (ptr_hook->callback_data);
- if (ptr_hook->type == HOOK_TYPE_FD)
- ptr_hook->running = 0;
+ ptr_hook->running = 0;
}
ptr_hook = next_hook;
@@ -607,7 +713,7 @@ hook_print (void *plugin, void *buffer, char *message, int strip_colors,
return NULL;
}
- hook_init (new_hook, plugin, HOOK_TYPE_PRINT, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_PRINT, callback_data);
new_hook->hook_data = new_hook_print;
new_hook_print->callback = callback;
@@ -632,10 +738,9 @@ hook_print_exec (void *buffer, time_t date, char *prefix, char *message)
if (!message || !message[0])
return;
-
- prefix_no_color = (char *)gui_color_decode ((unsigned char *)prefix);
- if (!prefix_no_color)
- return;
+
+ prefix_no_color = (prefix) ?
+ (char *)gui_color_decode ((unsigned char *)prefix) : NULL;
message_no_color = (char *)gui_color_decode ((unsigned char *)message);
if (!message_no_color)
@@ -646,13 +751,13 @@ hook_print_exec (void *buffer, time_t date, char *prefix, char *message)
hook_exec_recursion++;
- ptr_hook = weechat_hooks;
+ ptr_hook = weechat_hooks[HOOK_TYPE_PRINT];
while (ptr_hook)
{
next_hook = ptr_hook->next_hook;
- if ((ptr_hook->type == HOOK_TYPE_PRINT)
- && (!ptr_hook->running)
+ if (!ptr_hook->deleted
+ && !ptr_hook->running
&& (!HOOK_PRINT(ptr_hook, buffer)
|| ((struct t_gui_buffer *)buffer == HOOK_PRINT(ptr_hook, buffer)))
&& (!HOOK_PRINT(ptr_hook, message)
@@ -664,8 +769,7 @@ hook_print_exec (void *buffer, time_t date, char *prefix, char *message)
(ptr_hook->callback_data, buffer, date,
(HOOK_PRINT(ptr_hook, strip_colors)) ? prefix_no_color : prefix,
(HOOK_PRINT(ptr_hook, strip_colors)) ? message_no_color : message);
- if (ptr_hook->type == HOOK_TYPE_PRINT)
- ptr_hook->running = 0;
+ ptr_hook->running = 0;
}
ptr_hook = next_hook;
@@ -702,7 +806,7 @@ hook_signal (void *plugin, char *signal,
return NULL;
}
- hook_init (new_hook, plugin, HOOK_TYPE_SIGNAL, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_SIGNAL, callback_data);
new_hook->hook_data = new_hook_signal;
new_hook_signal->callback = callback;
@@ -724,21 +828,20 @@ hook_signal_exec (char *signal, void *pointer)
hook_exec_recursion++;
- ptr_hook = weechat_hooks;
+ ptr_hook = weechat_hooks[HOOK_TYPE_SIGNAL];
while (ptr_hook)
{
next_hook = ptr_hook->next_hook;
- if ((ptr_hook->type == HOOK_TYPE_SIGNAL)
- && (!ptr_hook->running)
+ if (!ptr_hook->deleted
+ && !ptr_hook->running
&& ((string_strcasecmp (HOOK_SIGNAL(ptr_hook, signal), "*") == 0)
|| (string_strcasecmp (HOOK_SIGNAL(ptr_hook, signal), signal) == 0)))
{
ptr_hook->running = 1;
(void) (HOOK_SIGNAL(ptr_hook, callback))
(ptr_hook->callback_data, signal, pointer);
- if (ptr_hook->type == HOOK_TYPE_SIGNAL)
- ptr_hook->running = 0;
+ ptr_hook->running = 0;
}
ptr_hook = next_hook;
@@ -772,7 +875,7 @@ hook_config (void *plugin, char *type, char *option,
return NULL;
}
- hook_init (new_hook, plugin, HOOK_TYPE_CONFIG, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_CONFIG, callback_data);
new_hook->hook_data = new_hook_config;
new_hook_config->callback = callback;
@@ -795,13 +898,13 @@ hook_config_exec (char *type, char *option, char *value)
hook_exec_recursion++;
- ptr_hook = weechat_hooks;
+ ptr_hook = weechat_hooks[HOOK_TYPE_CONFIG];
while (ptr_hook)
{
next_hook = ptr_hook->next_hook;
- if ((ptr_hook->type == HOOK_TYPE_CONFIG)
- && (!ptr_hook->running)
+ if (!ptr_hook->deleted
+ && !ptr_hook->running
&& (!HOOK_CONFIG(ptr_hook, type)
|| (string_strcasecmp (HOOK_CONFIG(ptr_hook, type),
type) == 0))
@@ -812,8 +915,7 @@ hook_config_exec (char *type, char *option, char *value)
ptr_hook->running = 1;
(void) (HOOK_CONFIG(ptr_hook, callback))
(ptr_hook->callback_data, type, option, value);
- if (ptr_hook->type == HOOK_TYPE_CONFIG)
- ptr_hook->running = 0;
+ ptr_hook->running = 0;
}
ptr_hook = next_hook;
@@ -850,7 +952,7 @@ hook_completion (void *plugin, char *completion,
return NULL;
}
- hook_init (new_hook, plugin, HOOK_TYPE_COMPLETION, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_COMPLETION, callback_data);
new_hook->hook_data = new_hook_completion;
new_hook_completion->callback = callback;
@@ -875,21 +977,20 @@ hook_completion_exec (void *plugin, char *completion, void *buffer, void *list)
hook_exec_recursion++;
- ptr_hook = weechat_hooks;
+ ptr_hook = weechat_hooks[HOOK_TYPE_COMPLETION];
while (ptr_hook)
{
next_hook = ptr_hook->next_hook;
- if ((ptr_hook->type == HOOK_TYPE_COMPLETION)
- && (!ptr_hook->running)
+ if (!ptr_hook->deleted
+ && !ptr_hook->running
&& (string_strcasecmp (HOOK_COMPLETION(ptr_hook, completion),
completion) == 0))
{
ptr_hook->running = 1;
(void) (HOOK_COMPLETION(ptr_hook, callback))
(ptr_hook->callback_data, completion, buffer, list);
- if (ptr_hook->type == HOOK_TYPE_COMPLETION)
- ptr_hook->running = 0;
+ ptr_hook->running = 0;
}
ptr_hook = next_hook;
@@ -911,23 +1012,23 @@ unhook (struct t_hook *hook)
{
struct t_hook *ptr_hook;
+ /* hook already deleted? */
+ if (hook->deleted)
+ return;
+
/* free data */
if (hook->hook_data)
{
switch (hook->type)
{
- case HOOK_TYPE_DELETED:
- /* hook will be deleted later, we do nothing here, hook data is
- already free */
- break;
case HOOK_TYPE_COMMAND:
/* decrease level for command hooks with same command name
and level higher than this one */
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook != hook)
- && (ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
+ && (ptr_hook != hook)
&& (string_strcasecmp (HOOK_COMMAND(ptr_hook, command),
HOOK_COMMAND(hook, command)) == 0)
&& (HOOK_COMMAND(ptr_hook, level) > HOOK_COMMAND(hook, level)))
@@ -975,6 +1076,10 @@ unhook (struct t_hook *hook)
free (HOOK_COMPLETION(hook, completion));
free ((struct t_hook_completion *)hook->hook_data);
break;
+ case HOOK_NUM_TYPES:
+ /* this constant is used to count types only,
+ it is never used as type */
+ break;
}
hook->hook_data = NULL;
}
@@ -987,7 +1092,8 @@ unhook (struct t_hook *hook)
else
{
/* there is one or more hook exec, then delete later */
- hook->type = HOOK_TYPE_DELETED;
+ hook->deleted = 1;
+ real_delete_pending = 1;
}
}
@@ -998,15 +1104,19 @@ unhook (struct t_hook *hook)
void
unhook_all_plugin (void *plugin)
{
+ int type;
struct t_hook *ptr_hook, *next_hook;
- ptr_hook = weechat_hooks;
- while (ptr_hook)
+ for (type = 0; type < HOOK_NUM_TYPES; type++)
{
- next_hook = ptr_hook->next_hook;
- if (ptr_hook->plugin == plugin)
- unhook (ptr_hook);
- ptr_hook = next_hook;
+ ptr_hook = weechat_hooks[type];
+ while (ptr_hook)
+ {
+ next_hook = ptr_hook->next_hook;
+ if (ptr_hook->plugin == plugin)
+ unhook (ptr_hook);
+ ptr_hook = next_hook;
+ }
}
}
@@ -1017,14 +1127,18 @@ unhook_all_plugin (void *plugin)
void
unhook_all ()
{
+ int type;
struct t_hook *ptr_hook, *next_hook;
- ptr_hook = weechat_hooks;
- while (ptr_hook)
+ for (type = 0; type < HOOK_NUM_TYPES; type++)
{
- next_hook = ptr_hook->next_hook;
- unhook (ptr_hook);
- ptr_hook = next_hook;
+ ptr_hook = weechat_hooks[type];
+ while (ptr_hook)
+ {
+ next_hook = ptr_hook->next_hook;
+ unhook (ptr_hook);
+ ptr_hook = next_hook;
+ }
}
}
@@ -1035,83 +1149,122 @@ unhook_all ()
void
hook_print_log ()
{
+ int type;
struct t_hook *ptr_hook;
+ struct tm *local_time;
+ char text_time[1024];
- for (ptr_hook = weechat_hooks; ptr_hook;
- ptr_hook = ptr_hook->next_hook)
+ for (type = 0; type < HOOK_NUM_TYPES; type++)
{
- log_printf ("");
- log_printf ("[hook (addr:0x%X)]", ptr_hook);
- log_printf (" plugin . . . . . . . . : 0x%X", ptr_hook->plugin);
- switch (ptr_hook->type)
+ for (ptr_hook = weechat_hooks[type]; ptr_hook;
+ ptr_hook = ptr_hook->next_hook)
{
- case HOOK_TYPE_DELETED:
- log_printf (" type . . . . . . . . . : %d (hook deleted)", ptr_hook->type);
- log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
- log_printf (" hook_data. . . . . . . : 0x%X", ptr_hook->hook_data);
- break;
- case HOOK_TYPE_COMMAND:
- log_printf (" type . . . . . . . . . : %d (command)", ptr_hook->type);
- log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
- log_printf (" command data:");
- log_printf (" callback . . . . . . : 0x%X", HOOK_COMMAND(ptr_hook, callback));
- log_printf (" command. . . . . . . : '%s'", HOOK_COMMAND(ptr_hook, command));
- log_printf (" level. . . . . . . . : %d", HOOK_COMMAND(ptr_hook, level));
- log_printf (" command_desc . . . . : '%s'", HOOK_COMMAND(ptr_hook, description));
- log_printf (" command_args . . . . : '%s'", HOOK_COMMAND(ptr_hook, args));
- log_printf (" command_args_desc. . : '%s'", HOOK_COMMAND(ptr_hook, args_description));
- log_printf (" command_completion . : '%s'", HOOK_COMMAND(ptr_hook, completion));
- break;
- case HOOK_TYPE_TIMER:
- log_printf (" type . . . . . . . . . : %d (timer)", ptr_hook->type);
- log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
- log_printf (" timer data:");
- log_printf (" callback . . . . . . : 0x%X", HOOK_TIMER(ptr_hook, callback));
- log_printf (" interval . . . . . . : %ld", HOOK_TIMER(ptr_hook, interval));
- log_printf (" last_exec.tv_sec . . : %ld", HOOK_TIMER(ptr_hook, last_exec.tv_sec));
- log_printf (" last_exec.tv_usec. . : %ld", HOOK_TIMER(ptr_hook, last_exec.tv_usec));
- break;
- case HOOK_TYPE_FD:
- log_printf (" type . . . . . . . . . : %d (fd)", ptr_hook->type);
- log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
- log_printf (" fd data:");
- log_printf (" callback . . . . . . : 0x%X", HOOK_FD(ptr_hook, callback));
- log_printf (" fd . . . . . . . . . : %ld", HOOK_FD(ptr_hook, fd));
- log_printf (" flags. . . . . . . . : %ld", HOOK_FD(ptr_hook, flags));
- break;
- case HOOK_TYPE_PRINT:
- log_printf (" type . . . . . . . . . : %d (print)", ptr_hook->type);
- log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
- log_printf (" print data:");
- log_printf (" callback . . . . . . : 0x%X", HOOK_PRINT(ptr_hook, callback));
- log_printf (" buffer . . . . . . . : 0x%X", HOOK_PRINT(ptr_hook, buffer));
- log_printf (" message. . . . . . . : '%s'", HOOK_PRINT(ptr_hook, message));
- break;
- case HOOK_TYPE_SIGNAL:
- log_printf (" type . . . . . . . . . : %d (signal)", ptr_hook->type);
- log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
- log_printf (" signal data:");
- log_printf (" callback . . . . . . : 0x%X", HOOK_SIGNAL(ptr_hook, callback));
- log_printf (" signal . . . . . . . : '%s'", HOOK_SIGNAL(ptr_hook, signal));
- break;
- case HOOK_TYPE_CONFIG:
- log_printf (" type . . . . . . . . . : %d (config)", ptr_hook->type);
- log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
- log_printf (" config data:");
- log_printf (" callback . . . . . . : 0x%X", HOOK_CONFIG(ptr_hook, callback));
- log_printf (" type . . . . . . . . : '%s'", HOOK_CONFIG(ptr_hook, type));
- log_printf (" option . . . . . . . : '%s'", HOOK_CONFIG(ptr_hook, option));
- break;
- case HOOK_TYPE_COMPLETION:
- log_printf (" type . . . . . . . . . : %d (completion)", ptr_hook->type);
- log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
- log_printf (" completion data:");
- log_printf (" callback . . . . . . : 0x%X", HOOK_COMPLETION(ptr_hook, callback));
- log_printf (" completion . . . . . : '%s'", HOOK_COMPLETION(ptr_hook, completion));
- break;
- }
- log_printf (" running. . . . . . . . : %d", ptr_hook->running);
- log_printf (" prev_hook. . . . . . . : 0x%X", ptr_hook->prev_hook);
- log_printf (" next_hook. . . . . . . : 0x%X", ptr_hook->next_hook);
+ log_printf ("");
+ log_printf ("[hook (addr:0x%X)]", ptr_hook);
+ log_printf (" plugin . . . . . . . . : 0x%X", ptr_hook->plugin);
+ log_printf (" deleted. . . . . . . . : %d", ptr_hook->deleted);
+ log_printf (" running. . . . . . . . : %d", ptr_hook->running);
+ switch (ptr_hook->type)
+ {
+ case HOOK_TYPE_COMMAND:
+ log_printf (" type . . . . . . . . . : %d (command)", ptr_hook->type);
+ log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
+ if (!ptr_hook->deleted)
+ {
+ log_printf (" command data:");
+ log_printf (" callback . . . . . . : 0x%X", HOOK_COMMAND(ptr_hook, callback));
+ log_printf (" command. . . . . . . : '%s'", HOOK_COMMAND(ptr_hook, command));
+ log_printf (" level. . . . . . . . : %d", HOOK_COMMAND(ptr_hook, level));
+ log_printf (" command_desc . . . . : '%s'", HOOK_COMMAND(ptr_hook, description));
+ log_printf (" command_args . . . . : '%s'", HOOK_COMMAND(ptr_hook, args));
+ log_printf (" command_args_desc. . : '%s'", HOOK_COMMAND(ptr_hook, args_description));
+ log_printf (" command_completion . : '%s'", HOOK_COMMAND(ptr_hook, completion));
+ }
+ break;
+ case HOOK_TYPE_TIMER:
+ log_printf (" type . . . . . . . . . : %d (timer)", ptr_hook->type);
+ log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
+ if (!ptr_hook->deleted)
+ {
+ log_printf (" timer data:");
+ log_printf (" callback . . . . . . : 0x%X", HOOK_TIMER(ptr_hook, callback));
+ log_printf (" interval . . . . . . : %ld", HOOK_TIMER(ptr_hook, interval));
+ local_time = localtime (&HOOK_TIMER(ptr_hook, last_exec).tv_sec);
+ strftime (text_time, sizeof (text_time),
+ "%d/%m/%Y %H:%M:%S", local_time);
+ log_printf (" last_exec.tv_sec . . : %ld (%s)",
+ HOOK_TIMER(ptr_hook, last_exec.tv_sec),
+ text_time);
+ log_printf (" last_exec.tv_usec. . : %ld", HOOK_TIMER(ptr_hook, last_exec.tv_usec));
+ local_time = localtime (&HOOK_TIMER(ptr_hook, next_exec).tv_sec);
+ strftime (text_time, sizeof (text_time),
+ "%d/%m/%Y %H:%M:%S", local_time);
+ log_printf (" next_exec.tv_sec . . : %ld (%s)",
+ HOOK_TIMER(ptr_hook, next_exec.tv_sec),
+ text_time);
+ log_printf (" next_exec.tv_usec. . : %ld", HOOK_TIMER(ptr_hook, next_exec.tv_usec));
+ }
+ break;
+ case HOOK_TYPE_FD:
+ log_printf (" type . . . . . . . . . : %d (fd)", ptr_hook->type);
+ log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
+ if (!ptr_hook->deleted)
+ {
+ log_printf (" fd data:");
+ log_printf (" callback . . . . . . : 0x%X", HOOK_FD(ptr_hook, callback));
+ log_printf (" fd . . . . . . . . . : %ld", HOOK_FD(ptr_hook, fd));
+ log_printf (" flags. . . . . . . . : %ld", HOOK_FD(ptr_hook, flags));
+ }
+ break;
+ case HOOK_TYPE_PRINT:
+ log_printf (" type . . . . . . . . . : %d (print)", ptr_hook->type);
+ log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
+ if (!ptr_hook->deleted)
+ {
+ log_printf (" print data:");
+ log_printf (" callback . . . . . . : 0x%X", HOOK_PRINT(ptr_hook, callback));
+ log_printf (" buffer . . . . . . . : 0x%X", HOOK_PRINT(ptr_hook, buffer));
+ log_printf (" message. . . . . . . : '%s'", HOOK_PRINT(ptr_hook, message));
+ }
+ break;
+ case HOOK_TYPE_SIGNAL:
+ log_printf (" type . . . . . . . . . : %d (signal)", ptr_hook->type);
+ log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
+ if (!ptr_hook->deleted)
+ {
+ log_printf (" signal data:");
+ log_printf (" callback . . . . . . : 0x%X", HOOK_SIGNAL(ptr_hook, callback));
+ log_printf (" signal . . . . . . . : '%s'", HOOK_SIGNAL(ptr_hook, signal));
+ }
+ break;
+ case HOOK_TYPE_CONFIG:
+ log_printf (" type . . . . . . . . . : %d (config)", ptr_hook->type);
+ log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
+ if (!ptr_hook->deleted)
+ {
+ log_printf (" config data:");
+ log_printf (" callback . . . . . . : 0x%X", HOOK_CONFIG(ptr_hook, callback));
+ log_printf (" type . . . . . . . . : '%s'", HOOK_CONFIG(ptr_hook, type));
+ log_printf (" option . . . . . . . : '%s'", HOOK_CONFIG(ptr_hook, option));
+ }
+ break;
+ case HOOK_TYPE_COMPLETION:
+ log_printf (" type . . . . . . . . . : %d (completion)", ptr_hook->type);
+ log_printf (" callback_data. . . . . : 0x%X", ptr_hook->callback_data);
+ if (!ptr_hook->deleted)
+ {
+ log_printf (" completion data:");
+ log_printf (" callback . . . . . . : 0x%X", HOOK_COMPLETION(ptr_hook, callback));
+ log_printf (" completion . . . . . : '%s'", HOOK_COMPLETION(ptr_hook, completion));
+ }
+ break;
+ case HOOK_NUM_TYPES:
+ /* this constant is used to count types only,
+ it is never used as type */
+ break;
+ }
+ log_printf (" prev_hook. . . . . . . : 0x%X", ptr_hook->prev_hook);
+ log_printf (" next_hook. . . . . . . : 0x%X", ptr_hook->next_hook);
+ }
}
}
diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h
index caeb5b822..09b5af483 100644
--- a/src/core/wee-hook.h
+++ b/src/core/wee-hook.h
@@ -24,14 +24,15 @@
enum t_hook_type
{
- HOOK_TYPE_DELETED = 0, /* used when hook is deleted */
- HOOK_TYPE_COMMAND, /* new command */
+ HOOK_TYPE_COMMAND = 0, /* new command */
HOOK_TYPE_TIMER, /* timer */
HOOK_TYPE_FD, /* socket of file descriptor */
HOOK_TYPE_PRINT, /* printed message */
HOOK_TYPE_SIGNAL, /* signal */
HOOK_TYPE_CONFIG, /* config option */
HOOK_TYPE_COMPLETION, /* custom completions */
+ /* number of hook types */
+ HOOK_NUM_TYPES,
};
#define HOOK_FD_FLAG_READ 1
@@ -52,12 +53,12 @@ struct t_hook
struct t_weechat_plugin *plugin; /* plugin which created this hook */
/* (NULL for hook created by WeeChat)*/
enum t_hook_type type; /* hook type */
+ int deleted; /* hook marked for deletion ? */
+ int running; /* 1 if hook is currently running */
void *callback_data; /* data sent to callback */
-
+
/* hook data (depends on hook type) */
void *hook_data; /* hook specific data */
-
- int running; /* 1 if hook is currently running */
struct t_hook *prev_hook; /* link to previous hook */
struct t_hook *next_hook; /* link to next hook */
};
@@ -84,6 +85,7 @@ struct t_hook_timer
long interval; /* timer interval (milliseconds) */
int remaining_calls; /* calls remaining (0 = unlimited) */
struct timeval last_exec; /* last time hook was executed */
+ struct timeval next_exec; /* next scheduled execution */
};
typedef int (t_hook_callback_fd)(void *);
@@ -133,20 +135,22 @@ struct t_hook_completion
/* hook variables */
-extern struct t_hook *weechat_hooks;
-extern struct t_hook *last_weechat_hook;
+extern struct t_hook *weechat_hooks[];
+extern struct t_hook *last_weechat_hook[];
/* hook functions */
+extern void hook_init ();
extern int hook_valid (struct t_hook *);
extern int hook_valid_for_plugin (void *, struct t_hook *);
extern struct t_hook *hook_command (void *, char *, char *, char *, char *,
char *, t_hook_callback_command *, void *);
extern int hook_command_exec (void *, char *, int);
-extern struct t_hook *hook_timer (void *, long, int, t_hook_callback_timer *,
- void *);
-extern void hook_timer_exec (struct timeval *);
+extern struct t_hook *hook_timer (void *, long, int, int,
+ t_hook_callback_timer *, void *);
+extern int hook_timer_time_to_next (struct timeval *);
+extern void hook_timer_exec ();
extern struct t_hook *hook_fd (void *, int, int, t_hook_callback_fd *,void *);
extern void hook_fd_set (fd_set *, fd_set *, fd_set *);
extern void hook_fd_exec (fd_set *, fd_set *, fd_set *);
diff --git a/src/core/wee-util.c b/src/core/wee-util.c
index b9238e5d3..e737c7592 100644
--- a/src/core/wee-util.c
+++ b/src/core/wee-util.c
@@ -37,6 +37,27 @@
/*
+ * util_timeval_cmp: compare two timeval structures
+ * return: -1 if tv1 < tv2
+ * 0 if tv1 == tv2
+ * 1 if tv1 > tv2
+ */
+
+int
+util_timeval_cmp (struct timeval *tv1, struct timeval *tv2)
+{
+ if (tv1->tv_sec < tv2->tv_sec)
+ return -1;
+ if (tv1->tv_sec > tv2->tv_sec)
+ return 1;
+ if (tv1->tv_usec < tv2->tv_usec)
+ return -1;
+ if (tv1->tv_usec > tv2->tv_usec)
+ return 1;
+ return 0;
+}
+
+/*
* util_timeval_diff: calculates difference between two times (return in
* milliseconds)
*/
@@ -58,6 +79,26 @@ util_timeval_diff (struct timeval *tv1, struct timeval *tv2)
}
/*
+ * util_timeval_add: add interval (in milliseconds) to a timeval struct
+ */
+
+void
+util_timeval_add (struct timeval *tv, long interval)
+{
+ long usec;
+
+ tv->tv_sec += (interval / 1000);
+ usec = tv->tv_usec + ((interval % 1000) * 1000);
+ if (usec > 1000000)
+ {
+ tv->tv_usec = usec % 1000000;
+ tv->tv_sec++;
+ }
+ else
+ tv->tv_usec = usec;
+}
+
+/*
* util_get_time_length: calculates time length with a time format
*/
diff --git a/src/core/wee-util.h b/src/core/wee-util.h
index db61830f4..504c0377f 100644
--- a/src/core/wee-util.h
+++ b/src/core/wee-util.h
@@ -20,7 +20,9 @@
#ifndef __WEECHAT_UTIL_H
#define __WEECHAT_UTIL_H 1
+extern int util_timeval_cmp (struct timeval *, struct timeval *);
extern long util_timeval_diff (struct timeval *, struct timeval *);
+extern void util_timeval_add (struct timeval *, long);
extern int util_get_time_length (char *);
extern int util_create_dir (char *, int);
extern void util_exec_on_files (char *, int (*)(char *));
diff --git a/src/core/weechat.c b/src/core/weechat.c
index bbbea7fec..8d6a74d9e 100644
--- a/src/core/weechat.c
+++ b/src/core/weechat.c
@@ -586,6 +586,7 @@ main (int argc, char *argv[])
signal (SIGQUIT, SIG_IGN); /* ignore SIGQUIT signal */
signal (SIGPIPE, SIG_IGN); /* ignore SIGPIPE signal */
signal (SIGSEGV, weechat_sigsegv); /* crash dump when SIGSEGV received */
+ hook_init (); /* initialize hooks */
gui_main_pre_init (&argc, &argv); /* pre-initiliaze interface */
weechat_init_vars (); /* initialize some variables */
command_init (); /* initialize WeeChat commands */
diff --git a/src/gui/curses/gui-curses-infobar.c b/src/gui/curses/gui-curses-infobar.c
index eec538c4b..c26db5840 100644
--- a/src/gui/curses/gui-curses-infobar.c
+++ b/src/gui/curses/gui-curses-infobar.c
@@ -28,7 +28,9 @@
#include "../../core/weechat.h"
#include "../../core/wee-config.h"
+#include "../../core/wee-hook.h"
#include "../../core/wee-string.h"
+#include "../../plugins/plugin.h"
#include "../gui-infobar.h"
#include "../gui-color.h"
#include "../gui-main.h"
@@ -146,3 +148,56 @@ gui_infobar_draw (struct t_gui_buffer *buffer, int erase)
refresh ();
}
}
+
+/*
+ * gui_infobar_refresh_timer_cb: timer callback for refresh of infobar
+ */
+
+int
+gui_infobar_refresh_timer_cb (void *data)
+{
+ /* make C compiler happy */
+ (void) data;
+
+ if (gui_ok)
+ {
+ if (data)
+ gui_infobar_draw (gui_current_window->buffer, 1);
+ else
+ gui_infobar_draw_time (gui_current_window->buffer);
+ wmove (GUI_CURSES(gui_current_window)->win_input,
+ 0, gui_current_window->win_input_cursor_x);
+ wrefresh (GUI_CURSES(gui_current_window)->win_input);
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * gui_infobar_highlight_timer_cb: timer callback for highlights in infobar
+ */
+
+int
+gui_infobar_highlight_timer_cb (void *data)
+{
+ /* make C compiler happy */
+ (void) data;
+
+ if (gui_ok)
+ {
+ if (gui_infobar && gui_infobar->remaining_time > 0)
+ {
+ gui_infobar->remaining_time--;
+ if (gui_infobar->remaining_time == 0)
+ {
+ gui_infobar_remove ();
+ gui_infobar_draw (gui_current_window->buffer, 1);
+ }
+ }
+ /* remove this timer if there's no more data for infobar */
+ if (!gui_infobar)
+ unhook (gui_infobar_highlight_timer);
+ }
+
+ return WEECHAT_RC_OK;
+}
diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c
index a885dafc5..eebdade5c 100644
--- a/src/gui/curses/gui-curses-main.c
+++ b/src/gui/curses/gui-curses-main.c
@@ -42,8 +42,6 @@
#include "../gui-infobar.h"
#include "../gui-input.h"
#include "../gui-history.h"
-#include "../gui-hotlist.h"
-#include "../gui-keyboard.h"
#include "../gui-window.h"
#include "gui-curses.h"
@@ -131,34 +129,28 @@ gui_main_quit ()
void
gui_main_loop ()
{
- fd_set read_fds, write_fds, except_fds;
- static struct timeval timeout;
struct t_gui_buffer *ptr_buffer;
- int old_day, old_min, old_sec;
- char text_time[1024], *text_time2;
- struct timeval tv_time;
- struct tm *local_time;
+ struct timeval tv_timeout;
+ fd_set read_fds, write_fds, except_fds;
quit_weechat = 0;
- gettimeofday (&tv_time, NULL);
- gui_keyboard_last_activity_time = tv_time.tv_sec;
- local_time = localtime (&tv_time.tv_sec);
- old_day = local_time->tm_mday;
-
- old_min = -1;
- old_sec = -1;
-
/* if SIGTERM or SIGHUP received => quit */
signal (SIGTERM, gui_main_quit);
signal (SIGHUP, gui_main_quit);
while (!quit_weechat)
{
+ /* execute hook timers */
+ hook_timer_exec ();
+
+ /* infobar count down */
+
+
/* refresh needed ? */
if (gui_refresh_screen_needed)
gui_window_refresh_screen (0);
-
+
for (ptr_buffer = gui_buffers; ptr_buffer;
ptr_buffer = ptr_buffer->next_buffer)
{
@@ -169,114 +161,22 @@ gui_main_loop ()
}
}
- gettimeofday (&tv_time, NULL);
- local_time = localtime (&tv_time.tv_sec);
-
- /* execute hook timers */
- hook_timer_exec (&tv_time);
-
- /* minute has changed ? => redraw infobar */
- if (local_time->tm_min != old_min)
- {
- old_min = local_time->tm_min;
- gui_infobar_draw (gui_current_window->buffer, 1);
-
- if (CONFIG_BOOLEAN(config_look_day_change)
- && (local_time->tm_mday != old_day))
- {
- strftime (text_time, sizeof (text_time),
- CONFIG_STRING(config_look_day_change_time_format),
- local_time);
- text_time2 = string_iconv_to_internal (NULL, text_time);
- gui_add_hotlist = 0;
- for (ptr_buffer = gui_buffers; ptr_buffer;
- ptr_buffer = ptr_buffer->next_buffer)
- {
- if (ptr_buffer->type == GUI_BUFFER_TYPE_FORMATED)
- gui_chat_printf (ptr_buffer,
- _("\t\tDay changed to %s"),
- (text_time2) ?
- text_time2 : text_time);
- }
- if (text_time2)
- free (text_time2);
- gui_add_hotlist = 1;
- }
- old_day = local_time->tm_mday;
- }
-
- /* second has changed ? */
- if (local_time->tm_sec != old_sec)
- {
- old_sec = local_time->tm_sec;
-
- /* display time in infobar (if seconds displayed) */
- if (CONFIG_BOOLEAN(config_look_infobar_seconds))
- {
- gui_infobar_draw_time (gui_current_window->buffer);
- wmove (GUI_CURSES(gui_current_window)->win_input,
- 0, gui_current_window->win_input_cursor_x);
- wrefresh (GUI_CURSES(gui_current_window)->win_input);
- }
-
- /* infobar count down */
- if (gui_infobar && gui_infobar->remaining_time > 0)
- {
- gui_infobar->remaining_time--;
- if (gui_infobar->remaining_time == 0)
- {
- gui_infobar_remove ();
- gui_infobar_draw (gui_current_window->buffer, 1);
- }
- }
- }
-
- /* read keyboard */
-
- /* on GNU/Hurd 2 select() are causing troubles with keyboard */
- /* waiting for a fix, we use only one select() */
-#ifndef __GNU__
+ /* wait for keyboard or network activity */
FD_ZERO (&read_fds);
- timeout.tv_sec = 0;
- timeout.tv_usec = 8000;
-
- FD_SET (STDIN_FILENO, &read_fds);
-
- if (select (FD_SETSIZE, &read_fds, NULL, NULL, &timeout) > 0)
- {
- if (FD_ISSET (STDIN_FILENO, &read_fds))
- {
- gui_keyboard_read ();
- }
- }
- else
- gui_keyboard_flush ();
-#endif
-
- /* read sockets/files/pipes */
+ FD_ZERO (&write_fds);
+ FD_ZERO (&except_fds);
hook_fd_set (&read_fds, &write_fds, &except_fds);
-
-#ifdef __GNU__
- timeout.tv_sec = 0;
- timeout.tv_usec = 10000;
FD_SET (STDIN_FILENO, &read_fds);
-#else
- timeout.tv_sec = 0;
- timeout.tv_usec = 2000;
-#endif
-
- if (select (FD_SETSIZE,
- &read_fds, &write_fds, &except_fds,
- &timeout) > 0)
+ if (hook_timer_time_to_next (&tv_timeout))
+ select (FD_SETSIZE, &read_fds, &write_fds, &except_fds, &tv_timeout);
+ else
+ select (FD_SETSIZE, &read_fds, &write_fds, &except_fds, NULL);
+ if (FD_ISSET (STDIN_FILENO, &read_fds))
{
-#ifdef __GNU__
- if (FD_ISSET (STDIN_FILENO, &read_fds))
- {
- gui_keyboard_read ();
- }
-#endif
- hook_fd_exec (&read_fds, &write_fds, &except_fds);
+ gui_keyboard_read ();
+ gui_keyboard_flush ();
}
+ hook_fd_exec (&read_fds, &write_fds, &except_fds);
}
}
diff --git a/src/gui/gtk/gui-gtk-infobar.c b/src/gui/gtk/gui-gtk-infobar.c
index b6bcafd33..4cbc5889e 100644
--- a/src/gui/gtk/gui-gtk-infobar.c
+++ b/src/gui/gtk/gui-gtk-infobar.c
@@ -28,6 +28,7 @@
#include "../../core/weechat.h"
#include "../../core/wee-config.h"
+#include "../../plugins/plugin.h"
#include "../gui-infobar.h"
#include "../gui-window.h"
#include "gui-gtk.h"
@@ -76,3 +77,29 @@ gui_infobar_draw (struct t_gui_buffer *buffer, int erase)
(void) buffer;
(void) erase;
}
+
+/*
+ * gui_infobar_refresh_timer_cb: timer callback for refresh of infobar
+ */
+
+int
+gui_infobar_refresh_timer_cb (void *data)
+{
+ /* make C compiler happy */
+ (void) data;
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * gui_infobar_highlight_timer_cb: timer callback for highlights in infobar
+ */
+
+int
+gui_infobar_highlight_timer_cb (void *data)
+{
+ /* make C compiler happy */
+ (void) data;
+
+ return WEECHAT_RC_OK;
+}
diff --git a/src/gui/gui-completion.c b/src/gui/gui-completion.c
index 32dd8015d..3689830ed 100644
--- a/src/gui/gui-completion.c
+++ b/src/gui/gui-completion.c
@@ -135,10 +135,10 @@ gui_completion_search_command (struct t_gui_completion *completion)
{
struct t_hook *ptr_hook;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& HOOK_COMMAND(ptr_hook, command)
&& HOOK_COMMAND(ptr_hook, command)[0]
&& (HOOK_COMMAND(ptr_hook, level) == 0)
@@ -382,10 +382,10 @@ gui_completion_list_add_command_hooks (struct t_gui_completion *completion)
{
struct t_hook *ptr_hook;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& (HOOK_COMMAND(ptr_hook, command))
&& (HOOK_COMMAND(ptr_hook, command)[0]))
gui_completion_list_add (completion,
@@ -592,10 +592,10 @@ gui_completion_list_add_weechat_cmd (struct t_gui_completion *completion)
{
struct t_hook *ptr_hook;
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& !ptr_hook->plugin
&& HOOK_COMMAND(ptr_hook, command)
&& HOOK_COMMAND(ptr_hook, command)[0])
@@ -939,10 +939,10 @@ gui_completion_command (struct t_gui_completion *completion)
other_completion = 0;
if (!completion->completion_list->items)
{
- for (ptr_hook = weechat_hooks; ptr_hook;
+ for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
ptr_hook = ptr_hook->next_hook)
{
- if ((ptr_hook->type == HOOK_TYPE_COMMAND)
+ if (!ptr_hook->deleted
&& HOOK_COMMAND(ptr_hook, command)
&& HOOK_COMMAND(ptr_hook, command)[0]
&& (HOOK_COMMAND(ptr_hook, level) == 0))
diff --git a/src/gui/gui-infobar.c b/src/gui/gui-infobar.c
index 99391f8ce..2f29dd5a8 100644
--- a/src/gui/gui-infobar.c
+++ b/src/gui/gui-infobar.c
@@ -28,13 +28,16 @@
#include <stdarg.h>
#include "../core/weechat.h"
+#include "../core/wee-hook.h"
#include "../core/wee-log.h"
#include "gui-infobar.h"
#include "gui-color.h"
#include "gui-window.h"
-struct t_gui_infobar *gui_infobar; /* pointer to infobar content */
+struct t_gui_infobar *gui_infobar = NULL; /* infobar content */
+struct t_hook *gui_infobar_refresh_timer = NULL; /* refresh timer */
+struct t_hook *gui_infobar_highlight_timer = NULL; /* highlight timer */
/*
@@ -73,6 +76,11 @@ gui_infobar_printf (int time_displayed, int color, char *message, ...)
gui_infobar_draw (gui_current_window->buffer, 1);
if (buf2)
free (buf2);
+
+ if (!gui_infobar_highlight_timer)
+ gui_infobar_highlight_timer = hook_timer (NULL, 1 * 1000, 0, 0,
+ &gui_infobar_highlight_timer_cb,
+ NULL);
}
else
log_printf (_("Error: not enough memory for infobar message"));
diff --git a/src/gui/gui-infobar.h b/src/gui/gui-infobar.h
index 4e2c776ba..080c02110 100644
--- a/src/gui/gui-infobar.h
+++ b/src/gui/gui-infobar.h
@@ -35,6 +35,8 @@ struct t_gui_infobar
/* infobar variables */
extern struct t_gui_infobar *gui_infobar;
+extern struct t_hook *gui_infobar_refresh_timer;
+extern struct t_hook *gui_infobar_highlight_timer;
/* infobar functions */
@@ -46,5 +48,7 @@ extern void gui_infobar_remove_all ();
extern void gui_infobar_draw_time (struct t_gui_buffer *);
extern void gui_infobar_draw (struct t_gui_buffer *, int);
+extern int gui_infobar_refresh_timer_cb (void *);
+extern int gui_infobar_highlight_timer_cb (void *);
#endif /* gui-infobar.h */
diff --git a/src/gui/gui-keyboard.c b/src/gui/gui-keyboard.c
index d80b7a670..edc519042 100644
--- a/src/gui/gui-keyboard.c
+++ b/src/gui/gui-keyboard.c
@@ -180,6 +180,20 @@ gui_keyboard_init ()
}
/*
+ * gui_keyboard_init_last_activity_time: init last activity time with current
+ * time
+ */
+
+void
+gui_keyboard_init_last_activity_time ()
+{
+ struct timeval tv_time;
+
+ gettimeofday (&tv_time, NULL);
+ gui_keyboard_last_activity_time = tv_time.tv_sec;
+}
+
+/*
* gui_keyboard_grab_init: init "grab" mode
*/
diff --git a/src/plugins/demo/demo.c b/src/plugins/demo/demo.c
index 186f95218..dd3ce4161 100644
--- a/src/plugins/demo/demo.c
+++ b/src/plugins/demo/demo.c
@@ -82,6 +82,26 @@ demo_printf_command_cb (void *data, void *buffer, int argc, char **argv,
}
/*
+ * demo_infobar_command_cb: demo command for infobar
+ */
+
+int
+demo_infobar_command_cb (void *data, void *buffer, int argc, char **argv,
+ char **argv_eol)
+{
+ /* make C compiler happy */
+ (void) data;
+ (void) buffer;
+ (void) argv;
+
+ weechat_infobar_printf (10, NULL,
+ (argc > 1) ?
+ argv_eol[1] : _("test infobar"));
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* demo_buffer_input_data_cb: callback for input data on buffer
*/
@@ -286,6 +306,14 @@ weechat_plugin_init (struct t_weechat_plugin *plugin)
"",
&demo_printf_command_cb, NULL);
+ weechat_hook_command ("demo_infobar",
+ _("demo command: print a message in infobar for 10 "
+ "seconds"),
+ _("[text]"),
+ _("text: write this text on infobar"),
+ "",
+ &demo_infobar_command_cb, NULL);
+
weechat_hook_command ("demo_buffer",
_("open a new buffer"),
_("category name"),
diff --git a/src/plugins/plugin-api.c b/src/plugins/plugin-api.c
index 0e5386f1d..d2afc619f 100644
--- a/src/plugins/plugin-api.c
+++ b/src/plugins/plugin-api.c
@@ -1255,9 +1255,15 @@ plugin_api_infobar_printf (struct t_weechat_plugin *plugin, int time_displayed,
va_end (argptr);
buf2 = string_iconv_to_internal (plugin->charset, buf);
- num_color = gui_color_search_config (color_name);
- if (num_color < 0)
+ if (color_name && color_name[0])
+ {
+ num_color = gui_color_search_config (color_name);
+ if (num_color < 0)
+ num_color = GUI_COLOR_INFOBAR;
+ }
+ else
num_color = GUI_COLOR_INFOBAR;
+
gui_infobar_printf (time_displayed,
num_color,
"%s",
@@ -1314,10 +1320,12 @@ plugin_api_hook_command (struct t_weechat_plugin *plugin, char *command,
struct t_hook *
plugin_api_hook_timer (struct t_weechat_plugin *plugin, long interval,
- int max_calls, int (*callback)(void *), void *data)
+ int align_second, int max_calls,
+ int (*callback)(void *), void *data)
{
if (plugin && (interval > 0) && callback)
- return hook_timer (plugin, interval, max_calls, callback, data);
+ return hook_timer (plugin, interval, align_second, max_calls,
+ callback, data);
return NULL;
}
diff --git a/src/plugins/plugin-api.h b/src/plugins/plugin-api.h
index d4e8c4777..ef1c31553 100644
--- a/src/plugins/plugin-api.h
+++ b/src/plugins/plugin-api.h
@@ -147,7 +147,7 @@ extern struct t_hook *plugin_api_hook_command (struct t_weechat_plugin *,
int (*)(void *, void *, int, char **, char **),
void *);
extern struct t_hook *plugin_api_hook_timer (struct t_weechat_plugin *,
- long, int,
+ long, int, int,
int (*)(void *), void *);
extern struct t_hook *plugin_api_hook_fd (struct t_weechat_plugin *,
int, int, int, int,
diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h
index e73755310..d03d0535f 100644
--- a/src/plugins/weechat-plugin.h
+++ b/src/plugins/weechat-plugin.h
@@ -160,7 +160,7 @@ struct t_weechat_plugin
char *, char *, char *,
int (*)(void *, void *, int, char **, char **),
void *);
- struct t_hook *(*hook_timer) (struct t_weechat_plugin *, long, int,
+ struct t_hook *(*hook_timer) (struct t_weechat_plugin *, long, int, int,
int (*)(void *), void *);
struct t_hook *(*hook_fd) (struct t_weechat_plugin *, int, int, int, int,
int (*)(void *), void *);
@@ -407,8 +407,10 @@ struct t_weechat_plugin
weechat_plugin->hook_command(weechat_plugin, __command, __description, \
__args, __args_desc, __completion, \
__callback, __data)
-#define weechat_hook_timer(__interval, __max_calls, __callback, __data) \
- weechat_plugin->hook_timer(weechat_plugin, __interval, __max_calls, \
+#define weechat_hook_timer(__interval, __align_second, __max_calls, \
+ __callback, __data) \
+ weechat_plugin->hook_timer(weechat_plugin, __interval, \
+ __align_second, __max_calls, \
__callback, __data)
#define weechat_hook_fd(__fd, __flag_read, __flag_write, \
__flag_exception, __callback, __data) \