summaryrefslogtreecommitdiff
path: root/src/plugins/typing/typing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/typing/typing.c')
-rw-r--r--src/plugins/typing/typing.c315
1 files changed, 272 insertions, 43 deletions
diff --git a/src/plugins/typing/typing.c b/src/plugins/typing/typing.c
index a061591e2..033ac5838 100644
--- a/src/plugins/typing/typing.c
+++ b/src/plugins/typing/typing.c
@@ -26,6 +26,7 @@
#include "../weechat-plugin.h"
#include "typing.h"
+#include "typing-bar-item.h"
#include "typing-config.h"
#include "typing-status.h"
@@ -43,6 +44,10 @@ struct t_hook *typing_signal_buffer_closing = NULL;
struct t_hook *typing_signal_input_text_changed = NULL;
struct t_hook *typing_modifier_input_text_for_buffer = NULL;
struct t_hook *typing_timer = NULL;
+struct t_hook *typing_signal_typing_set_nick = NULL;
+struct t_hook *typing_signal_typing_reset_buffer = NULL;
+
+int typing_update_item = 0;
/*
@@ -52,9 +57,7 @@ struct t_hook *typing_timer = NULL;
*/
int
-typing_send_signal (struct t_gui_buffer *buffer,
- struct t_typing_status *typing_status,
- const char *signal_name)
+typing_send_signal (struct t_gui_buffer *buffer, const char *signal_name)
{
if (weechat_typing_plugin->debug)
{
@@ -64,7 +67,6 @@ typing_send_signal (struct t_gui_buffer *buffer,
weechat_buffer_get_string (buffer, "full_name"));
}
- typing_status->last_signal_sent = time (NULL);
return weechat_hook_signal_send (signal_name,
WEECHAT_HOOK_SIGNAL_POINTER,
buffer);
@@ -86,6 +88,7 @@ typing_buffer_closing_signal_cb (const void *pointer, void *data,
(void) type_data;
weechat_hashtable_remove (typing_status_self, signal_data);
+ weechat_hashtable_remove (typing_status_nicks, signal_data);
return WEECHAT_RC_OK;
}
@@ -126,30 +129,33 @@ typing_input_text_changed_signal_cb (const void *pointer, void *data,
if (!ptr_input_for_buffer)
return WEECHAT_RC_OK;
- ptr_typing_status = weechat_hashtable_get (typing_status_self,
- ptr_buffer);
+ ptr_typing_status = typing_status_self_search (ptr_buffer);
if (!ptr_typing_status)
- ptr_typing_status = typing_status_add (ptr_buffer);
+ {
+ ptr_typing_status = typing_status_self_add (
+ ptr_buffer,
+ TYPING_STATUS_STATE_TYPING,
+ 0);
+ }
if (!ptr_typing_status)
return WEECHAT_RC_OK;
- ptr_typing_status->status = TYPING_STATUS_STATUS_TYPING;
+ ptr_typing_status->state = TYPING_STATUS_STATE_TYPING;
ptr_typing_status->last_typed = time (NULL);
}
else
{
/* user was typing something? */
- ptr_typing_status = weechat_hashtable_get (typing_status_self,
- ptr_buffer);
+ ptr_typing_status = typing_status_self_search (ptr_buffer);
if (ptr_typing_status
- && ((ptr_typing_status->status == TYPING_STATUS_STATUS_TYPING)
- || (ptr_typing_status->status == TYPING_STATUS_STATUS_PAUSED)))
+ && ((ptr_typing_status->state == TYPING_STATUS_STATE_TYPING)
+ || (ptr_typing_status->state == TYPING_STATUS_STATE_PAUSED)))
{
/*
* input cleared: maybe something was sent, not sure, so we just
- * set the status to "cleared", a signal can be sent later
+ * set the state to "cleared", a signal can be sent later
* in timer
*/
- ptr_typing_status->status = TYPING_STATUS_STATUS_CLEARED;
+ ptr_typing_status->state = TYPING_STATUS_STATE_CLEARED;
}
}
@@ -194,13 +200,17 @@ typing_input_text_for_buffer_modifier_cb (const void *pointer,
if (!ptr_input_for_buffer)
return NULL;
- ptr_typing_status = weechat_hashtable_get (typing_status_self, ptr_buffer);
+ ptr_typing_status = typing_status_self_search (ptr_buffer);
if (!ptr_typing_status)
- ptr_typing_status = typing_status_add (ptr_buffer);
+ {
+ ptr_typing_status = typing_status_self_add (ptr_buffer,
+ TYPING_STATUS_STATE_OFF,
+ 0);
+ }
if (!ptr_typing_status)
return NULL;
- typing_send_signal (ptr_buffer, ptr_typing_status, "typing_sent");
+ typing_send_signal (ptr_buffer, "typing_self_sent");
weechat_hashtable_remove (typing_status_self, ptr_buffer);
return NULL;
@@ -212,73 +222,251 @@ typing_input_text_for_buffer_modifier_cb (const void *pointer,
*/
void
-typing_status_self_map_cb (void *data,
- struct t_hashtable *hashtable,
- const void *key, const void *value)
+typing_status_self_status_map_cb (void *data,
+ struct t_hashtable *hashtable,
+ const void *key, const void *value)
{
struct t_gui_buffer *ptr_buffer;
struct t_typing_status *ptr_typing_status;
const char *ptr_input, *ptr_input_for_buffer;
+ time_t current_time;
int delay_pause;
- /* make C compiler happy */
- (void) data;
+ current_time = *((time_t *)data);
ptr_buffer = (struct t_gui_buffer *)key;
ptr_typing_status = (struct t_typing_status *)value;
- if (ptr_typing_status->status == TYPING_STATUS_STATUS_TYPING)
+ if (!ptr_buffer || !ptr_typing_status)
+ return;
+
+ if (ptr_typing_status->state == TYPING_STATUS_STATE_TYPING)
{
ptr_input = weechat_buffer_get_string (ptr_buffer, "input");
ptr_input_for_buffer = weechat_string_input_for_buffer (ptr_input);
if (ptr_input_for_buffer)
{
/* check if typing is paused */
- delay_pause = weechat_config_integer (typing_config_look_delay_pause);
- if (ptr_typing_status->last_typed < time (NULL) - delay_pause)
+ delay_pause = weechat_config_integer (typing_config_look_delay_set_paused);
+ if (ptr_typing_status->last_typed < current_time - delay_pause)
{
- ptr_typing_status->status = TYPING_STATUS_STATUS_PAUSED;
- typing_send_signal (ptr_buffer, ptr_typing_status,
- "typing_paused");
+ ptr_typing_status->state = TYPING_STATUS_STATE_PAUSED;
+ typing_send_signal (ptr_buffer, "typing_self_paused");
weechat_hashtable_remove (hashtable, ptr_buffer);
}
else
{
- typing_send_signal (ptr_buffer, ptr_typing_status,
- "typing_active");
+ typing_send_signal (ptr_buffer, "typing_self_typing");
}
}
else
{
- typing_send_signal (ptr_buffer, ptr_typing_status,
- "typing_cleared");
+ typing_send_signal (ptr_buffer, "typing_self_cleared");
weechat_hashtable_remove (hashtable, ptr_buffer);
}
}
- else if (ptr_typing_status->status == TYPING_STATUS_STATUS_CLEARED)
+ else if (ptr_typing_status->state == TYPING_STATUS_STATE_CLEARED)
{
- typing_send_signal (ptr_buffer, ptr_typing_status,
- "typing_cleared");
+ typing_send_signal (ptr_buffer, "typing_self_cleared");
weechat_hashtable_remove (hashtable, ptr_buffer);
}
}
/*
- * Callback for modifier "input_text_for_buffer".
+ * Callback called periodically (via a timer) for each entry in hashtable
+ * "typing_status_nicks".
+ */
+
+void
+typing_status_nicks_status_map_cb (void *data,
+ struct t_hashtable *hashtable,
+ const void *key, const void *value)
+{
+ const char *ptr_nick;
+ struct t_typing_status *ptr_typing_status;
+ time_t current_time;
+ int delay_purge_pause, delay_purge_typing;
+
+ current_time = *((time_t *)data);
+
+ ptr_nick = (const char *)key;
+ ptr_typing_status = (struct t_typing_status *)value;
+
+ if (!ptr_nick || !ptr_typing_status)
+ return;
+
+ delay_purge_pause = weechat_config_integer (
+ typing_config_look_delay_purge_paused);
+ delay_purge_typing = weechat_config_integer (
+ typing_config_look_delay_purge_typing);
+
+ if (((ptr_typing_status->state == TYPING_STATUS_STATE_PAUSED)
+ && (ptr_typing_status->last_typed < current_time - delay_purge_pause))
+ || ((ptr_typing_status->state == TYPING_STATUS_STATE_TYPING)
+ && (ptr_typing_status->last_typed < current_time - delay_purge_typing)))
+ {
+ weechat_hashtable_remove (hashtable, key);
+ typing_update_item = 1;
+ }
+}
+
+/*
+ * Callback called periodically (via a timer) for each entry in hashtable
+ * "typing_status_nicks".
+ */
+
+void
+typing_status_nicks_hash_map_cb (void *data,
+ struct t_hashtable *hashtable,
+ const void *key, const void *value)
+{
+ struct t_hashtable *ptr_nicks;
+
+ ptr_nicks = (struct t_hashtable *)value;
+
+ if (!ptr_nicks)
+ return;
+
+ weechat_hashtable_map (ptr_nicks,
+ &typing_status_nicks_status_map_cb,
+ data);
+
+ /* no more nicks for the buffer? then remove the buffer */
+ if (weechat_hashtable_get_integer (ptr_nicks, "items_count") == 0)
+ weechat_hashtable_remove (hashtable, key);
+}
+
+/*
+ * Typing timer used to send continuously the self typing status.
*/
int
-typing_timer_cb (const void *pointer,
- void *data,
- int remaining_calls)
+typing_timer_cb (const void *pointer, void *data, int remaining_calls)
{
+ time_t current_time;
+
/* make C compiler happy */
(void) pointer;
(void) data;
(void) remaining_calls;
+ typing_update_item = 0;
+ current_time = time (NULL);
+
weechat_hashtable_map (typing_status_self,
- &typing_status_self_map_cb, NULL);
+ &typing_status_self_status_map_cb, &current_time);
+ weechat_hashtable_map (typing_status_nicks,
+ &typing_status_nicks_hash_map_cb, &current_time);
+
+ if (typing_update_item)
+ weechat_bar_item_update (TYPING_BAR_ITEM_NAME);
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * Callback for signal "typing_set_nick".
+ */
+
+int
+typing_typing_set_nick_signal_cb (const void *pointer, void *data,
+ const char *signal,
+ const char *type_data, void *signal_data)
+{
+ char **items;
+ int num_items, rc, state, updated;
+ unsigned long value;
+ struct t_gui_buffer *ptr_buffer;
+ struct t_typing_status *ptr_typing_status;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) signal;
+ (void) type_data;
+
+ items = weechat_string_split ((const char *)signal_data, ";", NULL,
+ 0, 3, &num_items);
+ if (!items || (num_items != 3))
+ goto end;
+
+ rc = sscanf (items[0], "%lx", &value);
+ if ((rc == EOF) || (rc == 0))
+ goto end;
+ ptr_buffer = (struct t_gui_buffer *)value;
+ if (!ptr_buffer)
+ goto end;
+
+ state = typing_status_search_state (items[1]);
+ if (state < 0)
+ goto end;
+
+ if (!items[2][0])
+ goto end;
+
+ updated = 0;
+ ptr_typing_status = typing_status_nick_search (ptr_buffer, items[2]);
+ if ((state == TYPING_STATUS_STATE_TYPING)
+ || (state == TYPING_STATUS_STATE_PAUSED))
+ {
+ if (ptr_typing_status)
+ {
+ if (ptr_typing_status->state != state)
+ updated = 1;
+ ptr_typing_status->state = state;
+ ptr_typing_status->last_typed = time (NULL);
+ }
+ else
+ {
+ typing_status_nick_add (ptr_buffer, items[2], state, time (NULL));
+ updated = 1;
+ }
+ }
+ else
+ {
+ if (ptr_typing_status)
+ updated = 1;
+ typing_status_nick_remove (ptr_buffer, items[2]);
+ }
+
+ if (updated)
+ weechat_bar_item_update (TYPING_BAR_ITEM_NAME);
+
+end:
+ if (items)
+ weechat_string_free_split (items);
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * Callback for signal "typing_reset_buffer".
+ */
+
+int
+typing_typing_reset_buffer_signal_cb (const void *pointer, void *data,
+ const char *signal,
+ const char *type_data, void *signal_data)
+{
+ int items_count;
+ struct t_gui_buffer *ptr_buffer;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) signal;
+ (void) type_data;
+
+ ptr_buffer = (struct t_gui_buffer *)signal_data;
+
+ if (!typing_status_nicks)
+ return WEECHAT_RC_OK;
+
+ items_count = weechat_hashtable_get_integer (typing_status_nicks,
+ "items_count");
+ weechat_hashtable_remove (typing_status_nicks, ptr_buffer);
+ if (items_count > 0)
+ weechat_bar_item_update (TYPING_BAR_ITEM_NAME);
return WEECHAT_RC_OK;
}
@@ -290,12 +478,15 @@ typing_timer_cb (const void *pointer,
void
typing_setup_hooks ()
{
- if (weechat_config_boolean (typing_config_look_enabled))
+ if (weechat_config_boolean (typing_config_look_enabled_self))
{
if (!typing_signal_buffer_closing)
{
if (weechat_typing_plugin->debug >= 2)
- weechat_printf (NULL, "%s: creating hooks", TYPING_PLUGIN_NAME);
+ {
+ weechat_printf (NULL, "%s: creating hooks (self)",
+ TYPING_PLUGIN_NAME);
+ }
typing_signal_buffer_closing = weechat_hook_signal (
"buffer_closing",
&typing_buffer_closing_signal_cb, NULL, NULL);
@@ -315,7 +506,10 @@ typing_setup_hooks ()
if (typing_signal_buffer_closing)
{
if (weechat_typing_plugin->debug >= 2)
- weechat_printf (NULL, "%s: removing hooks", TYPING_PLUGIN_NAME);
+ {
+ weechat_printf (NULL, "%s: removing hooks (self)",
+ TYPING_PLUGIN_NAME);
+ }
weechat_unhook (typing_signal_buffer_closing);
typing_signal_buffer_closing = NULL;
weechat_unhook (typing_signal_input_text_changed);
@@ -326,6 +520,39 @@ typing_setup_hooks ()
typing_timer = NULL;
}
}
+
+ if (weechat_config_boolean (typing_config_look_enabled_nicks))
+ {
+ if (!typing_signal_typing_set_nick)
+ {
+ if (weechat_typing_plugin->debug >= 2)
+ {
+ weechat_printf (NULL, "%s: creating hooks (nicks)",
+ TYPING_PLUGIN_NAME);
+ }
+ typing_signal_typing_set_nick = weechat_hook_signal (
+ "typing_set_nick",
+ &typing_typing_set_nick_signal_cb, NULL, NULL);
+ typing_signal_typing_reset_buffer = weechat_hook_signal (
+ "typing_reset_buffer",
+ &typing_typing_reset_buffer_signal_cb, NULL, NULL);
+ }
+ }
+ else
+ {
+ if (typing_signal_typing_set_nick)
+ {
+ if (weechat_typing_plugin->debug >= 2)
+ {
+ weechat_printf (NULL, "%s: removing hooks (nicks)",
+ TYPING_PLUGIN_NAME);
+ }
+ weechat_unhook (typing_signal_typing_set_nick);
+ typing_signal_typing_set_nick = NULL;
+ weechat_unhook (typing_signal_typing_reset_buffer);
+ typing_signal_typing_reset_buffer = NULL;
+ }
+ }
}
/*
@@ -348,6 +575,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
typing_setup_hooks ();
+ typing_bar_item_init ();
+
return WEECHAT_RC_OK;
}