Added SILC Thread Queue API
[runtime.git] / apps / irssi / src / perl / common / Core.xs
1 #include "module.h"
2 #include "irssi-version.h"
3 #include "core.h"
4
5 #include "pidwait.h"
6 #include "session.h"
7
8 #define DEFAULT_COMMAND_CATEGORY "Perl scripts' commands"
9
10 void perl_signal_add_hash(int priority, SV *sv)
11 {
12         HV *hv;
13         HE *he;
14         I32 len;
15
16         if (!is_hvref(sv))
17                 croak("Usage: Irssi::signal_add(hash)");
18
19         hv = hvref(sv);
20         hv_iterinit(hv);
21         while ((he = hv_iternext(hv)) != NULL)
22                 perl_signal_add_full(hv_iterkey(he, &len), HeVAL(he), priority);
23 }
24
25 static void perl_command_bind_add_hash(int priority, SV *sv, char *category)
26 {
27         HV *hv;
28         HE *he;
29         I32 len;
30
31         hv = hvref(sv);
32         hv_iterinit(hv);
33         while ((he = hv_iternext(hv)) != NULL)
34                 perl_command_bind_to(hv_iterkey(he, &len), category, HeVAL(he), priority);
35 }
36
37 static void handle_command_bind(int priority, int items, SV *p0, SV *p1, SV *p2)
38 {
39         char *category;
40         int hash;
41
42         hash = items > 0 && is_hvref(p0);
43         if (!hash) {
44                 if (items < 2 || items > 3)
45                         croak("Usage: Irssi::command_bind(signal, func, category)");
46         } else if (items > 2)
47                 croak("Usage: Irssi::command_bind(signals_hash, category)");
48
49         if (!hash) {
50                 category = items < 3 ? DEFAULT_COMMAND_CATEGORY :
51                         (char *)SvPV(p2, PL_na);
52                 perl_command_bind_to((char *)SvPV(p0, PL_na), category, p1, priority);
53         } else {
54                 category = items < 2 ? DEFAULT_COMMAND_CATEGORY :
55                         (char *)SvPV(p1, PL_na);
56                 perl_command_bind_add_hash(priority, p0, category);
57         }
58 }
59
60 MODULE = Irssi::Core  PACKAGE = Irssi
61 PROTOTYPES: ENABLE
62
63 void
64 signal_emit(signal, ...)
65         char *signal
66 CODE:
67         void *p[SIGNAL_MAX_ARGUMENTS];
68         int n;
69
70         memset(p, 0, sizeof(p));
71         for (n = 1; n < items && n < SIGNAL_MAX_ARGUMENTS+1; n++) {
72                 if (SvPOKp(ST(n)))
73                         p[n-1] = SvPV(ST(n), PL_na);
74                 else if (irssi_is_ref_object(ST(n)))
75                         p[n-1] = irssi_ref_object(ST(n));
76                 else if (SvROK(ST(n)))
77                         p[n-1] = (void *) SvIV((SV*)SvRV(ST(n)));
78                 else if (SvIOK(ST(n)))
79                         p[n-1] = (void *)SvIV(ST(n));
80                 else
81                         p[n-1] = NULL;
82         }
83         signal_emit(signal, items-1, p[0], p[1], p[2], p[3], p[4], p[5]);
84
85 void
86 signal_continue(...)
87 CODE:
88         void *p[SIGNAL_MAX_ARGUMENTS];
89         int n;
90
91         memset(p, 0, sizeof(p));
92         for (n = 0; n < items && n < SIGNAL_MAX_ARGUMENTS; n++) {
93                 if (SvPOKp(ST(n)))
94                         p[n] = SvPV(ST(n), PL_na);
95                 else if (irssi_is_ref_object(ST(n)))
96                         p[n] = irssi_ref_object(ST(n));
97                 else if (SvROK(ST(n)))
98                         p[n] = (void *) SvIV((SV*)SvRV(ST(n)));
99                 else if (SvIOK(ST(n)))
100                         p[n] = (void *) SvIV(ST(n));
101                 else
102                         p[n] = NULL;
103         }
104         signal_continue(items, p[0], p[1], p[2], p[3], p[4], p[5]);
105
106 void
107 signal_add(...)
108 CODE:
109         if (items != 1 && items != 2)
110                 croak("Usage: Irssi::signal_add(signal, func)");
111         if (items == 2)
112                 perl_signal_add_full((char *)SvPV(ST(0),PL_na), ST(1),
113                                      SIGNAL_PRIORITY_DEFAULT);
114         else
115                 perl_signal_add_hash(SIGNAL_PRIORITY_DEFAULT, ST(0));
116
117 void
118 signal_add_first(...)
119 CODE:
120         if (items != 1 && items != 2)
121                 croak("Usage: Irssi::signal_add_first(signal, func)");
122         if (items == 2)
123                 perl_signal_add_full((char *)SvPV(ST(0),PL_na), ST(1),
124                                      SIGNAL_PRIORITY_HIGH);
125         else
126                 perl_signal_add_hash(SIGNAL_PRIORITY_HIGH, ST(0));
127
128 void
129 signal_add_last(...)
130 CODE:
131         if (items != 1 && items != 2)
132                 croak("Usage: Irssi::signal_add_last(signal, func)");
133         if (items == 2)
134                 perl_signal_add_full((char *)SvPV(ST(0),PL_na), ST(1),
135                                      SIGNAL_PRIORITY_LOW);
136         else
137                 perl_signal_add_hash(SIGNAL_PRIORITY_LOW, ST(0));
138
139 void
140 signal_add_priority(...)
141 CODE:
142         if (items != 2 && items != 3)
143                 croak("Usage: Irssi::signal_add_priority(signal, func, priority)");
144         if (items == 3)
145                 perl_signal_add_full((char *)SvPV(ST(0),PL_na), ST(1), SvIV(ST(2)));
146         else
147                 perl_signal_add_hash(SvIV(ST(0)), ST(1));
148
149 void
150 signal_register(...)
151 PREINIT:
152         HV *hv;
153         HE *he;
154         I32 len, pos;
155         const char *arr[7];
156 CODE:
157         if (items != 1 || !is_hvref(ST(0)))
158                 croak("Usage: Irssi::signal_register(hash)");
159
160         hv = hvref(ST(0));
161         hv_iterinit(hv);
162         while ((he = hv_iternext(hv)) != NULL) {
163                 const char *key = hv_iterkey(he, &len);
164                 SV *val = HeVAL(he);
165                 AV *av;
166
167                 if (!SvROK(val) || SvTYPE(SvRV(val)) != SVt_PVAV)
168                         croak("not array reference");
169
170                 av = (AV *) SvRV(val);
171                 len = av_len(av)+1;
172                 if (len > 6) len = 6;
173                 for (pos = 0; pos < len; pos++) {
174                         SV **val = av_fetch(av, pos, 0);
175                         arr[pos] = SvPV(*val, PL_na);
176                 }
177                 arr[pos] = NULL;
178                 perl_signal_register(key, arr);
179         }
180
181
182 int
183 SIGNAL_PRIORITY_LOW()
184 CODE:
185         RETVAL = SIGNAL_PRIORITY_LOW;
186 OUTPUT:
187         RETVAL
188
189 int
190 SIGNAL_PRIORITY_DEFAULT()
191 CODE:
192         RETVAL = SIGNAL_PRIORITY_DEFAULT;
193 OUTPUT:
194         RETVAL
195
196 int
197 SIGNAL_PRIORITY_HIGH()
198 CODE:
199         RETVAL = SIGNAL_PRIORITY_HIGH;
200 OUTPUT:
201         RETVAL
202
203 void
204 signal_remove(signal, func)
205         char *signal
206         SV *func
207 CODE:
208         perl_signal_remove(signal, func);
209
210 void
211 signal_stop()
212
213 void
214 signal_stop_by_name(signal)
215         char *signal
216
217 char *
218 signal_get_emitted()
219 CODE:
220         RETVAL = (char *) signal_get_emitted();
221 OUTPUT:
222         RETVAL
223
224 int
225 signal_get_emitted_id()
226
227 int
228 timeout_add(msecs, func, data)
229         int msecs
230         SV *func
231         SV *data
232 CODE:
233         if (msecs < 10) {
234                 croak("Irssi::timeout() : msecs must be >= 10");
235                 RETVAL = -1;
236         } else {
237                 RETVAL = perl_timeout_add(msecs, func, data, FALSE);
238         }
239 OUTPUT:
240         RETVAL
241
242 int
243 timeout_add_once(msecs, func, data)
244         int msecs
245         SV *func
246         SV *data
247 CODE:
248         if (msecs < 10) {
249                 croak("Irssi::timeout_once() : msecs must be >= 10");
250                 RETVAL = -1;
251         } else {
252                 RETVAL = perl_timeout_add(msecs, func, data, TRUE);
253         }
254 OUTPUT:
255         RETVAL
256
257 void
258 timeout_remove(tag)
259         int tag
260 CODE:
261         perl_source_remove(tag);
262
263
264 int
265 INPUT_READ()
266 CODE:
267         RETVAL = G_INPUT_READ;
268 OUTPUT:
269         RETVAL
270
271 int
272 INPUT_WRITE()
273 CODE:
274         RETVAL = G_INPUT_WRITE;
275 OUTPUT:
276         RETVAL
277
278 int
279 input_add(source, condition, func, data)
280         int source
281         int condition
282         SV *func
283         SV *data
284 CODE:
285         RETVAL = perl_input_add(source, condition, func, data, FALSE);
286 OUTPUT:
287         RETVAL
288
289 void
290 input_remove(tag)
291         int tag
292 CODE:
293         perl_source_remove(tag);
294
295 # maybe there's some easier way than this..? :)
296 int
297 MSGLEVEL_CRAP()
298 CODE:
299         RETVAL = MSGLEVEL_CRAP;
300 OUTPUT:
301         RETVAL
302
303 int
304 MSGLEVEL_MSGS()
305 CODE:
306         RETVAL = MSGLEVEL_MSGS;
307 OUTPUT:
308         RETVAL
309
310 int
311 MSGLEVEL_PUBLIC()
312 CODE:
313         RETVAL = MSGLEVEL_PUBLIC;
314 OUTPUT:
315         RETVAL
316
317 int
318 MSGLEVEL_NOTICES()
319 CODE:
320         RETVAL = MSGLEVEL_NOTICES;
321 OUTPUT:
322         RETVAL
323
324 int
325 MSGLEVEL_SNOTES()
326 CODE:
327         RETVAL = MSGLEVEL_SNOTES;
328 OUTPUT:
329         RETVAL
330
331 int
332 MSGLEVEL_CTCPS()
333 CODE:
334         RETVAL = MSGLEVEL_CTCPS;
335 OUTPUT:
336         RETVAL
337
338 int
339 MSGLEVEL_ACTIONS()
340 CODE:
341         RETVAL = MSGLEVEL_ACTIONS;
342 OUTPUT:
343         RETVAL
344
345 int
346 MSGLEVEL_JOINS()
347 CODE:
348         RETVAL = MSGLEVEL_JOINS;
349 OUTPUT:
350         RETVAL
351
352 int
353 MSGLEVEL_PARTS()
354 CODE:
355         RETVAL = MSGLEVEL_PARTS;
356 OUTPUT:
357         RETVAL
358
359 int
360 MSGLEVEL_QUITS()
361 CODE:
362         RETVAL = MSGLEVEL_QUITS;
363 OUTPUT:
364         RETVAL
365
366 int
367 MSGLEVEL_KICKS()
368 CODE:
369         RETVAL = MSGLEVEL_KICKS;
370 OUTPUT:
371         RETVAL
372
373 int
374 MSGLEVEL_MODES()
375 CODE:
376         RETVAL = MSGLEVEL_MODES;
377 OUTPUT:
378         RETVAL
379
380 int
381 MSGLEVEL_TOPICS()
382 CODE:
383         RETVAL = MSGLEVEL_TOPICS;
384 OUTPUT:
385         RETVAL
386
387 int
388 MSGLEVEL_WALLOPS()
389 CODE:
390         RETVAL = MSGLEVEL_WALLOPS;
391 OUTPUT:
392         RETVAL
393
394 int
395 MSGLEVEL_INVITES()
396 CODE:
397         RETVAL = MSGLEVEL_INVITES;
398 OUTPUT:
399         RETVAL
400
401 int
402 MSGLEVEL_NICKS()
403 CODE:
404         RETVAL = MSGLEVEL_NICKS;
405 OUTPUT:
406         RETVAL
407
408 int
409 MSGLEVEL_DCC()
410 CODE:
411         RETVAL = MSGLEVEL_DCC;
412 OUTPUT:
413         RETVAL
414
415 int
416 MSGLEVEL_DCCMSGS()
417 CODE:
418         RETVAL = MSGLEVEL_DCCMSGS;
419 OUTPUT:
420         RETVAL
421
422 int
423 MSGLEVEL_CLIENTNOTICE()
424 CODE:
425         RETVAL = MSGLEVEL_CLIENTNOTICE;
426 OUTPUT:
427         RETVAL
428
429 int
430 MSGLEVEL_CLIENTCRAP()
431 CODE:
432         RETVAL = MSGLEVEL_CLIENTCRAP;
433 OUTPUT:
434         RETVAL
435
436 int
437 MSGLEVEL_CLIENTERROR()
438 CODE:
439         RETVAL = MSGLEVEL_CLIENTERROR;
440 OUTPUT:
441         RETVAL
442
443 int
444 MSGLEVEL_HILIGHT()
445 CODE:
446         RETVAL = MSGLEVEL_HILIGHT;
447 OUTPUT:
448         RETVAL
449
450 int
451 MSGLEVEL_ALL()
452 CODE:
453         RETVAL = MSGLEVEL_ALL;
454 OUTPUT:
455         RETVAL
456
457 int
458 MSGLEVEL_NOHILIGHT()
459 CODE:
460         RETVAL = MSGLEVEL_NOHILIGHT;
461 OUTPUT:
462         RETVAL
463
464 int
465 MSGLEVEL_NO_ACT()
466 CODE:
467         RETVAL = MSGLEVEL_NO_ACT;
468 OUTPUT:
469         RETVAL
470
471 int
472 MSGLEVEL_NEVER()
473 CODE:
474         RETVAL = MSGLEVEL_NEVER;
475 OUTPUT:
476         RETVAL
477
478 int
479 MSGLEVEL_LASTLOG()
480 CODE:
481         RETVAL = MSGLEVEL_LASTLOG;
482 OUTPUT:
483         RETVAL
484
485 int
486 level2bits(str)
487         char *str
488
489 void
490 bits2level(bits)
491         int bits
492 PREINIT:
493         char *ret;
494 PPCODE:
495         ret = bits2level(bits);
496         XPUSHs(sv_2mortal(new_pv(ret)));
497         g_free(ret);
498
499 int
500 combine_level(level, str)
501         int level
502         char *str
503
504 void
505 command(cmd)
506         char *cmd
507 CODE:
508         perl_command(cmd, NULL, NULL);
509
510 void
511 commands()
512 PREINIT:
513         GSList *tmp;
514 PPCODE:
515         for (tmp = commands; tmp != NULL; tmp = tmp->next) {
516                 XPUSHs(sv_2mortal(plain_bless(tmp->data, "Irssi::Command")));
517         }
518
519 void
520 command_bind_first(...)
521 CODE:
522         handle_command_bind(SIGNAL_PRIORITY_HIGH, items, ST(0), ST(1), ST(2));
523
524 void
525 command_bind(...)
526 CODE:
527         handle_command_bind(SIGNAL_PRIORITY_DEFAULT, items, ST(0), ST(1), ST(2));
528
529 void
530 command_bind_last(...)
531 CODE:
532         handle_command_bind(SIGNAL_PRIORITY_LOW, items, ST(0), ST(1), ST(2));
533
534 void
535 command_runsub(cmd, data, server, item)
536         char *cmd
537         char *data
538         Irssi::Server server
539         Irssi::Windowitem item
540 CODE:
541         perl_command_runsub(cmd, data, server, item);
542
543 void
544 command_unbind(cmd, func)
545         char *cmd
546         SV *func
547 CODE:
548         perl_command_unbind(cmd, func);
549
550 void
551 command_set_options(cmd, options)
552         char *cmd
553         char *options
554
555 void
556 pidwait_add(pid)
557         int pid
558
559 void 
560 pidwait_remove(pid)
561         int pid
562
563 void
564 parse_special(cmd, data="", flags=0)
565         char *cmd
566         char *data
567         int flags
568 PREINIT:
569         char *ret;
570 PPCODE:
571         ret = parse_special_string(cmd, NULL, NULL, data, NULL, flags);
572         XPUSHs(sv_2mortal(new_pv(ret)));
573         g_free_not_null(ret);
574
575 char *
576 get_irssi_dir()
577 CODE:
578         RETVAL = (char *) get_irssi_dir();
579 OUTPUT:
580         RETVAL
581
582 char *
583 get_irssi_config()
584 CODE:
585         RETVAL = (char *) get_irssi_config();
586 OUTPUT:
587         RETVAL
588
589 char *
590 get_irssi_binary()
591 CODE:
592         RETVAL = irssi_binary;
593 OUTPUT:
594         RETVAL
595
596 char *
597 version()
598 PREINIT:
599         char version[100];
600 CODE:
601         g_snprintf(version, sizeof(version), "%d.%04d",
602                    IRSSI_VERSION_DATE, IRSSI_VERSION_TIME);
603         RETVAL = version;
604 OUTPUT:
605         RETVAL
606
607 int
608 get_gui()
609 CODE:
610         RETVAL = irssi_gui;
611 OUTPUT:
612         RETVAL
613
614 int
615 IRSSI_GUI_NONE()
616 CODE:
617         RETVAL = IRSSI_GUI_NONE;
618 OUTPUT:
619         RETVAL
620
621 int
622 IRSSI_GUI_TEXT()
623 CODE:
624         RETVAL = IRSSI_GUI_TEXT;
625 OUTPUT:
626         RETVAL
627
628 int
629 IRSSI_GUI_GTK()
630 CODE:
631         RETVAL = IRSSI_GUI_GTK;
632 OUTPUT:
633         RETVAL
634
635 int
636 IRSSI_GUI_GNOME()
637 CODE:
638         RETVAL = IRSSI_GUI_GNOME;
639 OUTPUT:
640         RETVAL
641
642 int
643 IRSSI_GUI_QT()
644 CODE:
645         RETVAL = IRSSI_GUI_QT;
646 OUTPUT:
647         RETVAL
648
649 int
650 IRSSI_GUI_KDE()
651 CODE:
652         RETVAL = IRSSI_GUI_KDE;
653 OUTPUT:
654         RETVAL
655
656 #*******************************
657 MODULE = Irssi::Core    PACKAGE = Irssi::Server
658 #*******************************
659
660 void
661 parse_special(server, cmd, data="", flags=0)
662         Irssi::Server server
663         char *cmd
664         char *data
665         int flags
666 PREINIT:
667         char *ret;
668 PPCODE:
669         ret = parse_special_string(cmd, server, NULL, data, NULL, flags);
670         XPUSHs(sv_2mortal(new_pv(ret)));
671         g_free_not_null(ret);
672
673 void
674 command(server, cmd)
675         Irssi::Server server
676         char *cmd
677 CODE:
678         perl_command(cmd, server, NULL);
679
680
681 #*******************************
682 MODULE = Irssi::Core    PACKAGE = Irssi::Windowitem
683 #*******************************
684
685 void
686 parse_special(item, cmd, data="", flags=0)
687         Irssi::Windowitem item
688         char *cmd
689         char *data
690         int flags
691 PREINIT:
692         char *ret;
693 PPCODE:
694         ret = parse_special_string(cmd, item->server, item, data, NULL, flags);
695         XPUSHs(sv_2mortal(new_pv(ret)));
696         g_free_not_null(ret);
697
698 void
699 command(item, cmd)
700         Irssi::Windowitem item
701         char *cmd
702 CODE:
703         perl_command(cmd, item->server, item);
704