From 184700e597f7374146ba0c0ca6932f83d8d6add2 Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Fri, 1 Feb 2008 18:56:12 +0100 Subject: [PATCH] New "close callback" for buffers, use of this callback in IRC plugin to leave channel or disconnect from server when buffer is closed --- src/gui/curses/gui-curses-main.c | 4 +- src/gui/gtk/gui-gtk-main.c | 4 +- src/gui/gui-buffer.c | 14 ++- src/gui/gui-buffer.h | 13 +- src/plugins/demo/demo.c | 30 ++++- src/plugins/irc/Makefile.am | 4 +- src/plugins/irc/irc-buffer.c | 117 ++++++++---------- src/plugins/irc/irc-buffer.h | 24 +--- src/plugins/irc/irc-channel.c | 4 +- src/plugins/irc/irc-command.c | 51 +++++--- src/plugins/irc/irc-command.h | 3 + src/plugins/irc/irc-input.c | 8 +- src/plugins/irc/irc-input.h | 4 +- src/plugins/irc/irc-protocol.c | 8 -- src/plugins/irc/irc-server.c | 4 +- src/plugins/plugin.c | 4 + src/plugins/scripts/lua/weechat-lua-api.c | 66 ++++++++-- src/plugins/scripts/perl/weechat-perl-api.c | 47 ++++++- .../scripts/python/weechat-python-api.c | 53 +++++++- src/plugins/scripts/ruby/weechat-ruby-api.c | 66 ++++++++-- src/plugins/scripts/script-api.c | 80 +++++++++--- src/plugins/scripts/script-api.h | 17 +-- src/plugins/weechat-plugin.h | 11 +- 23 files changed, 442 insertions(+), 194 deletions(-) diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c index e0f9e2547..d2230e3dd 100644 --- a/src/gui/curses/gui-curses-main.c +++ b/src/gui/curses/gui-curses-main.c @@ -102,7 +102,9 @@ gui_main_init () if (gui_window_new (NULL, 0, 0, COLS, LINES, 100, 100)) { gui_current_window = gui_windows; - ptr_buffer = gui_buffer_new (NULL, "weechat", "weechat", NULL, NULL); + ptr_buffer = gui_buffer_new (NULL, "weechat", "weechat", + NULL, NULL, + NULL, NULL); if (ptr_buffer) { gui_init_ok = 1; diff --git a/src/gui/gtk/gui-gtk-main.c b/src/gui/gtk/gui-gtk-main.c index 19add6ddc..b00ce369f 100644 --- a/src/gui/gtk/gui-gtk-main.c +++ b/src/gui/gtk/gui-gtk-main.c @@ -170,7 +170,9 @@ gui_main_init () if (gui_window_new (NULL, 0, 0, 0, 0, 100, 100)) { gui_current_window = gui_windows; - ptr_buffer = gui_buffer_new (NULL, "weechat", "weechat", NULL, NULL); + ptr_buffer = gui_buffer_new (NULL, "weechat", "weechat", + NULL, NULL, + NULL, NULL); if (ptr_buffer) { gui_init_ok = 1; diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index 4c2df12a1..a5a4bbdc6 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -69,7 +69,10 @@ gui_buffer_new (struct t_weechat_plugin *plugin, char *category, char *name, int (*input_callback)(void *data, struct t_gui_buffer *buffer, char *input_data), - void *input_callback_data) + void *input_callback_data, + int (*close_callback)(void *data, + struct t_gui_buffer *buffer), + void *close_callback_data) { struct t_gui_buffer *new_buffer; struct t_gui_completion *new_completion; @@ -99,6 +102,10 @@ gui_buffer_new (struct t_weechat_plugin *plugin, char *category, char *name, new_buffer->notify_level = GUI_BUFFER_NOTIFY_LEVEL_DEFAULT; new_buffer->num_displayed = 0; + /* close callback */ + new_buffer->close_callback = close_callback; + new_buffer->close_callback_data = close_callback_data; + /* title */ new_buffer->title = NULL; new_buffer->title_refresh_needed = 1; @@ -623,6 +630,11 @@ gui_buffer_close (struct t_gui_buffer *buffer, int switch_to_another) hook_signal_send ("buffer_close", WEECHAT_HOOK_SIGNAL_POINTER, buffer); + if (buffer->close_callback) + { + (void)(buffer->close_callback) (buffer->close_callback_data, buffer); + } + if (switch_to_another) { for (ptr_window = gui_windows; ptr_window; diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h index 63fb6dcce..f1fb94c91 100644 --- a/src/gui/gui-buffer.h +++ b/src/gui/gui-buffer.h @@ -64,6 +64,11 @@ struct t_gui_buffer /* 3 = highlight + msg + join/part */ int num_displayed; /* number of windows displaying buf. */ + /* close callback */ + int (*close_callback)(void *data, /* called when buffer is closed */ + struct t_gui_buffer *buffer); + void *close_callback_data; /* data for callback */ + /* buffer title */ char *title; /* buffer title */ int title_refresh_needed; /* refresh for title is needed ? */ @@ -87,10 +92,9 @@ struct t_gui_buffer /* inupt */ int input; /* = 1 if input is enabled */ - int (*input_callback)(void *data, + int (*input_callback)(void *data, /* called when user send data */ struct t_gui_buffer *buffer, char *input_data); - /* called when user send data */ void *input_callback_data; /* data for callback */ /* to this buffer */ char *input_nick; /* self nick */ @@ -139,7 +143,10 @@ extern struct t_gui_buffer *gui_buffer_new (struct t_weechat_plugin *plugin, int (*input_callback)(void *data, struct t_gui_buffer *buffer, char *input_data), - void *input_callback_data); + void *input_callback_data, + int (*close_callback)(void *data, + struct t_gui_buffer *buffer), + void *close_callback_data); extern int gui_buffer_valid (struct t_gui_buffer *buffer); extern void *gui_buffer_get (struct t_gui_buffer *buffer, char *property); extern void gui_buffer_set_category (struct t_gui_buffer *buffer, diff --git a/src/plugins/demo/demo.c b/src/plugins/demo/demo.c index f5fe25412..4865ecb05 100644 --- a/src/plugins/demo/demo.c +++ b/src/plugins/demo/demo.c @@ -115,7 +115,31 @@ demo_buffer_input_data_cb (void *data, struct t_gui_buffer *buffer, (void) data; weechat_printf (buffer, - "buffer input_data_cb: input_data = '%s'", input_data); + "buffer_input_data_cb: buffer = %x (%s / %s), " + "input_data = '%s'", + buffer, + weechat_buffer_get (buffer, "category"), + weechat_buffer_get (buffer, "name"), + input_data); + + return WEECHAT_RC_OK; +} + +/* + * demo_buffer_close_cb: callback for buffer closed + */ + +int +demo_buffer_close_cb (void *data, struct t_gui_buffer *buffer) +{ + /* make C compiler happy */ + (void) data; + + weechat_printf (NULL, + "buffer_close_cb: buffer = %x (%s / %s)", + buffer, + weechat_buffer_get (buffer, "category"), + weechat_buffer_get (buffer, "name")); return WEECHAT_RC_OK; } @@ -138,8 +162,8 @@ demo_buffer_command_cb (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { new_buffer = weechat_buffer_new (argv[1], argv[2], - &demo_buffer_input_data_cb, - NULL); + &demo_buffer_input_data_cb, NULL, + &demo_buffer_close_cb, NULL); if (new_buffer) weechat_buffer_set (new_buffer, "display", "1"); weechat_hook_signal_send ("logger_backlog", diff --git a/src/plugins/irc/Makefile.am b/src/plugins/irc/Makefile.am index 599886020..2314b8ba5 100644 --- a/src/plugins/irc/Makefile.am +++ b/src/plugins/irc/Makefile.am @@ -22,6 +22,8 @@ lib_LTLIBRARIES = irc.la irc_la_SOURCES = irc.c \ irc.h \ + irc-buffer.c \ + irc-buffer.h \ irc-channel.c \ irc-channel.h \ irc-color.c \ @@ -44,8 +46,6 @@ irc_la_SOURCES = irc.c \ irc-server.c \ irc-server.h -# irc-buffer.c \ -# irc-buffer.h \ # irc-dcc.c \ # irc-dcc.h \ # irc-log.c diff --git a/src/plugins/irc/irc-buffer.c b/src/plugins/irc/irc-buffer.c index 02384abfc..641d19a5a 100644 --- a/src/plugins/irc/irc-buffer.c +++ b/src/plugins/irc/irc-buffer.c @@ -26,76 +26,26 @@ #include #include -#include "../../core/weechat.h" +#include "../weechat-plugin.h" #include "irc.h" -#include "../../core/utf8.h" -#include "../../core/weechat-config.h" -#include "../../gui/gui.h" +#include "irc-buffer.h" +#include "irc-channel.h" +#include "irc-command.h" +#include "irc-server.h" -/* - * irc_buffer_data_create: create protocol data (for GUI buffer) - */ - -t_irc_buffer_data * -irc_buffer_data_create (t_irc_server *server) -{ - t_irc_buffer_data *buffer_data; - - buffer_data = (t_irc_buffer_data *)malloc (sizeof (t_irc_buffer_data)); - if (!buffer_data) - return NULL; - - buffer_data->server = server; - buffer_data->channel = NULL; - buffer_data->all_servers = irc_cfg_irc_one_server_buffer; - - return buffer_data; -} - -/* - * irc_buffer_data_free: free protocol data (in GUI buffer) - */ - -void -irc_buffer_data_free (t_gui_buffer *buffer) -{ - free ((t_irc_buffer_data *)buffer->protocol_data); -} - -/* - * irc_buffer_servers_search: search servers buffer - * (when same buffer is used for all servers) - */ - -t_gui_buffer * -irc_buffer_servers_search () -{ - t_gui_buffer *ptr_buffer; - - for (ptr_buffer = gui_buffers; ptr_buffer; - ptr_buffer = ptr_buffer->next_buffer) - { - if (IRC_BUFFER_ALL_SERVERS(ptr_buffer)) - return ptr_buffer; - - } - - /* buffer not found */ - return NULL; -} - /* * irc_buffer_merge_servers: merge server buffers in one buffer */ +/* void irc_buffer_merge_servers (t_gui_window *window) { t_gui_buffer *ptr_buffer_server, *ptr_buffer, *new_ptr_buffer; t_irc_server *ptr_server; - /* new server buffer is the first server buffer found */ + // new server buffer is the first server buffer found for (ptr_buffer_server = gui_buffers; ptr_buffer_server; ptr_buffer_server = ptr_buffer_server->next_buffer) { @@ -105,7 +55,7 @@ irc_buffer_merge_servers (t_gui_window *window) break; } - /* no server buffer found */ + // no server buffer found if (!ptr_buffer_server) return; @@ -119,7 +69,7 @@ irc_buffer_merge_servers (t_gui_window *window) { ptr_server = IRC_BUFFER_SERVER(ptr_buffer); - /* add (by pointer artefact) lines from buffer found to server buffer */ + // add (by pointer artefact) lines from buffer found to server buffer if (ptr_buffer->lines) { if (ptr_buffer_server->lines) @@ -138,14 +88,14 @@ irc_buffer_merge_servers (t_gui_window *window) } } - /* free buffer but not lines, because they're now used by - our unique server buffer */ + // free buffer but not lines, because they're now used by + // our unique server buffer new_ptr_buffer = ptr_buffer->next_buffer; ptr_buffer->lines = NULL; gui_buffer_free (ptr_buffer, 1); ptr_buffer = new_ptr_buffer; - /* asociate server with new server buffer */ + // asociate server with new server buffer ptr_server->buffer = ptr_buffer_server; } else @@ -155,11 +105,13 @@ irc_buffer_merge_servers (t_gui_window *window) IRC_BUFFER_ALL_SERVERS(ptr_buffer_server) = 1; gui_window_redraw_buffer (window->buffer); } +*/ /* * irc_buffer_split_server: split the server buffer into many buffers (one by server) */ +/* void irc_buffer_split_server (t_gui_window *window) { @@ -207,3 +159,44 @@ irc_buffer_split_server (t_gui_window *window) gui_input_draw (window->buffer, 1); } } +*/ + +/* + * irc_buffer_close_cb: callback called when a buffer is closed + */ + +int +irc_buffer_close_cb (void *data, struct t_gui_buffer *buffer) +{ + IRC_GET_SERVER_CHANNEL(buffer); + + /* make C compiler happy */ + (void) data; + + if (ptr_channel) + { + /* send PART for channel if its buffer is closed */ + if (ptr_channel->type == IRC_CHANNEL_TYPE_CHANNEL) + { + irc_command_part_channel (ptr_server, ptr_channel->name, NULL); + irc_channel_free (ptr_server, ptr_channel); + } + } + else + { + if (ptr_server) + { + /* send PART on all channels for server, then disconnect from server */ + for (ptr_channel = ptr_server->channels; ptr_channel; + ptr_channel = ptr_channel->next_channel) + { + irc_command_part_channel (ptr_server, ptr_channel->name, NULL); + irc_channel_free (ptr_server, ptr_channel); + } + irc_server_disconnect (ptr_server, 0); + ptr_server->buffer = NULL; + } + } + + return WEECHAT_RC_OK; +} diff --git a/src/plugins/irc/irc-buffer.h b/src/plugins/irc/irc-buffer.h index 876187d9d..82dd14848 100644 --- a/src/plugins/irc/irc-buffer.h +++ b/src/plugins/irc/irc-buffer.h @@ -20,28 +20,6 @@ #ifndef __WEECHAT_IRC_BUFFER_H #define __WEECHAT_IRC_BUFFER_H 1 -#define IRC_BUFFER_SERVER(buffer) (((t_irc_buffer_data *)(buffer->protocol_data))->server) -#define IRC_BUFFER_CHANNEL(buffer) (((t_irc_buffer_data *)(buffer->protocol_data))->channel) -#define IRC_BUFFER_ALL_SERVERS(buffer) (((t_irc_buffer_data *)(buffer->protocol_data))->all_servers) - -#define IRC_BUFFER_GET_SERVER(buffer) \ - t_irc_server *ptr_server = IRC_BUFFER_SERVER(buffer) -#define IRC_BUFFER_GET_CHANNEL(buffer) \ - t_irc_channel *ptr_channel = IRC_BUFFER_CHANNEL(buffer) -#define IRC_BUFFER_GET_SERVER_CHANNEL(buffer) \ - t_irc_server *ptr_server = IRC_BUFFER_SERVER(buffer); \ - t_irc_channel *ptr_channel = IRC_BUFFER_CHANNEL(buffer) - -struct t_irc_buffer_data -{ - struct t_irc_server *server; - struct t_irc_channel *channel; - int all_servers; -}; - -extern struct t_irc_buffer_data *irc_buffer_data_create (struct t_irc_server *server); -extern void irc_buffer_data_free (struct t_gui_buffer *buffer); -extern void irc_buffer_merge_servers (struct t_gui_window *window); -extern void irc_buffer_split_server (struct t_gui_window *window); +extern int irc_buffer_close_cb (void *data, struct t_gui_buffer *buffer); #endif /* irc-buffer.h */ diff --git a/src/plugins/irc/irc-channel.c b/src/plugins/irc/irc-channel.c index bfb825854..ae2c409c0 100644 --- a/src/plugins/irc/irc-channel.c +++ b/src/plugins/irc/irc-channel.c @@ -30,6 +30,7 @@ #include "../weechat-plugin.h" #include "irc.h" #include "irc-channel.h" +#include "irc-buffer.h" #include "irc-config.h" #include "irc-dcc.h" #include "irc-nick.h" @@ -60,7 +61,8 @@ irc_channel_new (struct t_irc_server *server, int channel_type, /* create buffer for channel */ new_buffer = weechat_buffer_new (server->name, channel_name, - &irc_input_data, NULL); + &irc_input_data_cb, NULL, + &irc_buffer_close_cb, NULL); if (!new_buffer) { free (new_channel); diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c index ea2a906b1..2e8c56feb 100644 --- a/src/plugins/irc/irc-command.c +++ b/src/plugins/irc/irc-command.c @@ -2102,6 +2102,35 @@ irc_command_oper (void *data, struct t_gui_buffer *buffer, int argc, return WEECHAT_RC_OK; } +/* + * irc_command_part_channel: send a part message for a channel + */ + +void +irc_command_part_channel (struct t_irc_server *server, char *channel_name, + char *part_message) +{ + char *ptr_arg, *buf, *version; + + ptr_arg = (part_message) ? part_message : + (weechat_config_string (irc_config_irc_default_msg_part) + && weechat_config_string (irc_config_irc_default_msg_part)[0]) ? + weechat_config_string (irc_config_irc_default_msg_part) : NULL; + + if (ptr_arg) + { + version = weechat_info_get ("version"); + buf = weechat_string_replace (ptr_arg, "%v", (version) ? version : ""); + irc_server_sendf (server, "PART %s :%s", + channel_name, + (buf) ? buf : ptr_arg); + if (buf) + free (buf); + } + else + irc_server_sendf (server, "PART %s", channel_name); +} + /* * irc_command_part: leave a channel or close a private window */ @@ -2110,7 +2139,7 @@ int irc_command_part (void *data, struct t_gui_buffer *buffer, int argc, char **argv, char **argv_eol) { - char *channel_name, *pos_args, *ptr_arg, *buf, *version; + char *channel_name, *pos_args; IRC_GET_SERVER_CHANNEL(buffer); if (!ptr_server || !ptr_server->is_connected) @@ -2157,31 +2186,13 @@ irc_command_part (void *data, struct t_gui_buffer *buffer, int argc, weechat_buffer_close (ptr_channel->buffer, 1); ptr_channel->buffer = NULL; irc_channel_free (ptr_server, ptr_channel); - //gui_status_draw (gui_current_window->buffer, 1); - //gui_input_draw (gui_current_window->buffer, 1); return WEECHAT_RC_OK; } channel_name = ptr_channel->name; pos_args = NULL; } - ptr_arg = (pos_args) ? pos_args : - (weechat_config_string (irc_config_irc_default_msg_part) - && weechat_config_string (irc_config_irc_default_msg_part)[0]) ? - weechat_config_string (irc_config_irc_default_msg_part) : NULL; - - if (ptr_arg) - { - version = weechat_info_get ("version"); - buf = weechat_string_replace (ptr_arg, "%v", (version) ? version : ""); - irc_server_sendf (ptr_server, "PART %s :%s", - channel_name, - (buf) ? buf : ptr_arg); - if (buf) - free (buf); - } - else - irc_server_sendf (ptr_server, "PART %s", channel_name); + irc_command_part_channel (ptr_server, channel_name, pos_args); return WEECHAT_RC_OK; } diff --git a/src/plugins/irc/irc-command.h b/src/plugins/irc/irc-command.h index 7aa0f6834..fbc346725 100644 --- a/src/plugins/irc/irc-command.h +++ b/src/plugins/irc/irc-command.h @@ -35,6 +35,9 @@ extern void irc_command_join_server (struct t_irc_server *server, char *arguments); extern void irc_command_mode_server (struct t_irc_server *server, char *arguments); +extern void irc_command_part_channel (struct t_irc_server *server, + char *channel_name, + char *part_message); extern void irc_command_quit_server (struct t_irc_server *server, char *arguments); extern void irc_command_init (); diff --git a/src/plugins/irc/irc-input.c b/src/plugins/irc/irc-input.c index fc0b6a450..93c8f026c 100644 --- a/src/plugins/irc/irc-input.c +++ b/src/plugins/irc/irc-input.c @@ -146,13 +146,13 @@ irc_input_send_user_message (struct t_gui_buffer *buffer, char *text) } /* - * irc_input_data: read data from user input - * Return: PROTOCOL_RC_OK if ok - * PROTOCOL_RC_KO if error + * irc_input_data_cb: callback for input data in a buffer + * Return: PROTOCOL_RC_OK if ok + * PROTOCOL_RC_KO if error */ int -irc_input_data (void *data, struct t_gui_buffer *buffer, char *input_data) +irc_input_data_cb (void *data, struct t_gui_buffer *buffer, char *input_data) { char *data_with_colors; diff --git a/src/plugins/irc/irc-input.h b/src/plugins/irc/irc-input.h index f7efa95a8..6310546ad 100644 --- a/src/plugins/irc/irc-input.h +++ b/src/plugins/irc/irc-input.h @@ -20,7 +20,7 @@ #ifndef __WEECHAT_IRC_INPUT_H #define __WEECHAT_IRC_INPUT_H 1 -extern int irc_input_data (void *data, struct t_gui_buffer *buffer, - char *input_data); +extern int irc_input_data_cb (void *data, struct t_gui_buffer *buffer, + char *input_data); #endif /* irc-input.h */ diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 1b63781d9..285b71c04 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -1491,14 +1491,6 @@ irc_protocol_cmd_part (struct t_irc_server *server, char *irc_message, char *hos irc_nick_free (ptr_channel, ptr_nick); } } - else - { - weechat_printf (server->buffer, - _("%s%s: channel \"%s\" not found for \"%s\" " - "command"), - weechat_prefix ("error"), "irc", arguments, "part"); - return WEECHAT_RC_ERROR; - } return WEECHAT_RC_OK; } diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 2d22f6cf9..96bb9729d 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -47,6 +47,7 @@ #include "../weechat-plugin.h" #include "irc.h" #include "irc-server.h" +#include "irc-buffer.h" #include "irc-channel.h" #include "irc-command.h" #include "irc-config.h" @@ -2263,7 +2264,8 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin) if (!server->buffer) { server->buffer = weechat_buffer_new (server->name, server->name, - NULL, NULL); + NULL, NULL, + &irc_buffer_close_cb, NULL); if (!server->buffer) return 0; weechat_buffer_set (server->buffer, "display", "1"); diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index ce621a63d..449a32923 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -526,7 +526,11 @@ plugin_remove (struct t_weechat_plugin *plugin) ptr_buffer = ptr_buffer->next_buffer) { if (ptr_buffer->plugin == plugin) + { ptr_buffer->plugin = NULL; + ptr_buffer->close_callback = NULL; + ptr_buffer->close_callback_data = NULL; + } } /* free data */ diff --git a/src/plugins/scripts/lua/weechat-lua-api.c b/src/plugins/scripts/lua/weechat-lua-api.c index b4cb6c488..9c79fdfe0 100644 --- a/src/plugins/scripts/lua/weechat-lua-api.c +++ b/src/plugins/scripts/lua/weechat-lua-api.c @@ -1164,7 +1164,7 @@ weechat_lua_api_config_option_change_cb (void *data) if (script_callback->function && script_callback->function[0]) { - lua_argv[1] = NULL; + lua_argv[0] = NULL; rc = (int *) weechat_lua_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, @@ -2016,11 +2016,13 @@ int weechat_lua_api_hook_timer_cb (void *data) { struct t_script_callback *script_callback; - char *lua_argv[1] = { NULL }; + char *lua_argv[1]; int *rc, ret; script_callback = (struct t_script_callback *)data; + lua_argv[0] = NULL; + rc = (int *) weechat_lua_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, script_callback->function, @@ -2093,11 +2095,13 @@ int weechat_lua_api_hook_fd_cb (void *data) { struct t_script_callback *script_callback; - char *lua_argv[1] = { NULL }; + char *lua_argv[1]; int *rc, ret; script_callback = (struct t_script_callback *)data; + lua_argv[0] = NULL; + rc = (int *) weechat_lua_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, script_callback->function, @@ -2749,8 +2753,42 @@ weechat_lua_api_input_data_cb (void *data, struct t_gui_buffer *buffer, script_callback = (struct t_script_callback *)data; lua_argv[0] = script_ptr2str (buffer); - lua_argv[2] = input_data; - lua_argv[3] = NULL; + lua_argv[1] = input_data; + lua_argv[2] = NULL; + + rc = (int *) weechat_lua_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + lua_argv); + + if (!rc) + ret = WEECHAT_RC_ERROR; + else + { + ret = *rc; + free (rc); + } + if (lua_argv[0]) + free (lua_argv[0]); + + return ret; +} + +/* + * weechat_lua_api_close_cb: callback for buffer closed + */ + +int +weechat_lua_api_close_cb (void *data, struct t_gui_buffer *buffer) +{ + struct t_script_callback *script_callback; + char *lua_argv[2]; + int *rc, ret; + + script_callback = (struct t_script_callback *)data; + + lua_argv[0] = script_ptr2str (buffer); + lua_argv[1] = NULL; rc = (int *) weechat_lua_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, @@ -2777,7 +2815,7 @@ weechat_lua_api_input_data_cb (void *data, struct t_gui_buffer *buffer, static int weechat_lua_api_buffer_new (lua_State *L) { - const char *category, *name, *function; + const char *category, *name, *function_input, *function_close; char *result; int n; @@ -2792,26 +2830,30 @@ weechat_lua_api_buffer_new (lua_State *L) category = NULL; name = NULL; - function = NULL; + function_input = NULL; + function_close = NULL; n = lua_gettop (lua_current_interpreter); - if (n < 3) + if (n < 4) { WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("buffer_new"); LUA_RETURN_EMPTY; } - category = lua_tostring (lua_current_interpreter, -3); - name = lua_tostring (lua_current_interpreter, -2); - function = lua_tostring (lua_current_interpreter, -1); + category = lua_tostring (lua_current_interpreter, -4); + name = lua_tostring (lua_current_interpreter, -3); + function_input = lua_tostring (lua_current_interpreter, -2); + function_close = lua_tostring (lua_current_interpreter, -1); result = script_ptr2str (script_api_buffer_new (weechat_lua_plugin, lua_current_script, (char *)category, (char *)name, &weechat_lua_api_input_data_cb, - (char *)function)); + (char *)function_input, + &weechat_lua_api_close_cb, + (char *)function_close)); LUA_RETURN_STRING_FREE(result); } diff --git a/src/plugins/scripts/perl/weechat-perl-api.c b/src/plugins/scripts/perl/weechat-perl-api.c index ddce8a7f6..91ea5defd 100644 --- a/src/plugins/scripts/perl/weechat-perl-api.c +++ b/src/plugins/scripts/perl/weechat-perl-api.c @@ -1601,11 +1601,13 @@ int weechat_perl_api_hook_timer_cb (void *data) { struct t_script_callback *script_callback; - char *perl_argv[1] = { NULL }; + char *perl_argv[1]; int *rc, ret; script_callback = (struct t_script_callback *)data; + perl_argv[0] = NULL; + rc = (int *) weechat_perl_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, script_callback->function, @@ -1664,11 +1666,13 @@ int weechat_perl_api_hook_fd_cb (void *data) { struct t_script_callback *script_callback; - char *perl_argv[1] = { NULL }; + char *perl_argv[1]; int *rc, ret; script_callback = (struct t_script_callback *)data; + perl_argv[0] = NULL; + rc = (int *) weechat_perl_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, script_callback->function, @@ -2247,6 +2251,39 @@ weechat_perl_api_input_data_cb (void *data, struct t_gui_buffer *buffer, return ret; } +/* + * weechat_perl_api_close_cb: callback for buffer closed + */ + +int +weechat_perl_api_close_cb (void *data, struct t_gui_buffer *buffer) +{ + struct t_script_callback *script_callback; + char *perl_argv[2]; + int *rc, ret; + + script_callback = (struct t_script_callback *)data; + + perl_argv[0] = script_ptr2str (buffer); + perl_argv[1] = NULL; + + rc = (int *) weechat_perl_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + perl_argv); + if (!rc) + ret = WEECHAT_RC_ERROR; + else + { + ret = *rc; + free (rc); + } + if (perl_argv[0]) + free (perl_argv[0]); + + return ret; +} + /* * weechat::buffer_new: create a new buffer */ @@ -2265,7 +2302,7 @@ static XS (XS_weechat_buffer_new) PERL_RETURN_EMPTY; } - if (items < 3) + if (items < 4) { WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("buffer_new"); PERL_RETURN_EMPTY; @@ -2276,7 +2313,9 @@ static XS (XS_weechat_buffer_new) SvPV (ST (0), PL_na), /* category */ SvPV (ST (1), PL_na), /* name */ &weechat_perl_api_input_data_cb, - SvPV (ST (2), PL_na))); /* perl function */ + SvPV (ST (2), PL_na), /* function input */ + &weechat_perl_api_close_cb, + SvPV (ST (3), PL_na))); /* function close */ PERL_RETURN_STRING_FREE(result); } diff --git a/src/plugins/scripts/python/weechat-python-api.c b/src/plugins/scripts/python/weechat-python-api.c index 1a183f8c0..f9893ff59 100644 --- a/src/plugins/scripts/python/weechat-python-api.c +++ b/src/plugins/scripts/python/weechat-python-api.c @@ -1762,11 +1762,13 @@ int weechat_python_api_hook_timer_cb (void *data) { struct t_script_callback *script_callback; - char *python_argv[1] = { NULL }; + char *python_argv[1]; int *rc, ret; script_callback = (struct t_script_callback *)data; + python_argv[0] = NULL; + rc = (int *) weechat_python_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, script_callback->function, @@ -1833,11 +1835,13 @@ int weechat_python_api_hook_fd_cb (void *data) { struct t_script_callback *script_callback; - char *python_argv[1] = { NULL }; + char *python_argv[1]; int *rc, ret; script_callback = (struct t_script_callback *)data; + python_argv[0] = NULL; + rc = (int *) weechat_python_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, script_callback->function, @@ -2457,6 +2461,39 @@ weechat_python_api_input_data_cb (void *data, struct t_gui_buffer *buffer, return ret; } +/* + * weechat_python_api_close_cb: callback for buffer closed + */ + +int +weechat_python_api_close_cb (void *data, struct t_gui_buffer *buffer) +{ + struct t_script_callback *script_callback; + char *python_argv[2]; + int *r, ret; + + script_callback = (struct t_script_callback *)data; + + python_argv[0] = script_ptr2str (buffer); + python_argv[1] = NULL; + + r = (int *) weechat_python_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + python_argv); + if (!r) + ret = WEECHAT_RC_ERROR; + else + { + ret = *r; + free (r); + } + if (python_argv[0]) + free (python_argv[0]); + + return ret; +} + /* * weechat_python_api_buffer_new: create a new buffer */ @@ -2464,7 +2501,7 @@ weechat_python_api_input_data_cb (void *data, struct t_gui_buffer *buffer, static PyObject * weechat_python_api_buffer_new (PyObject *self, PyObject *args) { - char *category, *name, *function, *result; + char *category, *name, *function_input, *function_close, *result; PyObject *object; /* make C compiler happy */ @@ -2478,9 +2515,11 @@ weechat_python_api_buffer_new (PyObject *self, PyObject *args) category = NULL; name = NULL; - function = NULL; + function_input = NULL; + function_close = NULL; - if (!PyArg_ParseTuple (args, "sss", &category, &name, &function)) + if (!PyArg_ParseTuple (args, "ssss", &category, &name, &function_input, + &function_close)) { WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("buffer_new"); PYTHON_RETURN_EMPTY; @@ -2491,7 +2530,9 @@ weechat_python_api_buffer_new (PyObject *self, PyObject *args) category, name, &weechat_python_api_input_data_cb, - function)); + function_input, + &weechat_python_api_close_cb, + function_close)); PYTHON_RETURN_STRING_FREE(result); } diff --git a/src/plugins/scripts/ruby/weechat-ruby-api.c b/src/plugins/scripts/ruby/weechat-ruby-api.c index 4ec76134e..8dc1d388f 100644 --- a/src/plugins/scripts/ruby/weechat-ruby-api.c +++ b/src/plugins/scripts/ruby/weechat-ruby-api.c @@ -1163,7 +1163,7 @@ weechat_ruby_api_config_option_change_cb (void *data) if (script_callback->function && script_callback->function[0]) { - ruby_argv[1] = NULL; + ruby_argv[0] = NULL; rc = (int *) weechat_ruby_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, @@ -2042,11 +2042,13 @@ int weechat_ruby_api_hook_timer_cb (void *data) { struct t_script_callback *script_callback; - char *ruby_argv[1] = { NULL }; + char *ruby_argv[1]; int *rc, ret; script_callback = (struct t_script_callback *)data; + ruby_argv[0] = NULL; + rc = (int *) weechat_ruby_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, script_callback->function, @@ -2124,11 +2126,13 @@ int weechat_ruby_api_hook_fd_cb (void *data) { struct t_script_callback *script_callback; - char *ruby_argv[1] = { NULL }; + char *ruby_argv[1]; int *rc, ret; script_callback = (struct t_script_callback *)data; + ruby_argv[0] = NULL; + rc = (int *) weechat_ruby_exec (script_callback->script, WEECHAT_SCRIPT_EXEC_INT, script_callback->function, @@ -2821,15 +2825,49 @@ weechat_ruby_api_input_data_cb (void *data, struct t_gui_buffer *buffer, return ret; } +/* + * weechat_ruby_api_close_cb: callback for closed buffer + */ + +int +weechat_ruby_api_close_cb (void *data, struct t_gui_buffer *buffer) +{ + struct t_script_callback *script_callback; + char *ruby_argv[2]; + int *rc, ret; + + script_callback = (struct t_script_callback *)data; + + ruby_argv[0] = script_ptr2str (buffer); + ruby_argv[1] = NULL; + + rc = (int *) weechat_ruby_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + ruby_argv); + + if (!rc) + ret = WEECHAT_RC_ERROR; + else + { + ret = *rc; + free (rc); + } + if (ruby_argv[0]) + free (ruby_argv[0]); + + return ret; +} + /* * weechat_ruby_api_buffer_new: create a new buffer */ static VALUE weechat_ruby_api_buffer_new (VALUE class, VALUE category, VALUE name, - VALUE function) + VALUE function_input, VALUE function_close) { - char *c_category, *c_name, *c_function, *result; + char *c_category, *c_name, *c_function_input, *c_function_close, *result; VALUE return_value; /* make C compiler happy */ @@ -2843,9 +2881,11 @@ weechat_ruby_api_buffer_new (VALUE class, VALUE category, VALUE name, c_category = NULL; c_name = NULL; - c_function = NULL; + c_function_input = NULL; + c_function_close = NULL; - if (NIL_P (category) || NIL_P (name) || NIL_P (function)) + if (NIL_P (category) || NIL_P (name) || NIL_P (function_input) + || NIL_P (function_close)) { WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("buffer_new"); RUBY_RETURN_EMPTY; @@ -2853,18 +2893,22 @@ weechat_ruby_api_buffer_new (VALUE class, VALUE category, VALUE name, Check_Type (category, T_STRING); Check_Type (name, T_STRING); - Check_Type (function, T_STRING); + Check_Type (function_input, T_STRING); + Check_Type (function_close, T_STRING); c_category = STR2CSTR (category); c_name = STR2CSTR (name); - c_function = STR2CSTR (function); + c_function_input = STR2CSTR (function_input); + c_function_close = STR2CSTR (function_close); result = script_ptr2str (script_api_buffer_new (weechat_ruby_plugin, ruby_current_script, c_category, c_name, &weechat_ruby_api_input_data_cb, - c_function)); + c_function_input, + &weechat_ruby_api_close_cb, + c_function_close)); RUBY_RETURN_STRING_FREE(result); } @@ -3489,7 +3533,7 @@ weechat_ruby_api_init (VALUE ruby_mWeechat) rb_define_module_function (ruby_mWeechat, "hook_modifier_exec", &weechat_ruby_api_hook_modifier_exec, 3); rb_define_module_function (ruby_mWeechat, "unhook", &weechat_ruby_api_unhook, 1); rb_define_module_function (ruby_mWeechat, "unhook_all", &weechat_ruby_api_unhook_all, 0); - rb_define_module_function (ruby_mWeechat, "buffer_new", &weechat_ruby_api_buffer_new, 3); + rb_define_module_function (ruby_mWeechat, "buffer_new", &weechat_ruby_api_buffer_new, 4); rb_define_module_function (ruby_mWeechat, "buffer_search", &weechat_ruby_api_buffer_search, 2); rb_define_module_function (ruby_mWeechat, "buffer_close", &weechat_ruby_api_buffer_close, 1); rb_define_module_function (ruby_mWeechat, "buffer_get", &weechat_ruby_api_buffer_get, 2); diff --git a/src/plugins/scripts/script-api.c b/src/plugins/scripts/script-api.c index db93927d5..7981282be 100644 --- a/src/plugins/scripts/script-api.c +++ b/src/plugins/scripts/script-api.c @@ -710,34 +710,76 @@ struct t_gui_buffer * script_api_buffer_new (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, char *category, char *name, - int (*callback)(void *data, - struct t_gui_buffer *buffer, - char *input_data), - char *function) + int (*input_callback)(void *data, + struct t_gui_buffer *buffer, + char *input_data), + char *function_input, + int (*close_callback)(void *data, + struct t_gui_buffer *buffer), + char *function_close) { - struct t_script_callback *new_script_callback; + struct t_script_callback *new_script_callback_input; + struct t_script_callback *new_script_callback_close; struct t_gui_buffer *new_buffer; - if (!function || !function[0]) - return weechat_buffer_new (category, name, NULL, NULL); + if ((!function_input || !function_input[0]) + && (!function_close || !function_close[0])) + return weechat_buffer_new (category, name, NULL, NULL, NULL, NULL); - new_script_callback = script_callback_alloc (); - if (!new_script_callback) - return NULL; + new_script_callback_input = NULL; + new_script_callback_close = NULL; - new_buffer = weechat_buffer_new (category, name, - callback, new_script_callback); - if (!new_buffer) + if (function_input && function_input[0]) { - free (new_script_callback); - return NULL; + new_script_callback_input = script_callback_alloc (); + if (!new_script_callback_input) + return NULL; } - new_script_callback->script = script; - new_script_callback->function = strdup (function); - new_script_callback->buffer = new_buffer; + if (function_close && function_close[0]) + { + new_script_callback_close = script_callback_alloc (); + if (!new_script_callback_close) + { + if (new_script_callback_input) + free (new_script_callback_input); + return NULL; + } + } - script_callback_add (script, new_script_callback); + new_buffer = weechat_buffer_new (category, name, + (new_script_callback_input) ? + input_callback : NULL, + (new_script_callback_input) ? + function_input : NULL, + (new_script_callback_close) ? + close_callback : NULL, + (new_script_callback_close) ? + function_close : NULL); + if (!new_buffer) + { + if (new_script_callback_input) + free (new_script_callback_input); + if (new_script_callback_close) + free (new_script_callback_close); + return NULL; + } + + if (new_script_callback_input) + { + new_script_callback_input->script = script; + new_script_callback_input->function = strdup (function_input); + new_script_callback_input->buffer = new_buffer; + script_callback_add (script, new_script_callback_input); + } + + if (new_script_callback_close) + { + new_script_callback_close->script = script; + new_script_callback_close->function = strdup (function_close); + new_script_callback_close->buffer = new_buffer; + script_callback_add (script, new_script_callback_close); + } return new_buffer; } diff --git a/src/plugins/scripts/script-api.h b/src/plugins/scripts/script-api.h index 4a970d8ba..2081d9c99 100644 --- a/src/plugins/scripts/script-api.h +++ b/src/plugins/scripts/script-api.h @@ -137,13 +137,16 @@ extern void script_api_unhook (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, struct t_hook *hook); extern void script_api_unhook_all (struct t_plugin_script *script); -struct t_gui_buffer *script_api_buffer_new (struct t_weechat_plugin *weechat_plugin, - struct t_plugin_script *script, - char *category, char *name, - int (*callback)(void *data, - struct t_gui_buffer *buffer, - char *input_data), - char *function); +extern struct t_gui_buffer *script_api_buffer_new (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + char *category, char *name, + int (*input_callback)(void *data, + struct t_gui_buffer *buffer, + char *input_data), + char *function_input, + int (*close_callback)(void *data, + struct t_gui_buffer *buffer), + char *function_close); extern void script_api_buffer_close (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, struct t_gui_buffer *buffer, diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index e4d201e44..34bda39d9 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -285,7 +285,10 @@ struct t_weechat_plugin int (*input_callback)(void *data, struct t_gui_buffer *buffer, char *input_data), - void *input_callback_data); + void *input_callback_data, + int (*close_callback)(void *data, + struct t_gui_buffer *buffer), + void *close_callback_data); struct t_gui_buffer *(*buffer_search) (char *category, char *name); void (*buffer_close) (struct t_gui_buffer *buffer, int switch_to_another); void *(*buffer_get) (struct t_gui_buffer *buffer, char *property); @@ -579,9 +582,11 @@ struct t_weechat_plugin /* buffers */ #define weechat_buffer_new(__category, __name, __input_callback, \ - __input_callback_data) \ + __input_callback_data, __close_callback, \ + __close_callback_data) \ weechat_plugin->buffer_new(weechat_plugin, __category, __name, \ - __input_callback, __input_callback_data) + __input_callback, __input_callback_data, \ + __close_callback, __close_callback_data) #define weechat_buffer_search(__category, __name) \ weechat_plugin->buffer_search(__category, __name) #define weechat_current_buffer \