diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2011-12-17 17:39:19 +0100 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2011-12-17 17:39:19 +0100 |
commit | 16ae7e26638f4b115b217231fc35ff4f40d66c63 (patch) | |
tree | 114f6e75f7e8902a79f3fb2c2064d10e18327b77 /src | |
parent | f0b81813953897e66cfe1ed5bd4b545111efe2e4 (diff) | |
download | weechat-16ae7e26638f4b115b217231fc35ff4f40d66c63.zip |
relay: add commands "sync" and "desync" in WeeChat protocol
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-msg.c | 82 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-msg.h | 6 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-protocol.c | 480 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-protocol.h | 13 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat.c | 152 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat.h | 11 |
6 files changed, 695 insertions, 49 deletions
diff --git a/src/plugins/relay/weechat/relay-weechat-msg.c b/src/plugins/relay/weechat/relay-weechat-msg.c index 188e1809e..e3bb00532 100644 --- a/src/plugins/relay/weechat/relay-weechat-msg.c +++ b/src/plugins/relay/weechat/relay-weechat-msg.c @@ -599,7 +599,7 @@ relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, void *pointer, const char *arguments) { - struct t_infolist *infolist; + struct t_infolist *ptr_infolist; const char *fields; char **list_fields; void *buf_ptr; @@ -607,8 +607,8 @@ relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, int pos_count_items, count_items, pos_count_vars, count_vars; uint32_t count32; - infolist = weechat_infolist_get (name, pointer, arguments); - if (!infolist) + ptr_infolist = weechat_infolist_get (name, pointer, arguments); + if (!ptr_infolist) return; /* start infolist in message */ @@ -620,9 +620,9 @@ relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, count_items = 0; relay_weechat_msg_add_int (msg, 0); - while (weechat_infolist_next (infolist)) + while (weechat_infolist_next (ptr_infolist)) { - fields = weechat_infolist_fields (infolist); + fields = weechat_infolist_fields (ptr_infolist); if (fields) { list_fields = weechat_string_split (fields, ",", 0, 0, &num_fields); @@ -643,24 +643,24 @@ relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, case 'i': relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_INT); relay_weechat_msg_add_int (msg, - weechat_infolist_integer (infolist, + weechat_infolist_integer (ptr_infolist, list_fields[i] + 2)); break; case 's': relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_STRING); relay_weechat_msg_add_string (msg, - weechat_infolist_string (infolist, + weechat_infolist_string (ptr_infolist, list_fields[i] + 2)); break; case 'p': relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_POINTER); relay_weechat_msg_add_pointer (msg, - weechat_infolist_pointer (infolist, + weechat_infolist_pointer (ptr_infolist, list_fields[i] + 2)); break; case 'b': relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_BUFFER); - buf_ptr = weechat_infolist_buffer (infolist, + buf_ptr = weechat_infolist_buffer (ptr_infolist, list_fields[i] + 2, &buf_size); relay_weechat_msg_add_buffer (msg, buf_ptr, buf_size); @@ -668,7 +668,7 @@ relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, case 't': relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_TIME); relay_weechat_msg_add_time (msg, - weechat_infolist_time (infolist, + weechat_infolist_time (ptr_infolist, list_fields[i] + 2)); break; } @@ -688,7 +688,7 @@ relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, count32 = htonl ((uint32_t)count_items); relay_weechat_msg_set_bytes (msg, pos_count_items, &count32, 4); - weechat_infolist_free (infolist); + weechat_infolist_free (ptr_infolist); } /* @@ -726,6 +726,10 @@ relay_weechat_msg_add_nicklist_buffer (struct t_relay_weechat_msg *msg, (char)weechat_hdata_integer(ptr_hdata_nick, ptr_nick, "visible")); + relay_weechat_msg_add_int (msg, + weechat_hdata_integer (ptr_hdata_nick, + ptr_nick, + "level")); relay_weechat_msg_add_string (msg, weechat_hdata_string (ptr_hdata_nick, ptr_nick, @@ -742,10 +746,6 @@ relay_weechat_msg_add_nicklist_buffer (struct t_relay_weechat_msg *msg, weechat_hdata_string (ptr_hdata_nick, ptr_nick, "prefix_color")); - relay_weechat_msg_add_int (msg, - weechat_hdata_integer (ptr_hdata_nick, - ptr_nick, - "level")); count++; } else @@ -757,6 +757,10 @@ relay_weechat_msg_add_nicklist_buffer (struct t_relay_weechat_msg *msg, (char)weechat_hdata_integer(ptr_hdata_group, ptr_group, "visible")); + relay_weechat_msg_add_int (msg, + weechat_hdata_integer (ptr_hdata_group, + ptr_group, + "level")); relay_weechat_msg_add_string (msg, weechat_hdata_string (ptr_hdata_group, ptr_group, @@ -767,10 +771,6 @@ relay_weechat_msg_add_nicklist_buffer (struct t_relay_weechat_msg *msg, "color")); relay_weechat_msg_add_string (msg, NULL); /* prefix */ relay_weechat_msg_add_string (msg, NULL); /* prefix_color */ - relay_weechat_msg_add_int (msg, - weechat_hdata_integer (ptr_hdata_group, - ptr_group, - "level")); count++; } weechat_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick); @@ -794,10 +794,11 @@ relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg, uint32_t count32; relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_HDATA); - relay_weechat_msg_add_string (msg, "buffer/nick_group"); + relay_weechat_msg_add_string (msg, "buffer/nicklist_item"); relay_weechat_msg_add_string (msg, - "group:chr,visible:chr,name:str,color:str," - "prefix:str,prefix_color:str,level:int"); + "group:chr,visible:chr,level:int," + "name:str,color:str," + "prefix:str,prefix_color:str"); /* "count" will be set later, with number of objects in hdata */ pos_count = msg->data_size; @@ -827,7 +828,8 @@ relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg, void relay_weechat_msg_send (struct t_relay_client *client, - struct t_relay_weechat_msg *msg) + struct t_relay_weechat_msg *msg, + int display_in_raw_buffer) { uint32_t size32; char compression; @@ -862,18 +864,20 @@ relay_weechat_msg_send (struct t_relay_client *client, num_sent = send (client->sock, dest, dest_size + 5, 0); /* display message in raw buffer */ - relay_raw_print (client, RELAY_RAW_FLAG_SEND, - "obj: %d/%d bytes (%d%%, %ldms), id: %s", - (int)dest_size + 5, - msg->data_size, - 100 - ((((int)dest_size + 5) * 100) / msg->data_size), - time_diff, - msg->id); - - if (num_sent < 0) + if (display_in_raw_buffer) { relay_raw_print (client, RELAY_RAW_FLAG_SEND, - "error: %s", strerror (errno)); + "obj: %d/%d bytes (%d%%, %ldms), id: %s", + (int)dest_size + 5, + msg->data_size, + 100 - ((((int)dest_size + 5) * 100) / msg->data_size), + time_diff, + msg->id); + if (num_sent < 0) + { + relay_raw_print (client, RELAY_RAW_FLAG_SEND, + "error: %s", strerror (errno)); + } } free (dest); @@ -894,13 +898,15 @@ relay_weechat_msg_send (struct t_relay_client *client, num_sent = send (client->sock, msg->data, msg->data_size, 0); /* display message in raw buffer */ - relay_raw_print (client, RELAY_RAW_FLAG_SEND, - "obj: %d bytes", msg->data_size); - - if (num_sent < 0) + if (display_in_raw_buffer) { relay_raw_print (client, RELAY_RAW_FLAG_SEND, - "error: %s", strerror (errno)); + "obj: %d bytes", msg->data_size); + if (num_sent < 0) + { + relay_raw_print (client, RELAY_RAW_FLAG_SEND, + "error: %s", strerror (errno)); + } } } diff --git a/src/plugins/relay/weechat/relay-weechat-msg.h b/src/plugins/relay/weechat/relay-weechat-msg.h index 044219969..d0eae96ab 100644 --- a/src/plugins/relay/weechat/relay-weechat-msg.h +++ b/src/plugins/relay/weechat/relay-weechat-msg.h @@ -64,9 +64,6 @@ extern void relay_weechat_msg_add_pointer (struct t_relay_weechat_msg *msg, void *pointer); extern void relay_weechat_msg_add_time (struct t_relay_weechat_msg *msg, time_t time); -extern void relay_weechat_msg_add_hdata1 (struct t_relay_weechat_msg *msg, - const char *name, const char *list, - const char *keys); extern void relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg, const char *path, const char *keys); extern void relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, @@ -76,7 +73,8 @@ extern void relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, extern void relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg, struct t_gui_buffer *buffer); extern void relay_weechat_msg_send (struct t_relay_client *client, - struct t_relay_weechat_msg *msg); + struct t_relay_weechat_msg *msg, + int display_in_raw_buffer); extern void relay_weechat_msg_free (struct t_relay_weechat_msg *msg); #endif /* __WEECHAT_RELAY_WEECHAT_MSG_H */ diff --git a/src/plugins/relay/weechat/relay-weechat-protocol.c b/src/plugins/relay/weechat/relay-weechat-protocol.c index 56902de0b..fe9b4c18b 100644 --- a/src/plugins/relay/weechat/relay-weechat-protocol.c +++ b/src/plugins/relay/weechat/relay-weechat-protocol.c @@ -49,6 +49,7 @@ relay_weechat_protocol_get_buffer (const char *arg) long unsigned int value; int rc; char *pos, *plugin; + struct t_hdata *ptr_hdata; ptr_buffer = NULL; @@ -56,7 +57,18 @@ relay_weechat_protocol_get_buffer (const char *arg) { rc = sscanf (arg, "%lx", &value); if ((rc != EOF) && (rc != 0)) - ptr_buffer = (void *)value; + ptr_buffer = (struct t_gui_buffer *)value; + if (ptr_buffer) + { + ptr_hdata = weechat_hdata_get ("buffer"); + if (!weechat_hdata_check_pointer (ptr_hdata, + weechat_hdata_get_list (ptr_hdata, "gui_buffers"), + ptr_buffer)) + { + /* invalid pointer! */ + ptr_buffer = NULL; + } + } } else { @@ -133,7 +145,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(hdata) { relay_weechat_msg_add_hdata (msg, argv[0], (argc > 1) ? argv_eol[1] : NULL); - relay_weechat_msg_send (client, msg); + relay_weechat_msg_send (client, msg, 1); relay_weechat_msg_free (msg); } @@ -159,7 +171,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(info) relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_INFO); relay_weechat_msg_add_string (msg, argv[0]); relay_weechat_msg_add_string (msg, info); - relay_weechat_msg_send (client, msg); + relay_weechat_msg_send (client, msg, 1); relay_weechat_msg_free (msg); } @@ -193,7 +205,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(infolist) args = argv_eol[2]; } relay_weechat_msg_add_infolist (msg, argv[0], (void *)value, args); - relay_weechat_msg_send (client, msg); + relay_weechat_msg_send (client, msg, 1); relay_weechat_msg_free (msg); } @@ -224,7 +236,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(nicklist) if (msg) { relay_weechat_msg_add_nicklist (msg, ptr_buffer); - relay_weechat_msg_send (client, msg); + relay_weechat_msg_send (client, msg, 1); relay_weechat_msg_free (msg); } @@ -249,6 +261,460 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(input) } /* + * relay_weechat_protocol_signal_buffer_cb: callback for "buffer_*" signals + */ + +int +relay_weechat_protocol_signal_buffer_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) +{ + struct t_relay_client *ptr_client; + struct t_gui_line *ptr_line; + struct t_hdata *ptr_hdata_line, *ptr_hdata_line_data; + struct t_gui_line_data *ptr_line_data; + struct t_gui_buffer *ptr_buffer; + struct t_relay_weechat_msg *msg; + char cmd_hdata[64]; + + /* make C compiler happy */ + (void) signal; + (void) type_data; + + ptr_client = (struct t_relay_client *)data; + if (!ptr_client || !relay_client_valid (ptr_client)) + return WEECHAT_RC_OK; + + if (strcmp (signal, "buffer_opened") == 0) + { + ptr_buffer = (struct t_gui_buffer *)signal_data; + if (!ptr_buffer) + return WEECHAT_RC_OK; + + msg = relay_weechat_msg_new ("_buffer_opened"); + if (msg) + { + snprintf (cmd_hdata, sizeof (cmd_hdata), + "buffer:0x%lx", (long unsigned int)ptr_buffer); + relay_weechat_msg_add_hdata (msg, cmd_hdata, + "number,full_name,short_name," + "nicklist,title," + "prev_buffer,next_buffer"); + relay_weechat_msg_send (ptr_client, msg, 0); + relay_weechat_msg_free (msg); + } + } + else if (strcmp (signal, "buffer_moved") == 0) + { + ptr_buffer = (struct t_gui_buffer *)signal_data; + if (!ptr_buffer) + return WEECHAT_RC_OK; + + msg = relay_weechat_msg_new ("_buffer_moved"); + if (msg) + { + snprintf (cmd_hdata, sizeof (cmd_hdata), + "buffer:0x%lx", (long unsigned int)ptr_buffer); + relay_weechat_msg_add_hdata (msg, cmd_hdata, + "number,full_name," + "prev_buffer,next_buffer"); + relay_weechat_msg_send (ptr_client, msg, 0); + relay_weechat_msg_free (msg); + } + } + else if (strcmp (signal, "buffer_merged") == 0) + { + ptr_buffer = (struct t_gui_buffer *)signal_data; + if (!ptr_buffer) + return WEECHAT_RC_OK; + + msg = relay_weechat_msg_new ("_buffer_merged"); + if (msg) + { + snprintf (cmd_hdata, sizeof (cmd_hdata), + "buffer:0x%lx", (long unsigned int)ptr_buffer); + relay_weechat_msg_add_hdata (msg, cmd_hdata, + "number,full_name," + "prev_buffer,next_buffer"); + relay_weechat_msg_send (ptr_client, msg, 0); + relay_weechat_msg_free (msg); + } + } + else if (strcmp (signal, "buffer_renamed") == 0) + { + ptr_buffer = (struct t_gui_buffer *)signal_data; + if (!ptr_buffer) + return WEECHAT_RC_OK; + + msg = relay_weechat_msg_new ("_buffer_renamed"); + if (msg) + { + snprintf (cmd_hdata, sizeof (cmd_hdata), + "buffer:0x%lx", (long unsigned int)ptr_buffer); + relay_weechat_msg_add_hdata (msg, cmd_hdata, + "number,full_name,short_name"); + relay_weechat_msg_send (ptr_client, msg, 0); + relay_weechat_msg_free (msg); + } + } + else if (strcmp (signal, "buffer_title_changed") == 0) + { + ptr_buffer = (struct t_gui_buffer *)signal_data; + if (!ptr_buffer) + return WEECHAT_RC_OK; + + msg = relay_weechat_msg_new ("_buffer_title_changed"); + if (msg) + { + snprintf (cmd_hdata, sizeof (cmd_hdata), + "buffer:0x%lx", (long unsigned int)ptr_buffer); + relay_weechat_msg_add_hdata (msg, cmd_hdata, + "number,full_name,title"); + relay_weechat_msg_send (ptr_client, msg, 0); + relay_weechat_msg_free (msg); + } + } + else if (strcmp (signal, "buffer_line_added") == 0) + { + ptr_line = (struct t_gui_line *)signal_data; + if (!ptr_line) + return WEECHAT_RC_OK; + + ptr_hdata_line = weechat_hdata_get ("line"); + if (!ptr_hdata_line) + return WEECHAT_RC_OK; + + ptr_hdata_line_data = weechat_hdata_get ("line_data"); + if (!ptr_hdata_line_data) + return WEECHAT_RC_OK; + + ptr_line_data = weechat_hdata_pointer (ptr_hdata_line, ptr_line, "data"); + if (!ptr_line_data) + return WEECHAT_RC_OK; + + ptr_buffer = weechat_hdata_pointer (ptr_hdata_line_data, ptr_line_data, + "buffer"); + if (!ptr_buffer) + return WEECHAT_RC_OK; + + /* check if buffer is synchronized (== able to receive events) */ + if (weechat_hashtable_has_key (RELAY_WEECHAT_DATA(ptr_client, buffers_sync), + "*") + || weechat_hashtable_has_key (RELAY_WEECHAT_DATA(ptr_client, buffers_sync), + weechat_buffer_get_string (ptr_buffer, + "full_name"))) + { + msg = relay_weechat_msg_new ("_buffer_line_added"); + if (msg) + { + snprintf (cmd_hdata, sizeof (cmd_hdata), + "line_data:0x%lx", + (long unsigned int)ptr_line_data); + relay_weechat_msg_add_hdata (msg, cmd_hdata, + "buffer,date,displayed,prefix,message"); + relay_weechat_msg_send (ptr_client, msg, 0); + relay_weechat_msg_free (msg); + } + } + } + else if (strcmp (signal, "buffer_closing") == 0) + { + ptr_buffer = (struct t_gui_buffer *)signal_data; + if (!ptr_buffer) + return WEECHAT_RC_OK; + + msg = relay_weechat_msg_new ("_buffer_closing"); + if (msg) + { + snprintf (cmd_hdata, sizeof (cmd_hdata), + "buffer:0x%lx", (long unsigned int)ptr_buffer); + weechat_hashtable_remove (RELAY_WEECHAT_DATA(ptr_client, buffers_nicklist), + cmd_hdata + 7); + relay_weechat_msg_add_hdata (msg, cmd_hdata, + "number,full_name"); + relay_weechat_msg_send (ptr_client, msg, 0); + relay_weechat_msg_free (msg); + } + } + + return WEECHAT_RC_OK; +} + +/* + * relay_weechat_protocol_nicklist_map_cb: callback for entries in hashtable + * "buffers_nicklist" of client + * (send nicklist for each buffer in + * this hashtable) + */ + +void +relay_weechat_protocol_nicklist_map_cb (void *data, + struct t_hashtable *hashtable, + const void *key, + const void *value) +{ + struct t_relay_client *ptr_client; + int rc; + long unsigned int buffer; + struct t_hdata *ptr_hdata; + struct t_relay_weechat_msg *msg; + + /* make C compiler happy */ + (void) hashtable; + (void) value; + + ptr_client = (struct t_relay_client *)data; + + rc = sscanf (key, "%lx", &buffer); + if ((rc != EOF) && (rc != 0)) + { + ptr_hdata = weechat_hdata_get ("buffer"); + if (ptr_hdata) + { + if (weechat_hdata_check_pointer (ptr_hdata, + weechat_hdata_get_list (ptr_hdata, "gui_buffers"), + (void *)buffer)) + { + msg = relay_weechat_msg_new ("_nicklist"); + if (msg) + { + relay_weechat_msg_add_nicklist (msg, (struct t_gui_buffer *)buffer); + relay_weechat_msg_send (ptr_client, msg, 1); + relay_weechat_msg_free (msg); + } + } + } + } +} + +/* + * relay_weechat_protocol_timer_nicklist_cb: callback for nicklist timer + */ + +int +relay_weechat_protocol_timer_nicklist_cb (void *data, int remaining_calls) +{ + struct t_relay_client *ptr_client; + + /* make C compiler happy */ + (void) remaining_calls; + + ptr_client = (struct t_relay_client *)data; + if (!ptr_client || !relay_client_valid (ptr_client)) + return WEECHAT_RC_OK; + + weechat_hashtable_map (RELAY_WEECHAT_DATA(ptr_client, buffers_nicklist), + &relay_weechat_protocol_nicklist_map_cb, + ptr_client); + + weechat_hashtable_remove_all (RELAY_WEECHAT_DATA(ptr_client, buffers_nicklist)); + + RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist) = NULL; + + return WEECHAT_RC_OK; +} + +/* + * relay_weechat_protocol_signal_nicklist_cb: callback for "nicklist_*" signals + */ + +int +relay_weechat_protocol_signal_nicklist_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) +{ + struct t_relay_client *ptr_client; + char *pos, *str_buffer; + + /* make C compiler happy */ + (void) signal; + (void) type_data; + + ptr_client = (struct t_relay_client *)data; + if (!ptr_client || !relay_client_valid (ptr_client)) + return WEECHAT_RC_OK; + + pos = strchr ((char *)signal_data, ','); + if (!pos) + return WEECHAT_RC_OK; + + str_buffer = weechat_strndup (signal_data, pos - (char *)signal_data); + if (!str_buffer) + return WEECHAT_RC_OK; + weechat_hashtable_set (RELAY_WEECHAT_DATA(ptr_client, buffers_nicklist), + str_buffer, "1"); + free (str_buffer); + + if (RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist)) + { + weechat_unhook (RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist)); + RELAY_WEECHAT_DATA(ptr_client, hook_timer_nicklist) = NULL; + } + relay_weechat_hook_timer_nicklist (ptr_client); + + return WEECHAT_RC_OK; +} + +/* + * relay_weechat_protocol_cb_sync: 'sync' command from client + */ + +RELAY_WEECHAT_PROTOCOL_CALLBACK(sync) +{ + char **buffers, **flags, *full_name; + int num_buffers, num_flags, i, add_flags, *ptr_old_flags, new_flags; + struct t_gui_buffer *ptr_buffer; + + RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0); + + buffers = weechat_string_split ((argc > 0) ? argv[1] : "*", ",", 0, 0, + &num_buffers); + if (buffers) + { + add_flags = RELAY_WEECHAT_PROTOCOL_SYNC_BUFFER | + RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST; + if (argc > 1) + { + flags = weechat_string_split (argv[2], ",", 0, 0, &num_flags); + if (flags) + { + add_flags = 0; + for (i = 0; i < num_flags; i++) + { + if (strcmp (flags[i], "buffer") == 0) + add_flags |= RELAY_WEECHAT_PROTOCOL_SYNC_BUFFER; + else if (strcmp (flags[i], "nicklist") == 0) + add_flags |= RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST; + } + if (add_flags == 0) + { + add_flags = RELAY_WEECHAT_PROTOCOL_SYNC_BUFFER | + RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST; + } + weechat_string_free_split (flags); + } + } + for (i = 0; i < num_buffers; i++) + { + full_name = NULL; + if (strcmp (buffers[i], "*") == 0) + { + full_name = strdup ("*"); + } + else + { + ptr_buffer = relay_weechat_protocol_get_buffer (buffers[i]); + if (ptr_buffer) + full_name = strdup (weechat_buffer_get_string (ptr_buffer, + "full_name")); + } + if (full_name) + { + ptr_old_flags = weechat_hashtable_get (RELAY_WEECHAT_DATA(client, buffers_sync), + full_name); + new_flags = ((ptr_old_flags) ? *ptr_old_flags : 0); + new_flags |= add_flags; + weechat_hashtable_set (RELAY_WEECHAT_DATA(client, buffers_sync), + full_name, + &new_flags); + free (full_name); + } + } + weechat_string_free_split (buffers); + } + + if (!RELAY_WEECHAT_DATA(client, hook_signal_buffer)) + relay_weechat_hook_signals (client); + + return WEECHAT_RC_OK; +} + +/* + * relay_weechat_protocol_cb_desync: 'desync' command from client + */ + +RELAY_WEECHAT_PROTOCOL_CALLBACK(desync) +{ + char **buffers, **flags, *full_name; + int num_buffers, num_flags, i, sub_flags, *ptr_old_flags, new_flags; + struct t_gui_buffer *ptr_buffer; + + RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0); + + buffers = weechat_string_split ((argc > 0) ? argv[1] : "*", ",", 0, 0, + &num_buffers); + if (buffers) + { + sub_flags = RELAY_WEECHAT_PROTOCOL_SYNC_BUFFER | + RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST; + if (argc > 1) + { + flags = weechat_string_split (argv[2], ",", 0, 0, &num_flags); + if (flags) + { + sub_flags = 0; + for (i = 0; i < num_flags; i++) + { + if (strcmp (flags[i], "buffer") == 0) + sub_flags |= RELAY_WEECHAT_PROTOCOL_SYNC_BUFFER; + else if (strcmp (flags[i], "nicklist") == 0) + sub_flags |= RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST; + } + if (sub_flags == 0) + { + sub_flags = RELAY_WEECHAT_PROTOCOL_SYNC_BUFFER | + RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST; + } + weechat_string_free_split (flags); + } + } + for (i = 0; i < num_buffers; i++) + { + full_name = NULL; + if (strcmp (buffers[i], "*") == 0) + { + full_name = strdup ("*"); + } + else + { + ptr_buffer = relay_weechat_protocol_get_buffer (buffers[i]); + if (ptr_buffer) + full_name = strdup (weechat_buffer_get_string (ptr_buffer, + "full_name")); + } + if (full_name) + { + ptr_old_flags = weechat_hashtable_get (RELAY_WEECHAT_DATA(client, buffers_sync), + full_name); + new_flags = ((ptr_old_flags) ? *ptr_old_flags : 0); + new_flags &= ~sub_flags; + if (new_flags) + { + weechat_hashtable_set (RELAY_WEECHAT_DATA(client, buffers_sync), + full_name, + &new_flags); + } + else + { + weechat_hashtable_remove (RELAY_WEECHAT_DATA(client, buffers_sync), + full_name); + } + free (full_name); + } + } + weechat_string_free_split (buffers); + } + + if (weechat_hashtable_get_integer (RELAY_WEECHAT_DATA(client, buffers_sync), + "items_count") == 0) + { + relay_weechat_unhook_signals (client); + } + + return WEECHAT_RC_OK; +} + +/* * relay_weechat_protocol_cb_test: 'test' command from client */ @@ -281,7 +747,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(test) relay_weechat_msg_add_pointer (msg, &msg); relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_TIME); relay_weechat_msg_add_time (msg, 1321993456); - relay_weechat_msg_send (client, msg); + relay_weechat_msg_send (client, msg, 1); relay_weechat_msg_free (msg); } @@ -317,6 +783,8 @@ relay_weechat_protocol_recv (struct t_relay_client *client, char *data) { "infolist", &relay_weechat_protocol_cb_infolist }, { "nicklist", &relay_weechat_protocol_cb_nicklist }, { "input", &relay_weechat_protocol_cb_input }, + { "sync", &relay_weechat_protocol_cb_sync }, + { "desync", &relay_weechat_protocol_cb_desync }, { "test", &relay_weechat_protocol_cb_test }, { "quit", &relay_weechat_protocol_cb_quit }, { NULL, NULL } diff --git a/src/plugins/relay/weechat/relay-weechat-protocol.h b/src/plugins/relay/weechat/relay-weechat-protocol.h index 8df7c76ee..e1a34b9a5 100644 --- a/src/plugins/relay/weechat/relay-weechat-protocol.h +++ b/src/plugins/relay/weechat/relay-weechat-protocol.h @@ -20,6 +20,9 @@ #ifndef __WEECHAT_RELAY_WEECHAT_PROTOCOL_H #define __WEECHAT_RELAY_WEECHAT_PROTOCOL_H 1 +#define RELAY_WEECHAT_PROTOCOL_SYNC_BUFFER 1 +#define RELAY_WEECHAT_PROTOCOL_SYNC_NICKLIST 2 + #define RELAY_WEECHAT_PROTOCOL_CALLBACK(__command) \ int \ relay_weechat_protocol_cb_##__command ( \ @@ -57,6 +60,16 @@ struct t_relay_weechat_protocol_cb t_relay_weechat_cmd_func *cmd_function; /* callback */ }; +extern int relay_weechat_protocol_signal_buffer_cb (void *data, + const char *signal, + const char *type_data, + void *signal_data); +extern int relay_weechat_protocol_signal_nicklist_cb (void *data, + const char *signal, + const char *type_data, + void *signal_data); +extern int relay_weechat_protocol_timer_nicklist_cb (void *data, + int remaining_calls); extern void relay_weechat_protocol_recv (struct t_relay_client *client, char *data); diff --git a/src/plugins/relay/weechat/relay-weechat.c b/src/plugins/relay/weechat/relay-weechat.c index 45f96aa2d..6c47be584 100644 --- a/src/plugins/relay/weechat/relay-weechat.c +++ b/src/plugins/relay/weechat/relay-weechat.c @@ -67,6 +67,55 @@ relay_weechat_compression_search (const char *compression) } /* + * relay_weechat_hook_signals: hook signals for a client + */ + +void +relay_weechat_hook_signals (struct t_relay_client *client) +{ + RELAY_WEECHAT_DATA(client, hook_signal_buffer) = + weechat_hook_signal ("buffer_*", + &relay_weechat_protocol_signal_buffer_cb, + client); + RELAY_WEECHAT_DATA(client, hook_signal_nicklist) = + weechat_hook_signal ("nicklist_*", + &relay_weechat_protocol_signal_nicklist_cb, + client); +} + +/* + * relay_weechat_unhook_signals: unhook signals for a client + */ + +void +relay_weechat_unhook_signals (struct t_relay_client *client) +{ + if (RELAY_WEECHAT_DATA(client, hook_signal_buffer)) + { + weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_buffer)); + RELAY_WEECHAT_DATA(client, hook_signal_buffer) = NULL; + } + if (RELAY_WEECHAT_DATA(client, hook_signal_nicklist)) + { + weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_nicklist)); + RELAY_WEECHAT_DATA(client, hook_signal_nicklist) = NULL; + } +} + +/* + * relay_weechat_hook_timer_nicklist: timer to update nicklists for a client + */ + +void +relay_weechat_hook_timer_nicklist (struct t_relay_client *client) +{ + RELAY_WEECHAT_DATA(client, hook_timer_nicklist) = + weechat_hook_timer (100, 0, 1, + &relay_weechat_protocol_timer_nicklist_cb, + client); +} + +/* * relay_weechat_recv: read data from client */ @@ -124,7 +173,7 @@ relay_weechat_recv (struct t_relay_client *client, const char *data) void relay_weechat_close_connection (struct t_relay_client *client) { - (void) client; + relay_weechat_unhook_signals (client); } /* @@ -148,6 +197,21 @@ relay_weechat_alloc (struct t_relay_client *client) #else RELAY_WEECHAT_DATA(client, compression) = 0; #endif + RELAY_WEECHAT_DATA(client, buffers_sync) = + weechat_hashtable_new (16, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_INTEGER, + NULL, + NULL); + RELAY_WEECHAT_DATA(client, hook_signal_buffer) = NULL; + RELAY_WEECHAT_DATA(client, hook_signal_nicklist) = NULL; + RELAY_WEECHAT_DATA(client, buffers_nicklist) = + weechat_hashtable_new (16, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + RELAY_WEECHAT_DATA(client, hook_timer_nicklist) = NULL; } } @@ -161,12 +225,70 @@ relay_weechat_alloc_with_infolist (struct t_relay_client *client, struct t_infolist *infolist) { struct t_relay_weechat_data *weechat_data; + int index, rc, value_int; + char name[64]; + const char *key, *value; client->protocol_data = malloc (sizeof (*weechat_data)); if (client->protocol_data) { + /* general stuff */ RELAY_WEECHAT_DATA(client, password_ok) = weechat_infolist_integer (infolist, "password_ok"); RELAY_WEECHAT_DATA(client, compression) = weechat_infolist_integer (infolist, "compression"); + + /* sync of buffers */ + RELAY_WEECHAT_DATA(client, buffers_sync) = weechat_hashtable_new (16, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + index = 0; + while (1) + { + snprintf (name, sizeof (name), "buffers_sync_name_%05d", index); + key = weechat_infolist_string (infolist, name); + if (!key) + break; + snprintf (name, sizeof (name), "buffers_sync_value_%05d", index); + value = weechat_infolist_string (infolist, name); + rc = sscanf (value, "%d", &value_int); + if ((rc == EOF) || (rc == 0)) + value_int = 0; + weechat_hashtable_set (RELAY_WEECHAT_DATA(client, buffers_sync), + key, + &value_int); + index++; + } + RELAY_WEECHAT_DATA(client, hook_signal_buffer) = NULL; + RELAY_WEECHAT_DATA(client, hook_signal_nicklist) = NULL; + RELAY_WEECHAT_DATA(client, buffers_nicklist) = + weechat_hashtable_new (16, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + index = 0; + while (1) + { + snprintf (name, sizeof (name), "buffers_nicklist_name_%05d", index); + key = weechat_infolist_string (infolist, name); + if (!key) + break; + snprintf (name, sizeof (name), "buffers_nicklist_value_%05d", index); + value = weechat_infolist_string (infolist, name); + weechat_hashtable_set (RELAY_WEECHAT_DATA(client, buffers_sync), + key, + value); + index++; + } + RELAY_WEECHAT_DATA(client, hook_timer_nicklist) = NULL; + + if (weechat_hashtable_get_integer (RELAY_WEECHAT_DATA(client, buffers_sync), + "items_count") > 0) + relay_weechat_hook_signals (client); + if (weechat_hashtable_get_integer (RELAY_WEECHAT_DATA(client, buffers_sync), + "items_count") > 0) + relay_weechat_hook_timer_nicklist (client); } } @@ -178,7 +300,20 @@ void relay_weechat_free (struct t_relay_client *client) { if (client->protocol_data) + { + if (RELAY_WEECHAT_DATA(client, buffers_sync)) + weechat_hashtable_free (RELAY_WEECHAT_DATA(client, buffers_sync)); + if (RELAY_WEECHAT_DATA(client, hook_signal_buffer)) + weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_buffer)); + if (RELAY_WEECHAT_DATA(client, hook_signal_nicklist)) + weechat_unhook (RELAY_WEECHAT_DATA(client, hook_signal_nicklist)); + if (RELAY_WEECHAT_DATA(client, buffers_nicklist)) + weechat_hashtable_free (RELAY_WEECHAT_DATA(client, buffers_nicklist)); + free (client->protocol_data); + + client->protocol_data = NULL; + } } /* @@ -197,6 +332,10 @@ relay_weechat_add_to_infolist (struct t_infolist_item *item, return 0; if (!weechat_infolist_new_var_integer (item, "compression", RELAY_WEECHAT_DATA(client, compression))) return 0; + if (!weechat_hashtable_add_to_infolist (RELAY_WEECHAT_DATA(client, buffers_sync), item, "buffers_sync")) + return 0; + if (!weechat_hashtable_add_to_infolist (RELAY_WEECHAT_DATA(client, buffers_nicklist), item, "buffers_nicklist")) + return 0; return 1; } @@ -213,5 +352,16 @@ relay_weechat_print_log (struct t_relay_client *client) { weechat_log_printf (" password_ok. . . . . . : %d", RELAY_WEECHAT_DATA(client, password_ok)); weechat_log_printf (" compression. . . . . . : %d", RELAY_WEECHAT_DATA(client, compression)); + weechat_log_printf (" buffers_sync . . . . . : 0x%lx (hashtable: '%s')", + RELAY_WEECHAT_DATA(client, buffers_sync), + weechat_hashtable_get_string (RELAY_WEECHAT_DATA(client, buffers_sync), + "keys_values")); + weechat_log_printf (" hook_signal_buffer . . : 0x%lx", RELAY_WEECHAT_DATA(client, hook_signal_buffer)); + weechat_log_printf (" hook_signal_nicklist . : 0x%lx", RELAY_WEECHAT_DATA(client, hook_signal_nicklist)); + weechat_log_printf (" buffers_nicklist . . . : 0x%lx (hashtable: '%s')", + RELAY_WEECHAT_DATA(client, buffers_nicklist), + weechat_hashtable_get_string (RELAY_WEECHAT_DATA(client, buffers_nicklist), + "keys_values")); + weechat_log_printf (" hook_timer_nicklist. . : 0x%lx", RELAY_WEECHAT_DATA(client, hook_timer_nicklist)); } } diff --git a/src/plugins/relay/weechat/relay-weechat.h b/src/plugins/relay/weechat/relay-weechat.h index 89cd9770e..1309d59ee 100644 --- a/src/plugins/relay/weechat/relay-weechat.h +++ b/src/plugins/relay/weechat/relay-weechat.h @@ -37,9 +37,20 @@ struct t_relay_weechat_data { int password_ok; /* password received and ok? */ int compression; /* compression type */ + + /* sync of buffers */ + struct t_hashtable *buffers_sync; /* buffers synchronized (events */ + /* received for these buffers) */ + struct t_hook *hook_signal_buffer; /* hook for signals "buffer_xxx" */ + struct t_hook *hook_signal_nicklist; /* hook for signals "nicklist_xxx"*/ + struct t_hashtable *buffers_nicklist; /* send nicklist for these buffers*/ + struct t_hook *hook_timer_nicklist; /* timer for sending nicklist */ }; extern int relay_weechat_compression_search (const char *compression); +extern void relay_weechat_hook_signals (struct t_relay_client *client); +extern void relay_weechat_unhook_signals (struct t_relay_client *client); +extern void relay_weechat_hook_timer_nicklist (struct t_relay_client *client); extern void relay_weechat_recv (struct t_relay_client *client, const char *data); extern void relay_weechat_close_connection (struct t_relay_client *client); |