summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2011-12-17 17:39:19 +0100
committerSebastien Helleu <flashcode@flashtux.org>2011-12-17 17:39:19 +0100
commit16ae7e26638f4b115b217231fc35ff4f40d66c63 (patch)
tree114f6e75f7e8902a79f3fb2c2064d10e18327b77 /src
parentf0b81813953897e66cfe1ed5bd4b545111efe2e4 (diff)
downloadweechat-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.c82
-rw-r--r--src/plugins/relay/weechat/relay-weechat-msg.h6
-rw-r--r--src/plugins/relay/weechat/relay-weechat-protocol.c480
-rw-r--r--src/plugins/relay/weechat/relay-weechat-protocol.h13
-rw-r--r--src/plugins/relay/weechat/relay-weechat.c152
-rw-r--r--src/plugins/relay/weechat/relay-weechat.h11
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);