diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/wee-hook.c | 96 | ||||
-rw-r--r-- | src/core/wee-hook.h | 20 | ||||
-rw-r--r-- | src/plugins/plugin.c | 2 | ||||
-rw-r--r-- | src/plugins/scripts/lua/weechat-lua-api.c | 131 | ||||
-rw-r--r-- | src/plugins/scripts/perl/weechat-perl-api.c | 117 | ||||
-rw-r--r-- | src/plugins/scripts/python/weechat-python-api.c | 124 | ||||
-rw-r--r-- | src/plugins/scripts/ruby/weechat-ruby-api.c | 132 | ||||
-rw-r--r-- | src/plugins/scripts/script-api.c | 37 | ||||
-rw-r--r-- | src/plugins/scripts/script-api.h | 8 | ||||
-rw-r--r-- | src/plugins/scripts/tcl/weechat-tcl-api.c | 125 | ||||
-rw-r--r-- | src/plugins/weechat-plugin.h | 15 |
11 files changed, 804 insertions, 3 deletions
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c index d49732ff4..dc0726231 100644 --- a/src/core/wee-hook.c +++ b/src/core/wee-hook.c @@ -53,8 +53,8 @@ char *hook_type_string[HOOK_NUM_TYPES] = { "command", "command_run", "timer", "fd", "process", "connect", "print", - "signal", "config", "completion", "modifier", "info", "info_hashtable", - "infolist" }; + "signal", "hsignal", "config", "completion", "modifier", + "info", "info_hashtable", "infolist" }; struct t_hook *weechat_hooks[HOOK_NUM_TYPES]; /* list of hooks */ struct t_hook *last_weechat_hook[HOOK_NUM_TYPES]; /* last hook */ int hook_exec_recursion = 0; /* 1 when a hook is executed */ @@ -1876,6 +1876,77 @@ hook_signal_send (const char *signal, const char *type_data, void *signal_data) } /* + * hook_hsignal: hook a hsignal (signal with hashtable) + */ + +struct t_hook * +hook_hsignal (struct t_weechat_plugin *plugin, const char *signal, + t_hook_callback_hsignal *callback, void *callback_data) +{ + struct t_hook *new_hook; + struct t_hook_hsignal *new_hook_hsignal; + int priority; + const char *ptr_signal; + + if (!signal || !signal[0] || !callback) + return NULL; + + new_hook = malloc (sizeof (*new_hook)); + if (!new_hook) + return NULL; + new_hook_hsignal = malloc (sizeof (*new_hook_hsignal)); + if (!new_hook_hsignal) + { + free (new_hook); + return NULL; + } + + hook_get_priority_and_name (signal, &priority, &ptr_signal); + hook_init_data (new_hook, plugin, HOOK_TYPE_HSIGNAL, priority, + callback_data); + + new_hook->hook_data = new_hook_hsignal; + new_hook_hsignal->callback = callback; + new_hook_hsignal->signal = strdup ((ptr_signal) ? ptr_signal : signal); + + hook_add_to_list (new_hook); + + return new_hook; +} + +/* + * hook_hsignal_send: send a hsignal (signal with hashtable) + */ + +void +hook_hsignal_send (const char *signal, struct t_hashtable *hashtable) +{ + struct t_hook *ptr_hook, *next_hook; + + hook_exec_start (); + + ptr_hook = weechat_hooks[HOOK_TYPE_HSIGNAL]; + while (ptr_hook) + { + next_hook = ptr_hook->next_hook; + + if (!ptr_hook->deleted + && !ptr_hook->running + && (string_match (signal, HOOK_HSIGNAL(ptr_hook, signal), 0))) + { + ptr_hook->running = 1; + (void) (HOOK_HSIGNAL(ptr_hook, callback)) + (ptr_hook->callback_data, signal, hashtable); + ptr_hook->running = 0; + } + + ptr_hook = next_hook; + } + + hook_exec_end (); +} + +/* * hook_config: hook a config option */ @@ -2553,6 +2624,10 @@ unhook (struct t_hook *hook) if (HOOK_SIGNAL(hook, signal)) free (HOOK_SIGNAL(hook, signal)); break; + case HOOK_TYPE_HSIGNAL: + if (HOOK_HSIGNAL(hook, signal)) + free (HOOK_HSIGNAL(hook, signal)); + break; case HOOK_TYPE_CONFIG: if (HOOK_CONFIG(hook, option)) free (HOOK_CONFIG(hook, option)); @@ -2865,6 +2940,15 @@ hook_add_to_infolist_type (struct t_infolist *infolist, return 0; } break; + case HOOK_TYPE_HSIGNAL: + if (!ptr_hook->deleted) + { + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_HSIGNAL(ptr_hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "signal", HOOK_HSIGNAL(ptr_hook, signal))) + return 0; + } + break; case HOOK_TYPE_CONFIG: if (!ptr_hook->deleted) { @@ -3181,6 +3265,14 @@ hook_print_log () log_printf (" signal. . . . . . . . : '%s'", HOOK_SIGNAL(ptr_hook, signal)); } break; + case HOOK_TYPE_HSIGNAL: + if (!ptr_hook->deleted) + { + log_printf (" signal data:"); + log_printf (" callback. . . . . . . : 0x%lx", HOOK_HSIGNAL(ptr_hook, callback)); + log_printf (" signal. . . . . . . . : '%s'", HOOK_HSIGNAL(ptr_hook, signal)); + } + break; case HOOK_TYPE_CONFIG: if (!ptr_hook->deleted) { diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h index 2e2b735d6..c849b36af 100644 --- a/src/core/wee-hook.h +++ b/src/core/wee-hook.h @@ -43,6 +43,7 @@ enum t_hook_type HOOK_TYPE_CONNECT, /* connect to peer with fork */ HOOK_TYPE_PRINT, /* printed message */ HOOK_TYPE_SIGNAL, /* signal */ + HOOK_TYPE_HSIGNAL, /* signal (using hashtable) */ HOOK_TYPE_CONFIG, /* config option */ HOOK_TYPE_COMPLETION, /* custom completions */ HOOK_TYPE_MODIFIER, /* string modifier */ @@ -76,6 +77,7 @@ enum t_hook_type #define HOOK_CONNECT(hook, var) (((struct t_hook_connect *)hook->hook_data)->var) #define HOOK_PRINT(hook, var) (((struct t_hook_print *)hook->hook_data)->var) #define HOOK_SIGNAL(hook, var) (((struct t_hook_signal *)hook->hook_data)->var) +#define HOOK_HSIGNAL(hook, var) (((struct t_hook_hsignal *)hook->hook_data)->var) #define HOOK_CONFIG(hook, var) (((struct t_hook_config *)hook->hook_data)->var) #define HOOK_COMPLETION(hook, var) (((struct t_hook_completion *)hook->hook_data)->var) #define HOOK_MODIFIER(hook, var) (((struct t_hook_modifier *)hook->hook_data)->var) @@ -252,6 +254,18 @@ struct t_hook_signal /* with "*", "*" == any signal) */ }; +/* hook hsignal */ + +typedef int (t_hook_callback_hsignal)(void *data, const char *signal, + struct t_hashtable *hashtable); + +struct t_hook_hsignal +{ + t_hook_callback_hsignal *callback; /* signal callback */ + char *signal; /* signal selected (may begin or end */ + /* with "*", "*" == any signal) */ +}; + /* hook config */ typedef int (t_hook_callback_config)(void *data, const char *option, @@ -409,6 +423,12 @@ extern struct t_hook *hook_signal (struct t_weechat_plugin *plugin, void *callback_data); extern void hook_signal_send (const char *signal, const char *type_data, void *signal_data); +extern struct t_hook *hook_hsignal (struct t_weechat_plugin *plugin, + const char *signal, + t_hook_callback_hsignal *callback, + void *callback_data); +extern void hook_hsignal_send (const char *signal, + struct t_hashtable *hashtable); extern struct t_hook *hook_config (struct t_weechat_plugin *plugin, const char *option, t_hook_callback_config *callback, diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 564f16065..c0cb75a44 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -588,6 +588,8 @@ plugin_load (const char *filename) new_plugin->hook_print = &hook_print; new_plugin->hook_signal = &hook_signal; new_plugin->hook_signal_send = &hook_signal_send; + new_plugin->hook_hsignal = &hook_hsignal; + new_plugin->hook_hsignal_send = &hook_hsignal_send; new_plugin->hook_config = &hook_config; new_plugin->hook_completion = &hook_completion; new_plugin->hook_completion_list_add = &hook_completion_list_add; diff --git a/src/plugins/scripts/lua/weechat-lua-api.c b/src/plugins/scripts/lua/weechat-lua-api.c index b4bd4d412..e531ceedc 100644 --- a/src/plugins/scripts/lua/weechat-lua-api.c +++ b/src/plugins/scripts/lua/weechat-lua-api.c @@ -4122,6 +4122,135 @@ weechat_lua_api_hook_signal_send (lua_State *L) } /* + * weechat_lua_api_hook_hsignal_cb: callback for hsignal hooked + */ + +int +weechat_lua_api_hook_hsignal_cb (void *data, const char *signal, + struct t_hashtable *hashtable) +{ + struct t_script_callback *script_callback; + void *lua_argv[3]; + char empty_arg[1] = { '\0' }; + int *rc, ret; + + script_callback = (struct t_script_callback *)data; + + if (script_callback && script_callback->function && script_callback->function[0]) + { + lua_argv[0] = (script_callback->data) ? script_callback->data : empty_arg; + lua_argv[1] = (signal) ? (char *)signal : empty_arg; + lua_argv[2] = hashtable; + + rc = (int *) weechat_lua_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + "ssh", lua_argv); + + if (!rc) + ret = WEECHAT_RC_ERROR; + else + { + ret = *rc; + free (rc); + } + + return ret; + } + + return WEECHAT_RC_ERROR; +} + +/* + * weechat_lua_api_hook_hsignal: hook a hsignal + */ + +static int +weechat_lua_api_hook_hsignal (lua_State *L) +{ + const char *signal, *function, *data; + char *result; + int n; + + /* make C compiler happy */ + (void) L; + + if (!lua_current_script || !lua_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(LUA_CURRENT_SCRIPT_NAME, "hook_hsignal"); + LUA_RETURN_EMPTY; + } + + signal = NULL; + function = NULL; + data = NULL; + + n = lua_gettop (lua_current_interpreter); + + if (n < 3) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(LUA_CURRENT_SCRIPT_NAME, "hook_hsignal"); + LUA_RETURN_EMPTY; + } + + signal = lua_tostring (lua_current_interpreter, -3); + function = lua_tostring (lua_current_interpreter, -2); + data = lua_tostring (lua_current_interpreter, -1); + + result = script_ptr2str (script_api_hook_hsignal (weechat_lua_plugin, + lua_current_script, + signal, + &weechat_lua_api_hook_hsignal_cb, + function, + data)); + + LUA_RETURN_STRING_FREE(result); +} + +/* + * weechat_lua_api_hook_hsignal_send: send a hsignal + */ + +static int +weechat_lua_api_hook_hsignal_send (lua_State *L) +{ + const char *signal; + struct t_hashtable *hashtable; + int n; + + /* make C compiler happy */ + (void) L; + + if (!lua_current_script || !lua_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(LUA_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + LUA_RETURN_ERROR; + } + + signal = NULL; + hashtable = NULL; + + n = lua_gettop (lua_current_interpreter); + + if (n < 2) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(LUA_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + LUA_RETURN_ERROR; + } + + signal = lua_tostring (lua_current_interpreter, -2); + hashtable = weechat_lua_tohashtable (lua_current_interpreter, -1, + WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE); + + weechat_hook_hsignal_send (signal, hashtable); + + if (hashtable) + weechat_hashtable_free (hashtable); + + LUA_RETURN_OK; +} + +/* * weechat_lua_api_hook_config_cb: callback for config option hooked */ @@ -7683,6 +7812,8 @@ const struct luaL_reg weechat_lua_api_funcs[] = { { "hook_print", &weechat_lua_api_hook_print }, { "hook_signal", &weechat_lua_api_hook_signal }, { "hook_signal_send", &weechat_lua_api_hook_signal_send }, + { "hook_hsignal", &weechat_lua_api_hook_hsignal }, + { "hook_hsignal_send", &weechat_lua_api_hook_hsignal_send }, { "hook_config", &weechat_lua_api_hook_config }, { "hook_completion", &weechat_lua_api_hook_completion }, { "hook_completion_list_add", &weechat_lua_api_hook_completion_list_add }, diff --git a/src/plugins/scripts/perl/weechat-perl-api.c b/src/plugins/scripts/perl/weechat-perl-api.c index 9f43dad39..aead39eda 100644 --- a/src/plugins/scripts/perl/weechat-perl-api.c +++ b/src/plugins/scripts/perl/weechat-perl-api.c @@ -3487,6 +3487,121 @@ XS (XS_weechat_api_hook_signal_send) } /* + * weechat_perl_api_hook_hsignal_cb: callback for hsignal hooked + */ + +int +weechat_perl_api_hook_hsignal_cb (void *data, const char *signal, + struct t_hashtable *hashtable) +{ + struct t_script_callback *script_callback; + void *perl_argv[3]; + char empty_arg[1] = { '\0' }; + int *rc, ret; + + script_callback = (struct t_script_callback *)data; + + if (script_callback && script_callback->function && script_callback->function[0]) + { + perl_argv[0] = (script_callback->data) ? script_callback->data : empty_arg; + perl_argv[1] = (signal) ? (char *)signal : empty_arg; + perl_argv[2] = hashtable; + + rc = (int *) weechat_perl_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + "ssh", perl_argv); + + if (!rc) + ret = WEECHAT_RC_ERROR; + else + { + ret = *rc; + free (rc); + } + + return ret; + } + + return WEECHAT_RC_ERROR; +} + +/* + * weechat::hook_hsignal: hook a hsignal + */ + +XS (XS_weechat_api_hook_hsignal) +{ + char *result, *signal, *function, *data; + dXSARGS; + + /* make C compiler happy */ + (void) cv; + + if (!perl_current_script || !perl_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(PERL_CURRENT_SCRIPT_NAME, "hook_hsignal"); + PERL_RETURN_EMPTY; + } + + if (items < 3) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(PERL_CURRENT_SCRIPT_NAME, "hook_hsignal"); + PERL_RETURN_EMPTY; + } + + signal = SvPV (ST (0), PL_na); + function = SvPV (ST (1), PL_na); + data = SvPV (ST (2), PL_na); + + result = script_ptr2str (script_api_hook_hsignal (weechat_perl_plugin, + perl_current_script, + signal, + &weechat_perl_api_hook_hsignal_cb, + function, + data)); + + PERL_RETURN_STRING_FREE(result); +} + +/* + * weechat::hook_hsignal_send: send a hsignal + */ + +XS (XS_weechat_api_hook_hsignal_send) +{ + char *signal; + struct t_hashtable *hashtable; + dXSARGS; + + /* make C compiler happy */ + (void) cv; + + if (!perl_current_script || !perl_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(PERL_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + PERL_RETURN_ERROR; + } + + if (items < 2) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(PERL_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + PERL_RETURN_ERROR; + } + + signal = SvPV (ST (0), PL_na); + hashtable = weechat_perl_hash_to_hashtable (ST (1), + WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE); + + weechat_hook_hsignal_send (signal, hashtable); + + if (hashtable) + weechat_hashtable_free (hashtable); + + PERL_RETURN_OK; +} + +/* * weechat_perl_api_hook_config_cb: callback for config option hooked */ @@ -6176,6 +6291,8 @@ weechat_perl_api_init (pTHX) newXS ("weechat::hook_print", XS_weechat_api_hook_print, "weechat"); newXS ("weechat::hook_signal", XS_weechat_api_hook_signal, "weechat"); newXS ("weechat::hook_signal_send", XS_weechat_api_hook_signal_send, "weechat"); + newXS ("weechat::hook_hsignal", XS_weechat_api_hook_hsignal, "weechat"); + newXS ("weechat::hook_hsignal_send", XS_weechat_api_hook_hsignal_send, "weechat"); newXS ("weechat::hook_config", XS_weechat_api_hook_config, "weechat"); newXS ("weechat::hook_completion", XS_weechat_api_hook_completion, "weechat"); newXS ("weechat::hook_completion_list_add", XS_weechat_api_hook_completion_list_add, "weechat"); diff --git a/src/plugins/scripts/python/weechat-python-api.c b/src/plugins/scripts/python/weechat-python-api.c index a2ca66541..d88e8b9f0 100644 --- a/src/plugins/scripts/python/weechat-python-api.c +++ b/src/plugins/scripts/python/weechat-python-api.c @@ -3681,6 +3681,128 @@ weechat_python_api_hook_signal_send (PyObject *self, PyObject *args) } /* + * weechat_python_api_hook_hsignal_cb: callback for hsignal hooked + */ + +int +weechat_python_api_hook_hsignal_cb (void *data, const char *signal, + struct t_hashtable *hashtable) +{ + struct t_script_callback *script_callback; + void *python_argv[3]; + char empty_arg[1] = { '\0' }; + int *rc, ret; + + script_callback = (struct t_script_callback *)data; + + if (script_callback && script_callback->function && script_callback->function[0]) + { + python_argv[0] = (script_callback->data) ? script_callback->data : empty_arg; + python_argv[1] = (signal) ? (char *)signal : empty_arg; + python_argv[2] = weechat_python_hashtable_to_dict (hashtable); + + rc = (int *) weechat_python_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + "ssO", python_argv); + + if (!rc) + ret = WEECHAT_RC_ERROR; + else + { + ret = *rc; + free (rc); + } + if (python_argv[2]) + { + Py_XDECREF((PyObject *)python_argv[2]); + } + + return ret; + } + + return WEECHAT_RC_ERROR; +} + +/* + * weechat_python_api_hook_hsignal: hook a hsignal + */ + +static PyObject * +weechat_python_api_hook_hsignal (PyObject *self, PyObject *args) +{ + char *signal, *function, *data, *result; + PyObject *object; + + /* make C compiler happy */ + (void) self; + + if (!python_current_script || !python_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(PYTHON_CURRENT_SCRIPT_NAME, "hook_hsignal"); + PYTHON_RETURN_EMPTY; + } + + signal = NULL; + function = NULL; + data = NULL; + + if (!PyArg_ParseTuple (args, "sss", &signal, &function, &data)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(PYTHON_CURRENT_SCRIPT_NAME, "hook_hsignal"); + PYTHON_RETURN_EMPTY; + } + + result = script_ptr2str (script_api_hook_hsignal (weechat_python_plugin, + python_current_script, + signal, + &weechat_python_api_hook_hsignal_cb, + function, + data)); + + PYTHON_RETURN_STRING_FREE(result); +} + +/* + * weechat_python_api_hook_hsignal_send: send a hsignal + */ + +static PyObject * +weechat_python_api_hook_hsignal_send (PyObject *self, PyObject *args) +{ + char *signal; + struct t_hashtable *hashtable; + PyObject *dict; + + /* make C compiler happy */ + (void) self; + + if (!python_current_script || !python_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(PYTHON_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + PYTHON_RETURN_ERROR; + } + + signal = NULL; + + if (!PyArg_ParseTuple (args, "sO", &signal, &dict)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(PYTHON_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + PYTHON_RETURN_ERROR; + } + + hashtable = weechat_python_dict_to_hashtable (dict, + WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE); + + weechat_hook_hsignal_send (signal, hashtable); + + if (hashtable) + weechat_hashtable_free (hashtable); + + PYTHON_RETURN_OK; +} + +/* * weechat_python_api_hook_config_cb: callback for config option hooked */ @@ -6496,6 +6618,8 @@ PyMethodDef weechat_python_funcs[] = { "hook_print", &weechat_python_api_hook_print, METH_VARARGS, "" }, { "hook_signal", &weechat_python_api_hook_signal, METH_VARARGS, "" }, { "hook_signal_send", &weechat_python_api_hook_signal_send, METH_VARARGS, "" }, + { "hook_hsignal", &weechat_python_api_hook_hsignal, METH_VARARGS, "" }, + { "hook_hsignal_send", &weechat_python_api_hook_hsignal_send, METH_VARARGS, "" }, { "hook_config", &weechat_python_api_hook_config, METH_VARARGS, "" }, { "hook_completion", &weechat_python_api_hook_completion, METH_VARARGS, "" }, { "hook_completion_list_add", &weechat_python_api_hook_completion_list_add, METH_VARARGS, "" }, diff --git a/src/plugins/scripts/ruby/weechat-ruby-api.c b/src/plugins/scripts/ruby/weechat-ruby-api.c index db6703605..7e35525fd 100644 --- a/src/plugins/scripts/ruby/weechat-ruby-api.c +++ b/src/plugins/scripts/ruby/weechat-ruby-api.c @@ -4249,6 +4249,136 @@ weechat_ruby_api_hook_signal_send (VALUE class, VALUE signal, VALUE type_data, } /* + * weechat_ruby_api_hook_hsignal_cb: callback for hsignal hooked + */ + +int +weechat_ruby_api_hook_hsignal_cb (void *data, const char *signal, + struct t_hashtable *hashtable) +{ + struct t_script_callback *script_callback; + void *ruby_argv[3]; + char empty_arg[1] = { '\0' }; + int *rc, ret; + + script_callback = (struct t_script_callback *)data; + + if (script_callback && script_callback->function && script_callback->function[0]) + { + ruby_argv[0] = (script_callback->data) ? script_callback->data : empty_arg; + ruby_argv[1] = (signal) ? (char *)signal : empty_arg; + ruby_argv[2] = (void *)weechat_ruby_hashtable_to_hash (hashtable); + + rc = (int *) weechat_ruby_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + "ssh", ruby_argv); + + if (!rc) + ret = WEECHAT_RC_ERROR; + else + { + ret = *rc; + free (rc); + } + + return ret; + } + + return WEECHAT_RC_ERROR; +} + +/* + * weechat_ruby_api_hook_hsignal: hook a hsignal + */ + +static VALUE +weechat_ruby_api_hook_hsignal (VALUE class, VALUE signal, VALUE function, + VALUE data) +{ + char *c_signal, *c_function, *c_data, *result; + VALUE return_value; + + /* make C compiler happy */ + (void) class; + + if (!ruby_current_script || !ruby_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(RUBY_CURRENT_SCRIPT_NAME, "hook_hsignal"); + RUBY_RETURN_EMPTY; + } + + c_signal = NULL; + c_function = NULL; + c_data = NULL; + + if (NIL_P (signal) || NIL_P (function) || NIL_P (data)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(RUBY_CURRENT_SCRIPT_NAME, "hook_hsignal"); + RUBY_RETURN_EMPTY; + } + + Check_Type (signal, T_STRING); + Check_Type (function, T_STRING); + Check_Type (data, T_STRING); + + c_signal = StringValuePtr (signal); + c_function = StringValuePtr (function); + c_data = StringValuePtr (data); + + result = script_ptr2str (script_api_hook_hsignal (weechat_ruby_plugin, + ruby_current_script, + c_signal, + &weechat_ruby_api_hook_hsignal_cb, + c_function, + c_data)); + + RUBY_RETURN_STRING_FREE(result); +} + +/* + * weechat_ruby_api_hook_hsignal_send: send a hsignal + */ + +static VALUE +weechat_ruby_api_hook_hsignal_send (VALUE class, VALUE signal, VALUE hashtable) +{ + char *c_signal; + struct t_hashtable *c_hashtable; + + /* make C compiler happy */ + (void) class; + + if (!ruby_current_script || !ruby_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(RUBY_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + RUBY_RETURN_ERROR; + } + + c_signal = NULL; + + if (NIL_P (signal) || NIL_P (hashtable)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(RUBY_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + RUBY_RETURN_ERROR; + } + + Check_Type (signal, T_STRING); + Check_Type (hashtable, T_HASH); + + c_signal = StringValuePtr (signal); + c_hashtable = weechat_ruby_hash_to_hashtable (hashtable, + WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE); + + weechat_hook_hsignal_send (c_signal, c_hashtable); + + if (c_hashtable) + weechat_hashtable_free (c_hashtable); + + RUBY_RETURN_OK; +} + +/* * weechat_ruby_api_hook_config_cb: callback for config option hooked */ @@ -7482,6 +7612,8 @@ weechat_ruby_api_init (VALUE ruby_mWeechat) rb_define_module_function (ruby_mWeechat, "hook_print", &weechat_ruby_api_hook_print, 6); rb_define_module_function (ruby_mWeechat, "hook_signal", &weechat_ruby_api_hook_signal, 3); rb_define_module_function (ruby_mWeechat, "hook_signal_send", &weechat_ruby_api_hook_signal_send, 3); + rb_define_module_function (ruby_mWeechat, "hook_hsignal", &weechat_ruby_api_hook_hsignal, 3); + rb_define_module_function (ruby_mWeechat, "hook_hsignal_send", &weechat_ruby_api_hook_hsignal_send, 2); rb_define_module_function (ruby_mWeechat, "hook_config", &weechat_ruby_api_hook_config, 3); rb_define_module_function (ruby_mWeechat, "hook_completion", &weechat_ruby_api_hook_completion, 4); rb_define_module_function (ruby_mWeechat, "hook_completion_list_add", &weechat_ruby_api_hook_completion_list_add, 4); diff --git a/src/plugins/scripts/script-api.c b/src/plugins/scripts/script-api.c index 1a56807d7..bf98328bb 100644 --- a/src/plugins/scripts/script-api.c +++ b/src/plugins/scripts/script-api.c @@ -1046,6 +1046,43 @@ script_api_hook_signal (struct t_weechat_plugin *weechat_plugin, } /* + * script_api_hook_hsignal: hook a hsignal + * return new hook, NULL if error + */ + +struct t_hook * +script_api_hook_hsignal (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + const char *signal, + int (*callback)(void *data, const char *signal, + struct t_hashtable *hashtable), + const char *function, + const char *data) +{ + struct t_script_callback *new_script_callback; + struct t_hook *new_hook; + + new_script_callback = script_callback_alloc (); + if (!new_script_callback) + return NULL; + + new_hook = weechat_hook_hsignal (signal, callback, new_script_callback); + if (!new_hook) + { + script_callback_free_data (new_script_callback); + free (new_script_callback); + return NULL; + } + + script_callback_init (new_script_callback, script, function, data); + new_script_callback->hook = new_hook; + + script_callback_add (script, new_script_callback); + + return new_hook; +} + +/* * script_api_hook_config: hook a config option * return new hook, NULL if error */ diff --git a/src/plugins/scripts/script-api.h b/src/plugins/scripts/script-api.h index f7d8b312f..e13bb17a1 100644 --- a/src/plugins/scripts/script-api.h +++ b/src/plugins/scripts/script-api.h @@ -206,6 +206,14 @@ extern struct t_hook *script_api_hook_signal (struct t_weechat_plugin *weechat_p void *signal_data), const char *function, const char *data); +extern struct t_hook *script_api_hook_hsignal (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + const char *signal, + int (*callback)(void *data, + const char *signal, + struct t_hashtable *hashtable), + const char *function, + const char *data); extern struct t_hook *script_api_hook_config (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, const char *option, diff --git a/src/plugins/scripts/tcl/weechat-tcl-api.c b/src/plugins/scripts/tcl/weechat-tcl-api.c index f0402d614..2ee76b65f 100644 --- a/src/plugins/scripts/tcl/weechat-tcl-api.c +++ b/src/plugins/scripts/tcl/weechat-tcl-api.c @@ -3950,6 +3950,127 @@ weechat_tcl_api_hook_signal_send (ClientData clientData, Tcl_Interp *interp, } /* + * weechat_tcl_api_hook_hsignal_cb: callback for hsignal hooked + */ + +int +weechat_tcl_api_hook_hsignal_cb (void *data, const char *signal, + struct t_hashtable *hashtable) +{ + struct t_script_callback *script_callback; + void *tcl_argv[3]; + char empty_arg[1] = { '\0' }; + int *rc, ret; + + script_callback = (struct t_script_callback *)data; + + if (script_callback && script_callback->function && script_callback->function[0]) + { + tcl_argv[0] = (script_callback->data) ? script_callback->data : empty_arg; + tcl_argv[1] = (signal) ? (char *)signal : empty_arg; + tcl_argv[2] = hashtable; + + rc = (int *) weechat_tcl_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + "ssh", tcl_argv); + + if (!rc) + ret = WEECHAT_RC_ERROR; + else + { + ret = *rc; + free (rc); + } + + return ret; + } + + return WEECHAT_RC_ERROR; +} + +/* + * weechat_tcl_api_hook_hsignal: hook a hsignal + */ + +static int +weechat_tcl_api_hook_hsignal (ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + Tcl_Obj *objp; + char *result, *signal, *function, *data; + int i; + + /* make C compiler happy */ + (void) clientData; + + if (!tcl_current_script || !tcl_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(TCL_CURRENT_SCRIPT_NAME, "hook_hsignal"); + TCL_RETURN_EMPTY; + } + + if (objc < 4) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(TCL_CURRENT_SCRIPT_NAME, "hook_hsignal"); + TCL_RETURN_EMPTY; + } + + signal = Tcl_GetStringFromObj (objv[1], &i); + function = Tcl_GetStringFromObj (objv[2], &i); + data = Tcl_GetStringFromObj (objv[3], &i); + + result = script_ptr2str (script_api_hook_hsignal (weechat_tcl_plugin, + tcl_current_script, + signal, + &weechat_tcl_api_hook_hsignal_cb, + function, + data)); + + TCL_RETURN_STRING_FREE(result); +} + +/* + * weechat_tcl_api_hook_hsignal_send: send a hsignal + */ + +static int +weechat_tcl_api_hook_hsignal_send (ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + Tcl_Obj *objp; + char *signal; + struct t_hashtable *hashtable; + int i; + + /* make C compiler happy */ + (void) clientData; + + if (!tcl_current_script || !tcl_current_script->name) + { + WEECHAT_SCRIPT_MSG_NOT_INIT(TCL_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + TCL_RETURN_ERROR; + } + + if (objc < 3) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGS(TCL_CURRENT_SCRIPT_NAME, "hook_hsignal_send"); + TCL_RETURN_ERROR; + } + + signal = Tcl_GetStringFromObj (objv[1], &i); + hashtable = weechat_tcl_dict_to_hashtable (interp, objv[2], + WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE); + + weechat_hook_hsignal_send (signal, hashtable); + + if (hashtable) + weechat_hashtable_free (hashtable); + + TCL_RETURN_OK; +} + +/* * weechat_tcl_api_hook_config_cb: callback for config option hooked */ @@ -7044,6 +7165,10 @@ void weechat_tcl_api_init (Tcl_Interp *interp) weechat_tcl_api_hook_signal, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateObjCommand (interp, "weechat::hook_signal_send", weechat_tcl_api_hook_signal_send, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateObjCommand (interp, "weechat::hook_hsignal", + weechat_tcl_api_hook_hsignal, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateObjCommand (interp, "weechat::hook_hsignal_send", + weechat_tcl_api_hook_hsignal_send, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateObjCommand (interp, "weechat::hook_config", weechat_tcl_api_hook_config, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateObjCommand (interp, "weechat::hook_completion", diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index d8a080000..68db356fe 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -45,7 +45,7 @@ struct timeval; */ /* API version (used to check that plugin has same API and can be loaded) */ -#define WEECHAT_PLUGIN_API_VERSION "20101017-01" +#define WEECHAT_PLUGIN_API_VERSION "20101023-01" /* macros for defining plugin infos */ #define WEECHAT_PLUGIN_NAME(__name) \ @@ -487,6 +487,14 @@ struct t_weechat_plugin void *callback_data); void (*hook_signal_send) (const char *signal, const char *type_data, void *signal_data); + struct t_hook *(*hook_hsignal) (struct t_weechat_plugin *plugin, + const char *signal, + int (*callback)(void *data, + const char *signal, + struct t_hashtable *hashtable), + void *callback_data); + void (*hook_hsignal_send) (const char *signal, + struct t_hashtable *hashtable); struct t_hook *(*hook_config) (struct t_weechat_plugin *plugin, const char *option, int (*callback)(void *data, @@ -1112,6 +1120,11 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin); #define weechat_hook_signal_send(__signal, __type_data, __signal_data) \ weechat_plugin->hook_signal_send(__signal, __type_data, \ __signal_data) +#define weechat_hook_hsignal(__signal, __callback, __data) \ + weechat_plugin->hook_hsignal(weechat_plugin, __signal, __callback, \ + __data) +#define weechat_hook_hsignal_send(__signal, __hashtable) \ + weechat_plugin->hook_hsignal_send(__signal, __hashtable) #define weechat_hook_config(__option, __callback, __data) \ weechat_plugin->hook_config(weechat_plugin, __option, __callback, \ __data) |