From 554a8556d27c66917ed274a76d8ba47bdc7ba13a Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:46:31 +0200 Subject: [PATCH 1/6] fix use of wrong "equal" function in meta hash tables --- src/core/servers.c | 2 +- src/fe-text/textbuffer-formats.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/servers.c b/src/core/servers.c index 159af0e1..30fc6844 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -369,7 +369,7 @@ void server_connect_init(SERVER_REC *server) server->type = module_get_uniq_id("SERVER", 0); server_ref(server); server->current_incoming_meta = - g_hash_table_new_full(g_str_hash, (GEqualFunc) g_strcmp0, + g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); server->nick = g_strdup(server->connrec->nick); diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 2aa06cb2..2cd0d4a3 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -116,7 +116,7 @@ void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec) static void meta_hash_create(struct _TEXT_BUFFER_META_REC *meta) { if (meta->hash == NULL) { - meta->hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_strcmp0, + meta->hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); } From 7d13cfba074b7dc849f095a3281952ee38518a92 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:48:37 +0200 Subject: [PATCH 2/6] add a meta table to all lines --- src/fe-common/core/formats.c | 32 +++++++++++++++++++++++++++++++- src/fe-common/core/formats.h | 12 ++++++++---- src/perl/ui/Formats.xs | 19 +++++++++++++++++++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 51588afb..b660b616 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -34,6 +34,7 @@ #include #include #include +#include static const char *format_backs = "04261537"; static const char *format_fores = "kbgcrmyw"; @@ -46,6 +47,8 @@ static int hide_text_style, hide_server_tags, hide_colors; static int timestamp_level; static int timestamp_timeout; +static GHashTable *global_meta; + int format_find_tag(const char *module, const char *tag) { FORMAT_REC *formats; @@ -453,6 +456,27 @@ void format_read_arglist(va_list va, FORMAT_REC *format, } } +void format_dest_meta_stash(TEXT_DEST_REC *dest, const char *meta_key, const char *meta_value) +{ + g_hash_table_replace(dest->meta, i_refstr_intern(meta_key), g_strdup(meta_value)); +} + +const char *format_dest_meta_stash_find(TEXT_DEST_REC *dest, const char *meta_key) +{ + return g_hash_table_lookup(dest->meta, meta_key); +} + +void format_dest_meta_clear_all(TEXT_DEST_REC *dest) +{ + g_hash_table_remove_all(dest->meta); +} + +static void clear_global_meta(WINDOW_REC *window, TEXT_DEST_REC *dest) +{ + if (dest != NULL && dest->meta == global_meta) + g_hash_table_remove_all(global_meta); +} + void format_create_dest_tag_meta(TEXT_DEST_REC *dest, void *server, const char *server_tag, const char *target, int level, WINDOW_REC *window, GHashTable *meta) @@ -465,7 +489,7 @@ void format_create_dest_tag_meta(TEXT_DEST_REC *dest, void *server, const char * dest->level = level; dest->window = window != NULL ? window : window_find_closest(server, target, level); - dest->meta = meta; + dest->meta = meta != NULL ? meta : global_meta; } void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, const char *server_tag, @@ -1705,12 +1729,18 @@ static void read_settings(void) void formats_init(void) { signal_gui_print_text = signal_get_uniq_id("gui print text"); + global_meta = + g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, + (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); read_settings(); signal_add("setup changed", (SIGNAL_FUNC) read_settings); + signal_add_last("gui print text finished", (SIGNAL_FUNC) clear_global_meta); } void formats_deinit(void) { + g_hash_table_destroy(global_meta); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); + signal_remove("gui print text finished", (SIGNAL_FUNC) clear_global_meta); } diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 12274638..c17bcc75 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -63,7 +63,7 @@ typedef struct _TEXT_DEST_REC { int hilight_priority; char *hilight_color; - int flags; + int flags; /* PRINT_FLAG */ GHashTable *meta; } TEXT_DEST_REC; @@ -116,12 +116,16 @@ char *format_get_line_start(THEME_REC *theme, TEXT_DEST_REC *dest, time_t t); void format_create_dest(TEXT_DEST_REC *dest, void *server, const char *target, int level, WINDOW_REC *window); -void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, - const char *server_tag, const char *target, - int level, WINDOW_REC *window); +void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, const char *server_tag, + const char *target, int level, WINDOW_REC *window); void format_newline(TEXT_DEST_REC *dest); +/* manipulate the meta table of a dest */ +void format_dest_meta_stash(TEXT_DEST_REC *dest, const char *meta_key, const char *meta_value); +const char *format_dest_meta_stash_find(TEXT_DEST_REC *dest, const char *meta_key); +void format_dest_meta_clear_all(TEXT_DEST_REC *dest); + /* Return how many characters in `str' must be skipped before `len' characters of text is skipped. */ int strip_real_length(const char *str, int len, diff --git a/src/perl/ui/Formats.xs b/src/perl/ui/Formats.xs index c03e6bb5..0f8b59b7 100644 --- a/src/perl/ui/Formats.xs +++ b/src/perl/ui/Formats.xs @@ -156,3 +156,22 @@ print(dest, str) char *str CODE: printtext_dest(dest, "%s", str); + +#******************************* +MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::TextDest PREFIX = format_dest_ +#******************************* + +void +format_dest_meta_stash(dest, meta_key, meta_value) + Irssi::UI::TextDest dest + char *meta_key + char *meta_value + +char * +format_dest_meta_stash_find(dest, meta_key) + Irssi::UI::TextDest dest + char *meta_key +CODE: + RETVAL = (char *) format_dest_meta_stash_find(dest, meta_key); +OUTPUT: + RETVAL From 9677b07488b6b7b4ee7a425d8f2826669404d058 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:49:40 +0200 Subject: [PATCH 3/6] fix wrong server_time in $line->get_meta --- src/perl/textui/TextBuffer.xs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index 6695eae0..301e2d4a 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -123,6 +123,8 @@ PPCODE: (void) hv_store(hv, key, strlen(key), new_pv(val), 0); } } - (void) hv_store(hv, "server_time", 11, newSViv(m->server_time), 0); + if (m->server_time) { + (void) hv_store(hv, "server_time", 11, newSViv(m->server_time), 0); + } } XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); From 8d314eadf1350619d481cc5729c7bd74eec85693 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:51:18 +0200 Subject: [PATCH 4/6] move TEXT_BUFFER_META_REC -> LINE_INFO_META_REC --- src/fe-common/core/formats.h | 5 +++++ src/fe-text/textbuffer-formats.c | 12 ++++++------ src/fe-text/textbuffer-formats.h | 8 ++------ src/fe-text/textbuffer.h | 2 +- src/perl/textui/TextBuffer.xs | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index c17bcc75..5666c73b 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -67,6 +67,11 @@ typedef struct _TEXT_DEST_REC { GHashTable *meta; } TEXT_DEST_REC; +typedef struct _LINE_INFO_META_REC { + gint64 server_time; + GHashTable *hash; +} LINE_INFO_META_REC; + #define window_get_theme(window) \ (window != NULL && (window)->theme != NULL ? \ (window)->theme : current_theme) diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 2cd0d4a3..b194a18a 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -102,7 +102,7 @@ static void format_rec_set_dest(TEXT_BUFFER_FORMAT_REC *rec, const TEXT_DEST_REC rec->flags = dest->flags & ~PRINT_FLAG_FORMAT; } -void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec) +void textbuffer_meta_rec_free(LINE_INFO_META_REC *rec) { if (rec == NULL) return; @@ -113,7 +113,7 @@ void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec) g_free(rec); } -static void meta_hash_create(struct _TEXT_BUFFER_META_REC *meta) +static void meta_hash_create(struct _LINE_INFO_META_REC *meta) { if (meta->hash == NULL) { meta->hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, @@ -122,9 +122,9 @@ static void meta_hash_create(struct _TEXT_BUFFER_META_REC *meta) } } -static TEXT_BUFFER_META_REC *line_meta_create(GHashTable *meta_hash) +static LINE_INFO_META_REC *line_meta_create(GHashTable *meta_hash) { - struct _TEXT_BUFFER_META_REC *meta; + struct _LINE_INFO_META_REC *meta; GHashTableIter iter; const char *key; const char *val; @@ -132,7 +132,7 @@ static TEXT_BUFFER_META_REC *line_meta_create(GHashTable *meta_hash) if (meta_hash == NULL || g_hash_table_size(meta_hash) == 0) return NULL; - meta = g_new0(struct _TEXT_BUFFER_META_REC, 1); + meta = g_new0(struct _LINE_INFO_META_REC, 1); g_hash_table_iter_init(&iter, meta_hash); while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { @@ -362,7 +362,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean THEME_REC *theme; int formatnum; TEXT_BUFFER_FORMAT_REC *format_rec; - TEXT_BUFFER_META_REC *meta; + LINE_INFO_META_REC *meta; char *str; curr = line; diff --git a/src/fe-text/textbuffer-formats.h b/src/fe-text/textbuffer-formats.h index 17a907c1..86587563 100644 --- a/src/fe-text/textbuffer-formats.h +++ b/src/fe-text/textbuffer-formats.h @@ -2,11 +2,7 @@ #define IRSSI_FE_TEXT_TEXTBUFFER_FORMATS_H #include - -typedef struct _TEXT_BUFFER_META_REC { - gint64 server_time; - GHashTable *hash; -} TEXT_BUFFER_META_REC; +#include typedef struct _TEXT_BUFFER_FORMAT_REC { char *module; @@ -22,7 +18,7 @@ typedef struct _TEXT_BUFFER_FORMAT_REC { } TEXT_BUFFER_FORMAT_REC; void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec); -void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec); +void textbuffer_meta_rec_free(LINE_INFO_META_REC *rec); char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean raw); void textbuffer_formats_init(void); void textbuffer_formats_deinit(void); diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index 5f5f9a27..6c72a569 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -24,7 +24,7 @@ typedef struct { int level; time_t time; char *text; - struct _TEXT_BUFFER_META_REC *meta; + struct _LINE_INFO_META_REC *meta; struct _TEXT_BUFFER_FORMAT_REC *format; } LINE_INFO_REC; diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index 301e2d4a..be83cc59 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -107,7 +107,7 @@ textbuffer_line_get_meta(line) PREINIT: HV *hv; LINE_REC *l; - TEXT_BUFFER_META_REC *m; + LINE_INFO_META_REC *m; GHashTableIter iter; char *key; char *val; From 5953b675b9411a87d111ea82ecd7c0876de3f186 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:53:44 +0200 Subject: [PATCH 5/6] store the hilight result in the meta table and apply it during the "gui render line text" signal --- src/fe-common/core/hilight-text.c | 98 +++++++++++++++++++++++++++---- src/fe-text/textbuffer-formats.c | 28 ++++++--- 2 files changed, 108 insertions(+), 18 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 153a7a15..4b5e4edd 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -323,6 +323,71 @@ void hilight_update_text_dest(TEXT_DEST_REC *dest, HILIGHT_REC *rec) static void hilight_print(int index, HILIGHT_REC *rec); +static void sig_render_line_text(TEXT_DEST_REC *dest, GString *str, LINE_INFO_META_REC *meta) +{ + char *color, *tmp, *tmp2; + + if (meta == NULL || meta->hash == NULL) + return; + + color = g_hash_table_lookup(meta->hash, "hilight-color"); + + if ((tmp = g_hash_table_lookup(meta->hash, "hilight-line")) != NULL) { + /* hilight whole line */ + + tmp = strip_codes(str->str); + + color = format_string_expand( + color != NULL ? color : settings_get_str("hilight_color"), NULL); + + g_string_truncate(str, 0); + g_string_append(str, color); + g_string_append(str, tmp); + + g_free(color); + g_free(tmp); + } else if ((tmp = g_hash_table_lookup(meta->hash, "hilight-start")) != NULL && + (tmp2 = g_hash_table_lookup(meta->hash, "hilight-end")) != NULL) { + /* hilight part of the line */ + int hilight_start, hilight_end; + int pos, color_pos, color_len; + char *middle; + GString *str2; + + hilight_start = atoi(tmp); + hilight_end = atoi(tmp2); + + /* start of the line */ + pos = strip_real_length(str->str, hilight_start, NULL, NULL); + + str2 = g_string_new_len(str->str, pos); + + /* color */ + color = format_string_expand( + color != NULL ? color : settings_get_str("hilight_color"), NULL); + g_string_append(str2, color); + g_free(color); + + /* middle of the line, stripped */ + middle = strip_codes(str->str + pos); + g_string_append_len(str2, middle, hilight_end - hilight_start); + g_free(middle); + + /* end of the line */ + pos = strip_real_length(str->str, hilight_end, &color_pos, &color_len); + if (color_pos > 0) { + g_string_append_len(str2, str->str + color_pos, color_len); + } else { + /* no colors in line, change back to default */ + g_string_append_c(str2, 4); + g_string_append_c(str2, FORMAT_STYLE_DEFAULTS); + } + g_string_append(str2, str->str + pos); + + g_string_assign(str, g_string_free(str2, FALSE)); + } +} + static void sig_print_text(TEXT_DEST_REC *dest, const char *text, const char *stripped) { @@ -372,38 +437,47 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, char *tmp = strip_codes(text); newstr = g_strconcat(color, tmp, NULL); g_free(tmp); + + format_dest_meta_stash(dest, "hilight-line", "\001"); } else { /* hilight part of the line */ - GString *tmp; - char *middle; + GString *str; + char *middle, *tmp; int pos, color_pos, color_len; /* start of the line */ pos = strip_real_length(text, hilight_start, NULL, NULL); - tmp = g_string_new_len(text, pos); + str = g_string_new_len(text, pos); /* color */ - g_string_append(tmp, color); + g_string_append(str, color); /* middle of the line, stripped */ middle = strip_codes(text + pos); - g_string_append_len(tmp, middle, hilight_len); + g_string_append_len(str, middle, hilight_len); g_free(middle); /* end of the line */ pos = strip_real_length(text, hilight_end, &color_pos, &color_len); if (color_pos > 0) { - g_string_append_len(tmp, text + color_pos, color_len); + g_string_append_len(str, text + color_pos, color_len); } else { /* no colors in line, change back to default */ - g_string_append_c(tmp, 4); - g_string_append_c(tmp, FORMAT_STYLE_DEFAULTS); + g_string_append_c(str, 4); + g_string_append_c(str, FORMAT_STYLE_DEFAULTS); } - g_string_append(tmp, text + pos); + g_string_append(str, text + pos); - newstr = tmp->str; - g_string_free(tmp, FALSE); + newstr = str->str; + g_string_free(str, FALSE); + + format_dest_meta_stash(dest, "hilight-start", + tmp = g_strdup_printf("%d", hilight_start)); + g_free(tmp); + format_dest_meta_stash(dest, "hilight-end", + tmp = g_strdup_printf("%d", hilight_end)); + g_free(tmp); } signal_emit("print text", 3, dest, newstr, stripped); @@ -721,6 +795,7 @@ void hilight_text_init(void) read_hilight_config(); signal_add_first("print text", (SIGNAL_FUNC) sig_print_text); + signal_add("gui render line text", (SIGNAL_FUNC) sig_render_line_text); signal_add("setup reread", (SIGNAL_FUNC) read_hilight_config); signal_add("setup changed", (SIGNAL_FUNC) read_settings); @@ -735,6 +810,7 @@ void hilight_text_deinit(void) nickmatch_deinit(nickmatch); signal_remove("print text", (SIGNAL_FUNC) sig_print_text); + signal_remove("gui render line text", (SIGNAL_FUNC) sig_render_line_text); signal_remove("setup reread", (SIGNAL_FUNC) read_hilight_config); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index b194a18a..5b15313f 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -16,6 +16,7 @@ TEXT_BUFFER_REC *color_buf; gboolean scrollback_format; gboolean show_server_time; +int signal_gui_render_line_text; #if GLIB_CHECK_VERSION(2, 56, 0) /* nothing */ @@ -363,7 +364,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean int formatnum; TEXT_BUFFER_FORMAT_REC *format_rec; LINE_INFO_META_REC *meta; - char *str; + char *tmp2; curr = line; line = NULL; @@ -396,6 +397,8 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean } if (text != NULL && *text != '\0') { + GString *str; + reference_time = curr->info.time; if (show_server_time && meta != NULL && meta->server_time != 0) { current_time = meta->server_time; @@ -403,18 +406,27 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean current_time = curr->info.time; } + str = g_string_new(text); + signal_emit_id(signal_gui_render_line_text, 3, &dest, str, meta); + if (g_strcmp0(text, str->str) == 0) { + g_string_free(str, TRUE); + } else { + g_free(text); + text = g_string_free(str, FALSE); + } + tmp = format_get_level_tag(theme, &dest); - str = !theme->info_eol ? format_add_linestart(text, tmp) : - format_add_lineend(text, tmp); + tmp2 = !theme->info_eol ? format_add_linestart(text, tmp) : + format_add_lineend(text, tmp); g_free_not_null(tmp); g_free_not_null(text); - text = str; + text = tmp2; tmp = format_get_line_start(theme, &dest, current_time); - str = !theme->info_eol ? format_add_linestart(text, tmp) : - format_add_lineend(text, tmp); + tmp2 = !theme->info_eol ? format_add_linestart(text, tmp) : + format_add_lineend(text, tmp); g_free_not_null(tmp); g_free_not_null(text); - text = str; + text = tmp2; /* str = g_strconcat(text, "\n", NULL); */ /* g_free(text); */ @@ -447,6 +459,8 @@ static void read_settings(void) void textbuffer_formats_init(void) { + signal_gui_render_line_text = signal_get_uniq_id("gui render line text"); + settings_add_bool("lookandfeel", "scrollback_format", TRUE); settings_add_bool("lookandfeel", "show_server_time", FALSE); From 6a52b5ac07fe57ebd5973871db64b775e41a3f84 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 00:44:33 +0200 Subject: [PATCH 6/6] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index bdbafca7..990cc0cf 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */ #define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */ -#define IRSSI_ABI_VERSION 36 +#define IRSSI_ABI_VERSION 37 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697