1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-02 07:46:38 +02:00

core: add mouse support (task #5435), free cursor movement, hook_focus, fix bugs with key "^" (bug #32072, bug #21381), fix bugs with bar windows, completion and /buffer

New features and bugs fixed:
- mouse support: new command /mouse, new option weechat.look.mouse, new key context "mouse"
- free movement of cursor: new command /cursor, new key context "cursor"
- new hook_focus (used by cursor and mouse)
- info "cursor_mode"
- bugs fixed with key "^"
- allow plugin name in /buffer name
- fix bugs with bar windows: do not create bar windows for hidden bars
- fix completion bug when two words for completion are equal but with different case
- automatic scroll direction in /bar scroll (x/y is now optional)
This commit is contained in:
Sebastien Helleu
2011-07-26 18:50:29 +02:00
parent 2fec843144
commit e0781f0390
97 changed files with 6338 additions and 1376 deletions
+282 -34
View File
@@ -55,6 +55,7 @@
#include "../gui/gui-buffer.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-color.h"
#include "../gui/gui-cursor.h"
#include "../gui/gui-filter.h"
#include "../gui/gui-history.h"
#include "../gui/gui-hotlist.h"
@@ -62,6 +63,7 @@
#include "../gui/gui-key.h"
#include "../gui/gui-layout.h"
#include "../gui/gui-main.h"
#include "../gui/gui-mouse.h"
#include "../gui/gui-window.h"
#include "../plugins/plugin.h"
#include "../plugins/plugin-config.h"
@@ -499,7 +501,7 @@ COMMAND_CALLBACK(buffer)
{
struct t_gui_buffer *ptr_buffer, *weechat_buffer;
long number, number1, number2;
char *error, *value, *pos, *str_number1, *pos_number2;
char *error, *value, *pos, *str_number1, *pos_number2, *plugin_name;
int i, target_buffer;
/* make C compiler happy */
@@ -897,7 +899,19 @@ COMMAND_CALLBACK(buffer)
else
{
ptr_buffer = NULL;
ptr_buffer = gui_buffer_search_by_partial_name (NULL, argv_eol[1]);
pos = strchr (argv_eol[1], '.');
if (pos)
{
plugin_name = string_strndup (argv_eol[1], pos - argv_eol[1]);
if (plugin_name)
{
ptr_buffer = gui_buffer_search_by_partial_name (plugin_name,
pos + 1);
free (plugin_name);
}
}
if (!ptr_buffer)
ptr_buffer = gui_buffer_search_by_partial_name (NULL, argv_eol[1]);
if (ptr_buffer)
{
gui_window_switch_to_buffer (gui_current_window, ptr_buffer, 1);
@@ -1098,6 +1112,89 @@ COMMAND_CALLBACK(command)
return WEECHAT_RC_OK;
}
/*
* command_cursor: free movement of cursor on screen
*/
COMMAND_CALLBACK(cursor)
{
char *pos, *str_x, *error;
int x, y;
/* make C compiler happy */
(void) data;
(void) buffer;
(void) argv_eol;
if (argc == 1)
{
gui_cursor_mode_toggle ();
return WEECHAT_RC_OK;
}
if (string_strcasecmp (argv[1], "go") == 0)
{
if (argc > 2)
{
pos = strchr (argv[2], ',');
if (pos)
{
str_x = string_strndup (argv[2], pos - argv[2]);
pos++;
if (str_x)
{
error = NULL;
x = (int) strtol (str_x, &error, 10);
if (error && !error[0])
{
error = NULL;
y = (int) strtol (pos, &error, 10);
if (error && !error[0])
{
gui_cursor_move_xy (x, y);
}
}
}
}
else
gui_cursor_move_area (argv[2]);
}
return WEECHAT_RC_OK;
}
if (string_strcasecmp (argv[1], "move") == 0)
{
if (argc > 2)
{
if (string_strcasecmp (argv[2], "up") == 0)
gui_cursor_move_add_xy (0, -1);
else if (string_strcasecmp (argv[2], "down") == 0)
gui_cursor_move_add_xy (0, 1);
else if (string_strcasecmp (argv[2], "left") == 0)
gui_cursor_move_add_xy (-1, 0);
else if (string_strcasecmp (argv[2], "right") == 0)
gui_cursor_move_add_xy (1, 0);
else if (string_strcasecmp (argv[2], "area_up") == 0)
gui_cursor_move_area_add_xy (0, -1);
else if (string_strcasecmp (argv[2], "area_down") == 0)
gui_cursor_move_area_add_xy (0, 1);
else if (string_strcasecmp (argv[2], "area_left") == 0)
gui_cursor_move_area_add_xy (-1, 0);
else if (string_strcasecmp (argv[2], "area_right") == 0)
gui_cursor_move_area_add_xy (1, 0);
}
return WEECHAT_RC_OK;
}
if (string_strcasecmp (argv[1], "stop") == 0)
{
gui_cursor_mode_toggle ();
return WEECHAT_RC_OK;
}
return WEECHAT_RC_OK;
}
/*
* command_debug: control debug for core/plugins
*/
@@ -1153,6 +1250,10 @@ COMMAND_CALLBACK(debug)
{
gui_color_dump (buffer);
}
else if (string_strcasecmp (argv[1], "cursor") == 0)
{
gui_cursor_debug_toggle ();
}
else if (string_strcasecmp (argv[1], "hdata") == 0)
{
if ((argc > 2) && (string_strcasecmp (argv[2], "free") == 0))
@@ -1168,6 +1269,10 @@ COMMAND_CALLBACK(debug)
{
debug_memory ();
}
else if (string_strcasecmp (argv[1], "mouse") == 0)
{
gui_mouse_debug_toggle ();
}
else if (string_strcasecmp (argv[1], "tags") == 0)
{
gui_chat_display_tags ^= 1;
@@ -2178,9 +2283,9 @@ COMMAND_CALLBACK(input)
else if (string_strcasecmp (argv[1], "hotlist_clear") == 0)
gui_input_hotlist_clear (buffer);
else if (string_strcasecmp (argv[1], "grab_key") == 0)
gui_input_grab_key (buffer);
gui_input_grab_key (buffer, (argc > 2) ? argv[2] : NULL);
else if (string_strcasecmp (argv[1], "grab_key_command") == 0)
gui_input_grab_key_command (buffer);
gui_input_grab_key_command (buffer, (argc > 2) ? argv[2] : NULL);
else if (string_strcasecmp (argv[1], "scroll_unread") == 0)
gui_input_scroll_unread (buffer);
else if (string_strcasecmp (argv[1], "set_unread") == 0)
@@ -2213,25 +2318,12 @@ void
command_key_display (struct t_gui_key *key, struct t_gui_key *default_key)
{
char *expanded_name;
char str_spaces[20 + 1];
int length_screen, num_spaces;
expanded_name = gui_key_get_expanded_name (key->key);
str_spaces[0] = '\0';
length_screen = utf8_strlen_screen ((expanded_name) ?
expanded_name : key->key);
num_spaces = 20 - length_screen;
if (num_spaces > 0)
{
memset (str_spaces, ' ', num_spaces);
str_spaces[num_spaces] = '\0';
}
if (default_key)
{
gui_chat_printf (NULL, " %s%s%s => %s%s %s(%s%s %s%s)",
str_spaces,
gui_chat_printf (NULL, " %s%s => %s%s %s(%s%s %s%s)",
(expanded_name) ? expanded_name : key->key,
GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS),
GUI_COLOR(GUI_COLOR_CHAT),
@@ -2244,8 +2336,7 @@ command_key_display (struct t_gui_key *key, struct t_gui_key *default_key)
}
else
{
gui_chat_printf (NULL, " %s%s%s => %s%s",
str_spaces,
gui_chat_printf (NULL, " %s%s => %s%s",
(expanded_name) ? expanded_name : key->key,
GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS),
GUI_COLOR(GUI_COLOR_CHAT),
@@ -2311,7 +2402,8 @@ command_key_display_listdiff (int context)
{
gui_chat_printf (NULL, "");
gui_chat_printf (NULL,
_("Key bindings added or redefined (%d) for "
/* TRANSLATORS: first "%d" is number of keys */
_("%d key bindings added or redefined for "
"context \"%s\":"),
count_added,
_(gui_key_context_string[context]));
@@ -2340,7 +2432,8 @@ command_key_display_listdiff (int context)
{
gui_chat_printf (NULL, "");
gui_chat_printf (NULL,
_("Key bindings deleted (%d) for context \"%s\":"),
/* TRANSLATORS: first "%d" is number of keys */
_("%d key bindings deleted for context \"%s\":"),
count_deleted,
_(gui_key_context_string[context]));
for (ptr_default_key = gui_default_keys[context]; ptr_default_key;
@@ -2357,6 +2450,7 @@ command_key_display_listdiff (int context)
/* display a message if all key bindings are default bindings */
if ((count_added == 0) && (count_deleted == 0))
{
gui_chat_printf (NULL, "");
gui_chat_printf (NULL,
_("No key binding added, redefined or removed "
"for context \"%s\""),
@@ -2480,8 +2574,9 @@ COMMAND_CALLBACK(key)
{
command_key_display_list (_("No key binding defined for "
"context \"%s\""),
_("Key bindings (%d) for "
"context \"%s\":"),
/* TRANSLATORS: first "%d" is number of keys */
_("%d key bindings for context "
"\"%s\":"),
i, gui_keys[i], gui_keys_count[i]);
}
}
@@ -2512,7 +2607,8 @@ COMMAND_CALLBACK(key)
{
command_key_display_list (_("No default key binding for "
"context \"%s\""),
_("Default key bindings (%d) for "
/* TRANSLATORS: first "%d" is number of keys */
_("%d default key bindings for "
"context \"%s\":"),
i,
gui_default_keys[i],
@@ -2939,6 +3035,96 @@ COMMAND_CALLBACK(layout)
return WEECHAT_RC_OK;
}
/*
* command_mouse_timer_cb: callback for mouse timer
*/
int
command_mouse_timer_cb (void *data, int remaining_calls)
{
/* make C compiler happy */
(void) data;
(void) remaining_calls;
if (gui_mouse_enabled)
gui_mouse_disable ();
else
gui_mouse_enable ();
return WEECHAT_RC_OK;
}
/*
* command_mouse_timer: timer for toggling mouse
*/
void
command_mouse_timer (const char *delay)
{
long seconds;
char *error;
error = NULL;
seconds = strtol (delay, &error, 10);
if (error && !error[0] && (seconds > 0))
{
hook_timer (NULL, seconds * 1000, 0, 1, &command_mouse_timer_cb, NULL);
}
}
/*
* command_mouse: mouse control
*/
COMMAND_CALLBACK(mouse)
{
/* make C compiler happy */
(void) data;
(void) buffer;
(void) argv_eol;
if (argc == 1)
{
gui_mouse_display_state ();
return WEECHAT_RC_OK;
}
if (string_strcasecmp (argv[1], "enable") == 0)
{
gui_mouse_enable ();
if (argc > 2)
command_mouse_timer (argv[2]);
return WEECHAT_RC_OK;
}
if (string_strcasecmp (argv[1], "disable") == 0)
{
gui_mouse_disable ();
if (argc > 2)
command_mouse_timer (argv[2]);
return WEECHAT_RC_OK;
}
if (string_strcasecmp (argv[1], "toggle") == 0)
{
if (gui_mouse_enabled)
gui_mouse_disable ();
else
gui_mouse_enable ();
if (argc > 2)
command_mouse_timer (argv[2]);
return WEECHAT_RC_OK;
}
if (string_strcasecmp (argv[1], "grab") == 0)
{
gui_mouse_grab_init ();
return WEECHAT_RC_OK;
}
return WEECHAT_RC_OK;
}
/*
* command_mute: execute a command mute
*/
@@ -4900,10 +5086,10 @@ command_init ()
" scroll: scroll bar\n"
" buffer: name of buffer to scroll ('*' "
"means current buffer, you should use '*' for root bars)\n"
" scroll_value: value for scroll: 'x' or 'y', followed by "
"'+', '-', 'b' (beginning) or 'e' (end), value (for +/-), "
"and optional %% (to scroll by %% of width/height, "
"otherwise value is number of chars)\n\n"
" scroll_value: value for scroll: 'x' or 'y' (optional), "
"followed by '+', '-', 'b' (beginning) or 'e' (end), "
"value (for +/-), and optional % (to scroll by % of "
"width/height, otherwise value is number of chars)\n\n"
"Examples:\n"
" create a bar with time, buffer number + name, and completion:\n"
" /bar add mybar root bottom 1 0 [time],buffer_number+:+buffer_name,completion\n"
@@ -5035,12 +5221,37 @@ command_init ()
"added if not found at beginning of command)"),
"%(plugins_names)|" PLUGIN_CORE " %(plugins_commands)",
&command_command, NULL);
hook_command (NULL, "cursor",
N_("free movement of cursor on screen to execute actions on "
"specific areas of screen"),
N_("go chat|<bar>|<x>,<y>"
" || move up|down|left|right|area_up|area_down|area_left|"
"area_right"
" || stop"),
N_(" go: move cursor to chat area, a bar (using bar name) "
"or coordinates \"x,y\"\n"
"move: move cursor with direction\n"
"stop: stop cursor mode\n\n"
"Without argument, this command toggles cursor mode.\n\n"
"When mouse is enabled (see /help mouse), by default a "
"middle click will start cursor mode at this point.\n\n"
"Examples:\n"
" go to nicklist:\n"
" /cursor go nicklist\n"
" go to coordinates x=10, y=5:\n"
" /cursor go 10,5"),
"go %(cursor_areas)"
" || move up|down|left|right|area_up|area_down|area_left|"
"area_right"
" || stop",
&command_cursor, NULL);
hook_command (NULL, "debug",
N_("control debug for core/plugins"),
N_("list"
" || set <plugin> <level>"
" || dump [<plugin>]"
" || buffer|color|infolists|memory|tags|term|windows"
" || buffer|color|cursor|infolists|memory|mouse|tags|"
"term|windows"
" || hdata [free]"),
N_(" list: list plugins with debug levels\n"
" set: set debug level for plugin\n"
@@ -5051,10 +5262,12 @@ command_init ()
" buffer: dump buffer content with hexadecimal values "
"in log file\n"
" color: display infos about current color pairs\n"
" cursor: toggle debug for cursor mode\n"
" hdata: display infos about hdata (with free: remove "
"all hdata in memory)\n"
"infolists: display infos about infolists\n"
" memory: display infos about memory usage\n"
" mouse: toggle debug for mouse\n"
" tags: display tags for lines\n"
" term: display infos about terminal\n"
" windows: display windows tree"),
@@ -5063,9 +5276,11 @@ command_init ()
" || dump %(plugins_names)|core"
" || buffer"
" || color"
" || cursor"
" || hdata free"
" || infolists"
" || memory"
" || mouse"
" || tags"
" || term"
" || windows",
@@ -5208,9 +5423,11 @@ command_init ()
"visited buffer\n"
" jump_next_visited_buffer: jump to next visited buffer\n"
" hotlist_clear: clear hotlist\n"
" grab_key: grab a key\n"
" grab_key: grab a key (optional argument: delay for end "
"of grab, default is 500 milliseconds)\n"
" grab_key_command: grab a key with its associated "
"command\n"
"command (optional argument: delay for end of grab, "
"default is 500 milliseconds)\n"
" scroll_unread: scroll to unread marker\n"
" set_unread: set unread marker for all buffers\n"
" set_unread_current_buffer: set unread marker for "
@@ -5272,6 +5489,14 @@ command_init ()
"When binding a command to a key, it is recommended to "
"use key alt+k (or Esc then k), and then press the key "
"to bind: this will insert key code in command line.\n\n"
"For context \"mouse\" (possible in context \"cursor\" "
"too), key has format: \"@area:key\" where area can be:\n"
" *: any area on screen\n"
" chat: chat area\n"
" bar(*): any bar\n"
" bar(xxx): bar \"xxx\"\n"
" item(*): any bar item\n"
" item(xxx): bar item \"xxx\"\n\n"
"Examples:\n"
" key alt-x to toggle nicklist bar:\n"
" /key bind meta-x /bar toggle nicklist\n"
@@ -5280,7 +5505,11 @@ command_init ()
" restore default binding for key alt-r:\n"
" /key reset meta-r\n"
" key \"tab\" to stop search in buffer:\n"
" /key bindctxt search ctrl-I /input search_stop"),
" /key bindctxt search ctrl-I /input search_stop\n"
" middle button of mouse on a nick to retrieve info on "
"nick:\n"
" /key bindctxt mouse @item(buffer_nicklist):button3 "
"/msg nickserv info ${nick}"),
"list %(keys_contexts)"
" || listdefault %(keys_contexts)"
" || listdiff %(keys_contexts)"
@@ -5290,7 +5519,7 @@ command_init ()
" || unbindctxt %(keys_contexts) %(keys_codes)"
" || reset %(keys_codes_for_reset)"
" || resetctxt %(keys_contexts) %(keys_codes_for_reset)"
" || resetall"
" || resetall %- %(keys_contexts)"
" || missing %(keys_contexts)",
&command_key, NULL);
hook_command (NULL, "layout",
@@ -5307,6 +5536,25 @@ command_init ()
"Without argument, this command displays saved layout."),
"save|apply|reset buffers|windows",
&command_layout, NULL);
hook_command (NULL, "mouse",
N_("mouse control"),
N_("enable|disable|toggle [<delay>]"),
N_(" enable: enable mouse\n"
"disable: disable mouse\n"
" toggle: toggle mouse\n"
" delay: delay (in seconds) after which initial mouse "
"state is restored (useful to temporarily disable mouse)\n\n"
"To enable/disable mouse at startup, use:\n"
" /set weechat.look.mouse on/off\n\n"
"Examples:\n"
" enable mouse:\n"
" /mouse enable\n"
" toggle mouse for 5 seconds:\n"
" /mouse toggle 5"),
"enable"
" || disable"
" || toggle",
&command_mouse, NULL);
hook_command (NULL, "mute",
N_("execute a command silently"),
N_("[-current | -buffer <name> | -all] command"),
+46
View File
@@ -45,11 +45,13 @@
#include "../plugins/plugin.h"
#include "../gui/gui-completion.h"
#include "../gui/gui-bar.h"
#include "../gui/gui-bar-window.h"
#include "../gui/gui-buffer.h"
#include "../gui/gui-color.h"
#include "../gui/gui-filter.h"
#include "../gui/gui-key.h"
#include "../gui/gui-nicklist.h"
#include "../gui/gui-window.h"
/*
@@ -1225,6 +1227,47 @@ completion_list_add_keys_codes_for_reset_cb (void *data,
return WEECHAT_RC_OK;
}
/*
* completion_list_add_cursor_areas_cb: add areas for free cursor movement
* ("chat" and bar names)
*/
int
completion_list_add_cursor_areas_cb (void *data,
const char *completion_item,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_gui_bar_window *ptr_bar_win;
struct t_gui_bar *ptr_bar;
/* make C compiler happy */
(void) data;
(void) completion_item;
(void) buffer;
/* add "chat" for chat area */
gui_completion_list_add (completion, "chat", 0, WEECHAT_LIST_POS_SORT);
/* add bar windows (of current window) */
for (ptr_bar_win = gui_current_window->bar_windows; ptr_bar_win;
ptr_bar_win = ptr_bar_win->next_bar_window)
{
gui_completion_list_add (completion, ptr_bar_win->bar->name,
0, WEECHAT_LIST_POS_SORT);
}
for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar)
{
if (ptr_bar->bar_window)
{
gui_completion_list_add (completion, ptr_bar->name,
0, WEECHAT_LIST_POS_SORT);
}
}
return WEECHAT_RC_OK;
}
/*
* completion_init: add hooks for completions done by WeeChat core
*/
@@ -1311,4 +1354,7 @@ completion_init ()
N_("key codes that can be reset (keys added, redefined "
"or removed)"),
&completion_list_add_keys_codes_for_reset_cb, NULL);
hook_completion (NULL, "cursor_areas",
N_("areas (\"chat\" or bar name) for free cursor movement"),
&completion_list_add_cursor_areas_cb, NULL);
}
+7
View File
@@ -56,6 +56,7 @@
#include "../gui/gui-layout.h"
#include "../gui/gui-line.h"
#include "../gui/gui-main.h"
#include "../gui/gui-mouse.h"
#include "../gui/gui-nicklist.h"
#include "../gui/gui-window.h"
#include "../plugins/plugin.h"
@@ -108,6 +109,7 @@ struct t_config_option *config_look_input_undo_max;
struct t_config_option *config_look_item_time_format;
struct t_config_option *config_look_jump_current_to_previous_buffer;
struct t_config_option *config_look_jump_previous_buffer_when_closing;
struct t_config_option *config_look_mouse;
struct t_config_option *config_look_nickmode;
struct t_config_option *config_look_nickmode_empty;
struct t_config_option *config_look_paste_max_lines;
@@ -1794,6 +1796,11 @@ config_weechat_init_options ()
N_("jump to previously visited buffer when closing a buffer (if "
"disabled, then jump to buffer number - 1)"),
NULL, 0, 0, "on", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
config_look_mouse = config_file_new_option (
weechat_config_file, ptr_section,
"mouse", "boolean",
N_("enable mouse support at startup (to enable it now, see /help mouse)"),
NULL, 0, 0, "off", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
config_look_nickmode = config_file_new_option (
weechat_config_file, ptr_section,
"nickmode", "boolean",
+1
View File
@@ -133,6 +133,7 @@ extern struct t_config_option *config_look_input_undo_max;
extern struct t_config_option *config_look_item_time_format;
extern struct t_config_option *config_look_jump_current_to_previous_buffer;
extern struct t_config_option *config_look_jump_previous_buffer_when_closing;
extern struct t_config_option *config_look_mouse;
extern struct t_config_option *config_look_nickmode;
extern struct t_config_option *config_look_nickmode_empty;
extern struct t_config_option *config_look_paste_max_lines;
+169
View File
@@ -49,9 +49,13 @@
#include "wee-utf8.h"
#include "wee-util.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-bar.h"
#include "../gui/gui-bar-window.h"
#include "../gui/gui-color.h"
#include "../gui/gui-completion.h"
#include "../gui/gui-cursor.h"
#include "../gui/gui-line.h"
#include "../gui/gui-window.h"
#include "../plugins/plugin.h"
@@ -2743,6 +2747,150 @@ hook_hdata_get (struct t_weechat_plugin *plugin, const char *hdata_name)
return NULL;
}
/*
* hook_focus: hook a focus
*/
struct t_hook *
hook_focus (struct t_weechat_plugin *plugin, const char *area,
t_hook_callback_focus *callback, void *callback_data)
{
struct t_hook *new_hook;
struct t_hook_focus *new_hook_focus;
int priority;
const char *ptr_area;
if (!area || !area[0] || !callback)
return NULL;
new_hook = malloc (sizeof (*new_hook));
if (!new_hook)
return NULL;
new_hook_focus = malloc (sizeof (*new_hook_focus));
if (!new_hook_focus)
{
free (new_hook);
return NULL;
}
hook_get_priority_and_name (area, &priority, &ptr_area);
hook_init_data (new_hook, plugin, HOOK_TYPE_FOCUS, priority,
callback_data);
new_hook->hook_data = new_hook_focus;
new_hook_focus->callback = callback;
new_hook_focus->area = strdup ((ptr_area) ? ptr_area : area);
hook_add_to_list (new_hook);
return new_hook;
}
/*
* hook_focus_hashtable_map_cb: add keys of a hashtable into another
*/
void
hook_focus_hashtable_map_cb (void *data, struct t_hashtable *hashtable,
const void *key, const void *value)
{
struct t_hashtable *hashtable1;
/* make C compiler happy */
(void) hashtable;
hashtable1 = (struct t_hashtable *)data;
if (hashtable1 && key && value)
hashtable_set (hashtable1, (const char *)key, (const char *)value);
}
/*
* hook_focus_get_data: get data for focus on (x,y) on screen
*/
struct t_hashtable *
hook_focus_get_data (struct t_gui_cursor_info *cursor_info)
{
struct t_hook *ptr_hook, *next_hook;
struct t_hashtable *hash_info, *hash_info2;
char str_value[64];
hook_exec_start ();
hash_info = hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (!hash_info)
return NULL;
/* fill hash_info with values from cursor_info */
snprintf (str_value, sizeof (str_value), "%d", cursor_info->x);
hashtable_set (hash_info, "_x", str_value);
snprintf (str_value, sizeof (str_value), "%d", cursor_info->y);
hashtable_set (hash_info, "_y", str_value);
snprintf (str_value, sizeof (str_value),
"0x%lx", (long unsigned int)cursor_info->window);
hashtable_set (hash_info, "_window", str_value);
snprintf (str_value, sizeof (str_value),
"0x%lx",
(cursor_info->window) ?
(long unsigned int)((cursor_info->window)->buffer) : 0);
hashtable_set (hash_info, "_buffer", str_value);
hashtable_set (hash_info, "_bar_name",
(cursor_info->bar_window) ?
((cursor_info->bar_window)->bar)->name : NULL);
hashtable_set (hash_info, "_bar_item_name",
cursor_info->bar_item);
snprintf (str_value, sizeof (str_value),
"%d", cursor_info->item_line);
hashtable_set (hash_info, "_item_line", str_value);
snprintf (str_value, sizeof (str_value),
"%d", cursor_info->item_col);
hashtable_set (hash_info, "_item_col", str_value);
ptr_hook = weechat_hooks[HOOK_TYPE_FOCUS];
while (ptr_hook)
{
next_hook = ptr_hook->next_hook;
if (!ptr_hook->deleted
&& !ptr_hook->running
&& ((cursor_info->chat
&& (strcmp (HOOK_FOCUS(ptr_hook, area), "chat") == 0))
|| (cursor_info->bar_item
&& (strcmp (HOOK_FOCUS(ptr_hook, area), cursor_info->bar_item) == 0))))
{
ptr_hook->running = 1;
hash_info2 = (HOOK_FOCUS(ptr_hook, callback))
(ptr_hook->callback_data, hash_info);
ptr_hook->running = 0;
if (hash_info2)
{
if (hash_info2 != hash_info)
{
/*
* add keys of hashtable2 into hashtable and destroy
* hashtable2
*/
hashtable_map (hash_info2, &hook_focus_hashtable_map_cb,
hash_info);
hashtable_free (hash_info2);
}
}
}
ptr_hook = next_hook;
}
hook_exec_end ();
return hash_info;
}
/*
* unhook: unhook something
*/
@@ -2933,6 +3081,10 @@ unhook (struct t_hook *hook)
if (HOOK_HDATA(hook, description))
free (HOOK_HDATA(hook, description));
break;
case HOOK_TYPE_FOCUS:
if (HOOK_FOCUS(hook, area))
free (HOOK_FOCUS(hook, area));
break;
case HOOK_NUM_TYPES:
/*
* this constant is used to count types only,
@@ -3372,6 +3524,15 @@ hook_add_to_infolist_type (struct t_infolist *infolist, int type,
return 0;
}
break;
case HOOK_TYPE_FOCUS:
if (!ptr_hook->deleted)
{
if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_FOCUS(ptr_hook, callback)))
return 0;
if (!infolist_new_var_string (ptr_item, "area", HOOK_FOCUS(ptr_hook, area)))
return 0;
}
break;
case HOOK_NUM_TYPES:
/*
* this constant is used to count types only,
@@ -3671,6 +3832,14 @@ hook_print_log ()
log_printf (" description . . . . . : '%s'", HOOK_HDATA(ptr_hook, description));
}
break;
case HOOK_TYPE_FOCUS:
if (!ptr_hook->deleted)
{
log_printf (" focus data:");
log_printf (" callback. . . . . . . : 0x%lx", HOOK_FOCUS(ptr_hook, callback));
log_printf (" area. . . . . . . . . : '%s'", HOOK_FOCUS(ptr_hook, area));
}
break;
case HOOK_NUM_TYPES:
/*
* this constant is used to count types only,
+21 -34
View File
@@ -24,9 +24,12 @@
#include <gnutls/gnutls.h>
#endif
struct t_gui_bar;
struct t_gui_buffer;
struct t_gui_line;
struct t_gui_completion;
struct t_gui_cursor_info;
struct t_gui_window;
struct t_weelist;
struct t_hashtable;
struct t_infolist;
@@ -51,6 +54,7 @@ enum t_hook_type
HOOK_TYPE_INFO_HASHTABLE, /* get some info as hashtable */
HOOK_TYPE_INFOLIST, /* get some info as infolist */
HOOK_TYPE_HDATA, /* get hdata pointer */
HOOK_TYPE_FOCUS, /* focus event (mouse/key) */
/* number of hook types */
HOOK_NUM_TYPES,
};
@@ -91,6 +95,7 @@ enum t_hook_type
#define HOOK_INFO_HASHTABLE(hook, var) (((struct t_hook_info_hashtable *)hook->hook_data)->var)
#define HOOK_INFOLIST(hook, var) (((struct t_hook_infolist *)hook->hook_data)->var)
#define HOOK_HDATA(hook, var) (((struct t_hook_hdata *)hook->hook_data)->var)
#define HOOK_FOCUS(hook, var) (((struct t_hook_focus *)hook->hook_data)->var)
struct t_hook
{
@@ -374,6 +379,17 @@ struct t_hook_hdata
char *description; /* description */
};
/* hook focus */
typedef struct t_hashtable *(t_hook_callback_focus)(void *data,
struct t_hashtable *info);
struct t_hook_focus
{
t_hook_callback_focus *callback; /* focus callback */
char *area; /* "chat" or bar item name */
};
/* hook variables */
extern struct t_hook *weechat_hooks[];
@@ -521,43 +537,14 @@ extern struct t_hook *hook_hdata (struct t_weechat_plugin *plugin,
void *callback_data);
extern struct t_hdata *hook_hdata_get (struct t_weechat_plugin *plugin,
const char *hdata_name);
extern struct t_hook *hook_focus (struct t_weechat_plugin *plugin,
const char *area,
t_hook_callback_focus *callback,
void *callback_data);
extern struct t_hashtable *hook_focus_get_data (struct t_gui_cursor_info *cursor_info);
extern void unhook (struct t_hook *hook);
extern void unhook_all_plugin (struct t_weechat_plugin *plugin);
extern void unhook_all ();
extern struct t_hdata *hook_hdata_hook_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_command_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_command_run_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_timer_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_fd_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_process_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_connect_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_print_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_signal_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_hsignal_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_config_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_completion_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_modifier_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_info_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_info_hashtable_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_infolist_cb (void *data,
const char *hdata_name);
extern struct t_hdata *hook_hdata_hook_hdata_cb (void *data,
const char *hdata_name);
extern int hook_add_to_infolist (struct t_infolist *infolist,
const char *arguments);
extern void hook_print_log ();
+87
View File
@@ -54,6 +54,7 @@
#include "weechat.h"
#include "wee-string.h"
#include "wee-config.h"
#include "wee-hashtable.h"
#include "wee-utf8.h"
#include "../gui/gui-color.h"
@@ -1602,3 +1603,89 @@ string_input_for_buffer (const char *string)
/* string is a command */
return NULL;
}
/*
* string_replace_with_hashtable: replace ${codes} with value from hashtable
* "errors" is set with number of keys not found
* in hashtable
*/
char *
string_replace_with_hashtable (const char *string,
struct t_hashtable *hashtable,
int *errors)
{
int length, length_value, index_string, index_result;
char *result, *key;
const char *pos_end_name, *ptr_value;
*errors = 0;
if (!string)
return NULL;
if (!hashtable)
return strdup (string);
length = strlen (string) + 1;
result = malloc (length);
if (result)
{
index_string = 0;
index_result = 0;
while (string[index_string])
{
if ((string[index_string] == '\\')
&& (string[index_string + 1] == '$'))
{
index_string++;
result[index_result++] = string[index_string++];
}
else if ((string[index_string] == '$')
&& (string[index_string + 1] == '{'))
{
pos_end_name = strchr (string + index_string + 2, '}');
if (pos_end_name)
{
key = string_strndup (string + index_string + 2,
pos_end_name - (string + index_string + 2));
if (key)
{
ptr_value = (const char *)hashtable_get (hashtable, key);
if (ptr_value)
{
length_value = strlen (ptr_value);
length += length_value;
result = realloc (result, length);
if (!result)
{
free (key);
return NULL;
}
strcpy (result + index_result, ptr_value);
index_result += length_value;
index_string += pos_end_name - string -
index_string + 1;
}
else
{
result[index_result++] = string[index_string++];
(*errors)++;
}
free (key);
}
else
result[index_result++] = string[index_string++];
}
else
result[index_result++] = string[index_string++];
}
else
result[index_result++] = string[index_string++];
}
result[index_result] = '\0';
}
return result;
}
+5
View File
@@ -22,6 +22,8 @@
#include <regex.h>
struct t_hashtable;
extern char *string_strndup (const char *string, int length);
extern void string_tolower (char *string);
extern void string_toupper (char *string);
@@ -66,5 +68,8 @@ extern void string_encode_base64 (const char *from, int length, char *to);
extern int string_decode_base64 (const char *from, char *to);
extern int string_is_command_char (const char *string);
extern const char *string_input_for_buffer (const char *string);
extern char *string_replace_with_hashtable (const char *string,
struct t_hashtable *hashtable,
int *errors);
#endif /* __WEECHAT_STRING_H */