1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-07 02:03:13 +02:00

Improved main loop (less CPU usage), better precision for timers, use of one list by hook type (for fast search in hooks)

This commit is contained in:
Sebastien Helleu
2007-12-14 17:01:02 +01:00
parent 70e44d3c54
commit e62ec5204c
19 changed files with 730 additions and 387 deletions
+2 -1
View File
@@ -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,
+22 -29
View File
@@ -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)
+105 -3
View File
@@ -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
@@ -317,6 +325,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;
}
/*
+360 -207
View File
@@ -38,11 +38,28 @@
#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->callback_data = callback_data;
hook->hook_data = NULL;
hook->deleted = 0;
hook->running = 0;
hook->callback_data = callback_data;
hook->hook_data = NULL;
}
/*
@@ -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,57 +427,133 @@ 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);
return new_hook;
}
/*
* 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);
}
}
}
+14 -10
View File
@@ -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 *);
+41
View File
@@ -36,6 +36,27 @@
#include "wee-string.h"
/*
* 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)
@@ -57,6 +78,26 @@ util_timeval_diff (struct timeval *tv1, struct timeval *tv2)
return ((diff_usec / 1000) + (diff_sec * 1000));
}
/*
* 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
*/
+2
View File
@@ -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 *));
+1
View File
@@ -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 */
+55
View File
@@ -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;
}
+20 -120
View File
@@ -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);
}
}
+27
View File
@@ -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;
}
+8 -8
View File
@@ -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))
+9 -1
View File
@@ -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"));
+4
View File
@@ -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 */
+14
View File
@@ -179,6 +179,20 @@ gui_keyboard_init ()
gui_keyboard_default_bindings ();
}
/*
* 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
*/
+28
View File
@@ -81,6 +81,26 @@ demo_printf_command_cb (void *data, void *buffer, int argc, char **argv,
return WEECHAT_RC_OK;
}
/*
* 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"),
+12 -4
View File
@@ -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;
}
+1 -1
View File
@@ -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,
+5 -3
View File
@@ -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) \