weechat/src/gui/gui-focus.c

258 lines
8.5 KiB
C

/*
* gui-focus.c - functions about focus (cursor mode and mouse) (used by all GUI)
*
* Copyright (C) 2011-2020 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* WeeChat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#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"
/*
* Gets info about what is pointed by cursor at (x,y).
*
* Returns pointer to focus info, NULL if error.
*
* Note: focus info must be freed after use.
*/
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);
focus_info->buffer = (focus_info->window) ? (focus_info->window)->buffer : NULL;
/* 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_line_x,
&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->bar_item_line,
&focus_info->bar_item_col,
&focus_info->buffer);
/* force current buffer if not buffer at all was found */
if (!focus_info->buffer && gui_current_window)
focus_info->buffer = gui_current_window->buffer;
return focus_info;
}
/*
* Frees 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);
}
/*
* Adds local variables of buffer in hashtable.
*/
void
gui_focus_buffer_localvar_map_cb (void *data,
struct t_hashtable *hashtable,
const void *key, const void *value)
{
struct t_hashtable *hashtable_focus;
char hash_key[512];
/* make C compiler happy */
(void) hashtable;
hashtable_focus = (struct t_hashtable *)data;
if (hashtable_focus && key && value)
{
snprintf (hash_key, sizeof (hash_key),
"_buffer_localvar_%s", (const char *)key);
hashtable_set (hashtable_focus, hash_key, (const char *)value);
}
}
/*
* Adds two focus info into hashtable.
*
* Returns pointer to new hashtable.
*
* Note: result must be freed after use.
*/
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], *str_time, *str_prefix, *str_tags, *str_message;
const char *nick;
hashtable = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!hashtable)
return NULL;
/* key (key from keyboard or mouse event) */
HASHTABLE_SET_STR("_key", key);
/* x,y */
HASHTABLE_SET_INT("_x", focus_info->x);
HASHTABLE_SET_INT("_y", focus_info->y);
/* window */
HASHTABLE_SET_POINTER("_window", focus_info->window);
if (focus_info->window)
{
HASHTABLE_SET_INT("_window_number", (focus_info->window)->number);
}
else
{
HASHTABLE_SET_STR("_window_number", "*");
}
/* buffer */
HASHTABLE_SET_POINTER("_buffer", focus_info->buffer);
if (focus_info->buffer)
{
HASHTABLE_SET_INT("_buffer_number", (focus_info->buffer)->number);
HASHTABLE_SET_STR("_buffer_plugin", plugin_get_name ((focus_info->buffer)->plugin));
HASHTABLE_SET_STR("_buffer_name", (focus_info->buffer)->name);
HASHTABLE_SET_STR("_buffer_full_name", (focus_info->buffer)->full_name);
hashtable_map ((focus_info->buffer)->local_variables,
&gui_focus_buffer_localvar_map_cb, hashtable);
}
else
{
HASHTABLE_SET_POINTER("_buffer", NULL);
HASHTABLE_SET_STR("_buffer_number", "-1");
HASHTABLE_SET_STR("_buffer_plugin", "");
HASHTABLE_SET_STR("_buffer_name", "");
HASHTABLE_SET_STR("_buffer_full_name", "");
}
/* chat area */
HASHTABLE_SET_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);
nick = gui_line_get_nick_tag (focus_info->chat_line);
HASHTABLE_SET_POINTER("_chat_line", focus_info->chat_line);
HASHTABLE_SET_INT("_chat_line_x", focus_info->chat_line_x);
HASHTABLE_SET_INT("_chat_line_y", ((focus_info->chat_line)->data)->y);
HASHTABLE_SET_TIME("_chat_line_date", ((focus_info->chat_line)->data)->date);
HASHTABLE_SET_TIME("_chat_line_date_printed", ((focus_info->chat_line)->data)->date_printed);
HASHTABLE_SET_STR_NOT_NULL("_chat_line_time", str_time);
HASHTABLE_SET_STR_NOT_NULL("_chat_line_tags", str_tags);
HASHTABLE_SET_STR_NOT_NULL("_chat_line_nick", nick);
HASHTABLE_SET_STR_NOT_NULL("_chat_line_prefix", str_prefix);
HASHTABLE_SET_STR_NOT_NULL("_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_POINTER("_chat_line", NULL);
HASHTABLE_SET_STR("_chat_line_x", "-1");
HASHTABLE_SET_STR("_chat_line_y", "-1");
HASHTABLE_SET_STR("_chat_line_date", "-1");
HASHTABLE_SET_STR("_chat_line_date_printed", "-1");
HASHTABLE_SET_STR("_chat_line_time", "");
HASHTABLE_SET_STR("_chat_line_tags", "");
HASHTABLE_SET_STR("_chat_line_nick", "");
HASHTABLE_SET_STR("_chat_line_prefix", "");
HASHTABLE_SET_STR("_chat_line_message", "");
}
HASHTABLE_SET_STR_NOT_NULL("_chat_word", focus_info->chat_word);
HASHTABLE_SET_STR_NOT_NULL("_chat_bol", focus_info->chat_bol);
HASHTABLE_SET_STR_NOT_NULL("_chat_eol", focus_info->chat_eol);
/* bar/item */
if (focus_info->bar_window)
{
HASHTABLE_SET_STR("_bar_name", ((focus_info->bar_window)->bar)->name);
HASHTABLE_SET_STR("_bar_filling", gui_bar_filling_string[gui_bar_get_filling ((focus_info->bar_window)->bar)]);
}
else
{
HASHTABLE_SET_STR("_bar_name", "");
HASHTABLE_SET_STR("_bar_filling", "");
}
HASHTABLE_SET_STR_NOT_NULL("_bar_item_name", focus_info->bar_item);
HASHTABLE_SET_INT("_bar_item_line", focus_info->bar_item_line);
HASHTABLE_SET_INT("_bar_item_col", focus_info->bar_item_col);
return hashtable;
}