diff --git a/docs/signals.txt b/docs/signals.txt index 1eefc7e0..4e5f85b4 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -358,6 +358,9 @@ gui-printtext.c: textbuffer-view.c "gui textbuffer line removed", TEXTBUFFER_VIEW_REC *view, LINE_REC *line, LINE_REC *prev_line +textbuffer-formats.c + "gui render line text", TEXT_DEST_REC, GString *str, LINE_INFO_META_REC + Perl ---- diff --git a/src/common.h b/src/common.h index 990cc0cf..cc334476 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 37 +#define IRSSI_ABI_VERSION 38 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/perl/get-signals.pl b/src/perl/get-signals.pl index 12aebdba..f7675f1b 100755 --- a/src/perl/get-signals.pl +++ b/src/perl/get-signals.pl @@ -19,6 +19,8 @@ while (<>) { s/GList \* of ([^,]*)s/glistptr_\1/g; s/GSList of ([^,]*)s/gslist_\1/g; + s/GString \*[^,]*/gstring/g; + s/char \*[^,]*/string/g; s/ulong \*[^,]*/ulongptr/g; s/int \*[^,]*/intptr/g; @@ -52,12 +54,13 @@ while (<>) { CLIENT_REC => 'Irssi::Irc::Client', # fe-common - THEME_REC => 'Irssi::UI::Theme', - KEYINFO_REC => 'Irssi::UI::Keyinfo', - PROCESS_REC => 'Irssi::UI::Process', - TEXT_DEST_REC => 'Irssi::UI::TextDest', - WINDOW_REC => 'Irssi::UI::Window', - WI_ITEM_REC => 'iobject', + THEME_REC => 'Irssi::UI::Theme', + KEYINFO_REC => 'Irssi::UI::Keyinfo', + PROCESS_REC => 'Irssi::UI::Process', + TEXT_DEST_REC => 'Irssi::UI::TextDest', + LINE_INFO_META_REC => 'Irssi::UI::LineInfoMeta', + WINDOW_REC => 'Irssi::UI::Window', + WI_ITEM_REC => 'iobject', # fe-text TEXTBUFFER_VIEW_REC => 'Irssi::TextUI::TextBufferView', diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 9f49fba8..683b4c3f 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -86,7 +86,8 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, unsigned long v_ulong; GSList *v_gslist; GList *v_glist; - } saved_args[SIGNAL_MAX_ARGUMENTS]; + GString *v_gstring; + } saved_args[SIGNAL_MAX_ARGUMENTS]; AV *aargs; void *p[SIGNAL_MAX_ARGUMENTS]; PERL_SIGNAL_ARGS_REC *rec; @@ -146,6 +147,12 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, } else if (g_strcmp0(rec->args[n], "intptr") == 0) { saved_args[n].v_int = SvIV(SvRV(arg)); c_arg = &saved_args[n].v_int; + } else if (g_strcmp0(rec->args[n], "gstring") == 0) { + char *pv; + size_t len; + + pv = SvPV(SvRV(arg), len); + c_arg = saved_args[n].v_gstring = g_string_new_len(pv, len); } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { GList *gl; int is_str; @@ -220,6 +227,16 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, SV *t = SvRV(arg); SvIOK_only(t); SvIV_set(t, saved_args[n].v_int); + } else if (g_strcmp0(rec->args[n], "gstring") == 0) { + GString *str; + SV *t; + + str = saved_args[n].v_gstring; + t = SvRV(arg); + SvPOK_only(t); + sv_setpvn(t, str->str, str->len); + + g_string_free(str, TRUE); } else if (strncmp(rec->args[n], "gslist_", 7) == 0) { g_slist_free(saved_args[n].v_gslist); } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { @@ -306,7 +323,10 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, perlarg = newSViv(*(unsigned long *) arg); else if (g_strcmp0(rec->args[n], "intptr") == 0) saved_args[n] = perlarg = newRV_noinc(newSViv(*(int *) arg)); - else if (g_strcmp0(rec->args[n], "formatnum_args") == 0 && n >= 3) { + else if (g_strcmp0(rec->args[n], "gstring") == 0) { + GString *str = arg; + saved_args[n] = perlarg = newRV_noinc(newSVpvn(str->str, str->len)); + } else if (g_strcmp0(rec->args[n], "formatnum_args") == 0 && n >= 3) { const THEME_REC *theme; const MODULE_THEME_REC *rec; const FORMAT_REC *formats; @@ -399,6 +419,7 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, if (SvTRUE(ERRSV)) { char *error = g_strdup(SvPV_nolen(ERRSV)); + perl_signal_remove_script(script); signal_emit("script error", 2, script, error); g_free(error); rec = NULL; @@ -415,8 +436,21 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, if (g_strcmp0(rec->args[n], "intptr") == 0) { int *val = arg; *val = SvIV(SvRV(saved_args[n])); + } else if (g_strcmp0(rec->args[n], "gstring") == 0) { + SV *os, *ns; + GString *str = arg; + + os = sv_2mortal(newSVpvn(str->str, str->len)); + ns = SvRV(saved_args[n]); + if (sv_cmp(os, ns) != 0) { + size_t len; + char *pv = SvPV(ns, len); + + g_string_truncate(str, 0); + g_string_append_len(str, pv, len); + } } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { - GList **ret = arg; + GList **ret = arg; GList *out = NULL; void *val; int count; diff --git a/src/perl/perl-sources.c b/src/perl/perl-sources.c index 9f5773f1..9f9ec6b5 100644 --- a/src/perl/perl-sources.c +++ b/src/perl/perl-sources.c @@ -83,6 +83,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) if (SvTRUE(ERRSV)) { char *error = g_strdup(SvPV_nolen(ERRSV)); + perl_source_remove_script(rec->script); signal_emit("script error", 2, rec->script, error); g_free(error); } diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index be83cc59..655dbd3c 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -101,30 +101,10 @@ PPCODE: } XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); -void +Irssi::UI::LineInfoMeta textbuffer_line_get_meta(line) Irssi::TextUI::Line line -PREINIT: - HV *hv; - LINE_REC *l; - LINE_INFO_META_REC *m; - GHashTableIter iter; - char *key; - char *val; -PPCODE: - hv = newHV(); - l = line->line; - if (l->info.meta != NULL) { - m = l->info.meta; - if (m->hash != NULL) { - g_hash_table_iter_init(&iter, m->hash); - while ( - g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { - (void) hv_store(hv, key, strlen(key), new_pv(val), 0); - } - } - if (m->server_time) { - (void) hv_store(hv, "server_time", 11, newSViv(m->server_time), 0); - } - } - XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); +CODE: + RETVAL = line->line->info.meta; +OUTPUT: + RETVAL diff --git a/src/perl/ui/UI.xs b/src/perl/ui/UI.xs index 5ac3da4e..30b0f637 100644 --- a/src/perl/ui/UI.xs +++ b/src/perl/ui/UI.xs @@ -64,6 +64,26 @@ static void perl_text_dest_fill_hash(HV *hv, TEXT_DEST_REC *dest) (void) hv_store(hv, "hilight_color", 13, new_pv(dest->hilight_color), 0); } +static void perl_line_info_meta_fill_hash(HV *hv, LINE_INFO_META_REC *meta) +{ + GHashTableIter iter; + char *key; + char *val; + + if (meta != NULL) { + if (meta->hash != NULL) { + g_hash_table_iter_init(&iter, meta->hash); + while ( + g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + (void) hv_store(hv, key, strlen(key), new_pv(val), 0); + } + } + if (meta->server_time) { + (void) hv_store(hv, "server_time", 11, newSViv(meta->server_time), 0); + } + } +} + static void perl_exec_fill_hash(HV *hv, EXEC_WI_REC *item) { g_return_if_fail(hv != NULL); @@ -81,6 +101,7 @@ static PLAIN_OBJECT_INIT_REC fe_plains[] = { { "Irssi::UI::Process", (PERL_OBJECT_FUNC) perl_process_fill_hash }, { "Irssi::UI::Window", (PERL_OBJECT_FUNC) perl_window_fill_hash }, { "Irssi::UI::TextDest", (PERL_OBJECT_FUNC) perl_text_dest_fill_hash }, + { "Irssi::UI::LineInfoMeta", (PERL_OBJECT_FUNC) perl_line_info_meta_fill_hash }, { NULL, NULL } }; diff --git a/src/perl/ui/module.h b/src/perl/ui/module.h index 4e19d4c0..4106aec4 100644 --- a/src/perl/ui/module.h +++ b/src/perl/ui/module.h @@ -12,3 +12,4 @@ typedef WINDOW_REC *Irssi__UI__Window; typedef TEXT_DEST_REC *Irssi__UI__TextDest; typedef THEME_REC *Irssi__UI__Theme; typedef KEYINFO_REC *Irssi__UI__Keyinfo; +typedef LINE_INFO_META_REC *Irssi__UI__LineInfoMeta; diff --git a/src/perl/ui/typemap b/src/perl/ui/typemap index 2a16fe44..4afb273d 100644 --- a/src/perl/ui/typemap +++ b/src/perl/ui/typemap @@ -3,6 +3,7 @@ Irssi::UI::Theme T_PlainObj Irssi::UI::Window T_PlainObj Irssi::UI::Keyinfo T_PlainObj Irssi::UI::TextDest T_PlainObj +Irssi::UI::LineInfoMeta T_PlainObj INPUT