New silcconfig library and server parser. Merged silc-newconfig-final.patch.
[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         g_free(key);
35         g_free(value);
36 }
37
38 void perl_statusbar_deinit(void)
39 {
40         signal_remove("script destroyed", (SIGNAL_FUNC) script_unregister_statusbars);
41
42         g_hash_table_foreach(perl_sbar_defs,
43                              (GHFunc) statusbar_item_def_destroy, NULL);
44         g_hash_table_destroy(perl_sbar_defs);
45 }
46
47 static void perl_statusbar_event(char *function, SBAR_ITEM_REC *item,
48                                  int get_size_only)
49 {
50         dSP;
51         int retcount;
52         SV *item_sv, **sv;
53         HV *hv;
54
55         ENTER;
56         SAVETMPS;
57
58         PUSHMARK(SP);
59         item_sv = plain_bless(item, "Irssi::TextUI::StatusbarItem");
60         XPUSHs(sv_2mortal(item_sv));
61         XPUSHs(sv_2mortal(newSViv(get_size_only)));
62         PUTBACK;
63
64         retcount = perl_call_pv(function, G_EVAL|G_DISCARD);
65         SPAGAIN;
66
67         if (SvTRUE(ERRSV)) {
68                 PERL_SCRIPT_REC *script;
69                 char *package;
70
71                 package = perl_function_get_package(function);
72                 script = perl_script_find_package(package);
73                 g_free(package);
74
75                 if (script != NULL) {
76                         /* make sure we don't get back here */
77                         script_unregister_statusbars(script);
78                 }
79                 signal_emit("script error", 2, script, SvPV(ERRSV, PL_na));
80         } else {
81                 /* min_size and max_size can be changed, move them to SBAR_ITEM_REC */
82                 hv = hvref(item_sv);
83                 if (hv != NULL) {
84                         sv = hv_fetch(hv, "min_size", 8, 0);
85                         if (sv != NULL) item->min_size = SvIV(*sv);
86                         sv = hv_fetch(hv, "max_size", 8, 0);
87                         if (sv != NULL) item->max_size = SvIV(*sv);
88                 }
89         }
90
91         PUTBACK;
92         FREETMPS;
93         LEAVE;
94 }
95
96
97 static void sig_perl_statusbar(SBAR_ITEM_REC *item, int get_size_only)
98 {
99         char *function;
100
101         function = g_hash_table_lookup(perl_sbar_defs, item->config->name);
102         if (function != NULL)
103                 perl_statusbar_event(function, item, get_size_only);
104         else {
105                 /* use default function - this shouldn't actually happen.. */
106                 statusbar_item_default_handler(item, get_size_only, NULL, "", TRUE);
107         }
108 }
109
110 MODULE = Irssi::TextUI::Statusbar  PACKAGE = Irssi
111 PROTOTYPES: ENABLE
112
113 void
114 statusbar_item_register(name, value, func = NULL)
115         char *name
116         char *value
117         char *func
118 CODE:
119         statusbar_item_register(name, value, func == NULL || *func == '\0' ? NULL : sig_perl_statusbar);
120         if (func != NULL) {
121                 g_hash_table_insert(perl_sbar_defs, g_strdup(name),
122                                     g_strdup_printf("%s::%s", perl_get_package(), func));
123         }
124
125 void
126 statusbar_item_unregister(name)
127         char *name
128 PREINIT:
129         gpointer key, value;
130 CODE:
131         if (g_hash_table_lookup_extended(perl_sbar_defs, name, &key, &value)) {
132                 g_hash_table_remove(perl_sbar_defs, name);
133                 g_free(key);
134                 g_free(value);
135         }
136         statusbar_item_unregister(name);
137
138 void
139 statusbar_items_redraw(name)
140         char *name
141
142 void
143 statusbars_recreate_items()
144
145 #*******************************
146 MODULE = Irssi::TextUI::Statusbar  PACKAGE = Irssi::TextUI::StatusbarItem  PREFIX = statusbar_item_
147 #*******************************
148
149 void
150 statusbar_item_default_handler(item, get_size_only, str, data, escape_vars = TRUE)
151         Irssi::TextUI::StatusbarItem item
152         int get_size_only
153         char *str
154         char *data
155         int escape_vars
156 PREINIT:
157         HV *hv;
158 CODE:
159         statusbar_item_default_handler(item, get_size_only,
160                                        *str == '\0' ? NULL : str,
161                                        data, escape_vars);
162         hv = hvref(ST(0));
163         hv_store(hv, "min_size", 8, newSViv(item->min_size), 0);
164         hv_store(hv, "max_size", 8, newSViv(item->max_size), 0);