summaryrefslogtreecommitdiffstats
path: root/src/perl/ui
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 20:18:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 20:18:39 +0000
commitfff5217f02d91268ce90c8c05665602c059faaef (patch)
tree2ba24d32dc96eafe7ed0a85269548e76796d849d /src/perl/ui
parentInitial commit. (diff)
downloadirssi-fff5217f02d91268ce90c8c05665602c059faaef.tar.xz
irssi-fff5217f02d91268ce90c8c05665602c059faaef.zip
Adding upstream version 1.4.5.upstream/1.4.5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/perl/ui')
-rw-r--r--src/perl/ui/Formats.xs177
-rw-r--r--src/perl/ui/Makefile.PL.in8
-rw-r--r--src/perl/ui/Themes.xs322
-rw-r--r--src/perl/ui/UI.pm29
-rw-r--r--src/perl/ui/UI.xs147
-rw-r--r--src/perl/ui/Window.xs443
-rw-r--r--src/perl/ui/meson.build35
-rw-r--r--src/perl/ui/module.h15
-rw-r--r--src/perl/ui/typemap17
9 files changed, 1193 insertions, 0 deletions
diff --git a/src/perl/ui/Formats.xs b/src/perl/ui/Formats.xs
new file mode 100644
index 0000000..0f8b59b
--- /dev/null
+++ b/src/perl/ui/Formats.xs
@@ -0,0 +1,177 @@
+#define PERL_NO_GET_CONTEXT
+#include "module.h"
+
+static int magic_free_text_dest(pTHX_ SV *sv, MAGIC *mg)
+{
+ TEXT_DEST_REC *dest = (TEXT_DEST_REC *) mg->mg_ptr;
+ char *target = (char *) dest->target;
+ g_free(target);
+ g_free(dest);
+ mg->mg_ptr = NULL;
+ sv_setiv(sv, 0);
+ return 0;
+}
+
+static MGVTBL vtbl_free_text_dest =
+{
+ NULL, NULL, NULL, NULL, magic_free_text_dest
+};
+
+static SV *perl_format_create_dest(SERVER_REC *server, char *target,
+ int level, WINDOW_REC *window)
+{
+ TEXT_DEST_REC *dest;
+ SV *sv, *ret_sv;
+
+ dest = g_new0(TEXT_DEST_REC, 1);
+ format_create_dest(dest, server, g_strdup(target), level, window);
+
+ ret_sv = plain_bless(dest, "Irssi::UI::TextDest");
+
+ sv = *hv_fetch(hvref(ret_sv), "_irssi", 6, 0);
+ sv_magic(sv, NULL, '~', NULL, 0);
+
+ SvMAGIC(sv)->mg_private = 0x1551; /* HF */
+ SvMAGIC(sv)->mg_virtual = &vtbl_free_text_dest;
+ SvMAGIC(sv)->mg_ptr = (char *) dest;
+
+ return ret_sv;
+}
+
+MODULE = Irssi::UI::Formats PACKAGE = Irssi
+PROTOTYPES: ENABLE
+
+int
+format_get_length(str)
+ char *str
+
+int
+format_real_length(str, len)
+ char *str
+ int len
+
+void
+format_string_expand(str)
+ char *str
+PREINIT:
+ char *ret;
+PPCODE:
+ ret = format_string_expand(str, NULL);
+ XPUSHs(sv_2mortal(new_pv(ret)));
+ g_free(ret);
+
+void
+strip_codes(input)
+ char *input
+PREINIT:
+ char *ret;
+PPCODE:
+ ret = strip_codes(input);
+ XPUSHs(sv_2mortal(new_pv(ret)));
+ g_free(ret);
+
+void
+format_string_unexpand(input)
+ char *input
+PREINIT:
+ char *ret;
+PPCODE:
+ ret = format_string_unexpand(input, 0);
+ XPUSHs(sv_2mortal(new_pv(ret)));
+ g_free(ret);
+
+void
+format_create_dest(target, level=MSGLEVEL_CLIENTNOTICE, window=NULL)
+ char *target
+ int level
+ Irssi::UI::Window window
+PPCODE:
+ XPUSHs(sv_2mortal(perl_format_create_dest(NULL, target, level, window)));
+
+#*******************************
+MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::Window
+#*******************************
+
+void
+format_get_text(window, module, server, target, format, ...)
+ Irssi::UI::Window window
+ char *module
+ Irssi::Server server
+ char *target
+ char *format
+PREINIT:
+ TEXT_DEST_REC dest;
+ THEME_REC *theme;
+ char **charargs;
+ char *ret;
+ int formatnum;
+ int n;
+PPCODE:
+ charargs = g_new0(char *, items-5+1);
+ for (n = 5; n < items; n++) {
+ charargs[n-5] = SvPV_nolen(ST(n));
+ }
+
+ format_create_dest(&dest, server, target, 0, window);
+ theme = window_get_theme(dest.window);
+ formatnum = format_find_tag(module, format);
+
+ ret = format_get_text_theme_charargs(theme, module, &dest, formatnum, charargs);
+ g_free(charargs);
+
+ XPUSHs(sv_2mortal(new_pv(ret)));
+ g_free_not_null(ret);
+
+#*******************************
+MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::Window
+#*******************************
+
+void
+format_create_dest(window=NULL, level=MSGLEVEL_CLIENTNOTICE)
+ Irssi::UI::Window window
+ int level
+PPCODE:
+ XPUSHs(sv_2mortal(perl_format_create_dest(NULL, NULL, level, window)));
+
+#*******************************
+MODULE = Irssi::UI::Formats PACKAGE = Irssi::Server
+#*******************************
+
+void
+format_create_dest(server, target=NULL, level=MSGLEVEL_CLIENTNOTICE, window=NULL)
+ Irssi::Server server
+ char *target
+ int level
+ Irssi::UI::Window window
+PPCODE:
+ XPUSHs(sv_2mortal(perl_format_create_dest(server, target, level, window)));
+
+#*******************************
+MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::TextDest
+#*******************************
+
+void
+print(dest, str)
+ Irssi::UI::TextDest dest
+ 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
diff --git a/src/perl/ui/Makefile.PL.in b/src/perl/ui/Makefile.PL.in
new file mode 100644
index 0000000..9507e74
--- /dev/null
+++ b/src/perl/ui/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::UI',
+ 'LIBS' => '',
+ 'OBJECT' => '$(O_FILES)',
+ 'TYPEMAPS' => ['../common/typemap'],
+ 'INC' => '-I../../.. @GLIB_CFLAGS@',
+ 'VERSION_FROM' => '@srcdir@/UI.pm');
diff --git a/src/perl/ui/Themes.xs b/src/perl/ui/Themes.xs
new file mode 100644
index 0000000..e9e5639
--- /dev/null
+++ b/src/perl/ui/Themes.xs
@@ -0,0 +1,322 @@
+#define PERL_NO_GET_CONTEXT
+#include "module.h"
+
+static void printformat_module_perl(TEXT_DEST_REC *dest, const char *module, char *format,
+ char **arglist)
+{
+ int formatnum;
+
+ formatnum = format_find_tag(module, format);
+ if (formatnum < 0) {
+ die("printformat(): unregistered format '%s'", format);
+ return;
+ }
+
+ printformat_module_dest_charargs(module, dest, formatnum, arglist);
+}
+
+static void printformat_perl(TEXT_DEST_REC *dest, char *format, char **arglist)
+{
+ char *module;
+
+ module = g_strdup(perl_get_package());
+ printformat_module_perl(dest, module, format, arglist);
+ g_free(module);
+}
+
+static void perl_unregister_theme(const char *package)
+{
+ FORMAT_REC *formats;
+ int n;
+
+ formats = g_hash_table_lookup(default_formats, package);
+ if (formats == NULL) return;
+
+ for (n = 0; formats[n].def != NULL; n++) {
+ g_free(formats[n].tag);
+ g_free(formats[n].def);
+ }
+ g_free(formats);
+ theme_unregister_module(package);
+}
+
+static void sig_script_destroyed(PERL_SCRIPT_REC *script)
+{
+ perl_unregister_theme(script->package);
+}
+
+void perl_themes_init(void)
+{
+ signal_add("script destroyed", (SIGNAL_FUNC) sig_script_destroyed);
+}
+
+void perl_themes_deinit(void)
+{
+ signal_remove("script destroyed", (SIGNAL_FUNC) sig_script_destroyed);
+}
+
+MODULE = Irssi::UI::Themes PACKAGE = Irssi
+PROTOTYPES: ENABLE
+
+Irssi::UI::Theme
+current_theme()
+CODE:
+ RETVAL = current_theme;
+OUTPUT:
+ RETVAL
+
+int
+EXPAND_FLAG_IGNORE_REPLACES()
+CODE:
+ RETVAL = EXPAND_FLAG_IGNORE_REPLACES;
+OUTPUT:
+ RETVAL
+
+int
+EXPAND_FLAG_IGNORE_EMPTY()
+CODE:
+ RETVAL = EXPAND_FLAG_IGNORE_EMPTY;
+OUTPUT:
+ RETVAL
+
+int
+EXPAND_FLAG_RECURSIVE_MASK()
+CODE:
+ RETVAL = EXPAND_FLAG_RECURSIVE_MASK;
+OUTPUT:
+ RETVAL
+
+void
+theme_register(formats)
+ SV *formats
+PREINIT:
+ AV *av;
+ FORMAT_REC *formatrecs;
+ char *key, *value;
+ int len, n, fpos;
+CODE:
+
+ if (!SvROK(formats))
+ croak("formats is not a reference");
+
+ av = (AV *) SvRV(formats);
+ if (SvTYPE(av) != SVt_PVAV)
+ croak("formats is not a reference to a list");
+
+ len = av_len(av)+1;
+ if (len == 0 || (len & 1) != 0)
+ croak("formats list is invalid - not divisible by 2 (%d)", len);
+
+ formatrecs = g_new0(FORMAT_REC, len/2+2);
+ formatrecs[0].tag = g_strdup(perl_get_package());
+ formatrecs[0].def = g_strdup("Perl script");
+
+ for (fpos = 1, n = 0; n < len; n++, fpos++) {
+ key = SvPV_nolen(*av_fetch(av, n, 0)); n++;
+ value = SvPV_nolen(*av_fetch(av, n, 0));
+
+ formatrecs[fpos].tag = g_strdup(key);
+ formatrecs[fpos].def = g_strdup(value);
+ formatrecs[fpos].params = MAX_FORMAT_PARAMS;
+ }
+
+ theme_register_module(perl_get_package(), formatrecs);
+
+void
+printformat(level, format, ...)
+ int level
+ char *format
+PREINIT:
+ TEXT_DEST_REC dest;
+ char *arglist[MAX_FORMAT_PARAMS+1];
+ int n;
+CODE:
+ format_create_dest(&dest, NULL, NULL, level, NULL);
+ memset(arglist, 0, sizeof(arglist));
+ for (n = 2; n < items && n < MAX_FORMAT_PARAMS+2; n++) {
+ arglist[n-2] = SvPV_nolen(ST(n));
+ }
+
+ printformat_perl(&dest, format, arglist);
+
+void
+abstracts_register(abstracts)
+ SV *abstracts
+PREINIT:
+ AV *av;
+ char *key, *value;
+ int i, len;
+CODE:
+ if (!SvROK(abstracts))
+ croak("abstracts is not a reference to list");
+ av = (AV *) SvRV(abstracts);
+ len = av_len(av)+1;
+ if (len == 0 || (len & 1) != 0)
+ croak("abstracts list is invalid - not divisible by 2 (%d)", len);
+
+ for (i = 0; i < len; i++) {
+ key = SvPV_nolen(*av_fetch(av, i, 0)); i++;
+ value = SvPV_nolen(*av_fetch(av, i, 0));
+
+ theme_set_default_abstract(key, value);
+ }
+ themes_reload();
+
+void
+themes_reload()
+
+#*******************************
+MODULE = Irssi::UI::Themes PACKAGE = Irssi::Server
+#*******************************
+
+void
+printformat(server, target, level, format, ...)
+ Irssi::Server server
+ char *target
+ int level
+ char *format
+PREINIT:
+ TEXT_DEST_REC dest;
+ char *arglist[MAX_FORMAT_PARAMS+1];
+ int n;
+CODE:
+ format_create_dest(&dest, server, target, level, NULL);
+ memset(arglist, 0, sizeof(arglist));
+ for (n = 4; n < items && n < MAX_FORMAT_PARAMS+4; n++) {
+ arglist[n-4] = SvPV_nolen(ST(n));
+ }
+
+ printformat_perl(&dest, format, arglist);
+
+#*******************************
+MODULE = Irssi::UI::Themes PACKAGE = Irssi::UI::Window
+#*******************************
+
+void
+printformat(window, level, format, ...)
+ Irssi::UI::Window window
+ int level
+ char *format
+PREINIT:
+ TEXT_DEST_REC dest;
+ char *arglist[MAX_FORMAT_PARAMS+1];
+ int n;
+CODE:
+ format_create_dest(&dest, NULL, NULL, level, window);
+ memset(arglist, 0, sizeof(arglist));
+ for (n = 3; n < items && n < MAX_FORMAT_PARAMS+3; n++) {
+ arglist[n-3] = SvPV_nolen(ST(n));
+ }
+
+ printformat_perl(&dest, format, arglist);
+
+#*******************************
+MODULE = Irssi::UI::Themes PACKAGE = Irssi::Windowitem
+#*******************************
+
+void
+printformat(item, level, format, ...)
+ Irssi::Windowitem item
+ int level
+ char *format
+PREINIT:
+ TEXT_DEST_REC dest;
+ char *arglist[MAX_FORMAT_PARAMS+1];
+ int n;
+CODE:
+ format_create_dest(&dest, item->server, item->visible_name, level, NULL);
+ memset(arglist, 0, sizeof(arglist));
+ for (n = 3; n < items && n < MAX_FORMAT_PARAMS+3; n++) {
+ arglist[n-3] = SvPV_nolen(ST(n));
+ }
+
+ printformat_perl(&dest, format, arglist);
+
+#*******************************
+MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::TextDest
+#*******************************
+
+void
+printformat(dest, format, ...)
+ Irssi::UI::TextDest dest
+ char *format
+PREINIT:
+ char *arglist[MAX_FORMAT_PARAMS + 1];
+ int n;
+CODE:
+ memset(arglist, 0, sizeof(arglist));
+ for (n = 2; n < items && n < MAX_FORMAT_PARAMS + 2; n++) {
+ arglist[n - 2] = SvPV_nolen(ST(n));
+ }
+
+ printformat_perl(dest, format, arglist);
+
+void
+printformat_module(dest, module, format, ...)
+ Irssi::UI::TextDest dest
+ char *module
+ char *format
+PREINIT:
+ char *arglist[MAX_FORMAT_PARAMS + 1];
+ int n;
+CODE:
+ memset(arglist, 0, sizeof(arglist));
+ for (n = 3; n < items && n < MAX_FORMAT_PARAMS + 3; n++) {
+ arglist[n - 3] = SvPV_nolen(ST(n));
+ }
+
+ printformat_module_perl(dest, module, format, arglist);
+
+#*******************************
+MODULE = Irssi::UI::Themes PACKAGE = Irssi::UI::Theme PREFIX = theme_
+#*******************************
+
+void
+theme_format_expand(theme, format, flags=0)
+ Irssi::UI::Theme theme
+ char *format
+ int flags
+PREINIT:
+ char *ret;
+PPCODE:
+ if (flags == 0) {
+ ret = theme_format_expand(theme, format);
+ } else {
+ theme_rm_col reset;
+ strcpy(reset.m, "n");
+ ret = theme_format_expand_data(theme, (const char **) &format,
+ reset, reset, NULL, NULL,
+ EXPAND_FLAG_ROOT | flags);
+ }
+ XPUSHs(sv_2mortal(new_pv(ret)));
+ g_free_not_null(ret);
+
+char *
+theme_get_format(theme, module, tag)
+ Irssi::UI::Theme theme
+ char *module
+ char *tag
+PREINIT:
+ MODULE_THEME_REC *modtheme;
+ FORMAT_REC *formats;
+ int i;
+CODE:
+ formats = g_hash_table_lookup(default_formats, module);
+ if (formats == NULL)
+ croak("Unknown module: %s", module);
+
+ for (i = 0; formats[i].def != NULL; i++) {
+ if (formats[i].tag != NULL &&
+ g_ascii_strcasecmp(formats[i].tag, tag) == 0)
+ break;
+ }
+
+ if (formats[i].def == NULL)
+ croak("Unknown format tag: %s", tag);
+
+ modtheme = g_hash_table_lookup(theme->modules, module);
+ RETVAL = modtheme == NULL ? NULL : modtheme->formats[i];
+ if (RETVAL == NULL)
+ RETVAL = formats[i].def;
+OUTPUT:
+ RETVAL
diff --git a/src/perl/ui/UI.pm b/src/perl/ui/UI.pm
new file mode 100644
index 0000000..83b9ef2
--- /dev/null
+++ b/src/perl/ui/UI.pm
@@ -0,0 +1,29 @@
+#
+# Perl interface to irssi functions.
+#
+
+package Irssi::UI;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+
+$VERSION = "0.9";
+
+require Exporter;
+require DynaLoader;
+
+sub Irssi::UI::Window::create_handle {
+ goto &Irssi::create_window_handle;
+}
+
+@ISA = qw(Exporter DynaLoader);
+@EXPORT = qw();
+@EXPORT_OK = qw();
+
+bootstrap Irssi::UI $VERSION if (!Irssi::Core::is_static());
+
+Irssi::UI::init();
+
+Irssi::EXPORT_ALL();
+
+1;
diff --git a/src/perl/ui/UI.xs b/src/perl/ui/UI.xs
new file mode 100644
index 0000000..30b0f63
--- /dev/null
+++ b/src/perl/ui/UI.xs
@@ -0,0 +1,147 @@
+#define PERL_NO_GET_CONTEXT
+#include "module.h"
+
+void perl_themes_init(void);
+void perl_themes_deinit(void);
+
+static int initialized = FALSE;
+
+static void perl_process_fill_hash(HV *hv, PROCESS_REC *process)
+{
+ (void) hv_store(hv, "id", 2, newSViv(process->id), 0);
+ (void) hv_store(hv, "name", 4, new_pv(process->name), 0);
+ (void) hv_store(hv, "args", 4, new_pv(process->args), 0);
+
+ (void) hv_store(hv, "pid", 3, newSViv(process->pid), 0);
+ (void) hv_store(hv, "target", 6, new_pv(process->target), 0);
+ if (process->target_win != NULL) {
+ (void) hv_store(hv, "target_win", 10,
+ plain_bless(process->target_win, "Irssi::UI::Window"), 0);
+ }
+ (void) hv_store(hv, "shell", 5, newSViv(process->shell), 0);
+ (void) hv_store(hv, "notice", 6, newSViv(process->notice), 0);
+ (void) hv_store(hv, "silent", 6, newSViv(process->silent), 0);
+}
+
+static void perl_window_fill_hash(HV *hv, WINDOW_REC *window)
+{
+ (void) hv_store(hv, "refnum", 6, newSViv(window->refnum), 0);
+ (void) hv_store(hv, "name", 4, new_pv(window->name), 0);
+ (void) hv_store(hv, "history_name", 12, new_pv(window->history_name), 0);
+
+ (void) hv_store(hv, "width", 5, newSViv(window->width), 0);
+ (void) hv_store(hv, "height", 6, newSViv(window->height), 0);
+
+ if (window->active)
+ (void) hv_store(hv, "active", 6, iobject_bless(window->active), 0);
+ if (window->active_server)
+ (void) hv_store(hv, "active_server", 13, iobject_bless(window->active_server), 0);
+
+ (void) hv_store(hv, "servertag", 9, new_pv(window->servertag), 0);
+ (void) hv_store(hv, "level", 5, newSViv(window->level), 0);
+
+ (void) hv_store(hv, "immortal", 8, newSViv(window->immortal), 0);
+ (void) hv_store(hv, "sticky_refnum", 13, newSViv(window->sticky_refnum), 0);
+
+ (void) hv_store(hv, "data_level", 10, newSViv(window->data_level), 0);
+ (void) hv_store(hv, "hilight_color", 13, new_pv(window->hilight_color), 0);
+
+ (void) hv_store(hv, "last_timestamp", 14, newSViv(window->last_timestamp), 0);
+ (void) hv_store(hv, "last_line", 9, newSViv(window->last_line), 0);
+
+ (void) hv_store(hv, "theme", 5, plain_bless(window->theme, "Irssi::UI::Theme"), 0);
+ (void) hv_store(hv, "theme_name", 10, new_pv(window->theme_name), 0);
+}
+
+static void perl_text_dest_fill_hash(HV *hv, TEXT_DEST_REC *dest)
+{
+ (void) hv_store(hv, "window", 6, plain_bless(dest->window, "Irssi::UI::Window"), 0);
+ (void) hv_store(hv, "server", 6, iobject_bless(dest->server), 0);
+ (void) hv_store(hv, "target", 6, new_pv(dest->target), 0);
+ (void) hv_store(hv, "level", 5, newSViv(dest->level), 0);
+
+ (void) hv_store(hv, "hilight_priority", 16, newSViv(dest->hilight_priority), 0);
+ (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);
+ g_return_if_fail(item != NULL);
+
+ perl_window_item_fill_hash(hv, (WI_ITEM_REC *) item);
+ /* we don't bless to Process here to avoid infinite recursion
+ in the simplistic script binding */
+ if (item->process != NULL) {
+ (void) hv_store(hv, "process_id", 10, newSViv(item->process->id), 0);
+ }
+}
+
+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 }
+};
+
+MODULE = Irssi::UI PACKAGE = Irssi::UI
+
+PROTOTYPES: ENABLE
+
+void
+processes()
+PREINIT:
+ GSList *tmp;
+PPCODE:
+ for (tmp = processes; tmp != NULL; tmp = tmp->next) {
+ XPUSHs(sv_2mortal(plain_bless(tmp->data, "Irssi::UI::Process")));
+ }
+
+
+void
+init()
+CODE:
+ if (initialized) return;
+ perl_api_version_check("Irssi::UI");
+ initialized = TRUE;
+
+ irssi_add_plains(fe_plains);
+ /* window items: fe-exec */
+ irssi_add_object(module_get_uniq_id_str("WINDOW ITEM TYPE", "EXEC"),
+ 0, "Irssi::UI::Exec",
+ (PERL_OBJECT_FUNC) perl_exec_fill_hash);
+ perl_themes_init();
+
+void
+deinit()
+CODE:
+ if (!initialized) return;
+ perl_themes_deinit();
+ initialized = FALSE;
+
+BOOT:
+ irssi_boot(UI__Formats);
+ irssi_boot(UI__Themes);
+ irssi_boot(UI__Window);
diff --git a/src/perl/ui/Window.xs b/src/perl/ui/Window.xs
new file mode 100644
index 0000000..d001f38
--- /dev/null
+++ b/src/perl/ui/Window.xs
@@ -0,0 +1,443 @@
+#define PERL_NO_GET_CONTEXT
+#include "module.h"
+
+#include <irssi/src/fe-common/core/window-activity.h>
+
+MODULE = Irssi::UI::Window PACKAGE = Irssi
+PROTOTYPES: ENABLE
+
+void
+windows()
+PREINIT:
+ GSList *tmp;
+PPCODE:
+ for (tmp = windows; tmp != NULL; tmp = tmp->next) {
+ XPUSHs(sv_2mortal(plain_bless(tmp->data, "Irssi::UI::Window")));
+ }
+
+
+Irssi::UI::Window
+active_win()
+CODE:
+ RETVAL = active_win;
+OUTPUT:
+ RETVAL
+
+Irssi::Server
+active_server()
+CODE:
+ RETVAL = active_win->active_server;
+OUTPUT:
+ RETVAL
+
+void
+print(str, level=MSGLEVEL_CLIENTNOTICE)
+ char *str
+ int level;
+CODE:
+ printtext_string(NULL, NULL, level, str);
+
+Irssi::UI::Window
+window_find_name(name)
+ char *name
+
+Irssi::UI::Window
+window_find_refnum(refnum)
+ int refnum
+
+int
+window_refnum_prev(refnum, wrap)
+ int refnum
+ int wrap
+
+int
+window_refnum_next(refnum, wrap)
+ int refnum
+ int wrap
+
+int
+windows_refnum_last()
+
+Irssi::UI::Window
+window_find_level(level)
+ int level
+CODE:
+ RETVAL = window_find_level(NULL, level);
+OUTPUT:
+ RETVAL
+
+Irssi::UI::Window
+window_find_item(name)
+ char *name
+CODE:
+ RETVAL = window_find_item(NULL, name);
+OUTPUT:
+ RETVAL
+
+Irssi::UI::Window
+window_find_closest(name, level)
+ char *name
+ int level
+CODE:
+ RETVAL = window_find_closest(NULL, name, level);
+OUTPUT:
+ RETVAL
+
+Irssi::Windowitem
+window_item_find(name)
+ char *name
+CODE:
+ RETVAL = window_item_find(NULL, name);
+OUTPUT:
+ RETVAL
+
+
+#*******************************
+MODULE = Irssi::UI::Window PACKAGE = Irssi::Server
+#*******************************
+
+void
+print(server, channel, str, level=MSGLEVEL_CLIENTNOTICE)
+ Irssi::Server server
+ char *channel
+ char *str
+ int level
+CODE:
+ printtext_string(server, channel, level, str);
+
+Irssi::Windowitem
+window_item_find(server, name)
+ Irssi::Server server
+ char *name
+
+Irssi::UI::Window
+window_find_item(server, name)
+ Irssi::Server server
+ char *name
+
+Irssi::UI::Window
+window_find_level(server, level)
+ Irssi::Server server
+ int level
+
+Irssi::UI::Window
+window_find_closest(server, name, level)
+ Irssi::Server server
+ char *name
+ int level
+
+
+#*******************************
+MODULE = Irssi::UI::Window PACKAGE = Irssi::UI::Window PREFIX=window_
+#*******************************
+
+void
+items(window)
+ Irssi::UI::Window window
+PREINIT:
+ GSList *tmp;
+PPCODE:
+ for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
+ CHANNEL_REC *rec = tmp->data;
+
+ XPUSHs(sv_2mortal(iobject_bless(rec)));
+ }
+
+void
+print(window, str, level=MSGLEVEL_CLIENTNOTICE)
+ Irssi::UI::Window window
+ char *str
+ int level;
+CODE:
+ printtext_string_window(window, level, str);
+
+void
+command(window, cmd)
+ Irssi::UI::Window window
+ char *cmd
+PREINIT:
+ WINDOW_REC *old;
+CODE:
+ old = active_win;
+ active_win = window;
+ perl_command(cmd, window->active_server, window->active);
+ if (active_win == window &&
+ g_slist_find(windows, old) != NULL)
+ active_win = old;
+
+void
+window_item_add(window, item, automatic)
+ Irssi::UI::Window window
+ Irssi::Windowitem item
+ int automatic
+
+void
+window_item_remove(item)
+ Irssi::Windowitem item
+
+void
+window_item_destroy(item)
+ Irssi::Windowitem item
+
+void
+window_item_prev(window)
+ Irssi::UI::Window window
+
+void
+window_item_next(window)
+ Irssi::UI::Window window
+
+void
+window_destroy(window)
+ Irssi::UI::Window window
+
+void
+window_set_active(window)
+ Irssi::UI::Window window
+
+void
+window_change_server(window, server)
+ Irssi::UI::Window window
+ Irssi::Server server
+
+void
+window_set_refnum(window, refnum)
+ Irssi::UI::Window window
+ int refnum
+
+void
+window_set_name(window, name)
+ Irssi::UI::Window window
+ char *name
+
+void
+window_set_history(window, name)
+ Irssi::UI::Window window
+ char *name
+
+void
+window_set_level(window, level)
+ Irssi::UI::Window window
+ int level
+
+void
+window_activity(window, data_level, hilight_color=NULL)
+ Irssi::UI::Window window
+ int data_level
+ char *hilight_color
+
+char *
+window_get_active_name(window)
+ Irssi::UI::Window window
+CODE:
+ RETVAL = (char *) window_get_active_name(window);
+OUTPUT:
+ RETVAL
+
+Irssi::Windowitem
+window_item_find(window, server, name)
+ Irssi::UI::Window window
+ Irssi::Server server
+ char *name
+CODE:
+ RETVAL = window_item_find_window(window, server, name);
+OUTPUT:
+ RETVAL
+
+void
+window_get_history_lines(window)
+ Irssi::UI::Window window
+PREINIT:
+ HISTORY_REC *rec;
+ GList *tmp;
+PPCODE:
+ rec = command_history_current(window);
+ for (tmp = command_history_list_first(rec); tmp != NULL; tmp = command_history_list_next(rec, tmp))
+ XPUSHs(sv_2mortal(new_pv(((HISTORY_ENTRY_REC *)tmp->data)->text)));
+
+void
+window_get_history_entries(window)
+ Irssi::UI::Window window
+PREINIT:
+ HISTORY_REC *rec;
+ HISTORY_ENTRY_REC *ent;
+ WINDOW_REC *win;
+ GList *tmp;
+ GSList *stmp;
+ HV *hv;
+PPCODE:
+ rec = window == NULL ? NULL : command_history_current(window);
+ for (tmp = command_history_list_first(rec); tmp != NULL; tmp = command_history_list_next(rec, tmp)) {
+ hv = (HV*)sv_2mortal((SV*)newHV());
+ ent = tmp->data;
+ hv_store(hv, "text", 4, newSVpv(ent->text, 0), 0);
+ hv_store(hv, "time", 4, newSViv(ent->time), 0);
+ if (ent->history == command_history_current(NULL)) {
+ hv_store(hv, "history", 7, newSV(0), 0);
+ hv_store(hv, "window", 6, newSV(0), 0);
+ } else {
+ if (ent->history->name == NULL) {
+ hv_store(hv, "history", 7, newSV(0), 0);
+ for (stmp = windows; stmp != NULL; stmp = stmp->next) {
+ win = stmp->data;
+ if (win->history == ent->history) {
+ hv_store(hv, "window", 6, newSViv(win->refnum), 0);
+ break;
+ }
+ }
+ } else {
+ hv_store(hv, "history", 7, new_pv(ent->history->name), 0);
+ hv_store(hv, "window", 6, newSV(0), 0);
+ }
+ }
+ XPUSHs(sv_2mortal(newRV_inc((SV*)hv)));
+ }
+
+void
+window_load_history_entries(window, ...)
+ Irssi::UI::Window window
+PREINIT:
+ HV *hv;
+ SV **sv;
+ HISTORY_REC *history;
+ WINDOW_REC *tmp;
+ const char *text;
+ long hist_time;
+ int i;
+PPCODE:
+ for (i = 1; i < items; i++) {
+ if (!is_hvref(ST(i))) {
+ croak("Usage: Irssi::UI::Window::load_history_entries(window, hash...)");
+ }
+ hv = hvref(ST(i));
+ if (hv != NULL) {
+ tmp = NULL;
+ text = NULL;
+ hist_time = time(NULL);
+ history = command_history_current(NULL);
+
+ sv = hv_fetch(hv, "text", 4, 0);
+ if (sv != NULL) text = SvPV_nolen(*sv);
+ sv = hv_fetch(hv, "time", 4, 0);
+ if (sv != NULL && SvOK(*sv)) hist_time = SvIV(*sv);
+
+ if (window != NULL) {
+ history = command_history_current(window);
+ } else {
+ sv = hv_fetch(hv, "history", 7, 0);
+ if (sv != NULL && SvOK(*sv)) {
+ history = command_history_find_name(SvPV_nolen(*sv));
+ }
+
+ sv = hv_fetch(hv, "window", 6, 0);
+ if (sv != NULL && SvOK(*sv)) {
+ tmp = window_find_refnum(SvIV(*sv));
+ if (tmp != NULL) {
+ history = tmp->history;
+ }
+ }
+ }
+
+ if (text != NULL && history != NULL) {
+ command_history_load_entry(hist_time, history, text);
+ }
+ }
+ }
+
+void
+window_delete_history_entries(window, ...)
+ Irssi::UI::Window window
+PREINIT:
+ HV *hv;
+ SV **sv;
+ HISTORY_REC *history;
+ WINDOW_REC *tmp;
+ const char *text;
+ long hist_time;
+ int i;
+PPCODE:
+ for (i = 1; i < items; i++) {
+ if (!is_hvref(ST(i))) {
+ croak("Usage: Irssi::UI::Window::delete_history_entries(window, hash...)");
+ }
+ hv = hvref(ST(i));
+ if (hv != NULL) {
+ tmp = NULL;
+ text = NULL;
+ hist_time = -1;
+ history = command_history_current(NULL);
+
+ sv = hv_fetch(hv, "text", 4, 0);
+ if (sv != NULL) text = SvPV_nolen(*sv);
+ sv = hv_fetch(hv, "time", 4, 0);
+ if (sv != NULL && SvOK(*sv)) hist_time = SvIV(*sv);
+
+ if (window != NULL) {
+ history = command_history_current(window);
+ } else {
+ sv = hv_fetch(hv, "history", 7, 0);
+ if (sv != NULL && SvOK(*sv)) {
+ history = command_history_find_name(SvPV_nolen(*sv));
+ }
+
+ sv = hv_fetch(hv, "window", 6, 0);
+ if (sv != NULL && SvOK(*sv)) {
+ tmp = window_find_refnum(SvIV(*sv));
+ if (tmp != NULL) {
+ history = tmp->history;
+ }
+ }
+ }
+
+ if (text != NULL && history != NULL) {
+ XPUSHs(boolSV(command_history_delete_entry(hist_time, history, text)));
+ }
+ }
+ }
+
+#*******************************
+MODULE = Irssi::UI::Window PACKAGE = Irssi::Windowitem PREFIX = window_item_
+#*******************************
+
+void
+print(item, str, level=MSGLEVEL_CLIENTNOTICE)
+ Irssi::Windowitem item
+ int level
+ char *str
+CODE:
+ printtext_string(item->server, item->visible_name, level, str);
+
+Irssi::UI::Window
+window_create(item, automatic)
+ Irssi::Windowitem item
+ int automatic
+
+Irssi::UI::Window
+window(item)
+ Irssi::Windowitem item
+CODE:
+ RETVAL = window_item_window(item);
+OUTPUT:
+ RETVAL
+
+void
+window_item_change_server(item, server)
+ Irssi::Windowitem item
+ Irssi::Server server
+
+int
+window_item_is_active(item)
+ Irssi::Windowitem item
+
+void
+window_item_set_active(item)
+ Irssi::Windowitem item
+CODE:
+ window_item_set_active(window_item_window(item), item);
+
+void
+window_item_activity(item, data_level, hilight_color=NULL)
+ Irssi::Windowitem item
+ int data_level
+ char *hilight_color
+
diff --git a/src/perl/ui/meson.build b/src/perl/ui/meson.build
new file mode 100644
index 0000000..26ef42e
--- /dev/null
+++ b/src/perl/ui/meson.build
@@ -0,0 +1,35 @@
+libperl_Irssi_UI_a = shared_module('UI',
+ [ xsubpp.process(
+ files(
+ 'Formats.xs',
+ 'Themes.xs',
+ 'UI.xs',
+ 'Window.xs',
+ ),
+ extra_args : [
+ '-typemap',
+ '../common/typemap',
+ ],
+ ) ]
+ + files(
+ 'module.h',
+ ),
+ name_prefix : '',
+ name_suffix : perl_module_suffix,
+ install : true,
+ install_dir : perlmoddir / 'auto' / 'Irssi' / 'UI',
+ include_directories : rootinc,
+ implicit_include_directories : true,
+ dependencies : dep + [ perl_dep ],
+ link_with : dl_cross_perl_core,
+)
+
+install_headers(
+ files(
+ 'UI.pm',
+ ),
+ install_dir : perlmoddir / 'Irssi',
+)
+
+# 'Makefile.PL.in',
+# 'typemap',
diff --git a/src/perl/ui/module.h b/src/perl/ui/module.h
new file mode 100644
index 0000000..4106aec
--- /dev/null
+++ b/src/perl/ui/module.h
@@ -0,0 +1,15 @@
+#include <irssi/src/perl/common/module.h>
+
+#include <irssi/src/fe-common/core/fe-windows.h>
+#include <irssi/src/fe-common/core/fe-exec.h>
+#include <irssi/src/fe-common/core/formats.h>
+#include <irssi/src/fe-common/core/printtext.h>
+#include <irssi/src/fe-common/core/window-items.h>
+#include <irssi/src/fe-common/core/themes.h>
+#include <irssi/src/fe-common/core/keyboard.h>
+
+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
new file mode 100644
index 0000000..9835519
--- /dev/null
+++ b/src/perl/ui/typemap
@@ -0,0 +1,17 @@
+TYPEMAP
+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
+
+T_PlainObj
+ $var = irssi_ref_object($arg)
+
+OUTPUT
+
+T_PlainObj
+ $arg = plain_bless($var, \"$ntype\");
+