comparison plugins/perl/perl-handlers.c @ 6549:ed796f756237

[gaim-migrate @ 7071] Added the C framework for perl signal handlers. Untested, not implemented in perl, and may crash. Should be fun! committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Thu, 21 Aug 2003 08:38:32 +0000
parents 2e2593d95121
children 28b38803d0bb
comparison
equal deleted inserted replaced
6548:d01ba50e3f3e 6549:ed796f756237
1 #include "perl-common.h" 1 #include "perl-common.h"
2 #include "perl-handlers.h" 2 #include "perl-handlers.h"
3 3
4 #include "debug.h" 4 #include "debug.h"
5 #include "signals.h"
5 6
6 static GList *timeout_handlers = NULL; 7 static GList *timeout_handlers = NULL;
8 static GList *signal_handlers = NULL;
7 9
8 extern PerlInterpreter *my_perl; 10 extern PerlInterpreter *my_perl;
9 11
10 static void 12 static void
11 destroy_timeout_handler(GaimPerlTimeoutHandler *handler) 13 destroy_timeout_handler(GaimPerlTimeoutHandler *handler)
14 16
15 g_free(handler->name); 17 g_free(handler->name);
16 g_free(handler); 18 g_free(handler);
17 } 19 }
18 20
21 static void
22 destroy_signal_handler(GaimPerlSignalHandler *handler)
23 {
24 signal_handlers = g_list_remove(signal_handlers, handler);
25
26 g_free(handler->signal);
27 g_free(handler->func);
28 g_free(handler);
29 }
30
19 static int 31 static int
20 perl_timeout_cb(gpointer data) 32 perl_timeout_cb(gpointer data)
21 { 33 {
22 void *atmp[2] = { NULL, NULL };
23 GaimPerlTimeoutHandler *handler = (GaimPerlTimeoutHandler *)data; 34 GaimPerlTimeoutHandler *handler = (GaimPerlTimeoutHandler *)data;
24 35
25 dSP; 36 dSP;
26 ENTER; 37 ENTER;
27 SAVETMPS; 38 SAVETMPS;
29 XPUSHs((SV *)handler->args); 40 XPUSHs((SV *)handler->args);
30 PUTBACK; 41 PUTBACK;
31 call_pv(handler->name, G_EVAL | G_SCALAR); 42 call_pv(handler->name, G_EVAL | G_SCALAR);
32 SPAGAIN; 43 SPAGAIN;
33 44
34 atmp[0] = handler->args;
35
36 PUTBACK; 45 PUTBACK;
37 FREETMPS; 46 FREETMPS;
38 LEAVE; 47 LEAVE;
39 48
40 destroy_timeout_handler(handler); 49 destroy_timeout_handler(handler);
41 50
42 return 0; 51 return 0;
43 } 52 }
44 53
54 static void *
55 perl_signal_cb(va_list args, void *data)
56 {
57 GaimPerlSignalHandler *handler = (GaimPerlSignalHandler *)data;
58 void *arg;
59 void *ret_val = NULL;
60 int count;
61
62 dSP;
63 ENTER;
64 SAVETMPS;
65 PUSHMARK(sp);
66
67 while ((arg = va_arg(args, void *)) != NULL)
68 XPUSHs((SV *)arg);
69
70 XPUSHs((SV *)handler->data);
71
72 PUTBACK;
73 count = call_pv(handler->func, G_EVAL | G_SCALAR);
74 SPAGAIN;
75
76 if (count > 1)
77 ret_val = POPp;
78
79 PUTBACK;
80 FREETMPS;
81 LEAVE;
82
83 return ret_val;
84 }
85
86 static GaimPerlSignalHandler *
87 find_signal_handler(GaimPlugin *plugin, void *instance,
88 const char *signal, const char *func)
89 {
90 GaimPerlSignalHandler *handler;
91 GList *l;
92
93 for (l = signal_handlers; l != NULL; l = l->next)
94 {
95 handler = (GaimPerlSignalHandler *)l->data;
96
97 if (handler->plugin == plugin &&
98 handler->instance == instance &&
99 !strcmp(handler->signal, signal) &&
100 !strcmp(handler->func, func))
101 {
102 return handler;
103 }
104 }
105
106 return NULL;
107 }
108
45 void 109 void
46 gaim_perl_timeout_add(GaimPlugin *plugin, int seconds, const char *func, 110 gaim_perl_timeout_add(GaimPlugin *plugin, int seconds, const char *func,
47 void *args) 111 void *args)
48 { 112 {
49 GaimPerlTimeoutHandler *handler; 113 GaimPerlTimeoutHandler *handler;
50 114
51 if (plugin == NULL) 115 if (plugin == NULL)
52 { 116 {
53 gaim_debug(GAIM_DEBUG_ERROR, "perl", 117 croak("Invalid handle in adding perl timeout handler.\n");
54 "Invalid handle in adding perl timeout handler.\n");
55 return; 118 return;
56 } 119 }
57 120
58 handler = g_new0(GaimPerlTimeoutHandler, 1); 121 handler = g_new0(GaimPerlTimeoutHandler, 1);
59 122
83 } 146 }
84 147
85 void 148 void
86 gaim_perl_timeout_clear(void) 149 gaim_perl_timeout_clear(void)
87 { 150 {
88 while (timeout_handlers) 151 while (timeout_handlers != NULL)
89 destroy_timeout_handler(timeout_handlers->data); 152 destroy_timeout_handler(timeout_handlers->data);
90 } 153 }
91 154
155 void
156 gaim_perl_signal_connect(GaimPlugin *plugin, void *instance,
157 const char *signal, const char *func, void *data)
158 {
159 GaimPerlSignalHandler *handler;
160
161 handler = g_new0(GaimPerlSignalHandler, 1);
162 handler->plugin = plugin;
163 handler->instance = instance;
164 handler->signal = g_strdup(signal);
165 handler->func = g_strdup(func);
166 handler->data = data;
167
168 signal_handlers = g_list_append(signal_handlers, handler);
169
170 gaim_signal_connect(instance, signal,
171 plugin, GAIM_CALLBACK(perl_signal_cb), handler);
172 }
173
174 void
175 gaim_perl_signal_disconnect(GaimPlugin *plugin, void *instance,
176 const char *signal, const char *func)
177 {
178 GaimPerlSignalHandler *handler;
179
180 handler = find_signal_handler(plugin, instance, signal, func);
181
182 if (handler == NULL)
183 {
184 croak("Invalid signal handler information in "
185 "disconnecting a perl signal handler.\n");
186 return;
187 }
188
189 destroy_signal_handler(handler);
190 }
191
192 void
193 gaim_perl_signal_clear_for_plugin(GaimPlugin *plugin)
194 {
195 GaimPerlSignalHandler *handler;
196 GList *l, *l_next;
197
198 for (l = signal_handlers; l != NULL; l = l_next)
199 {
200 l_next = l->next;
201
202 handler = (GaimPerlSignalHandler *)l->data;
203
204 if (handler->plugin == plugin)
205 destroy_signal_handler(handler);
206 }
207 }
208
209 void
210 gaim_perl_signal_clear(void)
211 {
212 while (signal_handlers != NULL)
213 destroy_signal_handler(signal_handlers->data);
214 }
215