summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2011-08-14 11:30:08 +0200
committerSebastien Helleu <flashcode@flashtux.org>2011-08-14 11:30:08 +0200
commit1cb7c6a6c5ef1ffd647779f41806a4be7f557622 (patch)
tree246aed1c6bc394a63c0d70f38354601134b4cfbc /src
parentfb4c1ed1e9ece94ad1ed9a0a42b91e16a371566f (diff)
downloadweechat-1cb7c6a6c5ef1ffd647779f41806a4be7f557622.zip
core: return info about line/word for chat area in focus hashtable, add keys m/q/Q to quote line in cursor mode, sort mouse keys by priority
Diffstat (limited to 'src')
-rw-r--r--src/core/wee-command.c27
-rw-r--r--src/core/wee-hook.c93
-rw-r--r--src/core/wee-hook.h6
-rw-r--r--src/gui/curses/gui-curses-chat.c50
-rw-r--r--src/gui/curses/gui-curses-key.c10
-rw-r--r--src/gui/curses/gui-curses-mouse.c44
-rw-r--r--src/gui/curses/gui-curses-window.c22
-rw-r--r--src/gui/gtk/gui-gtk-window.c13
-rw-r--r--src/gui/gui-bar-item.c16
-rw-r--r--src/gui/gui-bar-window.c35
-rw-r--r--src/gui/gui-bar-window.h4
-rw-r--r--src/gui/gui-chat.c89
-rw-r--r--src/gui/gui-chat.h5
-rw-r--r--src/gui/gui-cursor.c94
-rw-r--r--src/gui/gui-cursor.h2
-rw-r--r--src/gui/gui-focus.c180
-rw-r--r--src/gui/gui-focus.h12
-rw-r--r--src/gui/gui-key.c286
-rw-r--r--src/gui/gui-line.c15
-rw-r--r--src/gui/gui-mouse.c13
-rw-r--r--src/gui/gui-mouse.h2
-rw-r--r--src/gui/gui-window.c198
-rw-r--r--src/gui/gui-window.h27
-rw-r--r--src/plugins/irc/irc-bar-item.c3
24 files changed, 925 insertions, 321 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 5ad50b6ee..1e31036a1 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -1215,6 +1215,7 @@ COMMAND_CALLBACK(debug)
{
struct t_config_option *ptr_option;
struct t_weechat_plugin *ptr_plugin;
+ int debug;
/* make C compiler happy */
(void) data;
@@ -1264,7 +1265,14 @@ COMMAND_CALLBACK(debug)
}
else if (string_strcasecmp (argv[1], "cursor") == 0)
{
- gui_cursor_debug_toggle ();
+ if (gui_cursor_debug)
+ gui_cursor_debug_set (0);
+ else
+ {
+ debug = ((argc > 2)
+ && (string_strcasecmp (argv[2], "verbose") == 0)) ? 2 : 1;
+ gui_cursor_debug_set (debug);
+ }
}
else if (string_strcasecmp (argv[1], "hdata") == 0)
{
@@ -1283,7 +1291,14 @@ COMMAND_CALLBACK(debug)
}
else if (string_strcasecmp (argv[1], "mouse") == 0)
{
- gui_mouse_debug_toggle ();
+ if (gui_mouse_debug)
+ gui_mouse_debug_set (0);
+ else
+ {
+ debug = ((argc > 2)
+ && (string_strcasecmp (argv[2], "verbose") == 0)) ? 2 : 1;
+ gui_mouse_debug_set (debug);
+ }
}
else if (string_strcasecmp (argv[1], "tags") == 0)
{
@@ -5425,8 +5440,8 @@ command_init ()
N_("list"
" || set <plugin> <level>"
" || dump [<plugin>]"
- " || buffer|color|cursor|infolists|memory|mouse|tags|"
- "term|windows"
+ " || buffer|color|infolists|memory|tags|term|windows"
+ " || mouse|cursor [verbose]"
" || hdata [free]"),
N_(" list: list plugins with debug levels\n"
" set: set debug level for plugin\n"
@@ -5451,11 +5466,11 @@ command_init ()
" || dump %(plugins_names)|core"
" || buffer"
" || color"
- " || cursor"
+ " || cursor verbose"
" || hdata free"
" || infolists"
" || memory"
- " || mouse"
+ " || mouse verbose"
" || tags"
" || term"
" || windows",
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index 5eeaa64d3..cd1e2d7c3 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -2840,25 +2840,33 @@ hook_focus_hashtable_map2_cb (void *data, struct t_hashtable *hashtable,
/*
* hook_focus_get_data: get data for focus on (x,y) on screen
- * focus_info2 is not NULL only for a mouse gesture (it's
- * for point where mouse button is released)
+ * hashtable_focus2 is not NULL only for a mouse gesture
+ * (it's for point where mouse button has been released)
*/
struct t_hashtable *
-hook_focus_get_data (struct t_gui_focus_info *focus_info1,
- struct t_gui_focus_info *focus_info2,
- const char *key)
+hook_focus_get_data (struct t_hashtable *hashtable_focus1,
+ struct t_hashtable *hashtable_focus2)
{
struct t_hook *ptr_hook, *next_hook;
- struct t_hashtable *hash_info1, *hash_info2, *hash_info_ret;
- const char *keys;
+ struct t_hashtable *hashtable1, *hashtable2, *hashtable_ret;
+ const char *focus1_chat, *focus1_bar_item_name, *keys;
char **list_keys, *new_key;
- int num_keys, i, length;
+ int num_keys, i, length, focus1_is_chat;
- hook_exec_start ();
+ if (!hashtable_focus1)
+ return NULL;
+
+ focus1_chat = hashtable_get (hashtable_focus1, "_chat");
+ focus1_is_chat = (focus1_chat && (strcmp (focus1_chat, "1") == 0));
+ focus1_bar_item_name = hashtable_get (hashtable_focus1, "_bar_item_name");
- hash_info1 = gui_focus_to_hashtable (focus_info1, key);
- hash_info2 = (focus_info2) ? gui_focus_to_hashtable (focus_info2, key) : NULL;
+ hashtable1 = hashtable_dup (hashtable_focus1);
+ if (!hashtable1)
+ return NULL;
+ hashtable2 = (hashtable_focus2) ? hashtable_dup (hashtable_focus2) : NULL;
+
+ hook_exec_start ();
ptr_hook = weechat_hooks[HOOK_TYPE_FOCUS];
while (ptr_hook)
@@ -2867,50 +2875,50 @@ hook_focus_get_data (struct t_gui_focus_info *focus_info1,
if (!ptr_hook->deleted
&& !ptr_hook->running
- && ((focus_info1->chat
+ && ((focus1_is_chat
&& (strcmp (HOOK_FOCUS(ptr_hook, area), "chat") == 0))
- || (focus_info1->bar_item
- && (strcmp (HOOK_FOCUS(ptr_hook, area), focus_info1->bar_item) == 0))))
+ || (focus1_bar_item_name && focus1_bar_item_name[0]
+ && (strcmp (HOOK_FOCUS(ptr_hook, area), focus1_bar_item_name) == 0))))
{
- /* run callback for focus_info1 */
+ /* run callback for focus #1 */
ptr_hook->running = 1;
- hash_info_ret = (HOOK_FOCUS(ptr_hook, callback))
- (ptr_hook->callback_data, hash_info1);
+ hashtable_ret = (HOOK_FOCUS(ptr_hook, callback))
+ (ptr_hook->callback_data, hashtable1);
ptr_hook->running = 0;
- if (hash_info_ret)
+ if (hashtable_ret)
{
- if (hash_info_ret != hash_info1)
+ if (hashtable_ret != hashtable1)
{
/*
- * add keys of hash_info_ret into hash_info and destroy
- * hash_info_ret
+ * add keys of hashtable_ret into hashtable1
+ * and destroy it
*/
- hashtable_map (hash_info_ret,
+ hashtable_map (hashtable_ret,
&hook_focus_hashtable_map_cb,
- hash_info1);
- hashtable_free (hash_info_ret);
+ hashtable1);
+ hashtable_free (hashtable_ret);
}
}
- /* run callback for focus_info2 */
- if (hash_info2)
+ /* run callback for focus #2 */
+ if (hashtable2)
{
ptr_hook->running = 1;
- hash_info_ret = (HOOK_FOCUS(ptr_hook, callback))
- (ptr_hook->callback_data, hash_info2);
+ hashtable_ret = (HOOK_FOCUS(ptr_hook, callback))
+ (ptr_hook->callback_data, hashtable2);
ptr_hook->running = 0;
- if (hash_info_ret)
+ if (hashtable_ret)
{
- if (hash_info_ret != hash_info2)
+ if (hashtable_ret != hashtable2)
{
/*
- * add keys of hash_info_ret into hash_info and destroy
- * hash_info_ret
+ * add keys of hashtable_ret into hashtable2
+ * and destroy it
*/
- hashtable_map (hash_info_ret,
+ hashtable_map (hashtable_ret,
&hook_focus_hashtable_map_cb,
- hash_info2);
- hashtable_free (hash_info_ret);
+ hashtable2);
+ hashtable_free (hashtable_ret);
}
}
}
@@ -2919,14 +2927,14 @@ hook_focus_get_data (struct t_gui_focus_info *focus_info1,
ptr_hook = next_hook;
}
- if (hash_info2)
+ if (hashtable2)
{
- hashtable_map (hash_info2, &hook_focus_hashtable_map2_cb, hash_info1);
- hashtable_free (hash_info2);
+ hashtable_map (hashtable2, &hook_focus_hashtable_map2_cb, hashtable1);
+ hashtable_free (hashtable2);
}
else
{
- keys = hashtable_get_string (hash_info1, "keys");
+ keys = hashtable_get_string (hashtable1, "keys");
if (keys)
{
list_keys = string_split (keys, ",", 0, 0, &num_keys);
@@ -2939,8 +2947,9 @@ hook_focus_get_data (struct t_gui_focus_info *focus_info1,
if (new_key)
{
snprintf (new_key, length, "%s2", list_keys[i]);
- hashtable_set (hash_info1, new_key,
- hashtable_get (hash_info1, list_keys[i]));
+ hashtable_set (hashtable1, new_key,
+ hashtable_get (hashtable1,
+ list_keys[i]));
free (new_key);
}
}
@@ -2951,7 +2960,7 @@ hook_focus_get_data (struct t_gui_focus_info *focus_info1,
hook_exec_end ();
- return hash_info1;
+ return hashtable1;
}
/*
diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h
index ae0c880f6..7b092de17 100644
--- a/src/core/wee-hook.h
+++ b/src/core/wee-hook.h
@@ -28,7 +28,6 @@ struct t_gui_bar;
struct t_gui_buffer;
struct t_gui_line;
struct t_gui_completion;
-struct t_gui_focus_info;
struct t_gui_window;
struct t_weelist;
struct t_hashtable;
@@ -541,9 +540,8 @@ 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_focus_info *focus_info1,
- struct t_gui_focus_info *focus_info2,
- const char *key);
+extern struct t_hashtable *hook_focus_get_data (struct t_hashtable *hashtable_focus1,
+ struct t_hashtable *hashtable_focus2);
extern void unhook (struct t_hook *hook);
extern void unhook_all_plugin (struct t_weechat_plugin *plugin);
extern void unhook_all ();
diff --git a/src/gui/curses/gui-curses-chat.c b/src/gui/curses/gui-curses-chat.c
index b295abe61..43c425457 100644
--- a/src/gui/curses/gui-curses-chat.c
+++ b/src/gui/curses/gui-curses-chat.c
@@ -105,7 +105,8 @@ gui_chat_marker_for_line (struct t_gui_buffer *buffer, struct t_gui_line *line)
*/
void
-gui_chat_display_new_line (struct t_gui_window *window, int num_lines, int count,
+gui_chat_display_new_line (struct t_gui_window *window,
+ int num_lines, int count,
int *lines_displayed, int simulate)
{
if ((count == 0) || (*lines_displayed >= num_lines - count))
@@ -137,6 +138,7 @@ gui_chat_display_horizontal_line (struct t_gui_window *window, int simulate)
if (!simulate)
{
+ gui_window_coords_init_line (window, window->win_chat_cursor_y);
if (CONFIG_INTEGER(config_look_read_marker) == CONFIG_LOOK_READ_MARKER_LINE)
{
read_marker_string = CONFIG_STRING(config_look_read_marker_string);
@@ -260,9 +262,11 @@ gui_chat_display_word_raw (struct t_gui_window *window, const char *string,
int x, chars_displayed, display_char, size_on_screen;
if (display)
+ {
wmove (GUI_WINDOW_OBJECTS(window)->win_chat,
window->win_chat_cursor_y,
window->win_chat_cursor_x);
+ }
chars_displayed = 0;
x = window->win_chat_cursor_x;
@@ -332,6 +336,9 @@ gui_chat_display_word (struct t_gui_window *window,
((!simulate) && (window->win_chat_cursor_y >= window->win_chat_height)))
return;
+ if (!simulate)
+ window->coords[window->win_chat_cursor_y].line = line;
+
end_line = data + strlen (data);
if (end_offset && end_offset[0])
@@ -386,6 +393,7 @@ gui_chat_display_word (struct t_gui_window *window,
if (!simulate)
wattr_set (GUI_WINDOW_OBJECTS(window)->win_chat, attrs, pair, NULL);
}
+ window->coords[window->win_chat_cursor_y].data = data;
}
chars_to_display = gui_chat_strlen_screen (data);
@@ -440,30 +448,36 @@ gui_chat_display_word (struct t_gui_window *window,
}
/*
- * gui_chat_display_time_and_prefix: display time and prefix for a line
+ * gui_chat_display_time_to_prefix: display time, buffer name (for merged
+ * buffers) and prefix for a line
*/
void
-gui_chat_display_time_and_prefix (struct t_gui_window *window,
- struct t_gui_line *line,
- int num_lines, int count,
- int *lines_displayed,
- int simulate)
+gui_chat_display_time_to_prefix (struct t_gui_window *window,
+ struct t_gui_line *line,
+ int num_lines, int count,
+ int *lines_displayed,
+ int simulate)
{
char str_space[] = " ", str_plus[] = "+", *prefix_highlighted;
int i, length, length_allowed, num_spaces;
struct t_gui_lines *mixed_lines;
if (!simulate)
+ {
+ window->coords[window->win_chat_cursor_y].line = line;
gui_window_reset_style (GUI_WINDOW_OBJECTS(window)->win_chat, GUI_COLOR_CHAT);
+ }
/* display time */
if (window->buffer->time_for_each_line
&& (line->data->str_time && line->data->str_time[0]))
{
+ window->coords[window->win_chat_cursor_y].time_x1 = window->win_chat_cursor_x;
gui_chat_display_word (window, line, line->data->str_time,
NULL, 1, num_lines, count, lines_displayed,
simulate);
+ window->coords[window->win_chat_cursor_y].time_x2 = window->win_chat_cursor_x - 1;
if (!simulate)
gui_window_reset_style (GUI_WINDOW_OBJECTS(window)->win_chat, GUI_COLOR_CHAT);
@@ -510,6 +524,8 @@ gui_chat_display_time_and_prefix (struct t_gui_window *window,
GUI_COLOR_CHAT_PREFIX_BUFFER);
}
+ window->coords[window->win_chat_cursor_y].buffer_x1 = window->win_chat_cursor_x;
+
/* not enough space to display full buffer name? => truncate it! */
if ((CONFIG_INTEGER(config_look_prefix_buffer_align) != CONFIG_LOOK_PREFIX_BUFFER_ALIGN_NONE)
&& (num_spaces < 0))
@@ -530,6 +546,8 @@ gui_chat_display_time_and_prefix (struct t_gui_window *window,
simulate);
}
+ window->coords[window->win_chat_cursor_y].buffer_x2 = window->win_chat_cursor_x - 1;
+
if ((CONFIG_INTEGER(config_look_prefix_buffer_align) != CONFIG_LOOK_PREFIX_BUFFER_ALIGN_NONE)
&& (num_spaces < 0))
{
@@ -614,6 +632,8 @@ gui_chat_display_time_and_prefix (struct t_gui_window *window,
}
}
+ window->coords[window->win_chat_cursor_y].prefix_x1 = window->win_chat_cursor_x;
+
/* not enough space to display full prefix? => truncate it! */
if ((CONFIG_INTEGER(config_look_prefix_align) != CONFIG_LOOK_PREFIX_ALIGN_NONE)
&& (num_spaces < 0))
@@ -636,6 +656,8 @@ gui_chat_display_time_and_prefix (struct t_gui_window *window,
simulate);
}
+ window->coords[window->win_chat_cursor_y].prefix_x2 = window->win_chat_cursor_x - 1;
+
if (prefix_highlighted)
free (prefix_highlighted);
@@ -750,8 +772,13 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line,
marker_line = gui_chat_marker_for_line (window->buffer, line);
/* display time and prefix */
- gui_chat_display_time_and_prefix (window, line, num_lines, count,
- &lines_displayed, simulate);
+ gui_chat_display_time_to_prefix (window, line, num_lines, count,
+ &lines_displayed, simulate);
+ if (!simulate && !gui_chat_display_tags)
+ {
+ window->coords[window->win_chat_cursor_y].data = line->data->message;
+ window->coords_x_message = window->win_chat_cursor_x;
+ }
/* reset color & style for a new line */
if (!simulate)
@@ -908,6 +935,9 @@ gui_chat_display_line_y (struct t_gui_window *window, struct t_gui_line *line,
window->win_chat_cursor_x = 0;
window->win_chat_cursor_y = y;
+ window->coords[y].line = line;
+ window->coords[y].data = line->data->message;
+
wmove (GUI_WINDOW_OBJECTS(window)->win_chat,
window->win_chat_cursor_y,
window->win_chat_cursor_x);
@@ -1040,6 +1070,8 @@ gui_chat_draw (struct t_gui_buffer *buffer, int erase)
{
if (ptr_win->buffer->number == buffer->number)
{
+ gui_window_coords_alloc (ptr_win);
+
if (erase)
{
gui_window_set_weechat_color (GUI_WINDOW_OBJECTS(ptr_win)->win_chat,
diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c
index a8adafff8..9a96275b0 100644
--- a/src/gui/curses/gui-curses-key.c
+++ b/src/gui/curses/gui-curses-key.c
@@ -223,6 +223,7 @@ gui_key_default_bindings (int context)
}
else if (context == GUI_KEY_CONTEXT_CURSOR)
{
+ /* general & move */
BIND(/* Enter */ "ctrl-M", "/cursor stop");
BIND(/* Enter */ "ctrl-J", "/cursor stop");
BIND(/* up */ "meta2-A", "/cursor move up");
@@ -237,6 +238,11 @@ gui_key_default_bindings (int context)
BIND(/* m-left */ "meta2-1;3D", "/cursor move area_left");
BIND(/* m-right */ "meta-meta2-C", "/cursor move area_right");
BIND(/* m-right */ "meta2-1;3C", "/cursor move area_right");
+ /* chat */
+ BIND(/* m */ "@chat:m", "hsignal:chat_quote_message;/cursor stop");
+ BIND(/* q */ "@chat:q", "hsignal:chat_quote_prefix_message;/cursor stop");
+ BIND(/* Q */ "@chat:Q", "hsignal:chat_quote_time_prefix_message;/cursor stop");
+ /* nicklist */
BIND(/* b */ "@item(buffer_nicklist):b", "/window ${_window_number};/ban ${nick}");
BIND(/* k */ "@item(buffer_nicklist):k", "/window ${_window_number};/kick ${nick}");
BIND(/* K */ "@item(buffer_nicklist):K", "/window ${_window_number};/kickban ${nick}");
@@ -266,8 +272,8 @@ gui_key_default_bindings (int context)
/* mouse events on input */
BIND("@bar(input):button2", "/input grab_mouse_area");
/* mouse wheel on any bar */
- BIND("@bar(*):wheelup", "/bar scroll ${_bar_name} ${_window_number} -10%");
- BIND("@bar(*):wheeldown", "/bar scroll ${_bar_name} ${_window_number} +10%");
+ BIND("@bar:wheelup", "/bar scroll ${_bar_name} ${_window_number} -20%");
+ BIND("@bar:wheeldown", "/bar scroll ${_bar_name} ${_window_number} +20%");
/* middle click to enable cursor mode at position */
BIND("@*:button3", "/cursor go ${_x},${_y}");
}
diff --git a/src/gui/curses/gui-curses-mouse.c b/src/gui/curses/gui-curses-mouse.c
index 2e1a40436..a1a2c875a 100644
--- a/src/gui/curses/gui-curses-mouse.c
+++ b/src/gui/curses/gui-curses-mouse.c
@@ -102,30 +102,34 @@ gui_mouse_grab_init (int area)
char *
gui_mouse_grab_event2input ()
{
- struct t_gui_focus_info focus_info;
+ struct t_gui_focus_info *focus_info;
static char area[256];
- gui_focus_get_info (gui_mouse_event_x[0],
- gui_mouse_event_y[0],
- &focus_info);
+ area[0] = '\0';
- if (focus_info.bar_item)
+ focus_info = gui_focus_get_info (gui_mouse_event_x[0],
+ gui_mouse_event_y[0]);
+ if (focus_info)
{
- snprintf (area, sizeof (area),
- "@item(%s)", focus_info.bar_item);
- }
- else if (focus_info.bar_window)
- {
- snprintf (area, sizeof (area),
- "@bar(%s)", ((focus_info.bar_window)->bar)->name);
- }
- else if (focus_info.chat)
- {
- snprintf (area, sizeof (area), "@chat");
- }
- else
- {
- snprintf (area, sizeof (area), "@*");
+ if (focus_info->bar_item)
+ {
+ snprintf (area, sizeof (area),
+ "@item(%s)", focus_info->bar_item);
+ }
+ else if (focus_info->bar_window)
+ {
+ snprintf (area, sizeof (area),
+ "@bar(%s)", ((focus_info->bar_window)->bar)->name);
+ }
+ else if (focus_info->chat)
+ {
+ snprintf (area, sizeof (area), "@chat");
+ }
+ else
+ {
+ snprintf (area, sizeof (area), "@*");
+ }
+ gui_focus_free_info (focus_info);
}
return area;
diff --git a/src/gui/curses/gui-curses-window.c b/src/gui/curses/gui-curses-window.c
index d7214829a..73008c0cd 100644
--- a/src/gui/curses/gui-curses-window.c
+++ b/src/gui/curses/gui-curses-window.c
@@ -2205,6 +2205,28 @@ gui_window_set_title (const char *title)
}
/*
+ * gui_window_send_clipboard: copy text to clipboard (sent to terminal)
+ */
+
+void
+gui_window_send_clipboard (const char *storage_unit, const char *text)
+{
+ char *text_base64;
+ int length;
+
+ length = strlen (text);
+ text_base64 = malloc ((length * 4) + 1);
+ if (text_base64)
+ {
+ string_encode_base64 (text, length, text_base64);
+ fprintf (stderr, "\033]52;%s;%s\a",
+ (storage_unit) ? storage_unit : "",
+ text_base64);
+ free (text_base64);
+ }
+}
+
+/*
* gui_window_move_cursor: move cursor on screen (for cursor mode)
*/
diff --git a/src/gui/gtk/gui-gtk-window.c b/src/gui/gtk/gui-gtk-window.c
index baa0dd326..3c44bb418 100644
--- a/src/gui/gtk/gui-gtk-window.c
+++ b/src/gui/gtk/gui-gtk-window.c
@@ -849,6 +849,19 @@ gui_window_set_title (const char *title)
}
/*
+ * gui_window_send_clipboard: copy text to clipboard (sent to terminal)
+ */
+
+void
+gui_window_send_clipboard (const char *storage_unit, const char *text)
+{
+ (void) storage_unit;
+ (void) text;
+
+ /* TODO: write this function for Gtk */
+}
+
+/*
* gui_window_move_cursor: move cursor on screen (for cursor mode)
*/
diff --git a/src/gui/gui-bar-item.c b/src/gui/gui-bar-item.c
index 2e071e9bc..e9e438a29 100644
--- a/src/gui/gui-bar-item.c
+++ b/src/gui/gui-bar-item.c
@@ -1453,9 +1453,9 @@ gui_bar_item_focus_buffer_nicklist (void *data,
{
struct t_gui_nick_group *ptr_group;
struct t_gui_nick *ptr_nick;
- int i, rc, item_line;
+ int i, rc, bar_item_line;
unsigned long int value;
- const char *str_window;
+ const char *str_window, *str_bar_item_line;
struct t_gui_window *window;
char *error;
@@ -1463,6 +1463,12 @@ gui_bar_item_focus_buffer_nicklist (void *data,
(void) data;
str_window = hashtable_get (info, "_window");
+ str_bar_item_line = hashtable_get (info, "_bar_item_line");
+
+ if (!str_window || !str_window[0]
+ || !str_bar_item_line || !str_bar_item_line[0])
+ return NULL;
+
rc = sscanf (str_window, "%lx", &value);
if ((rc == EOF) || (rc == 0))
return NULL;
@@ -1472,7 +1478,7 @@ gui_bar_item_focus_buffer_nicklist (void *data,
window = gui_current_window;
error = NULL;
- item_line = (int) strtol (hashtable_get (info, "_item_line"), &error, 10);
+ bar_item_line = (int) strtol (str_bar_item_line, &error, 10);
if (!error || error[0])
return NULL;
@@ -1487,14 +1493,14 @@ gui_bar_item_focus_buffer_nicklist (void *data,
&& window->buffer->nicklist_display_groups
&& ptr_group->visible))
{
- if (i == item_line)
+ if (i == bar_item_line)
break;
i++;
}
gui_nicklist_get_next_item (window->buffer, &ptr_group, &ptr_nick);
}
- if (i != item_line)
+ if (i != bar_item_line)
return NULL;
if (ptr_nick)
diff --git a/src/gui/gui-bar-window.c b/src/gui/gui-bar-window.c
index a791ee034..8d8066e13 100644
--- a/src/gui/gui-bar-window.c
+++ b/src/gui/gui-bar-window.c
@@ -115,7 +115,8 @@ gui_bar_window_search_bar (struct t_gui_window *window, struct t_gui_bar *bar)
void
gui_bar_window_search_by_xy (struct t_gui_window *window, int x, int y,
struct t_gui_bar_window **bar_window,
- char **bar_item, int *item_line, int *item_col)
+ char **bar_item,
+ int *bar_item_line, int *bar_item_col)
{
struct t_gui_bar *ptr_bar;
struct t_gui_bar_window *ptr_bar_window;
@@ -124,8 +125,8 @@ gui_bar_window_search_by_xy (struct t_gui_window *window, int x, int y,
*bar_window = NULL;
*bar_item = NULL;
- *item_line = -1;
- *item_col = -1;
+ *bar_item_line = -1;
+ *bar_item_col = -1;
if (window)
{
@@ -161,24 +162,24 @@ gui_bar_window_search_by_xy (struct t_gui_window *window, int x, int y,
{
filling = gui_bar_get_filling ((*bar_window)->bar);
- *item_line = y - (*bar_window)->y + (*bar_window)->scroll_y;
- *item_col = x - (*bar_window)->x + (*bar_window)->scroll_x;
+ *bar_item_line = y - (*bar_window)->y + (*bar_window)->scroll_y;
+ *bar_item_col = x - (*bar_window)->x + (*bar_window)->scroll_x;
if ((filling == GUI_BAR_FILLING_COLUMNS_HORIZONTAL)
&& ((*bar_window)->screen_col_size > 0))
{
num_cols = (*bar_window)->width / (*bar_window)->screen_col_size;
- column = *item_col / (*bar_window)->screen_col_size;
- *item_line = (*item_line * num_cols) + column;
- *item_col = *item_col - (column * ((*bar_window)->screen_col_size));
+ column = *bar_item_col / (*bar_window)->screen_col_size;
+ *bar_item_line = (*bar_item_line * num_cols) + column;
+ *bar_item_col = *bar_item_col - (column * ((*bar_window)->screen_col_size));
}
if ((filling == GUI_BAR_FILLING_COLUMNS_VERTICAL)
&& ((*bar_window)->screen_col_size > 0))
{
- column = *item_col / (*bar_window)->screen_col_size;
- *item_line = (column * ((*bar_window)->height)) + *item_line;
- *item_col = *item_col % ((*bar_window)->screen_col_size);
+ column = *bar_item_col / (*bar_window)->screen_col_size;
+ *bar_item_line = (column * ((*bar_window)->height)) + *bar_item_line;
+ *bar_item_col = *bar_item_col % ((*bar_window)->screen_col_size);
}
if (filling == GUI_BAR_FILLING_HORIZONTAL)
@@ -201,8 +202,8 @@ gui_bar_window_search_by_xy (struct t_gui_window *window, int x, int y,
if ((item >= 0) && (subitem >= 0))
{
*bar_item = (*bar_window)->bar->items_name[item][subitem];
- *item_line = (*bar_window)->coords[i]->line;
- *item_col = x - (*bar_window)->coords[i]->x;
+ *bar_item_line = (*bar_window)->coords[i]->line;
+ *bar_item_col = x - (*bar_window)->coords[i]->x;
}
break;
}
@@ -213,8 +214,8 @@ gui_bar_window_search_by_xy (struct t_gui_window *window, int x, int y,
item = (*bar_window)->coords[i]->item;
subitem = (*bar_window)->coords[i]->subitem;
*bar_item = (*bar_window)->bar->items_name[item][subitem];
- *item_line = (*bar_window)->coords[i]->line;
- *item_col = x - (*bar_window)->coords[i]->x;
+ *bar_item_line = (*bar_window)->coords[i]->line;
+ *bar_item_col = x - (*bar_window)->coords[i]->x;
break;
}
i++;
@@ -230,7 +231,7 @@ gui_bar_window_search_by_xy (struct t_gui_window *window, int x, int y,
{
lines_old = lines;
lines += (*bar_window)->items_num_lines[i][j];
- if (*item_line < lines)
+ if (*bar_item_line < lines)
{
*bar_item = (*bar_window)->bar->items_name[i][j];
break;
@@ -242,7 +243,7 @@ gui_bar_window_search_by_xy (struct t_gui_window *window, int x, int y,
i++;
}
}
- *item_line -= lines_old;
+ *bar_item_line -= lines_old;
}
}
}
diff --git a/src/gui/gui-bar-window.h b/src/gui/gui-bar-window.h
index 337e9254e..184a060c8 100644
--- a/src/gui/gui-bar-window.h
+++ b/src/gui/gui-bar-window.h
@@ -66,8 +66,8 @@ extern void gui_bar_window_search_by_xy (struct t_gui_window *window,
int x, int y,
struct t_gui_bar_window **bar_window,
char **bar_item,
- int *item_line,
- int *item_col);
+ int *bar_item_line,
+ int *bar_item_col);
extern void gui_bar_window_calculate_pos_size (struct t_gui_bar_window *bar_window,
struct t_gui_window *window);
extern void gui_bar_window_content_build (struct t_gui_bar_window *bar_window,
diff --git a/src/gui/gui-chat.c b/src/gui/gui-chat.c
index 250b654f3..3f7b2c123 100644
--- a/src/gui/gui-chat.c
+++ b/src/gui/gui-chat.c
@@ -34,6 +34,7 @@
#include "../core/weechat.h"
#include "../core/wee-config.h"
+#include "../core/wee-hashtable.h"
#include "../core/wee-hook.h"
#include "../core/wee-string.h"
#include "../core/wee-utf8.h"
@@ -42,6 +43,7 @@
#include "gui-buffer.h"
#include "gui-color.h"
#include "gui-filter.h"
+#include "gui-input.h"
#include "gui-line.h"
#include "gui-main.h"
#include "gui-window.h"
@@ -69,6 +71,14 @@ gui_chat_init ()
gui_chat_prefix[GUI_CHAT_PREFIX_ACTION] = strdup (gui_chat_prefix_empty);
gui_chat_prefix[GUI_CHAT_PREFIX_JOIN] = strdup (gui_chat_prefix_empty);
gui_chat_prefix[GUI_CHAT_PREFIX_QUIT] = strdup (gui_chat_prefix_empty);
+
+ /* some hsignals */
+ hook_hsignal (NULL, "chat_quote_time_prefix_message",
+ &gui_chat_hsignal_quote_line_cb, NULL);
+ hook_hsignal (NULL, "chat_quote_prefix_message",
+ &gui_chat_hsignal_quote_line_cb, NULL);
+ hook_hsignal (NULL, "chat_quote_message",
+ &gui_chat_hsignal_quote_line_cb, NULL);
}
/*
@@ -187,6 +197,32 @@ gui_chat_string_add_offset (const char *string, int offset)
}
/*
+ * gui_chat_string_add_offset_screen: move forward N chars (using size on screen)
+ * in a string, skipping all formatting chars
+ * (like colors,..)
+ */
+
+char *
+gui_chat_string_add_offset_screen (const char *string, int offset_screen)
+{
+ int size_on_screen;
+
+ while (string && string[0] && (offset_screen > 0))
+ {
+ string = gui_chat_string_next_char (NULL,
+ (unsigned char *)string,
+ 0);
+ if (string)
+ {
+ size_on_screen = (gui_chat_utf_char_valid (string)) ? utf8_char_size_screen (string) : 1;
+ offset_screen -= size_on_screen;
+ string = utf8_next_char (string);
+ }
+ }
+ return (char *)string;
+}
+
+/*
* gui_chat_string_real_pos: get real position in string
* (ignoring color/bold/.. chars)
*/
@@ -767,6 +803,59 @@ gui_chat_printf_y (struct t_gui_buffer *buffer, int y, const char *message, ...)
}
/*
+ * gui_chat_hsignal_chat_quote_line_cb: quote a line
+ */
+
+int
+gui_chat_hsignal_quote_line_cb (void *data, const char *signal,
+ struct t_hashtable *hashtable)
+{
+ const char *time, *prefix, *message;
+ int length_time, length_prefix, length_message, length;
+ char *str;
+
+ /* make C compiler happy */
+ (void) data;
+
+ if (!gui_current_window->buffer->input)
+ return WEECHAT_RC_OK;
+
+ time = (strstr (signal, "time")) ?
+ hashtable_get (hashtable, "_chat_line_time") : NULL;
+ prefix = (strstr (signal, "prefix")) ?
+ hashtable_get (hashtable, "_chat_line_prefix") : NULL;
+ message = hashtable_get (hashtable, "_chat_line_message");
+
+ if (!message)
+ return WEECHAT_RC_OK;
+
+ length_time = (time) ? strlen (time) : 0;
+ length_prefix = (prefix) ? strlen (prefix) : 0;
+ length_message = strlen (message);
+
+ length = length_time + 1 + length_prefix + 1 +
+ strlen (CONFIG_STRING(config_look_prefix_suffix)) + 1 +
+ length_message + 1 + 1;
+ str = malloc (length);
+ if (str)
+ {
+ snprintf (str, length, "%s%s%s%s%s%s%s ",
+ (time) ? time : "",
+ (time) ? " " : "",
+ (prefix) ? prefix : "",
+ (prefix) ? " " : "",
+ (time || prefix) ? CONFIG_STRING(config_look_prefix_suffix) : "",
+ (time || prefix) ? " " : "",
+ message);
+ gui_input_insert_string (gui_current_window->buffer, str, -1);
+ gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, 1);
+ free (str);
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* gui_chat_end: free some variables allocated for chat area
*/
diff --git a/src/gui/gui-chat.h b/src/gui/gui-chat.h
index 009877f3c..f62ef808b 100644
--- a/src/gui/gui-chat.h
+++ b/src/gui/gui-chat.h
@@ -20,6 +20,7 @@
#ifndef __WEECHAT_GUI_CHAT_H
#define __WEECHAT_GUI_CHAT_H 1
+struct t_hashtable;
struct t_gui_window;
struct t_gui_buffer;
struct t_gui_line;
@@ -61,6 +62,8 @@ extern void gui_chat_prefix_build ();
extern int gui_chat_utf_char_valid (const char *utf_char);
extern int gui_chat_strlen_screen (const char *string);
extern char *gui_chat_string_add_offset (const char *string, int offset);
+extern char *gui_chat_string_add_offset_screen (const char *string,
+ int offset_screen);
extern int gui_chat_string_real_pos (const char *string, int pos);
extern void gui_chat_get_word_info (struct t_gui_window *window,
const char *data, int *word_start_offset,
@@ -77,6 +80,8 @@ extern void gui_chat_printf_date_tags (struct t_gui_buffer *buffer,
const char *message, ...);
extern void gui_chat_printf_y (struct t_gui_buffer *buffer, int y,
const char *message, ...);
+extern int gui_chat_hsignal_quote_line_cb (void *data, const char *signal,
+ struct t_hashtable *hashtable);
extern void gui_chat_end ();
/* chat functions (GUI dependent) */
diff --git a/src/gui/gui-cursor.c b/src/gui/gui-cursor.c
index 7871d808c..78dabfd65 100644
--- a/src/gui/gui-cursor.c
+++ b/src/gui/gui-cursor.c
@@ -42,7 +42,7 @@
int gui_cursor_mode = 0; /* cursor mode? (free movement) */
-int gui_cursor_debug = 0; /* debug mode (show info in input) */
+int gui_cursor_debug = 0; /* debug mode (0-2) */
int gui_cursor_x = 0; /* position of cursor in cursor mode */
int gui_cursor_y = 0; /* position of cursor in cursor mode */
@@ -75,16 +75,19 @@ gui_cursor_mode_toggle ()
}
/*
- * gui_cursor_debug_toggle: toggle debug for cursor mode
+ * gui_cursor_debug_set: set debug for cursor mode
*/
void
-gui_cursor_debug_toggle ()
+gui_cursor_debug_set (int debug)
{
- gui_cursor_debug ^= 1;
-
+ gui_cursor_debug = debug;
+
if (gui_cursor_debug)
- gui_chat_printf (NULL, _("Debug enabled for cursor mode"));
+ {
+ gui_chat_printf (NULL, _("Debug enabled for cursor mode (%s)"),
+ (debug > 1) ? _("verbose") : _("normal"));
+ }
else
gui_chat_printf (NULL, _("Debug disabled for cursor mode"));
}
@@ -96,29 +99,34 @@ gui_cursor_debug_toggle ()
void
gui_cursor_display_debug_info ()
{
- struct t_gui_focus_info focus_info;
+ struct t_gui_focus_info *focus_info;
char str_info[1024];
if (!gui_cursor_debug)
return;
- gui_focus_get_info (gui_cursor_x, gui_cursor_y, &focus_info);
-
- snprintf (str_info, sizeof (str_info),
- "%s(%d,%d) window:0x%lx (buffer: %s), chat: %d, "
- "bar_window:0x%lx (bar: %s, item: %s, line: %d, col: %d)",
- gui_color_get_custom ("yellow,red"),
- focus_info.x, focus_info.y,
- (long unsigned int)focus_info.window,
- (focus_info.window) ? (focus_info.window)->buffer->name : "-",
- focus_info.chat,
- (long unsigned int)focus_info.bar_window,
- (focus_info.bar_window) ? (focus_info.bar_window)->bar->name : "-",
- (focus_info.bar_item) ? focus_info.bar_item : "-",
- focus_info.item_line,
- focus_info.item_col);
- gui_input_delete_line (gui_current_window->buffer);
- gui_input_insert_string (gui_current_window->buffer, str_info, -1);
+ focus_info = gui_focus_get_info (gui_cursor_x, gui_cursor_y);
+ if (focus_info)
+ {
+ snprintf (str_info, sizeof (str_info),
+ "%s(%d,%d) window:0x%lx (buffer: %s), "
+ "bar_window:0x%lx (bar: %s, item: %s, line: %d, col: %d), "
+ "chat: %d, word: \"%s\"",
+ gui_color_get_custom ("yellow,red"),
+ focus_info->x, focus_info->y,
+ (long unsigned int)focus_info->window,
+ (focus_info->window) ? (focus_info->window)->buffer->name : "-",
+ (long unsigned int)focus_info->bar_window,
+ (focus_info->bar_window) ? ((focus_info->bar_window)->bar)->name : "-",
+ (focus_info->bar_item) ? focus_info->bar_item : "-",
+ focus_info->bar_item_line,
+ focus_info->bar_item_col,
+ focus_info->chat,
+ focus_info->chat_word);
+ gui_input_delete_line (gui_current_window->buffer);
+ gui_input_insert_string (gui_current_window->buffer, str_info, -1);
+ gui_focus_free_info (focus_info);
+ }
}
/*
@@ -184,7 +192,7 @@ void
gui_cursor_move_area_add_xy (int add_x, int add_y)
{
int x, y, width, height, area_found;
- struct t_gui_focus_info focus_info_old, focus_info_new;
+ struct t_gui_focus_info *focus_info_old, *focus_info_new;
if (!gui_cursor_mode)
gui_cursor_mode_toggle ();
@@ -196,7 +204,10 @@ gui_cursor_move_area_add_xy (int add_x, int add_y)
width = gui_window_get_width ();
height = gui_window_get_height ();
- gui_focus_get_info (x, y, &focus_info_old);
+ focus_info_old = gui_focus_get_info (x, y);
+ if (!focus_info_old)
+ return;
+ focus_info_new = NULL;
if (add_x != 0)
x += add_x;
@@ -205,11 +216,16 @@ gui_cursor_move_area_add_xy (int add_x, int add_y)
while ((x >= 0) && (x < width) && (y >= 0) && (y < height))
{
- gui_focus_get_info (x, y, &focus_info_new);
- if (((focus_info_new.window && focus_info_new.chat)
- || focus_info_new.bar_window)
- && ((focus_info_old.window != focus_info_new.window)
- || (focus_info_old.bar_window != focus_info_new.bar_window)))
+ focus_info_new = gui_focus_get_info (x, y);
+ if (!focus_info_new)
+ {
+ gui_focus_free_info (focus_info_old);
+ return;
+ }
+ if (((focus_info_new->window && focus_info_new->chat)
+ || focus_info_new->bar_window)
+ && ((focus_info_old->window != focus_info_new->window)
+ || (focus_info_old->bar_window != focus_info_new->bar_window)))
{
area_found = 1;
break;
@@ -223,15 +239,15 @@ gui_cursor_move_area_add_xy (int add_x, int add_y)
if (area_found)
{
- if (focus_info_new.window && focus_info_new.chat)
+ if (focus_info_new->window && focus_info_new->chat)
{
- x = (focus_info_new.window)->win_chat_x;
- y = (focus_info_new.window)->win_chat_y;
+ x = (focus_info_new->window)->win_chat_x;
+ y = (focus_info_new->window)->win_chat_y;
}
- else if (focus_info_new.bar_window)
+ else if (focus_info_new->bar_window)
{
- x = (focus_info_new.bar_window)->x;
- y = (focus_info_new.bar_window)->y;
+ x = (focus_info_new->bar_window)->x;
+ y = (focus_info_new->bar_window)->y;
}
else
area_found = 0;
@@ -244,6 +260,10 @@ gui_cursor_move_area_add_xy (int add_x, int add_y)
gui_cursor_display_debug_info ();
gui_window_move_cursor ();
}
+
+ gui_focus_free_info (focus_info_old);
+ if (focus_info_new)
+ gui_focus_free_info (focus_info_new);
}
/*
diff --git a/src/gui/gui-cursor.h b/src/gui/gui-cursor.h
index d0d2b4832..4c83a6a74 100644
--- a/src/gui/gui-cursor.h
+++ b/src/gui/gui-cursor.h
@@ -30,7 +30,7 @@ extern int gui_cursor_y;
/* cursor functions */
extern void gui_cursor_mode_toggle ();
-extern void gui_cursor_debug_toggle ();
+extern void gui_cursor_debug_set (int debug);
extern void gui_cursor_move_xy (int x, int y);
extern void gui_cursor_move_add_xy (int add_x, int add_y);
extern void gui_cursor_move_area_add_xy (int add_x, int add_y);
diff --git a/src/gui/gui-focus.c b/src/gui/gui-focus.c
index 739738f89..70d9e8eb6 100644
--- a/src/gui/gui-focus.c
+++ b/src/gui/gui-focus.c
@@ -30,46 +30,87 @@
#include "../core/weechat.h"
#include "../core/wee-hashtable.h"
+#include "../core/wee-string.h"
#include "../plugins/plugin.h"
#include "gui-bar.h"
#include "gui-bar-window.h"
#include "gui-buffer.h"
+#include "gui-color.h"
#include "gui-focus.h"
+#include "gui-line.h"
#include "gui-window.h"
+#define FOCUS_STR(__name, __string) \
+ hashtable_set (hashtable, __name, __string);
+#define FOCUS_STR_VAR(__name, __var) \
+ hashtable_set (hashtable, __name, (__var) ? __var : "");
+#define FOCUS_INT(__name, __int) \
+ snprintf (str_value, sizeof (str_value), "%d", __int); \
+ hashtable_set (hashtable, __name, str_value);
+#define FOCUS_TIME(__name, __time) \
+ snprintf (str_value, sizeof (str_value), "%ld", __time); \
+ hashtable_set (hashtable, __name, str_value);
+#define FOCUS_PTR(__name, __pointer) \
+ snprintf (str_value, sizeof (str_value), \
+ "0x%lx", (long unsigned int)__pointer); \
+ hashtable_set (hashtable, __name, str_value);
+
+
/*
* gui_focus_get_info: get info about what is pointed by cursor at (x,y)
*/
-void
-gui_focus_get_info (int x, int y, struct t_gui_focus_info *focus_info)
+struct t_gui_focus_info *
+gui_focus_get_info (int x, int y)
{
+ struct t_gui_focus_info *focus_info;
+
+ focus_info = malloc (sizeof (*focus_info));
+ if (!focus_info)
+ return NULL;
+
focus_info->x = x;
focus_info->y = y;
/* search window */
focus_info->window = gui_window_search_by_xy (x, y);
- /* chat area in this window? */
- if (focus_info->window
- && (x >= (focus_info->window)->win_chat_x)
- && (y >= (focus_info->window)->win_chat_y)
- && (x <= (focus_info->window)->win_chat_x + (focus_info->window)->win_chat_width - 1)
- && (y <= (focus_info->window)->win_chat_y + (focus_info->window)->win_chat_height - 1))
- {
- focus_info->chat = 1;
- }
- else
- focus_info->chat = 0;
+ /* fill info about chat area */
+ gui_window_get_context_at_xy (focus_info->window,
+ x, y,
+ &focus_info->chat,
+ &focus_info->chat_line,
+ &focus_info->chat_word,
+ &focus_info->chat_bol,
+ &focus_info->chat_eol);
/* search bar window, item, and line/col in item */
gui_bar_window_search_by_xy (focus_info->window,
x, y,
&focus_info->bar_window,
&focus_info->bar_item,
- &focus_info->item_line,
- &focus_info->item_col);
+ &focus_info->bar_item_line,
+ &focus_info->bar_item_col);
+
+ return focus_info;
+}
+
+/*
+ * gui_focus_free_info: free a focus info structure
+ */
+
+void
+gui_focus_free_info (struct t_gui_focus_info *focus_info)
+{
+ if (focus_info->chat_word)
+ free (focus_info->chat_word);
+ if (focus_info->chat_bol)
+ free (focus_info->chat_bol);
+ if (focus_info->chat_eol)
+ free (focus_info->chat_eol);
+
+ free (focus_info);
}
/*
@@ -80,7 +121,7 @@ struct t_hashtable *
gui_focus_to_hashtable (struct t_gui_focus_info *focus_info, const char *key)
{
struct t_hashtable *hashtable;
- char str_value[128];
+ char str_value[128], *str_time, *str_prefix, *str_tags, *str_message;
hashtable = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
@@ -91,58 +132,85 @@ gui_focus_to_hashtable (struct t_gui_focus_info *focus_info, const char *key)
return NULL;
/* key (key from keyboard or mouse event) */
- hashtable_set (hashtable, "_key", key);
+ FOCUS_STR("_key", key);
/* x,y */
- snprintf (str_value, sizeof (str_value), "%d", focus_info->x);
- hashtable_set (hashtable, "_x", str_value);
- snprintf (str_value, sizeof (str_value), "%d", focus_info->y);
- hashtable_set (hashtable, "_y", str_value);
+ FOCUS_INT("_x", focus_info->x);
+ FOCUS_INT("_y", focus_info->y);
/* window/buffer */
- snprintf (str_value, sizeof (str_value),
- "0x%lx", (long unsigned int)focus_info->window);
- hashtable_set (hashtable, "_window", str_value);
- snprintf (str_value, sizeof (str_value),
- "0x%lx",
- (focus_info->window) ?
- (long unsigned int)((focus_info->window)->buffer) : 0);
- hashtable_set (hashtable, "_buffer", str_value);
+ FOCUS_PTR("_window", focus_info->window);
if (focus_info->window)
{
- snprintf (str_value, sizeof (str_value), "%d",
- (focus_info->window)->number);
- hashtable_set (hashtable, "_window_number", str_value);
- snprintf (str_value, sizeof (str_value), "%d",
- ((focus_info->window)->buffer)->number);
- hashtable_set (hashtable, "_buffer_number", str_value);
- hashtable_set (hashtable, "_buffer_plugin",
- plugin_get_name (((focus_info->window)->buffer)->plugin));
- hashtable_set (hashtable, "_buffer_name",
- ((focus_info->window)->buffer)->name);
+ FOCUS_INT("_window_number", (focus_info->window)->number);
+ FOCUS_PTR("_buffer", focus_info->window->buffer);
+ FOCUS_INT("_buffer_number", ((focus_info->window)->buffer)->number);
+ FOCUS_STR("_buffer_plugin", plugin_get_name (((focus_info->window)->buffer)->plugin));
+ FOCUS_STR("_buffer_name", ((focus_info->window)->buffer)->name);
+ }
+ else
+ {
+ FOCUS_STR("_window_number", "*");
+ FOCUS_PTR("_buffer", NULL);
+ FOCUS_STR("_buffer_number", "-1");
+ FOCUS_STR("_buffer_plugin", "");
+ FOCUS_STR("_buffer_name", "");
+ }
+
+ /* chat area */
+ FOCUS_INT("_chat", focus_info->chat);
+ str_time = NULL;
+ str_prefix = NULL;
+ if (focus_info->chat_line)
+ {
+ str_time = gui_color_decode (((focus_info->chat_line)->data)->str_time, NULL);
+ str_prefix = gui_color_decode (((focus_info->chat_line)->data)->prefix, NULL);
+ str_tags = string_build_with_split_string ((const char **)((focus_info->chat_line)->data)->tags_array, ",");
+ str_message = gui_color_decode (((focus_info->chat_line)->data)->message, NULL);
+ FOCUS_INT("_chat_line_y", ((focus_info->chat_line)->data)->y);
+ FOCUS_TIME("_chat_line_date", ((focus_info->chat_line)->data)->date);
+ FOCUS_TIME("_chat_line_date_printed", ((focus_info->chat_line)->data)->date_printed);
+ FOCUS_STR_VAR("_chat_line_time", str_time);
+ FOCUS_STR_VAR("_chat_line_tags", str_tags);
+ FOCUS_STR_VAR("_chat_line_prefix", str_prefix);
+ FOCUS_STR_VAR("_chat_line_message", str_message);
+ if (str_time)
+ free (str_time);
+ if (str_prefix)
+ free (str_prefix);
+ if (str_tags)
+ free (str_tags);
+ if (str_message)
+ free (str_message);
}
else
{
- hashtable_set (hashtable, "_window_number", "*");
- hashtable_set (hashtable, "_buffer_number", "");
- hashtable_set (hashtable, "_buffer_plugin", "");
- hashtable_set (hashtable, "_buffer_name", "");
+ FOCUS_STR("_chat_line_y", "-1");
+ FOCUS_STR("_chat_line_date", "-1");
+ FOCUS_STR("_chat_line_date_printed", "-1");
+ FOCUS_STR("_chat_line_time", "");
+ FOCUS_STR("_chat_line_tags", "");
+ FOCUS_STR("_chat_line_prefix", "");
+ FOCUS_STR("_chat_line_message", "");
}
- hashtable_set (hashtable, "_chat", (focus_info->chat) ? "1" : "0");
+ FOCUS_STR_VAR("_chat_word", focus_info->chat_word);
+ FOCUS_STR_VAR("_chat_bol", focus_info->chat_bol);
+ FOCUS_STR_VAR("_chat_eol", focus_info->chat_eol);
/* bar/item */
- hashtable_set (hashtable, "_bar_name",
- (focus_info->bar_window) ?
- ((focus_info->bar_window)->bar)->name : "");
- hashtable_set (hashtable, "_bar_filling",
- (focus_info->bar_window) ?
- gui_bar_filling_string[gui_bar_get_filling ((focus_info->bar_window)->bar)] : "");
- hashtable_set (hashtable, "_bar_item_name",
- (focus_info->bar_item) ? focus_info->bar_item : "");
- snprintf (str_value, sizeof (str_value), "%d", focus_info->item_line);
- hashtable_set (hashtable, "_item_line", str_value);
- snprintf (str_value, sizeof (str_value), "%d", focus_info->item_col);
- hashtable_set (hashtable, "_item_col", str_value);
+ if (focus_info->bar_window)
+ {
+ FOCUS_STR("_bar_name", ((focus_info->bar_window)->bar)->name);
+ FOCUS_STR("_bar_filling", gui_bar_filling_string[gui_bar_get_filling ((focus_info->bar_window)->bar)]);
+ }
+ else
+ {
+ FOCUS_STR("_bar_name", "");
+ FOCUS_STR("_bar_filling", "");
+ }
+ FOCUS_STR_VAR("_bar_item_name", focus_info->bar_item);
+ FOCUS_INT("_bar_item_line", focus_info->bar_item_line);
+ FOCUS_INT("_bar_item_col", focus_info->bar_item_col);
return hashtable;
}
diff --git a/src/gui/gui-focus.h b/src/gui/gui-focus.h
index 71e5072ae..471f24d26 100644
--- a/src/gui/gui-focus.h
+++ b/src/gui/gui-focus.h
@@ -27,16 +27,20 @@ struct t_gui_focus_info
int x, y; /* (x,y) on screen */
struct t_gui_window *window; /* window found */
int chat; /* 1 for chat area, otherwise 0 */
+ struct t_gui_line *chat_line; /* line in chat area */
+ char *chat_word; /* word at (x,y) */
+ char *chat_bol; /* beginnong of line until (x,y) */
+ char *chat_eol; /* (x,y) until end of line */
struct t_gui_bar_window *bar_window; /* bar window found */
char *bar_item; /* bar item found */
- int item_line; /* line in bar item */
- int item_col; /* column in bar item */
+ int bar_item_line; /* line in bar item */
+ int bar_item_col; /* column in bar item */
};
/* focus functions */
-extern void gui_focus_get_info (int x, int y,
- struct t_gui_focus_info *focus_info);
+extern struct t_gui_focus_info *gui_focus_get_info (int x, int y);
+extern void gui_focus_free_info (struct t_gui_focus_info *focus_info);
extern struct t_hashtable *gui_focus_to_hashtable (struct t_gui_focus_info *focus_info,
const char *key);
diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c
index 959060f87..4a3c2b471 100644
--- a/src/gui/gui-key.c
+++ b/src/gui/gui-key.c
@@ -37,6 +37,7 @@
#include "../core/wee-hook.h"
#include "../core/wee-infolist.h"
#include "../core/wee-input.h"
+#include "../core/wee-list.h"
#include "../core/wee-log.h"
#include "../core/wee-string.h"
#include "../core/wee-utf8.h"
@@ -342,6 +343,88 @@ gui_key_get_expanded_name (const char *key)
}
/*
+ * gui_key_get_area: get area (any, chat, bar or item) and name
+ */
+
+void
+gui_key_get_area (const char *key, int *area_type, char **area_name)
+{
+ int i, length;
+ char *pos_end;
+
+ *area_type = GUI_KEY_FOCUS_ANY;
+ *area_name = NULL;
+
+ for (i = 0; i < GUI_KEY_NUM_FOCUS; i++)
+ {
+ length = strlen (gui_key_focus_string[i]);
+ if (strncmp (key + 1, gui_key_focus_string[i], length) == 0)
+ {
+ if (i == GUI_KEY_FOCUS_ANY)
+ {
+ *area_type = i;
+ *area_name = strdup ("*");
+ return;
+ }
+ if (key[1 + length] == ':')
+ {
+ *area_type = i;
+ *area_name = strdup ("*");
+ return;
+ }
+ if ((key[1 + length] == '(') && key[1 + length + 1])
+ {
+ pos_end = strchr (key + 1 + length, ')');
+ if (pos_end)
+ {
+ *area_type = i;
+ *area_name = string_strndup (key + 1 + length + 1,
+ pos_end - key - length - 2);
+ return;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * gui_key_score: compute a score key for sorting keys
+ * (high score == at the end of list)
+ */
+
+int
+gui_key_score (const char *key)
+{
+ int score, bonus, area_type;
+ char *area_name;
+
+ score = 0;
+ bonus = 8;
+
+ if (key[0] != '@')
+ return score;
+
+ /* basic score for key with area */
+ score |= 1 << bonus--;
+
+ gui_key_get_area (key, &area_type, &area_name);
+ if (!area_name)
+ return score;
+
+ /* bonus if area type is "any" */
+ if (area_type == GUI_KEY_FOCUS_ANY)
+ score |= 1 << bonus--;
+
+ /* bonus if area name is "*" */
+ if (strcmp (area_name, "*") == 0)
+ score |= 1 << bonus--;
+
+ free (area_name);
+
+ return score;
+}
+
+/*
* gui_key_find_pos: find position for a key (for sorting keys list)
*/
@@ -349,11 +432,17 @@ struct t_gui_key *
gui_key_find_pos (struct t_gui_key *keys, struct t_gui_key *key)
{
struct t_gui_key *ptr_key;
+ int score1, score2;
+ score1 = gui_key_score (key->key);
for (ptr_key = keys; ptr_key; ptr_key = ptr_key->next_key)
{
- if (strcmp (key->key, ptr_key->key) < 0)
+ score2 = gui_key_score (ptr_key->key);
+ if ((score1 < score2)
+ || ((score1 == score2) && (strcmp (key->key, ptr_key->key) < 0)))
+ {
return ptr_key;
+ }
}
return NULL;
}
@@ -625,52 +714,44 @@ gui_key_unbind (struct t_gui_buffer *buffer, int context, const char *key,
int
gui_key_focus_matching (int area_type, const char *area_name,
- int focus_specific, int focus_any,
- struct t_gui_focus_info *focus_info)
+ struct t_hashtable *hashtable_focus)
{
- int match, match_any;
+ int match;
char buffer_full_name[512];
-
- match_any = (strcmp (area_name, "*") == 0) ? 1 : 0;
-
- if (!focus_specific && !match_any)
- return 0;
-
- if (!focus_any && match_any)
- return 0;
-
- if (area_type == GUI_KEY_FOCUS_ANY)
- return 1;
+ const char *chat, *buffer_plugin, *buffer_name, *bar_name, *bar_item_name;
match = 0;
-
switch (area_type)
{
case GUI_KEY_FOCUS_ANY:
match = 1;
break;
case GUI_KEY_FOCUS_CHAT:
- if (focus_info->chat && focus_info->window)
+ chat = hashtable_get (hashtable_focus, "_chat");
+ buffer_plugin = hashtable_get (hashtable_focus, "_buffer_plugin");
+ buffer_name = hashtable_get (hashtable_focus, "_buffer_name");
+ if (chat && (strcmp (chat, "1") == 0)
+ && buffer_plugin && buffer_plugin[0]
+ && buffer_name && buffer_name[0])
{
- snprintf (buffer_full_name, sizeof (buffer_full_name), "%s.%s",
- gui_buffer_get_plugin_name ((focus_info->window)->buffer),
- ((focus_info->window)->buffer)->name);
+ snprintf (buffer_full_name, sizeof (buffer_full_name),
+ "%s.%s", buffer_plugin, buffer_name);
if (string_match (buffer_full_name, area_name, 0))
- {
match = 1;
- }
}
break;
case GUI_KEY_FOCUS_BAR:
- if (focus_info->bar_window
- && (string_match ((focus_info->bar_window)->bar->name, area_name, 0)))
+ bar_name = hashtable_get (hashtable_focus, "_bar_name");
+ if (bar_name && bar_name[0]
+ && (string_match (bar_name, area_name, 0)))
{
match = 1;
}
break;
case GUI_KEY_FOCUS_ITEM:
- if (focus_info->bar_item
- && (string_match (focus_info->bar_item, area_name, 0)))
+ bar_item_name = hashtable_get (hashtable_focus, "_bar_item_name");
+ if (bar_item_name && bar_item_name[0]
+ && (string_match (bar_item_name, area_name, 0)))
{
match = 1;
}
@@ -683,68 +764,27 @@ gui_key_focus_matching (int area_type, const char *area_name,
}
/*
- * gui_key_focus_get_area: get area focus (any, chat, bar or item) and name
- */
-
-void
-gui_key_focus_get_area (const char *key, int *area_type, char **area_name)
-{
- int i, length;
- char *pos_end;
-
- *area_type = GUI_KEY_FOCUS_ANY;
- *area_name = NULL;
-
- for (i = 0; i < GUI_KEY_NUM_FOCUS; i++)
- {
- length = strlen (gui_key_focus_string[i]);
- if (strncmp (key + 1, gui_key_focus_string[i], length) == 0)
- {
- if (i == GUI_KEY_FOCUS_ANY)
- {
- *area_type = i;
- *area_name = strdup ("*");
- return;
- }
- if (key[1 + length] == ':')
- {
- *area_type = i;
- *area_name = strdup ("*");
- return;
- }
- if ((key[1 + length] == '(') && key[1 + length + 1])
- {
- pos_end = strchr (key + 1 + length, ')');
- if (pos_end)
- {
- *area_type = i;
- *area_name = string_strndup (key + 1 + length + 1,
- pos_end - key - length - 2);
- return;
- }
- }
- }
- }
-}
-
-/*
* gui_key_focus_command: run command according to focus
* return 1 if a command was executed, otherwise 0
*/
int
gui_key_focus_command (const char *key, int context,
- int focus_specific, int focus_any,
- struct t_gui_focus_info *focus_info1,
- struct t_gui_focus_info *focus_info2)
+ struct t_hashtable *hashtable_focus1,
+ struct t_hashtable *hashtable_focus2)
{
struct t_gui_key *ptr_key;
int i, errors, matching, area_type, debug;
char *pos, *command, **commands, *area_name;
struct t_hashtable *hashtable;
+ struct t_weelist *list_keys;
+ struct t_weelist_item *ptr_item;
- debug = ((gui_cursor_debug && (context == GUI_KEY_CONTEXT_CURSOR))
- || (gui_mouse_debug && (context == GUI_KEY_CONTEXT_MOUSE)));
+ debug = 0;
+ if (gui_cursor_debug && (context == GUI_KEY_CONTEXT_CURSOR))
+ debug = gui_cursor_debug;
+ else if (gui_mouse_debug && (context == GUI_KEY_CONTEXT_MOUSE))
+ debug = gui_mouse_debug;
for (ptr_key = gui_keys[context]; ptr_key;
ptr_key = ptr_key->next_key)
@@ -759,31 +799,40 @@ gui_key_focus_command (const char *key, int context,
if (gui_key_cmp (key, pos + 1, context) != 0)
continue;
- gui_key_focus_get_area (ptr_key->key, &area_type, &area_name);
+ gui_key_get_area (ptr_key->key, &area_type, &area_name);
if (!area_name)
continue;
matching = gui_key_focus_matching (area_type, area_name,
- focus_specific, focus_any,
- focus_info1);
+ hashtable_focus1);
free (area_name);
if (!matching)
continue;
+ hashtable = hook_focus_get_data (hashtable_focus1, hashtable_focus2);
+ if (!hashtable)
+ continue;
+
if ((context == GUI_KEY_CONTEXT_CURSOR) && gui_cursor_debug)
{
gui_input_delete_line (gui_current_window->buffer);
}
- hashtable = hook_focus_get_data (focus_info1,
- focus_info2,
- key);
+ if (debug > 1)
+ {
+ gui_chat_printf (NULL, _("Hashtable focus:"));
+ list_keys = hashtable_get_list_keys (hashtable);
+ for (ptr_item = list_keys->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ gui_chat_printf (NULL, " %s: \"%s\"",
+ ptr_item->data,
+ hashtable_get (hashtable, ptr_item->data));
+ }
+ }
if (debug)
{
- gui_chat_printf (NULL, _("Hashtable focus: %s"),
- hashtable_get_string (hashtable,
- "keys_values_sorted"));
gui_chat_printf (NULL, _("Command for key: \"%s\""),
ptr_key->command);
}
@@ -828,8 +877,7 @@ gui_key_focus_command (const char *key, int context,
}
string_free_split_command (commands);
}
- if (hashtable)
- hashtable_free (hashtable);
+ hashtable_free (hashtable);
return 1;
}
@@ -845,12 +893,36 @@ gui_key_focus_command (const char *key, int context,
int
gui_key_focus (const char *key, int context)
{
- struct t_gui_focus_info focus_info1, focus_info2, *ptr_focus_info2;
+ struct t_gui_focus_info *focus_info1, *focus_info2;
+ struct t_hashtable *hashtable_focus1, *hashtable_focus2;
+ int rc;
- ptr_focus_info2 = NULL;
+ rc = 0;
+ focus_info1 = NULL;
+ focus_info2 = NULL;
+ hashtable_focus1 = NULL;
+ hashtable_focus2 = NULL;
if (context == GUI_KEY_CONTEXT_MOUSE)
{
+ focus_info1 = gui_focus_get_info (gui_mouse_event_x[0],
+ gui_mouse_event_y[0]);
+ if (!focus_info1)
+ goto end;
+ hashtable_focus1 = gui_focus_to_hashtable (focus_info1, key);
+ if (!hashtable_focus1)
+ goto end;
+ if ((gui_mouse_event_x[0] != gui_mouse_event_x[1])
+ || (gui_mouse_event_y[0] != gui_mouse_event_y[1]))
+ {
+ focus_info2 = gui_focus_get_info (gui_mouse_event_x[1],
+ gui_mouse_event_y[1]);
+ if (!focus_info2)
+ goto end;
+ hashtable_focus2 = gui_focus_to_hashtable (focus_info2, key);
+ if (!hashtable_focus2)
+ goto end;
+ }
if (gui_mouse_debug)
{
gui_chat_printf (NULL, "Mouse: %s, (%d,%d) -> (%d,%d)",
@@ -858,29 +930,31 @@ gui_key_focus (const char *key, int context)
gui_mouse_event_x[0], gui_mouse_event_y[0],
gui_mouse_event_x[1], gui_mouse_event_y[1]);
}
- gui_focus_get_info (gui_mouse_event_x[0], gui_mouse_event_y[0],
- &focus_info1);
- if ((gui_mouse_event_x[0] != gui_mouse_event_x[1])
- || (gui_mouse_event_y[0] != gui_mouse_event_y[1]))
- {
- gui_focus_get_info (gui_mouse_event_x[1], gui_mouse_event_y[1],
- &focus_info2);
- ptr_focus_info2 = &focus_info2;
- }
}
else
{
- gui_focus_get_info (gui_cursor_x, gui_cursor_y, &focus_info1);
+ focus_info1 = gui_focus_get_info (gui_cursor_x, gui_cursor_y);
+ if (!focus_info1)
+ goto end;
+ hashtable_focus1 = gui_focus_to_hashtable (focus_info1, key);
+ if (!hashtable_focus1)
+ goto end;
}
- if (gui_key_focus_command (key, context, 1, 0,
- &focus_info1, ptr_focus_info2))
- {
- return 1;
- }
+ rc = gui_key_focus_command (key, context,
+ hashtable_focus1, hashtable_focus2);
+
+end:
+ if (focus_info1)
+ gui_focus_free_info (focus_info1);
+ if (focus_info2)
+ gui_focus_free_info (focus_info2);
+ if (hashtable_focus1)
+ hashtable_free (hashtable_focus1);
+ if (hashtable_focus2)
+ hashtable_free (hashtable_focus2);
- return gui_key_focus_command (key, context, 0, 1, &focus_info1,
- ptr_focus_info2);
+ return rc;
}
/*
diff --git a/src/gui/gui-line.c b/src/gui/gui-line.c
index a23784906..f97b13486 100644
--- a/src/gui/gui-line.c
+++ b/src/gui/gui-line.c
@@ -574,11 +574,11 @@ gui_line_remove_from_list (struct t_gui_buffer *buffer,
{
struct t_gui_window *ptr_win;
struct t_gui_window_scroll *ptr_scroll;
- int update_prefix_max_length;
+ int i, update_prefix_max_length;
- /* reset scroll for any window scroll starting with this line */
for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
{
+ /* reset scroll for any window scroll starting with this line */
for (ptr_scroll = ptr_win->scroll; ptr_scroll;
ptr_scroll = ptr_scroll->next_scroll)
{
@@ -589,6 +589,15 @@ gui_line_remove_from_list (struct t_gui_buffer *buffer,
gui_buffer_ask_chat_refresh (buffer, 2);
}
}
+ /* remove line from coords */
+ if (ptr_win->coords)
+ {
+ for (i = 0; i < ptr_win->coords_size; i++)
+ {
+ if (ptr_win->coords[i].line == line)
+ gui_window_coords_init_line (ptr_win, i);
+ }
+ }
}
update_prefix_max_length =
@@ -803,7 +812,7 @@ gui_line_add (struct t_gui_buffer *buffer, time_t date,
/* fill data in new line */
new_line->data->buffer = buffer;
- new_line->data->y = 0;
+ new_line->data->y = -1;
new_line->data->date = date;
new_line->data->date_printed = date_printed;
new_line->data->str_time = (date == 0) ?
diff --git a/src/gui/gui-mouse.c b/src/gui/gui-mouse.c
index 8a062d89c..0ea04429c 100644
--- a/src/gui/gui-mouse.c
+++ b/src/gui/gui-mouse.c
@@ -33,7 +33,7 @@
int gui_mouse_enabled = 0; /* 1 if mouse support is enabled */
-int gui_mouse_debug = 0; /* debug mode for mouse */
+int gui_mouse_debug = 0; /* debug mode for mouse (0-2) */
int gui_mouse_grab = 0; /* 1 if grab mode enabled */
/* mouse event */
@@ -49,16 +49,19 @@ char gui_mouse_event_button = '#'; /* button pressed (or wheel) */
/*
- * gui_mouse_debug_toggle: toggle debug for mouse events
+ * gui_mouse_debug_set: set debug for mouse events
*/
void
-gui_mouse_debug_toggle ()
+gui_mouse_debug_set (int debug)
{
- gui_mouse_debug ^= 1;
+ gui_mouse_debug = debug;
if (gui_mouse_debug)
- gui_chat_printf (NULL, _("Debug enabled for mouse"));
+ {
+ gui_chat_printf (NULL, _("Debug enabled for mouse (%s)"),
+ (debug > 1) ? _("verbose") : _("normal"));
+ }
else
gui_chat_printf (NULL, _("Debug disabled for mouse"));
}
diff --git a/src/gui/gui-mouse.h b/src/gui/gui-mouse.h
index a930a32d5..db5adac2f 100644
--- a/src/gui/gui-mouse.h
+++ b/src/gui/gui-mouse.h
@@ -34,7 +34,7 @@ extern char gui_mouse_event_button;
/* mouse functions */
-extern void gui_mouse_debug_toggle ();
+extern void gui_mouse_debug_set (int debug);
extern void gui_mouse_event_reset ();
/* mouse functions (GUI dependent) */
diff --git a/src/gui/gui-window.c b/src/gui/gui-window.c
index 9c1c253ce..e6e757bf0 100644
--- a/src/gui/gui-window.c
+++ b/src/gui/gui-window.c
@@ -48,6 +48,8 @@
#include "gui-bar.h"
#include "gui-bar-window.h"
#include "gui-buffer.h"
+#include "gui-chat.h"
+#include "gui-color.h"
#include "gui-filter.h"
#include "gui-input.h"
#include "gui-hotlist.h"
@@ -119,6 +121,147 @@ gui_window_search_by_xy (int x, int y)
}
/*
+ * gui_window_get_context_at_xy: return following info:
+ * - chat (0/1)
+ * - line
+ * - word at (x,y)
+ * - beginning of line until (x,y)
+ * - (x,y) until end of line
+ */
+
+void
+gui_window_get_context_at_xy (struct t_gui_window *window,
+ int x, int y,
+ int *chat,
+ struct t_gui_line **line,
+ char **word,
+ char **beginning,
+ char **end)
+{
+ int win_x, win_y;
+ char *ptr_data, *data_next_line, *str_temp;
+ char *word_start, *word_end, *last_space;
+
+ *chat = 0;
+ *line = NULL;
+ *word = NULL;
+ *beginning = NULL;
+ *end = NULL;
+
+ /* not in a window? */
+ if (!window)
+ return;
+
+ /* in window, but not in chat area? */
+ win_x = x - window->win_chat_x;
+ win_y = y - window->win_chat_y;
+ if ((win_x < 0)
+ || (win_y < 0)
+ || (win_x > window->win_chat_width - 1)
+ || (win_y > window->win_chat_height - 1))
+ {
+ return;
+ }
+
+ /* add horizontal scroll (buffers with free content) */
+ if (window->scroll->start_col > 0)
+ win_x += window->scroll->start_col;
+
+ /* we are in chat area */
+ *chat = 1;
+
+ /* get line */
+ *line = window->coords[win_y].line;
+ if (!*line)
+ return;
+
+ /* no data for line? */
+ if (!window->coords[win_y].data)
+ return;
+
+ if (win_x < window->coords_x_message)
+ {
+ /* X is before message (time/buffer/prefix) */
+ if ((win_x >= window->coords[win_y].time_x1)
+ && (win_x <= window->coords[win_y].time_x2))
+ {
+ *word = gui_color_decode ((*line)->data->str_time, NULL);
+ }
+ else if ((win_x >= window->coords[win_y].buffer_x1)
+ && (win_x <= window->coords[win_y].buffer_x2))
+ {
+ *word = gui_color_decode ((*line)->data->buffer->short_name, NULL);
+ }
+ else if ((win_x >= window->coords[win_y].prefix_x1)
+ && (win_x <= window->coords[win_y].prefix_x2))
+ {
+ *word = gui_color_decode ((*line)->data->prefix, NULL);
+ }
+ }
+ else
+ {
+ /* X is in message (or after) */
+ data_next_line = ((win_y < window->win_chat_height - 1)
+ && (window->coords[win_y + 1].line == *line)) ?
+ window->coords[win_y + 1].data : NULL;
+ ptr_data = gui_chat_string_add_offset_screen (window->coords[win_y].data,
+ win_x - window->coords_x_message);
+ if (ptr_data && ptr_data[0]
+ && (!data_next_line || (ptr_data < data_next_line)))
+ {
+ str_temp = string_strndup ((*line)->data->message,
+ ptr_data - (*line)->data->message);
+ if (str_temp)
+ {
+ *beginning = gui_color_decode (str_temp, NULL);
+ free (str_temp);
+ }
+ *end = gui_color_decode (ptr_data, NULL);
+ if (ptr_data[0] != ' ')
+ {
+ last_space = NULL;
+ word_start = (*line)->data->message;
+ while (word_start < ptr_data)
+ {
+ word_start = (char *)gui_chat_string_next_char (NULL,
+ (unsigned char *)word_start,
+ 0);
+ if (word_start)
+ {
+ if (word_start[0] == ' ')
+ last_space = word_start;
+ word_start = utf8_next_char (word_start);
+ }
+ }
+ word_start = (last_space) ? last_space + 1 : (*line)->data->message;
+ word_end = ptr_data;
+ while (word_end && word_end[0])
+ {
+ word_end = (char *)gui_chat_string_next_char (NULL,
+ (unsigned char *)word_end,
+ 0);
+ if (word_end)
+ {
+ if (word_end[0] == ' ')
+ break;
+ word_end = utf8_next_char (word_end);
+ }
+ }
+ if (word_start && word_end)
+ {
+ str_temp = string_strndup (word_start, word_end - word_start);
+ if (str_temp)
+ {
+ *word = gui_color_decode (str_temp, NULL);
+ free (str_temp);
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
* gui_window_ask_refresh: set "gui_window_refresh_needed" flag
*/
@@ -485,6 +628,11 @@ gui_window_new (struct t_gui_window *parent_window, struct t_gui_buffer *buffer,
/* scroll */
gui_window_scroll_init (new_window->scroll, buffer);
+ /* coordinates */
+ new_window->coords_size = 0;
+ new_window->coords = NULL;
+ new_window->coords_x_message = 0;
+
/* tree */
new_window->ptr_tree = ptr_leaf;
ptr_leaf->window = new_window;
@@ -683,6 +831,53 @@ gui_window_set_layout_buffer_name (struct t_gui_window *window,
}
/*
+ * gui_window_coords_init_line: initialize a line in window coordinates
+ */
+
+void
+gui_window_coords_init_line (struct t_gui_window *window, int line)
+{
+ if (!window->coords || (line < 0) || (line >= window->coords_size))
+ return;
+
+ window->coords[line].line = NULL;
+ window->coords[line].data = NULL;
+ window->coords[line].time_x1 = -1;
+ window->coords[line].time_x2 = -1;
+ window->coords[line].buffer_x1 = -1;
+ window->coords[line].buffer_x2 = -1;
+ window->coords[line].prefix_x1 = -1;
+ window->coords[line].prefix_x2 = -1;
+}
+
+/*
+ * gui_window_coords_alloc: allocate and initialize coordinates for window
+ */
+
+void
+gui_window_coords_alloc (struct t_gui_window *window)
+{
+ int i;
+
+ if (window->coords && (window->coords_size != window->win_chat_height))
+ {
+ free (window->coords);
+ window->coords = NULL;
+ }
+ window->coords_size = window->win_chat_height;
+ if (!window->coords)
+ window->coords = malloc (window->coords_size * sizeof (window->coords[0]));
+ if (window->coords)
+ {
+ for (i = 0; i < window->win_chat_height; i++)
+ {
+ gui_window_coords_init_line (window, i);
+ }
+ }
+ window->coords_x_message = 0;
+}
+
+/*
* gui_window_free: delete a window
*/
@@ -1547,6 +1742,9 @@ gui_window_print_log ()
log_printf (" layout_plugin_name. : '%s'", ptr_window->layout_plugin_name);
log_printf (" layout_buffer_name. : '%s'", ptr_window->layout_buffer_name);
log_printf (" scroll. . . . . . . : 0x%lx", ptr_window->scroll);
+ log_printf (" coords_size . . . . : %d", ptr_window->coords_size);
+ log_printf (" coords. . . . . . . : 0x%lx", ptr_window->coords);
+ log_printf (" coords_x_message. . : %d", ptr_window->coords_x_message);
log_printf (" ptr_tree. . . . . . : 0x%lx", ptr_window->ptr_tree);
log_printf (" prev_window . . . . : 0x%lx", ptr_window->prev_window);
log_printf (" next_window . . . . : 0x%lx", ptr_window->next_window);
diff --git a/src/gui/gui-window.h b/src/gui/gui-window.h
index 54b405a9a..c31cc05e4 100644
--- a/src/gui/gui-window.h
+++ b/src/gui/gui-window.h
@@ -36,6 +36,15 @@ extern int gui_window_cursor_x, gui_window_cursor_y;
/* window structures */
+struct t_gui_window_coords
+{
+ struct t_gui_line *line; /* pointer to line */
+ char *data; /* pointer to data */
+ int time_x1, time_x2; /* start/end of time on screen */
+ int buffer_x1, buffer_x2; /* start/end of buffer name on screen*/
+ int prefix_x1, prefix_x2; /* start/end of prefix on screen */
+};
+
struct t_gui_window
{
int number; /* window number (first is 1) */
@@ -73,7 +82,12 @@ struct t_gui_window
/* scroll */
struct t_gui_window_scroll *scroll; /* scroll infos for each buffer */
/* scrolled in this window */
-
+
+ /* coordinates (for focus) */
+ int coords_size; /* size of coords (number of lines) */
+ struct t_gui_window_coords *coords;/* coords for window */
+ int coords_x_message; /* start X for messages */
+
/* tree */
struct t_gui_window_tree *ptr_tree;/* pointer to leaf in windows tree */
@@ -123,6 +137,13 @@ extern struct t_gui_window_tree *gui_windows_tree;
extern struct t_gui_window *gui_window_search_by_number (int number);
extern struct t_gui_window *gui_window_search_by_xy (int x, int y);
+extern void gui_window_get_context_at_xy (struct t_gui_window *window,
+ int x, int y,
+ int *chat,
+ struct t_gui_line **line,
+ char **word,
+ char **beginning,
+ char **end);
extern void gui_window_ask_refresh (int refresh);
extern int gui_window_tree_init (struct t_gui_window *window);
extern void gui_window_tree_node_to_leaf (struct t_gui_window_tree *node,
@@ -148,6 +169,8 @@ extern void gui_window_set_layout_plugin_name (struct t_gui_window *window,
const char *plugin_name);
extern void gui_window_set_layout_buffer_name (struct t_gui_window *window,
const char *buffer_name);
+extern void gui_window_coords_init_line (struct t_gui_window *window, int line);
+extern void gui_window_coords_alloc (struct t_gui_window *window);
extern void gui_window_free (struct t_gui_window *window);
extern void gui_window_switch_previous (struct t_gui_window *window);
extern void gui_window_switch_next (struct t_gui_window *window);
@@ -208,6 +231,8 @@ extern int gui_window_balance (struct t_gui_window_tree *tree);
extern void gui_window_swap (struct t_gui_window *window, int direction);
extern void gui_window_refresh_screen (int full_refresh);
extern void gui_window_set_title (const char *title);
+extern void gui_window_send_clipboard (const char *storage_unit,
+ const char *text);
extern void gui_window_move_cursor ();
extern void gui_window_term_display_infos ();
extern void gui_window_objects_print_log (struct t_gui_window *window);
diff --git a/src/plugins/irc/irc-bar-item.c b/src/plugins/irc/irc-bar-item.c
index 61c5b461f..9625b3cfa 100644
--- a/src/plugins/irc/irc-bar-item.c
+++ b/src/plugins/irc/irc-bar-item.c
@@ -507,6 +507,9 @@ irc_bar_item_focus_buffer_nicklist (void *data,
const char *str_buffer, *nick;
str_buffer = weechat_hashtable_get (info, "_buffer");
+ if (!str_buffer || !str_buffer[0])
+ return NULL;
+
rc = sscanf (str_buffer, "%lx", &value);
if ((rc == EOF) || (rc == 0))
return NULL;