Merge Irssi 0.8.16-rc1
[silc.git] / apps / irssi / src / perl / common / Core.xs
index 4db742c044e29ebc29c6ae573f482bab21505784..76ea00938c1537d4ff36636ebdc4a15698cfab88 100644 (file)
@@ -1,9 +1,13 @@
 #include "module.h"
 #include "irssi-version.h"
+#include "core.h"
+
+#include "pidwait.h"
+#include "session.h"
 
 #define DEFAULT_COMMAND_CATEGORY "Perl scripts' commands"
 
-void perl_signal_add_hash(int priority, SV *sv)
+static void perl_signal_add_hash(int priority, SV *sv)
 {
        HV *hv;
         HE *he;
@@ -15,7 +19,7 @@ void perl_signal_add_hash(int priority, SV *sv)
         hv = hvref(sv);
        hv_iterinit(hv);
        while ((he = hv_iternext(hv)) != NULL)
-                perl_signal_add_to(hv_iterkey(he, &len), HeVAL(he), priority);
+                perl_signal_add_full(hv_iterkey(he, &len), HeVAL(he), priority);
 }
 
 static void perl_command_bind_add_hash(int priority, SV *sv, char *category)
@@ -53,6 +57,23 @@ static void handle_command_bind(int priority, int items, SV *p0, SV *p1, SV *p2)
        }
 }
 
+static void add_tuple(gpointer key_, gpointer value_, gpointer user_data)
+{
+       HV *hash = user_data;
+       char *key = key_;
+       char *value = value_;
+       hv_store(hash, key, strlen(key), new_pv(value), 0);
+}
+
+static void wrap_signal_emit(void *signal, void **p) {
+       signal_emit(signal, 6, p[0], p[1], p[2], p[3], p[4], p[5]);
+}
+
+static void wrap_signal_continue(void *dummy, void **p) {
+       (void)dummy;
+       signal_continue(6, p[0], p[1], p[2], p[3], p[4], p[5]);
+}
+
 MODULE = Irssi::Core  PACKAGE = Irssi
 PROTOTYPES: ENABLE
 
@@ -60,21 +81,34 @@ void
 signal_emit(signal, ...)
        char *signal
 CODE:
-       void *p[SIGNAL_MAX_ARGUMENTS];
-       int n;
-
-       memset(p, 0, sizeof(p));
-       for (n = 1; n < items && n < SIGNAL_MAX_ARGUMENTS+1; n++) {
-               if (SvPOKp(ST(n)))
-                       p[n-1] = SvPV(ST(n), PL_na);
-               else if (irssi_is_ref_object(ST(n)))
-                       p[n-1] = irssi_ref_object(ST(n));
-               else if (SvROK(ST(n)))
-                       p[n-1] = (void *) SvIV((SV*)SvRV(ST(n)));
-               else
-                       p[n-1] = NULL;
+       int signal_id;
+       SV *args[SIGNAL_MAX_ARGUMENTS];
+       int n, used;
+
+       signal_id = signal_get_uniq_id(signal);
+       used = items - 1;
+       if (used > SIGNAL_MAX_ARGUMENTS) {
+               used = SIGNAL_MAX_ARGUMENTS;
+       }
+       for (n = 0; n < used; ++n) {
+               args[n] = ST(n + 1);
        }
-       signal_emit(signal, items-1, p[0], p[1], p[2], p[3], p[4], p[5]);
+       perl_signal_args_to_c(wrap_signal_emit, signal, signal_id, args, used);
+
+void
+signal_continue(...)
+CODE:
+       SV *args[SIGNAL_MAX_ARGUMENTS];
+       int n, used;
+
+       used = items;
+       if (used > SIGNAL_MAX_ARGUMENTS) {
+               used = SIGNAL_MAX_ARGUMENTS;
+       }
+       for (n = 0; n < used; ++n) {
+               args[n] = ST(n);
+       }
+       perl_signal_args_to_c(wrap_signal_continue, NULL, signal_get_emitted_id(), args, used);
 
 void
 signal_add(...)
@@ -82,9 +116,10 @@ CODE:
        if (items != 1 && items != 2)
                croak("Usage: Irssi::signal_add(signal, func)");
        if (items == 2)
-               perl_signal_add((char *)SvPV(ST(0),PL_na), ST(1));
+               perl_signal_add_full((char *)SvPV(ST(0),PL_na), ST(1),
+                                    SIGNAL_PRIORITY_DEFAULT);
        else
-               perl_signal_add_hash(1, ST(0));
+               perl_signal_add_hash(SIGNAL_PRIORITY_DEFAULT, ST(0));
 
 void
 signal_add_first(...)
@@ -92,9 +127,10 @@ CODE:
        if (items != 1 && items != 2)
                croak("Usage: Irssi::signal_add_first(signal, func)");
        if (items == 2)
-               perl_signal_add_first((char *)SvPV(ST(0),PL_na), ST(1));
+               perl_signal_add_full((char *)SvPV(ST(0),PL_na), ST(1),
+                                    SIGNAL_PRIORITY_HIGH);
        else
-               perl_signal_add_hash(0, ST(0));
+               perl_signal_add_hash(SIGNAL_PRIORITY_HIGH, ST(0));
 
 void
 signal_add_last(...)
@@ -102,9 +138,74 @@ CODE:
        if (items != 1 && items != 2)
                croak("Usage: Irssi::signal_add_last(signal, func)");
        if (items == 2)
-               perl_signal_add_last((char *)SvPV(ST(0),PL_na), ST(1));
+               perl_signal_add_full((char *)SvPV(ST(0),PL_na), ST(1),
+                                    SIGNAL_PRIORITY_LOW);
        else
-               perl_signal_add_hash(2, ST(0));
+               perl_signal_add_hash(SIGNAL_PRIORITY_LOW, ST(0));
+
+void
+signal_add_priority(...)
+CODE:
+       if (items != 2 && items != 3)
+               croak("Usage: Irssi::signal_add_priority(signal, func, priority)");
+       if (items == 3)
+               perl_signal_add_full((char *)SvPV(ST(0),PL_na), ST(1), SvIV(ST(2)));
+       else
+               perl_signal_add_hash(SvIV(ST(0)), ST(1));
+
+void
+signal_register(...)
+PREINIT:
+       HV *hv;
+        HE *he;
+       I32 len, pos;
+       const char *arr[7];
+CODE:
+       if (items != 1 || !is_hvref(ST(0)))
+               croak("Usage: Irssi::signal_register(hash)");
+
+        hv = hvref(ST(0));
+       hv_iterinit(hv);
+       while ((he = hv_iternext(hv)) != NULL) {
+               const char *key = hv_iterkey(he, &len);
+               SV *val = HeVAL(he);
+               AV *av;
+
+               if (!SvROK(val) || SvTYPE(SvRV(val)) != SVt_PVAV)
+                       croak("not array reference");
+
+               av = (AV *) SvRV(val);
+               len = av_len(av)+1;
+               if (len > 6) len = 6;
+               for (pos = 0; pos < len; pos++) {
+                       SV **val = av_fetch(av, pos, 0);
+                       arr[pos] = SvPV(*val, PL_na);
+               }
+               arr[pos] = NULL;
+               perl_signal_register(key, arr);
+       }
+
+
+int
+SIGNAL_PRIORITY_LOW()
+CODE:
+       RETVAL = SIGNAL_PRIORITY_LOW;
+OUTPUT:
+       RETVAL
+
+int
+SIGNAL_PRIORITY_DEFAULT()
+CODE:
+       RETVAL = SIGNAL_PRIORITY_DEFAULT;
+OUTPUT:
+       RETVAL
+
+int
+SIGNAL_PRIORITY_HIGH()
+CODE:
+       RETVAL = SIGNAL_PRIORITY_HIGH;
+OUTPUT:
+       RETVAL
 
 void
 signal_remove(signal, func)
@@ -136,7 +237,27 @@ timeout_add(msecs, func, data)
        SV *func
        SV *data
 CODE:
-       RETVAL = perl_timeout_add(msecs, func, data);
+       if (msecs < 10) {
+               croak("Irssi::timeout() : msecs must be >= 10");
+               RETVAL = -1;
+       } else {
+               RETVAL = perl_timeout_add(msecs, func, data, FALSE);
+       }
+OUTPUT:
+       RETVAL
+
+int
+timeout_add_once(msecs, func, data)
+       int msecs
+       SV *func
+       SV *data
+CODE:
+       if (msecs < 10) {
+               croak("Irssi::timeout_once() : msecs must be >= 10");
+               RETVAL = -1;
+       } else {
+               RETVAL = perl_timeout_add(msecs, func, data, TRUE);
+       }
 OUTPUT:
        RETVAL
 
@@ -168,7 +289,7 @@ input_add(source, condition, func, data)
        SV *func
        SV *data
 CODE:
-       RETVAL = perl_input_add(source, condition, func, data);
+       RETVAL = perl_input_add(source, condition, func, data, FALSE);
 OUTPUT:
        RETVAL
 
@@ -371,10 +492,20 @@ OUTPUT:
 int
 level2bits(str)
        char *str
+CODE:
+       RETVAL = level2bits(str, NULL);
+OUTPUT:
+       RETVAL
 
-char *
+void
 bits2level(bits)
        int bits
+PREINIT:
+       char *ret;
+PPCODE:
+       ret = bits2level(bits);
+       XPUSHs(sv_2mortal(new_pv(ret)));
+       g_free(ret);
 
 int
 combine_level(level, str)
@@ -399,17 +530,17 @@ PPCODE:
 void
 command_bind_first(...)
 CODE:
-       handle_command_bind(0, items, ST(0), ST(1), ST(2));
+       handle_command_bind(SIGNAL_PRIORITY_HIGH, items, ST(0), ST(1), ST(2));
 
 void
 command_bind(...)
 CODE:
-       handle_command_bind(1, items, ST(0), ST(1), ST(2));
+       handle_command_bind(SIGNAL_PRIORITY_DEFAULT, items, ST(0), ST(1), ST(2));
 
 void
 command_bind_last(...)
 CODE:
-       handle_command_bind(2, items, ST(0), ST(1), ST(2));
+       handle_command_bind(SIGNAL_PRIORITY_LOW, items, ST(0), ST(1), ST(2));
 
 void
 command_runsub(cmd, data, server, item)
@@ -432,6 +563,28 @@ command_set_options(cmd, options)
        char *cmd
        char *options
 
+void
+command_parse_options(cmd, data)
+       char *cmd
+       char *data
+PREINIT:
+       HV *hash;
+       GHashTable *optlist;
+       void *free_arg;
+       char *ptr;
+PPCODE:
+       if (cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST,
+                          cmd, &optlist, &ptr)) {
+               hash = newHV();
+               g_hash_table_foreach(optlist, add_tuple, hash);
+               XPUSHs(sv_2mortal(newRV_noinc((SV*)hash)));
+               XPUSHs(sv_2mortal(new_pv(ptr)));
+               cmd_params_free(free_arg);
+       } else {
+               XPUSHs(&PL_sv_undef);
+               XPUSHs(&PL_sv_undef);
+       }
+
 void
 pidwait_add(pid)
        int pid
@@ -440,7 +593,7 @@ void
 pidwait_remove(pid)
        int pid
 
-char *
+void
 parse_special(cmd, data="", flags=0)
        char *cmd
        char *data
@@ -466,6 +619,13 @@ CODE:
 OUTPUT:
        RETVAL
 
+char *
+get_irssi_binary()
+CODE:
+       RETVAL = irssi_binary;
+OUTPUT:
+       RETVAL
+
 char *
 version()
 PREINIT:
@@ -477,6 +637,55 @@ CODE:
 OUTPUT:
         RETVAL
 
+int
+get_gui()
+CODE:
+       RETVAL = irssi_gui;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_NONE()
+CODE:
+       RETVAL = IRSSI_GUI_NONE;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_TEXT()
+CODE:
+       RETVAL = IRSSI_GUI_TEXT;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_GTK()
+CODE:
+       RETVAL = IRSSI_GUI_GTK;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_GNOME()
+CODE:
+       RETVAL = IRSSI_GUI_GNOME;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_QT()
+CODE:
+       RETVAL = IRSSI_GUI_QT;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_KDE()
+CODE:
+       RETVAL = IRSSI_GUI_KDE;
+OUTPUT:
+       RETVAL
+
 #*******************************
 MODULE = Irssi::Core   PACKAGE = Irssi::Server
 #*******************************