Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / perl / textui / Statusbar.xs
1 #include "module.h"
2
3 static GHashTable *perl_sbar_defs;
4
5 static int check_sbar_destroy(char *key, char *value, char *script)
6 {
7         if (strncmp(value, script, strlen(script)) == 0 &&
8             value[strlen(script)] == ':') {
9                 statusbar_item_unregister(key);
10                 g_free(key);
11                 g_free(value);
12                 return TRUE;
13         }
14
15         return FALSE;
16 }
17
18 static void script_unregister_statusbars(PERL_SCRIPT_REC *script)
19 {
20         g_hash_table_foreach_remove(perl_sbar_defs,
21                                     (GHRFunc) check_sbar_destroy,
22                                     script->package);
23 }
24
25 void perl_statusbar_init(void)
26 {
27         perl_sbar_defs = g_hash_table_new((GHashFunc) g_str_hash,
28                                           (GCompareFunc) g_str_equal);
29         signal_add("script destroyed", (SIGNAL_FUNC) script_unregister_statusbars);
30 }
31
32 static void statusbar_item_def_destroy(void *key, void *value)
33 {
34         statusbar_item_unregister(key);
35         g_free(key);
36         g_free(value);
37 }
38
39 void perl_statusbar_deinit(void)
40 {
41         signal_remove("script destroyed", (SIGNAL_FUNC) script_unregister_statusbars);
42
43         g_hash_table_foreach(perl_sbar_defs,
44                              (GHFunc) statusbar_item_def_destroy, NULL);
45         g_hash_table_destroy(perl_sbar_defs);
46 }
47
48 static void perl_statusbar_event(char *function, SBAR_ITEM_REC *item,
49                                  int get_size_only)
50 {
51         dSP;
52         int retcount;
53         SV *item_sv, **sv;
54         HV *hv;
55
56         ENTER;
57         SAVETMPS;
58
59         PUSHMARK(SP);
60         item_sv = plain_bless(item, "Irssi::TextUI::StatusbarItem");
61         XPUSHs(sv_2mortal(item_sv));
62         XPUSHs(sv_2mortal(newSViv(get_size_only)));
63         PUTBACK;
64
65         retcount = perl_call_pv(function, G_EVAL|G_DISCARD);
66         SPAGAIN;
67
68         if (SvTRUE(ERRSV)) {
69                 PERL_SCRIPT_REC *script;
70                 char *package;
71
72                 package = perl_function_get_package(function);
73                 script = perl_script_find_package(package);
74                 g_free(package);
75
76                 if (script != NULL) {
77                         /* make sure we don't get back here */
78                         script_unregister_statusbars(script);
79                 }
80                 signal_emit("script error", 2, script, SvPV(ERRSV, PL_na));
81         } else {
82                 /* min_size and max_size can be changed, move them to SBAR_ITEM_REC */
83                 hv = hvref(item_sv);
84                 if (hv != NULL) {
85                         sv = hv_fetch(hv, "min_size", 8, 0);
86                         if (sv != NULL) item->min_size = SvIV(*sv);
87                         sv = hv_fetch(hv, "max_size", 8, 0);
88                         if (sv != NULL) item->max_size = SvIV(*sv);
89                 }
90         }
91
92         PUTBACK;
93         FREETMPS;
94         LEAVE;
95 }
96
97
98 static void sig_perl_statusbar(SBAR_ITEM_REC *item, int get_size_only)
99 {
100         char *function;
101
102         function = g_hash_table_lookup(perl_sbar_defs, item->config->name);
103         if (function != NULL)
104                 perl_statusbar_event(function, item, get_size_only);
105         else {
106                 /* use default function - this shouldn't actually happen.. */
107                 statusbar_item_default_handler(item, get_size_only, NULL, "", TRUE);
108         }
109 }
110
111 MODULE = Irssi::TextUI::Statusbar  PACKAGE = Irssi
112 PROTOTYPES: ENABLE
113
114 void
115 statusbar_item_register(name, value, func = NULL)
116         char *name
117         char *value
118         char *func
119 CODE:
120         statusbar_item_register(name, value, func == NULL || *func == '\0' ? NULL : sig_perl_statusbar);
121         if (func != NULL) {
122                 g_hash_table_insert(perl_sbar_defs, g_strdup(name),
123                                     g_strdup_printf("%s::%s", perl_get_package(), func));
124         }
125
126 void
127 statusbar_item_unregister(name)
128         char *name
129 PREINIT:
130         gpointer key, value;
131 CODE:
132         if (g_hash_table_lookup_extended(perl_sbar_defs, name, &key, &value)) {
133                 g_hash_table_remove(perl_sbar_defs, name);
134                 g_free(key);
135                 g_free(value);
136         }
137         statusbar_item_unregister(name);
138
139 void
140 statusbar_items_redraw(name)
141         char *name
142
143 void
144 statusbars_recreate_items()
145
146 #*******************************
147 MODULE = Irssi::TextUI::Statusbar  PACKAGE = Irssi::TextUI::StatusbarItem  PREFIX = statusbar_item_
148 #*******************************
149
150 void
151 statusbar_item_default_handler(item, get_size_only, str, data, escape_vars = TRUE)
152         Irssi::TextUI::StatusbarItem item
153         int get_size_only
154         char *str
155         char *data
156         int escape_vars
157 PREINIT:
158         HV *hv;
159 CODE:
160         statusbar_item_default_handler(item, get_size_only,
161                                        *str == '\0' ? NULL : str,
162                                        data, escape_vars);
163         hv = hvref(ST(0));
164         hv_store(hv, "min_size", 8, newSViv(item->min_size), 0);
165         hv_store(hv, "max_size", 8, newSViv(item->max_size), 0);