From 468d8b0c78b371466c092c54308013cdda3bf8f5 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 23 Jul 2020 00:18:22 +0200 Subject: [PATCH] fix missing wrapping of line in signals --- src/perl/perl-common.h | 2 ++ src/perl/perl-signals.c | 47 +++++++++++++++++++++++++++++++++++---- src/perl/perl-signals.h | 2 ++ src/perl/textui/TextUI.xs | 14 +++++++++++- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/perl/perl-common.h b/src/perl/perl-common.h index 88adaa7e..1b802c6d 100644 --- a/src/perl/perl-common.h +++ b/src/perl/perl-common.h @@ -13,6 +13,8 @@ typedef void (*PERL_OBJECT_FUNC) (HV *hv, void *object); +typedef SV *(*PERL_BLESS_FUNC)(void *object, void *arg1, void *arg2, void *arg3); + typedef struct { char *name; PERL_OBJECT_FUNC fill_func; diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index f5f9d6e2..9dd73cdb 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -46,10 +46,16 @@ typedef struct { #include "perl-signals-list.h" -static GHashTable *signals; +static GHashTable *signals, *signal_stashes; static GHashTable *perl_signal_args_hash; static GSList *perl_signal_args_partial; +void irssi_add_signal_arg_conv(const char *stash, PERL_BLESS_FUNC func) +{ + if (g_hash_table_lookup(signal_stashes, stash) == NULL) + g_hash_table_insert(signal_stashes, g_strdup(stash), func); +} + static PERL_SIGNAL_ARGS_REC *perl_signal_args_find(int signal_id) { PERL_SIGNAL_ARGS_REC *rec; @@ -348,8 +354,36 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, int type; as it's first variable (dcc) */ perlarg = simple_iobject_bless((SERVER_REC *) arg); } else { - /* blessed object */ - perlarg = plain_bless(arg, rec->args[n]); + PERL_BLESS_FUNC bless_func; + + bless_func = g_hash_table_lookup(signal_stashes, rec->args[n]); + if (bless_func != NULL) { + void *a1 = NULL; + void *a2 = NULL; + void *a3 = NULL; + if (g_strcmp0(rec->args[n], "Irssi::TextUI::Line") == 0) { + /* need to find the corresponding buffer */ + int j; + + for (j = n - 1; j >= 0; j--) { + if (g_strcmp0(rec->args[j], + "Irssi::TextUI::TextBufferView") == + 0) { + a1 = (void *) args[j]; + break; + } else if (g_strcmp0(rec->args[j], + "Irssi::UI::Window") == 0) { + a2 = (void *) args[j]; + break; + } + } + } + + perlarg = bless_func(rec->args[n], a1, a2, a3); + } else { + /* blessed object */ + perlarg = plain_bless(arg, rec->args[n]); + } } XPUSHs(sv_2mortal(perlarg)); } @@ -628,6 +662,7 @@ void perl_signals_init(void) { int n; + signal_stashes = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal); perl_signal_args_hash = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal); perl_signal_args_partial = NULL; @@ -662,5 +697,9 @@ void perl_signals_deinit(void) g_hash_table_foreach(perl_signal_args_hash, (GHFunc) signal_args_hash_free, NULL); - g_hash_table_destroy(perl_signal_args_hash); + g_hash_table_destroy(perl_signal_args_hash); + + g_hash_table_foreach(signal_stashes, (GHFunc) g_free, NULL); + g_hash_table_destroy(signal_stashes); + signal_stashes = NULL; } diff --git a/src/perl/perl-signals.h b/src/perl/perl-signals.h index cb636d3c..0110b5ae 100644 --- a/src/perl/perl-signals.h +++ b/src/perl/perl-signals.h @@ -24,6 +24,8 @@ void perl_command_unbind(const char *cmd, SV *func); void perl_command_runsub(const char *cmd, const char *data, SERVER_REC *server, WI_ITEM_REC *item); +void irssi_add_signal_arg_conv(const char *stash, PERL_BLESS_FUNC func); + void perl_signal_register(const char *signal, const char **args); void perl_signals_start(void); diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index e87efb65..0ebcc7a6 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -85,6 +85,16 @@ static void perl_statusbar_item_fill_hash(HV *hv, SBAR_ITEM_REC *item) (void) hv_store(hv, "window", 6, plain_bless(item->bar->parent_window->active, "Irssi::UI::Window"), 0); } +static SV *perl_line_signal_arg_conv(LINE_REC *line, TEXT_BUFFER_VIEW_REC *view, WINDOW_REC *window) +{ + if (view != NULL) + return buffer_line_bless(view->buffer, line); + else if (window != NULL) + return buffer_line_bless(WINDOW_GUI(window)->view->buffer, line); + else + return &PL_sv_undef; +} + static PLAIN_OBJECT_INIT_REC textui_plains[] = { { "Irssi::TextUI::MainWindow", (PERL_OBJECT_FUNC) perl_main_window_fill_hash }, { "Irssi::TextUI::TextBuffer", (PERL_OBJECT_FUNC) perl_text_buffer_fill_hash }, @@ -109,7 +119,9 @@ CODE: initialized = TRUE; irssi_add_plains(textui_plains); - perl_statusbar_init(); + irssi_add_signal_arg_conv("Irssi::TextUI::Line", + (PERL_BLESS_FUNC) perl_line_signal_arg_conv); + perl_statusbar_init(); void deinit()