mirror of
https://github.com/weechat/weechat.git
synced 2026-07-09 03:03:12 +02:00
cf6aca1619
This pointer is the first argument received by callbacks, and the existing argument "data" is now automatically freed by WeeChat when the object containing the callback is removed. With this new pointer, the linked list of callbacks in scripts has been removed. This will improve speed of scripts (using a lot of hooks), reduce memory used by scripts and reduce time to unload scripts. Following functions are affected in the C API: * exec_on_files * config_new * config_new_section * config_new_option * hook_command * hook_command_run * hook_timer * hook_fd * hook_process * hook_process_hashtable * hook_connect * hook_print * hook_signal * hook_hsignal * hook_config * hook_completion * hook_modifier * hook_info * hook_info_hashtable * hook_infolist * hook_hdata * hook_focus * unhook_all_plugin * buffer_new * bar_item_new * upgrade_new * upgrade_read
281 lines
9.4 KiB
C
281 lines
9.4 KiB
C
/*
|
|
* gui-focus.c - functions about focus (cursor mode and mouse) (used by all GUI)
|
|
*
|
|
* Copyright (C) 2011-2016 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 <http://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"
|
|
|
|
|
|
#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", (long)__time); \
|
|
hashtable_set (hashtable, __name, str_value);
|
|
#define FOCUS_PTR(__name, __pointer) \
|
|
if (__pointer) \
|
|
{ \
|
|
snprintf (str_value, sizeof (str_value), \
|
|
"0x%lx", (long unsigned int)__pointer); \
|
|
hashtable_set (hashtable, __name, str_value); \
|
|
} \
|
|
else \
|
|
{ \
|
|
hashtable_set (hashtable, __name, ""); \
|
|
}
|
|
|
|
|
|
/*
|
|
* 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) */
|
|
FOCUS_STR("_key", key);
|
|
|
|
/* x,y */
|
|
FOCUS_INT("_x", focus_info->x);
|
|
FOCUS_INT("_y", focus_info->y);
|
|
|
|
/* window */
|
|
FOCUS_PTR("_window", focus_info->window);
|
|
if (focus_info->window)
|
|
{
|
|
FOCUS_INT("_window_number", (focus_info->window)->number);
|
|
}
|
|
else
|
|
{
|
|
FOCUS_STR("_window_number", "*");
|
|
}
|
|
|
|
/* buffer */
|
|
FOCUS_PTR("_buffer", focus_info->buffer);
|
|
if (focus_info->buffer)
|
|
{
|
|
FOCUS_INT("_buffer_number", (focus_info->buffer)->number);
|
|
FOCUS_STR("_buffer_plugin", plugin_get_name ((focus_info->buffer)->plugin));
|
|
FOCUS_STR("_buffer_name", (focus_info->buffer)->name);
|
|
FOCUS_STR("_buffer_full_name", (focus_info->buffer)->full_name);
|
|
hashtable_map ((focus_info->buffer)->local_variables,
|
|
&gui_focus_buffer_localvar_map_cb, hashtable);
|
|
}
|
|
else
|
|
{
|
|
FOCUS_PTR("_buffer", NULL);
|
|
FOCUS_STR("_buffer_number", "-1");
|
|
FOCUS_STR("_buffer_plugin", "");
|
|
FOCUS_STR("_buffer_name", "");
|
|
FOCUS_STR("_buffer_full_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);
|
|
nick = gui_line_get_nick_tag (focus_info->chat_line);
|
|
FOCUS_PTR("_chat_line", focus_info->chat_line);
|
|
FOCUS_INT("_chat_line_x", focus_info->chat_line_x);
|
|
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_nick", nick);
|
|
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
|
|
{
|
|
FOCUS_PTR("_chat_line", NULL);
|
|
FOCUS_STR("_chat_line_x", "-1");
|
|
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_nick", "");
|
|
FOCUS_STR("_chat_line_prefix", "");
|
|
FOCUS_STR("_chat_line_message", "");
|
|
}
|
|
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 */
|
|
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;
|
|
}
|