diff options
Diffstat (limited to 'src/perl/textui')
-rw-r--r-- | src/perl/textui/Makefile.PL.in | 8 | ||||
-rw-r--r-- | src/perl/textui/Statusbar.xs | 167 | ||||
-rw-r--r-- | src/perl/textui/TextBuffer.xs | 110 | ||||
-rw-r--r-- | src/perl/textui/TextBufferView.xs | 115 | ||||
-rw-r--r-- | src/perl/textui/TextUI.pm | 26 | ||||
-rw-r--r-- | src/perl/textui/TextUI.xs | 318 | ||||
-rw-r--r-- | src/perl/textui/meson.build | 37 | ||||
-rw-r--r-- | src/perl/textui/module.h | 17 | ||||
-rw-r--r-- | src/perl/textui/typemap | 24 | ||||
-rw-r--r-- | src/perl/textui/wrapper_buffer_line.h | 90 |
10 files changed, 912 insertions, 0 deletions
diff --git a/src/perl/textui/Makefile.PL.in b/src/perl/textui/Makefile.PL.in new file mode 100644 index 0000000..2b0a148 --- /dev/null +++ b/src/perl/textui/Makefile.PL.in @@ -0,0 +1,8 @@ +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; + +WriteMakefile('NAME' => 'Irssi::TextUI', + 'LIBS' => '', + 'OBJECT' => '$(O_FILES)', + 'TYPEMAPS' => ['../common/typemap', '../ui/typemap'], + 'INC' => '-I../../.. @GLIB_CFLAGS@', + 'VERSION_FROM' => '@srcdir@/TextUI.pm'); diff --git a/src/perl/textui/Statusbar.xs b/src/perl/textui/Statusbar.xs new file mode 100644 index 0000000..111deaa --- /dev/null +++ b/src/perl/textui/Statusbar.xs @@ -0,0 +1,167 @@ +#define PERL_NO_GET_CONTEXT +#include "module.h" + +static GHashTable *perl_sbar_defs; + +static int check_sbar_destroy(char *key, char *value, char *script) +{ + if (strncmp(value, script, strlen(script)) == 0 && + value[strlen(script)] == ':') { + statusbar_item_unregister(key); + g_free(key); + g_free(value); + return TRUE; + } + + return FALSE; +} + +static void script_unregister_statusbars(PERL_SCRIPT_REC *script) +{ + g_hash_table_foreach_remove(perl_sbar_defs, + (GHRFunc) check_sbar_destroy, + script->package); +} + +void perl_statusbar_init(void) +{ + perl_sbar_defs = g_hash_table_new((GHashFunc) g_str_hash, + (GCompareFunc) g_str_equal); + signal_add("script destroyed", (SIGNAL_FUNC) script_unregister_statusbars); +} + +static void statusbar_item_def_destroy(void *key, void *value) +{ + statusbar_item_unregister(key); + g_free(key); + g_free(value); +} + +void perl_statusbar_deinit(void) +{ + signal_remove("script destroyed", (SIGNAL_FUNC) script_unregister_statusbars); + + g_hash_table_foreach(perl_sbar_defs, + (GHFunc) statusbar_item_def_destroy, NULL); + g_hash_table_destroy(perl_sbar_defs); +} + +static void perl_statusbar_event(char *function, SBAR_ITEM_REC *item, + int get_size_only) +{ + dSP; + SV *item_sv, **sv; + HV *hv; + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + item_sv = plain_bless(item, "Irssi::TextUI::StatusbarItem"); + XPUSHs(sv_2mortal(item_sv)); + XPUSHs(sv_2mortal(newSViv(get_size_only))); + PUTBACK; + + perl_call_pv(function, G_EVAL|G_DISCARD); + SPAGAIN; + + if (SvTRUE(ERRSV)) { + PERL_SCRIPT_REC *script; + char *package, *error; + + package = perl_function_get_package(function); + script = perl_script_find_package(package); + g_free(package); + + if (script != NULL) { + /* make sure we don't get back here */ + script_unregister_statusbars(script); + } + + error = g_strdup(SvPV_nolen(ERRSV)); + signal_emit("script error", 2, script, error); + g_free(error); + } else { + /* min_size and max_size can be changed, move them to SBAR_ITEM_REC */ + hv = hvref(item_sv); + if (hv != NULL) { + sv = hv_fetch(hv, "min_size", 8, 0); + if (sv != NULL) item->min_size = SvIV(*sv); + sv = hv_fetch(hv, "max_size", 8, 0); + if (sv != NULL) item->max_size = SvIV(*sv); + } + } + + FREETMPS; + LEAVE; +} + + +static void sig_perl_statusbar(SBAR_ITEM_REC *item, int get_size_only) +{ + char *function; + + function = g_hash_table_lookup(perl_sbar_defs, item->config->name); + if (function != NULL) + perl_statusbar_event(function, item, get_size_only); + else { + /* use default function - this shouldn't actually happen.. */ + statusbar_item_default_handler(item, get_size_only, NULL, "", TRUE); + } +} + +MODULE = Irssi::TextUI::Statusbar PACKAGE = Irssi +PROTOTYPES: ENABLE + +void +statusbar_item_register(name, value, func = NULL) + char *name + char *value + char *func +CODE: + statusbar_item_register(name, value, func == NULL || *func == '\0' ? NULL : sig_perl_statusbar); + if (func != NULL) { + g_hash_table_insert(perl_sbar_defs, g_strdup(name), + g_strdup_printf("%s::%s", perl_get_package(), func)); + } + +void +statusbar_item_unregister(name) + char *name +PREINIT: + gpointer key, value; +CODE: + if (g_hash_table_lookup_extended(perl_sbar_defs, name, &key, &value)) { + g_hash_table_remove(perl_sbar_defs, name); + g_free(key); + g_free(value); + } + statusbar_item_unregister(name); + +void +statusbar_items_redraw(name) + char *name + +void +statusbars_recreate_items() + +#******************************* +MODULE = Irssi::TextUI::Statusbar PACKAGE = Irssi::TextUI::StatusbarItem PREFIX = statusbar_item_ +#******************************* + +void +statusbar_item_default_handler(item, get_size_only, str, data, escape_vars = TRUE) + Irssi::TextUI::StatusbarItem item + int get_size_only + char *str + char *data + int escape_vars +PREINIT: + HV *hv; +CODE: + statusbar_item_default_handler(item, get_size_only, + *str == '\0' ? NULL : str, + data, escape_vars); + hv = hvref(ST(0)); + (void) hv_store(hv, "min_size", 8, newSViv(item->min_size), 0); + (void) hv_store(hv, "max_size", 8, newSViv(item->max_size), 0); diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs new file mode 100644 index 0000000..655dbd3 --- /dev/null +++ b/src/perl/textui/TextBuffer.xs @@ -0,0 +1,110 @@ +#define PERL_NO_GET_CONTEXT +#include "module.h" +#include "wrapper_buffer_line.h" +#include <irssi/src/fe-text/textbuffer-formats.h> + +MODULE = Irssi::TextUI::TextBuffer PACKAGE = Irssi +PROTOTYPES: ENABLE + +#******************************* +MODULE = Irssi::TextUI::TextBuffer PACKAGE = Irssi +#******************************* + +int +COLORING_STRIP() +CODE: + RETVAL = COLORING_STRIP; +OUTPUT: + RETVAL + +int +COLORING_EXPAND() +CODE: + RETVAL = COLORING_EXPAND; +OUTPUT: + RETVAL + +int +COLORING_UNEXPAND() +CODE: + RETVAL = COLORING_UNEXPAND; +OUTPUT: + RETVAL + +int +COLORING_RAW() +CODE: + RETVAL = COLORING_RAW; +OUTPUT: + RETVAL + +#******************************* +MODULE = Irssi::TextUI::TextBuffer PACKAGE = Irssi::TextUI::Line PREFIX = textbuffer_line_ +#******************************* + +Irssi::TextUI::Line +textbuffer_line_prev(line) + Irssi::TextUI::Line line +CODE: + RETVAL = perl_wrap_buffer_line(line->buffer, line->line->prev); +OUTPUT: + RETVAL + +Irssi::TextUI::Line +textbuffer_line_next(line) + Irssi::TextUI::Line line +CODE: + RETVAL = perl_wrap_buffer_line(line->buffer, line->line->next); +OUTPUT: + RETVAL + +void +textbuffer_line_get_text(line, coloring) + Irssi::TextUI::Line line + int coloring +PREINIT: + GString *str; + SV *result; +PPCODE: + str = g_string_new(NULL); + textbuffer_line2text(line->buffer, line->line, coloring, str); + result = new_pv(str->str); + XPUSHs(sv_2mortal(result)); + g_string_free(str, TRUE); + +void +textbuffer_line_get_format(line) + Irssi::TextUI::Line line +PREINIT: + HV *hv; + AV *av; + LINE_REC *l; + TEXT_BUFFER_FORMAT_REC *f; + int i; +PPCODE: + hv = newHV(); + l = line->line; + if (l->info.format != NULL) { + f = l->info.format; + (void) hv_store(hv, "module", 6, new_pv(f->module), 0); + (void) hv_store(hv, "format", 6, new_pv(f->format), 0); + (void) hv_store(hv, "server_tag", 10, new_pv(f->server_tag), 0); + (void) hv_store(hv, "target", 6, new_pv(f->target), 0); + (void) hv_store(hv, "nick", 4, new_pv(f->nick), 0); + av = newAV(); + for (i = 0; i < f->nargs; i++) { + av_push(av, new_pv(f->args[i])); + } + (void) hv_store(hv, "args", 4, newRV_noinc((SV *) av), 0); + } else { + (void) hv_store(hv, "text", 4, new_pv(l->info.text), 0); + } + XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); + +Irssi::UI::LineInfoMeta +textbuffer_line_get_meta(line) + Irssi::TextUI::Line line +CODE: + RETVAL = line->line->info.meta; +OUTPUT: + RETVAL diff --git a/src/perl/textui/TextBufferView.xs b/src/perl/textui/TextBufferView.xs new file mode 100644 index 0000000..e4cfe67 --- /dev/null +++ b/src/perl/textui/TextBufferView.xs @@ -0,0 +1,115 @@ +#define PERL_NO_GET_CONTEXT +#include "module.h" +#include "wrapper_buffer_line.h" + +MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::TextUI::TextBuffer PREFIX = textbuffer_ +PROTOTYPES: ENABLE + +#******************************* +MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::TextUI::TextBufferView PREFIX = textbuffer_view_ +#******************************* + +void +textbuffer_view_set_default_indent(view, default_indent, longword_noindent) + Irssi::TextUI::TextBufferView view + int default_indent + int longword_noindent +CODE: + textbuffer_view_set_default_indent(view, default_indent, longword_noindent, NULL); + +void +textbuffer_view_set_hidden_level(view, level) + Irssi::TextUI::TextBufferView view + int level + +void +textbuffer_view_set_scroll(view, scroll) + Irssi::TextUI::TextBufferView view + int scroll + +void +textbuffer_view_clear(view) + Irssi::TextUI::TextBufferView view + +Irssi::TextUI::Line +textbuffer_view_get_lines(view) + Irssi::TextUI::TextBufferView view +CODE: + RETVAL = perl_wrap_buffer_line(view->buffer, textbuffer_view_get_lines(view)); +OUTPUT: + RETVAL + +void +textbuffer_view_scroll(view, lines) + Irssi::TextUI::TextBufferView view + int lines + +void +textbuffer_view_scroll_line(view, line) + Irssi::TextUI::TextBufferView view + Irssi::TextUI::Line line +CODE: + textbuffer_view_scroll_line(view, Line(line)); + +Irssi::TextUI::LineCache +textbuffer_view_get_line_cache(view, line) + Irssi::TextUI::TextBufferView view + Irssi::TextUI::Line line +CODE: + RETVAL = textbuffer_view_get_line_cache(view, Line(line)); +OUTPUT: + RETVAL + +void +textbuffer_view_remove_line(view, line) + Irssi::TextUI::TextBufferView view + Irssi::TextUI::Line line +CODE: + textbuffer_view_remove_line(view, Line(line)); + +void +textbuffer_view_remove_all_lines(view) + Irssi::TextUI::TextBufferView view + +void +textbuffer_view_remove_lines_by_level(view, level) + Irssi::TextUI::TextBufferView view + int level + +void +textbuffer_view_set_bookmark(view, name, line) + Irssi::TextUI::TextBufferView view + char *name + Irssi::TextUI::Line line +CODE: + textbuffer_view_set_bookmark(view, name, Line(line)); + +void +textbuffer_view_set_bookmark_bottom(view, name) + Irssi::TextUI::TextBufferView view + char *name + +Irssi::TextUI::Line +textbuffer_view_get_bookmark(view, name) + Irssi::TextUI::TextBufferView view + char *name +CODE: + RETVAL = perl_wrap_buffer_line(view->buffer, textbuffer_view_get_bookmark(view, name)); +OUTPUT: + RETVAL + +void +textbuffer_view_redraw(view) + Irssi::TextUI::TextBufferView view + +#******************************* +MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::UI::Window +#******************************* + +Irssi::TextUI::TextBufferView +view(window) + Irssi::UI::Window window +CODE: + RETVAL = WINDOW_GUI(window)->view; +OUTPUT: + RETVAL diff --git a/src/perl/textui/TextUI.pm b/src/perl/textui/TextUI.pm new file mode 100644 index 0000000..50f247c --- /dev/null +++ b/src/perl/textui/TextUI.pm @@ -0,0 +1,26 @@ +# +# Perl interface to irssi functions. +# + +package Irssi::TextUI; + +use strict; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); + +$VERSION = "0.9"; + +require Exporter; +require DynaLoader; + +@ISA = qw(Exporter DynaLoader); +@EXPORT = qw(); +@EXPORT_OK = qw(); + +bootstrap Irssi::TextUI $VERSION if (!Irssi::Core::is_static()); + +Irssi::TextUI::init(); + +Irssi::EXPORT_ALL(); + +1; + diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs new file mode 100644 index 0000000..0ebcc7a --- /dev/null +++ b/src/perl/textui/TextUI.xs @@ -0,0 +1,318 @@ +#define PERL_NO_GET_CONTEXT +#include "module.h" +#include "wrapper_buffer_line.h" + +void perl_statusbar_init(void); +void perl_statusbar_deinit(void); + +static int initialized = FALSE; + +static SV *buffer_line_bless(TEXT_BUFFER_REC *buffer, LINE_REC *line) +{ + return perl_buffer_line_bless(perl_wrap_buffer_line(buffer, line)); +} + +static void perl_main_window_fill_hash(HV *hv, MAIN_WINDOW_REC *window) +{ + (void) hv_store(hv, "active", 6, plain_bless(window->active, "Irssi::UI::Window"), 0); + + (void) hv_store(hv, "first_line", 10, newSViv(window->first_line), 0); + (void) hv_store(hv, "last_line", 9, newSViv(window->last_line), 0); + (void) hv_store(hv, "width", 5, newSViv(window->width), 0); + (void) hv_store(hv, "height", 6, newSViv(window->height), 0); + + (void) hv_store(hv, "statusbar_lines", 15, newSViv(window->statusbar_lines), 0); +} + +static void perl_text_buffer_fill_hash(HV *hv, TEXT_BUFFER_REC *buffer) +{ + (void) hv_store(hv, "first_line", 10, buffer_line_bless(buffer, buffer->first_line), 0); + (void) hv_store(hv, "lines_count", 11, newSViv(buffer->lines_count), 0); + (void) hv_store(hv, "cur_line", 8, buffer_line_bless(buffer, buffer->cur_line), 0); + (void) hv_store(hv, "last_eol", 8, newSViv(buffer->last_eol), 0); +} + +static void perl_text_buffer_view_fill_hash(HV *hv, TEXT_BUFFER_VIEW_REC *view) +{ + (void) hv_store(hv, "buffer", 6, plain_bless(view->buffer, "Irssi::TextUI::TextBuffer"), 0); + (void) hv_store(hv, "width", 5, newSViv(view->width), 0); + (void) hv_store(hv, "height", 6, newSViv(view->height), 0); + + (void) hv_store(hv, "default_indent", 14, newSViv(view->default_indent), 0); + (void) hv_store(hv, "longword_noindent", 17, newSViv(view->longword_noindent), 0); + (void) hv_store(hv, "scroll", 6, newSViv(view->scroll), 0); + + (void) hv_store(hv, "ypos", 4, newSViv(view->ypos), 0); + + (void) hv_store(hv, "startline", 9, buffer_line_bless(view->buffer, view->startline), 0); + (void) hv_store(hv, "subline", 7, newSViv(view->subline), 0); + (void) hv_store(hv, "hidden_level", 12, newSViv(view->hidden_level), 0); + + (void) hv_store(hv, "bottom_startline", 16, + buffer_line_bless(view->buffer, view->bottom_startline), 0); + (void) hv_store(hv, "bottom_subline", 14, newSViv(view->bottom_subline), 0); + + (void) hv_store(hv, "empty_linecount", 15, newSViv(view->empty_linecount), 0); + (void) hv_store(hv, "bottom", 6, newSViv(view->bottom), 0); +} + +static void perl_line_fill_hash(HV *hv, struct Buffer_Line_Wrapper *line) +{ + (void) hv_store(hv, "info", 4, plain_bless(&Line(line)->info, "Irssi::TextUI::LineInfo"), + 0); +} + +static void perl_line_cache_fill_hash(HV *hv, LINE_CACHE_REC *cache) +{ + (void) hv_store(hv, "last_access", 11, newSViv(cache->last_access), 0); + (void) hv_store(hv, "count", 5, newSViv(cache->count), 0); + /*LINE_CACHE_SUB_REC lines[1];*/ +} + +static void perl_line_info_fill_hash(HV *hv, LINE_INFO_REC *info) +{ + (void) hv_store(hv, "level", 5, newSViv(info->level), 0); + (void) hv_store(hv, "time", 4, newSViv(info->time), 0); +} + +static void perl_statusbar_item_fill_hash(HV *hv, SBAR_ITEM_REC *item) +{ + (void) hv_store(hv, "min_size", 8, newSViv(item->min_size), 0); + (void) hv_store(hv, "max_size", 8, newSViv(item->max_size), 0); + (void) hv_store(hv, "xpos", 4, newSViv(item->xpos), 0); + (void) hv_store(hv, "size", 4, newSViv(item->size), 0); + if (item->bar->parent_window != NULL) + (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 }, + { "Irssi::TextUI::TextBufferView", (PERL_OBJECT_FUNC) perl_text_buffer_view_fill_hash }, + { "Irssi::TextUI::Line", (PERL_OBJECT_FUNC) perl_line_fill_hash }, + { "Irssi::TextUI::LineCache", (PERL_OBJECT_FUNC) perl_line_cache_fill_hash }, + { "Irssi::TextUI::LineInfo", (PERL_OBJECT_FUNC) perl_line_info_fill_hash }, + { "Irssi::TextUI::StatusbarItem", (PERL_OBJECT_FUNC) perl_statusbar_item_fill_hash }, + + { NULL, NULL } +}; + +MODULE = Irssi::TextUI PACKAGE = Irssi::TextUI + +PROTOTYPES: ENABLE + +void +init() +CODE: + if (initialized) return; + perl_api_version_check("Irssi::TextUI"); + initialized = TRUE; + + irssi_add_plains(textui_plains); + irssi_add_signal_arg_conv("Irssi::TextUI::Line", + (PERL_BLESS_FUNC) perl_line_signal_arg_conv); + perl_statusbar_init(); + +void +deinit() +CODE: + if (!initialized) return; + perl_statusbar_deinit(); + initialized = FALSE; + +MODULE = Irssi::TextUI PACKAGE = Irssi + +void +gui_printtext(xpos, ypos, str) + int xpos + int ypos + char *str + +void +gui_input_set(str) + char *str +CODE: + gui_entry_set_text(active_entry, str); + +void +gui_input_set_extent(pos, text) + int pos + char *text +PREINIT: + char *tt; +CODE: + tt = text != NULL ? format_string_expand(text, NULL) : NULL; + gui_entry_set_extent(active_entry, pos, tt); + g_free(tt); + +void +gui_input_set_extents(pos, len, left, right) + int pos + int len + char *left + char *right +PREINIT: + char *tl; + char *tr; +CODE: + tl = left != NULL ? format_string_expand(left, NULL) : NULL; + tr = right != NULL ? format_string_expand(right, NULL) : NULL; + gui_entry_set_extents(active_entry, pos, len, tl, tr); + g_free(tl); + g_free(tr); + +void +gui_input_clear_extents(pos, len = 0) + int pos + int len +CODE: + gui_entry_clear_extents(active_entry, pos, len); + +char * +gui_input_get_extent(pos) + int pos +CODE: + RETVAL = gui_entry_get_extent(active_entry, pos); +OUTPUT: + RETVAL + +void +gui_input_get_text_and_extents() +PREINIT: + GSList *ret, *tmp; +PPCODE: + ret = gui_entry_get_text_and_extents(active_entry); + for (tmp = ret; tmp != NULL; tmp = tmp->next) { + XPUSHs(sv_2mortal(new_pv(tmp->data))); + } + g_slist_free_full(ret, g_free); + +void +gui_input_set_text_and_extents(...) +PREINIT: + GSList *list; + int i; +PPCODE: + list = NULL; + for (i = items; i > 0; i--) { + list = g_slist_prepend(list, SvPV_nolen(ST(i-1))); + } + gui_entry_set_text_and_extents(active_entry, list); + g_slist_free(list); + +int +gui_input_get_pos() +CODE: + RETVAL = gui_entry_get_pos(active_entry); +OUTPUT: + RETVAL + +void +gui_input_set_pos(pos) + int pos +CODE: + gui_entry_set_pos(active_entry, pos); + +int +wcwidth(c) + char *c +CODE: + if (term_type == TERM_TYPE_UTF8) { + unichar chr = g_utf8_get_char_validated((const char *) c, -1); + + if (chr & 0x80000000) { + RETVAL = 1; + } else { + RETVAL = i_wcwidth(chr); + } + } else if (term_type != TERM_TYPE_BIG5 || + c[1] == '\0' || + !is_big5((unsigned char) c[0], (unsigned char) c[1])) { + RETVAL = i_wcwidth((unsigned char) *c); + } else { + RETVAL = 2; + } +OUTPUT: + RETVAL + +MODULE = Irssi::TextUI PACKAGE = Irssi::UI::Window + +void +print_after(window, prev, level, str, time = 0) + Irssi::UI::Window window + Irssi::TextUI::Line prev + int level + char *str + time_t time +PREINIT: + TEXT_DEST_REC dest; + char *text; + char *text2; +CODE: + format_create_dest(&dest, NULL, NULL, level, window); + text = format_string_expand(str, NULL); + text2 = g_strconcat(text, "\n", NULL); + gui_printtext_after_time(&dest, Line(prev), text2, time); + g_free(text); + g_free(text2); + +void +gui_printtext_after(window, prev, level, str, time = 0) + Irssi::UI::Window window + Irssi::TextUI::Line prev + int level + char *str + time_t time +PREINIT: + TEXT_DEST_REC dest; +CODE: + format_create_dest(&dest, NULL, NULL, level, window); + gui_printtext_after_time(&dest, Line(prev), str, time); + +Irssi::TextUI::Line +last_line_insert(window) + Irssi::UI::Window window +CODE: + RETVAL = perl_wrap_buffer_line(WINDOW_GUI(window)->view->buffer, + WINDOW_GUI(window)->insert_after); +OUTPUT: + RETVAL + +MODULE = Irssi::TextUI PACKAGE = Irssi::Server + +void +gui_printtext_after(server, target, prev, level, str, time = 0) + Irssi::Server server + char *target + Irssi::TextUI::Line prev + int level + char *str + time_t time +PREINIT: + TEXT_DEST_REC dest; +CODE: + format_create_dest(&dest, server, target, level, NULL); + gui_printtext_after_time(&dest, Line(prev), str, time); + +BOOT: + irssi_boot(TextUI__Statusbar); + irssi_boot(TextUI__TextBuffer); + irssi_boot(TextUI__TextBufferView); + +MODULE = Irssi::TextUI PACKAGE = Irssi + +void +term_refresh_freeze() + +void +term_refresh_thaw() diff --git a/src/perl/textui/meson.build b/src/perl/textui/meson.build new file mode 100644 index 0000000..429e988 --- /dev/null +++ b/src/perl/textui/meson.build @@ -0,0 +1,37 @@ +libperl_Irssi_TextUI_a = shared_module('TextUI', + [ xsubpp.process( + files( + 'Statusbar.xs', + 'TextBufferView.xs', + 'TextBuffer.xs', + 'TextUI.xs', + ), + extra_args : [ + '-typemap', + '../common/typemap', + '-typemap', + '../ui/typemap', + ], + ) ] + + files( + 'module.h', + ), + name_prefix : '', + name_suffix : perl_module_suffix, + install : true, + install_dir : perlmoddir / 'auto' / 'Irssi' / 'TextUI', + include_directories : rootinc, + implicit_include_directories : true, + dependencies : dep + [ perl_dep ], + link_with : dl_cross_perl_core, +) + +install_headers( + files( + 'TextUI.pm', + ), + install_dir : perlmoddir / 'Irssi', +) + +# 'Makefile.PL.in', +# 'typemap', diff --git a/src/perl/textui/module.h b/src/perl/textui/module.h new file mode 100644 index 0000000..aba5bd7 --- /dev/null +++ b/src/perl/textui/module.h @@ -0,0 +1,17 @@ +#include <irssi/src/perl/ui/module.h> + +#include <irssi/src/fe-text/mainwindows.h> +#include <irssi/src/fe-text/gui-windows.h> +#include <irssi/src/fe-text/gui-printtext.h> +#include <irssi/src/fe-text/statusbar.h> +#include <irssi/src/fe-text/textbuffer.h> +#include <irssi/src/fe-text/textbuffer-view.h> +#include <irssi/src/fe-text/gui-entry.h> + +typedef MAIN_WINDOW_REC *Irssi__TextUI__MainWindow; +typedef TEXT_BUFFER_REC *Irssi__TextUI__TextBuffer; +typedef TEXT_BUFFER_VIEW_REC *Irssi__TextUI__TextBufferView; +typedef struct Buffer_Line_Wrapper *Irssi__TextUI__Line; +typedef LINE_CACHE_REC *Irssi__TextUI__LineCache; +typedef LINE_INFO_REC *Irssi__TextUI__LineInfo; +typedef SBAR_ITEM_REC *Irssi__TextUI__StatusbarItem; diff --git a/src/perl/textui/typemap b/src/perl/textui/typemap new file mode 100644 index 0000000..e597c58 --- /dev/null +++ b/src/perl/textui/typemap @@ -0,0 +1,24 @@ +TYPEMAP +Irssi::TextUI::MainWindow T_PlainObj +Irssi::TextUI::TextBuffer T_PlainObj +Irssi::TextUI::TextBufferView T_PlainObj +Irssi::TextUI::Line T_BufferLineWrapper +Irssi::TextUI::LineCache T_PlainObj +Irssi::TextUI::LineInfo T_PlainObj +Irssi::TextUI::StatusbarItem T_PlainObj + +INPUT + +T_PlainObj + $var = irssi_ref_object($arg) + +T_BufferLineWrapper + $var = irssi_ref_buffer_line_wrap($arg) + +OUTPUT + +T_PlainObj + $arg = plain_bless($var, \"$ntype\"); + +T_BufferLineWrapper + $arg = perl_buffer_line_bless($var); diff --git a/src/perl/textui/wrapper_buffer_line.h b/src/perl/textui/wrapper_buffer_line.h new file mode 100644 index 0000000..3431065 --- /dev/null +++ b/src/perl/textui/wrapper_buffer_line.h @@ -0,0 +1,90 @@ +#ifndef IRSSI_PERL_TEXTUI_WRAPPER_BUFFER_LINE_H +#define IRSSI_PERL_TEXTUI_WRAPPER_BUFFER_LINE_H + +/* This Buffer_Line_Wrapper is a compatibility shim so that the Perl + * API does not change in Irssi ABI 24 even though the C API was + * changed. That way scripts can continue to work unchanged. */ + +struct Buffer_Line_Wrapper { + LINE_REC *line; + TEXT_BUFFER_REC *buffer; +}; + +#define Line(wrapper) ((wrapper) == NULL ? NULL : (wrapper)->line) + +static int magic_free_buffer_line(pTHX_ SV *sv, MAGIC *mg) +{ + struct Buffer_Line_Wrapper *wrap = (struct Buffer_Line_Wrapper *) mg->mg_ptr; + g_free(wrap); + mg->mg_ptr = NULL; + sv_setiv(sv, 0); + return 0; +} + +static MGVTBL vtbl_free_buffer_line = { NULL, NULL, NULL, NULL, magic_free_buffer_line }; + +static struct Buffer_Line_Wrapper *perl_wrap_buffer_line(TEXT_BUFFER_REC *buffer, LINE_REC *line) +{ + struct Buffer_Line_Wrapper *wrap; + + if (line == NULL) + return NULL; + + wrap = g_new0(struct Buffer_Line_Wrapper, 1); + wrap->buffer = buffer; + wrap->line = line; + + return wrap; +} + +/* This function is more or less a copy of plain_bless, but with a + special divertion to put the wrapper in _wrapper and the original + line pointer in _irssi, in order to stay compatible with signals + and scripts */ +static SV *perl_buffer_line_bless(struct Buffer_Line_Wrapper *object) +{ + SV *ret, **tmp; + HV *hv; + const char *stash = "Irssi::TextUI::Line"; + + if (object == NULL) + return &PL_sv_undef; + + ret = irssi_bless_plain(stash, object); + hv = hvref(ret); + + tmp = hv_fetch(hv, "_irssi", 6, 0); + + sv_magic(*tmp, NULL, '~', NULL, 0); + + SvMAGIC(*tmp)->mg_private = 0x1551; /* HF */ + SvMAGIC(*tmp)->mg_virtual = &vtbl_free_buffer_line; + SvMAGIC(*tmp)->mg_ptr = (char *) object; + + (void) hv_store(hv, "_wrapper", 8, *tmp, 0); + /* We have to put the Line Pointer in _irssi, not the + compatibility wrapper */ + *tmp = newSViv((IV) object->line); + return ret; +} + +/* This function is a copy of irssi_ref_object, but looking up the + wrapper object in _wrapper instead */ +static void *irssi_ref_buffer_line_wrap(SV *o) +{ + SV **sv; + HV *hv; + void *p; + + hv = hvref(o); + if (hv == NULL) + return NULL; + + sv = hv_fetch(hv, "_wrapper", 8, 0); + if (sv == NULL) + croak("variable is damaged"); + p = GINT_TO_POINTER(SvIV(*sv)); + return p; +} + +#endif |