summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2011-07-26 18:50:29 +0200
committerSebastien Helleu <flashcode@flashtux.org>2011-07-26 18:50:29 +0200
commite0781f0390291e264e6dd9c17beae1342e87f9a2 (patch)
treeaac2f19ab7e527180952db15867d8daaa23c4a91 /src/core
parent2fec84314433c2b7152c6c47b1172a621257fe6f (diff)
downloadweechat-e0781f0390291e264e6dd9c17beae1342e87f9a2.zip
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)
Diffstat (limited to 'src/core')
-rw-r--r--src/core/wee-command.c316
-rw-r--r--src/core/wee-completion.c46
-rw-r--r--src/core/wee-config.c7
-rw-r--r--src/core/wee-config.h1
-rw-r--r--src/core/wee-hook.c169
-rw-r--r--src/core/wee-hook.h55
-rw-r--r--src/core/wee-string.c87
-rw-r--r--src/core/wee-string.h5
8 files changed, 618 insertions, 68 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 24c886190..02de535df 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -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);
@@ -1099,6 +1113,89 @@ COMMAND_CALLBACK(command)
}
/*
+ * 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],
@@ -2940,6 +3036,96 @@ COMMAND_CALLBACK(layout)
}
/*
+ * 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"),
diff --git a/src/core/wee-completion.c b/src/core/wee-completion.c
index 49cdf9a91..7879fa4da 100644
--- a/src/core/wee-completion.c
+++ b/src/core/wee-completion.c
@@ -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"
/*
@@ -1226,6 +1228,47 @@ completion_list_add_keys_codes_for_reset_cb (void *data,
}
/*
+ * 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);
}
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index da8de105b..92e552528 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -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",
diff --git a/src/core/wee-config.h b/src/core/wee-config.h
index c09544a1a..a617e8f98 100644
--- a/src/core/wee-config.h
+++ b/src/core/wee-config.h
@@ -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;
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index 9cb6404a9..89005dea7 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -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"
@@ -2744,6 +2748,150 @@ hook_hdata_get (struct t_weechat_plugin *plugin, const char *hdata_name)
}
/*
+ * 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,
diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h
index 054976259..65df6e7d0 100644
--- a/src/core/wee-hook.h
+++ b/src/core/wee-hook.h
@@ -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 ();
diff --git a/src/core/wee-string.c b/src/core/wee-string.c
index 1a8dd090f..6d1270221 100644
--- a/src/core/wee-string.c
+++ b/src/core/wee-string.c
@@ -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;
+}
diff --git a/src/core/wee-string.h b/src/core/wee-string.h
index 8b4465256..48832408f 100644
--- a/src/core/wee-string.h
+++ b/src/core/wee-string.h
@@ -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 */