source: perlglue.xs @ eb897c6

release-1.10release-1.8release-1.9
Last change on this file since eb897c6 was bcde7926, checked in by David Benjamin <davidben@mit.edu>, 13 years ago
Reimplement BarnOwl::add_io_dispatch with AnyEvent We can emulate the interesting semantics with perl. The one difference is that perl code can now register an IO dispatch on file descriptors C code was interested in. This isn't a big deal was Glib can handle multiple watches on the same FD. Granted, more than one reader on an FD would cause trouble, but there was nothing stopping perl code from reading from an FD we cared about anyway. AnyEvent also does not support select's exceptfd, so this is a slight behavior change, but probably an uninteresting one.
  • Property mode set to 100644
File size: 10.7 KB
RevLine 
[dd16bdd]1/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8 -*- */
[8a54409]2#ifdef HAVE_LIBZEPHYR
[f1e629d]3#include <zephyr/zephyr.h>
[8a54409]4#endif
[f1e629d]5#include <EXTERN.h>
[8ee73f8d]6
[1152d45]7#define OWL_PERL
8#include "owl.h"
[8ee73f8d]9
[db8b00b]10#define SV_IS_CODEREF(sv) (SvROK((sv)) && SvTYPE(SvRV((sv))) == SVt_PVCV)
11
[39e81f7]12typedef char utf8;
13
[74fc22a]14        /*************************************************************
15         * NOTE
16         *************************************************************
17         * These functions, when they are intended to be user-visible,
[fd8dfe7]18         * are documented in perl/lib/BarnOwl.pm. If you add functions
19         * to this file, add the appropriate documentation there!
[74fc22a]20         *
21         * If the function is simple enough, we simply define its
22         * entire functionality here in XS. If, however, it needs
23         * complex argument processing or something, we define a
24         * simple version here that takes arguments in as flat a
[25cccdc]25         * manner as possible, to simplify the XS code, put it in
[952f137]26         * BarnOwl::Internal::, and write a perl wrapper in BarnOwl.pm
[25cccdc]27         * that munges the arguments as appropriate and calls the
28         * internal version.
[74fc22a]29         */
[8ee73f8d]30
[65fea01]31MODULE = BarnOwl                PACKAGE = BarnOwl
32
[39e81f7]33const utf8 *
[c4ba74d]34command(cmd, ...)
[e19eb97]35        const char *cmd
[8ee73f8d]36        PREINIT:
37                char *rv = NULL;
[e19eb97]38                const char **argv;
[c4ba74d]39                int i;
[8ee73f8d]40        CODE:
[c4ba74d]41        {
42                if (items == 1) {
43                        rv = owl_function_command(cmd);
44                } else {
[6a71113]45                        /* Ensure this is NULL-terminated. */
46                        argv = g_new0(const char *, items + 1);
[c4ba74d]47                        argv[0] = cmd;
48                        for(i = 1; i < items; i++) {
49                                argv[i] = SvPV_nolen(ST(i));
50                        }
51                        rv = owl_function_command_argv(argv, items);
[ddbbcffa]52                        g_free(argv);
[c4ba74d]53                }
54                RETVAL = rv;
55        }
[8ee73f8d]56        OUTPUT:
57                RETVAL
58        CLEANUP:
[3b8a563]59                g_free(rv);
[8ee73f8d]60
[f1e629d]61SV *
62getcurmsg()
63        CODE:
[19bab8e]64                RETVAL = owl_perlconfig_curmessage2hashref();
65        OUTPUT:
66                RETVAL
[f1e629d]67
68int
69getnumcols()
70        CODE:
71                RETVAL = owl_global_get_cols(&g);
72        OUTPUT:
73                RETVAL
[7f792c1]74               
75time_t
76getidletime()
77        CODE:
78                RETVAL = owl_global_get_idletime(&g);
79        OUTPUT:
80                RETVAL
[f1e629d]81
[39e81f7]82const utf8 *
[f1e629d]83zephyr_getrealm()
84        CODE:
[8a54409]85                RETVAL = owl_zephyr_get_realm();
[f1e629d]86        OUTPUT:
87                RETVAL
88
[39e81f7]89const utf8 *
[f1e629d]90zephyr_getsender()
91        CODE:
[8a54409]92                RETVAL = owl_zephyr_get_sender();
[f1e629d]93        OUTPUT:
94                RETVAL
95
[e1c4636]96void
[f1e629d]97zephyr_zwrite(cmd,msg)
[e19eb97]98        const char *cmd
99        const char *msg
[e1c4636]100        PREINIT:
101                int i;
102        CODE:
103                i = owl_zwrite_create_and_send_from_line(cmd, msg);
104
[39e81f7]105const utf8 *
[e1c4636]106ztext_stylestrip(ztext)
[e19eb97]107        const char *ztext
[e1c4636]108        PREINIT:
109                char *rv = NULL;
110        CODE:
[1fd0b25]111                rv = owl_function_ztext_stylestrip(ztext);
[e1c4636]112                RETVAL = rv;
113        OUTPUT:
114                RETVAL
115        CLEANUP:
[3b8a563]116                g_free(rv);
[e1c4636]117
[39e81f7]118const utf8 *
[740d5f7]119zephyr_smartstrip_user(in)
[e19eb97]120        const char *in
[740d5f7]121        PREINIT:
122                char *rv = NULL;
123        CODE:
124        {
125                rv = owl_zephyr_smartstripped_user(in);
126                RETVAL = rv;
127        }
128        OUTPUT:
129                RETVAL
130        CLEANUP:
[ddbbcffa]131                g_free(rv);
[740d5f7]132
[39e81f7]133const utf8 *
[acb13bb]134zephyr_getsubs()
135        PREINIT:
136                char *rv = NULL;
137        CODE:
138                rv = owl_zephyr_getsubs();
139                RETVAL = rv;
140    OUTPUT:
141                RETVAL
142    CLEANUP:
[3b8a563]143                g_free(rv);
[acb13bb]144
[5791bf7]145void
146queue_message(msg)
[dd16bdd]147        SV *msg
148        PREINIT:
149                owl_message *m;
150        CODE:
[1b6b2f3]151        {
[dd16bdd]152                if(!SvROK(msg) || SvTYPE(SvRV(msg)) != SVt_PVHV) {
[3066d23]153                        croak("Usage: BarnOwl::queue_message($message)");
[dd16bdd]154                }
[17eed9c]155
[30678ae]156                m = owl_perlconfig_hashref2message(msg);
[dd16bdd]157
158                owl_global_messagequeue_addmsg(&g, m);
[1b6b2f3]159        }
[db8b00b]160
[5791bf7]161void
162admin_message(header, body)
[e19eb97]163        const char *header
164        const char *body
[1c2e0b3]165        CODE:
166        {
167                owl_function_adminmsg(header, body);           
168        }
169
[5791bf7]170void
171start_question(line, callback)
[e19eb97]172        const char *line
[db8b00b]173        SV *callback
174        PREINIT:
[9186c75]175                owl_editwin *e;
[db8b00b]176        CODE:
177        {
178                if(!SV_IS_CODEREF(callback))
179                        croak("Callback must be a subref");
180
[9186c75]181                e = owl_function_start_question(line);
[db8b00b]182
[9186c75]183                owl_editwin_set_cbdata(e,
[1b1cd2c]184                                       newSVsv(callback),
185                                       owl_perlconfig_dec_refcnt);
[9186c75]186                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
[db8b00b]187        }
188
[5791bf7]189void
190start_password(line, callback)
[e19eb97]191        const char *line
[db8b00b]192        SV *callback
193        PREINIT:
[9186c75]194                owl_editwin *e;
[db8b00b]195        CODE:
196        {
197                if(!SV_IS_CODEREF(callback))
198                        croak("Callback must be a subref");
199
[9186c75]200                e = owl_function_start_password(line);
[db8b00b]201
[9186c75]202                owl_editwin_set_cbdata(e,
[1b1cd2c]203                                       newSVsv(callback),
204                                       owl_perlconfig_dec_refcnt);
[9186c75]205                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
[db8b00b]206        }
207
[5791bf7]208void
209start_edit_win(line, callback)
[e19eb97]210        const char *line
[db8b00b]211        SV *callback
212        CODE:
213        {
214                if(!SV_IS_CODEREF(callback))
215                        croak("Callback must be a subref");
216
[1b1cd2c]217                owl_function_start_edit_win(line,
218                                            owl_perlconfig_edit_callback,
219                                            newSVsv(callback),
220                                            owl_perlconfig_dec_refcnt);
[db8b00b]221        }
[6b3f797]222
223
[e19eb97]224const char * 
[6b3f797]225get_data_dir ()
226        CODE:
[ba6c8bd]227                RETVAL = owl_get_datadir();
[6b3f797]228        OUTPUT:
229        RETVAL
[b6a253c]230
[e19eb97]231const char * 
[b363d83]232get_config_dir ()
233        CODE:
[ba6c8bd]234                RETVAL = owl_global_get_confdir(&g);
[b363d83]235        OUTPUT:
236        RETVAL 
237
[b6a253c]238void
239popless_text(text) 
[e19eb97]240        const char *text
[b6a253c]241        CODE:
242        {
243                owl_function_popless_text(text);
244        }
245
246void
247popless_ztext(text) 
[e19eb97]248        const char *text
[b6a253c]249        CODE:
250        {
251                owl_fmtext fm;
252                owl_fmtext_init_null(&fm);
253                owl_fmtext_append_ztext(&fm, text);
254                owl_function_popless_fmtext(&fm);
[7ab0020]255                owl_fmtext_cleanup(&fm);
[b6a253c]256        }
[0ff2528]257
258void
259error(text) 
[e19eb97]260        const char *text
[0ff2528]261        CODE:
262        {
263                owl_function_error("%s", text);
264        }
[b6c067a]265
266void
[eede1bf]267debug(text)
[e19eb97]268        const char *text
[eede1bf]269        CODE:
270        {
271                owl_function_debugmsg("%s", text);
272        }
273
274void
[747d6a5]275message(text)
[e19eb97]276        const char *text
[747d6a5]277        CODE:
278        {
279                owl_function_makemsg("%s", text);
280        }
281
282void
[b67ab6b]283create_style(name, object)
[e19eb97]284     const char *name
[864ed35]285     SV  *object
[b6c067a]286     PREINIT:
287                owl_style *s;
288     CODE:
289        {
[96828e4]290                s = g_new(owl_style, 1);
[fde6d80]291                owl_style_create_perl(s, name, newSVsv(object));
[b6c067a]292                owl_global_add_style(&g, s);
293        }
[c2c5c77]294
295int
296getnumcolors()
297        CODE:
298                RETVAL = owl_function_get_color_count();
299        OUTPUT:
300                RETVAL
301
302void
303_remove_filter(filterName)
[e19eb97]304        const char *filterName
[c2c5c77]305        CODE:
306        {
307                /* Don't delete the current view, or the 'all' filter */
308                if (strcmp(filterName, owl_view_get_filtname(owl_global_get_current_view(&g)))
309                    && strcmp(filterName, "all")) {
310                        owl_global_remove_filter(&g,filterName);
311                }
312        }
[f6b319c]313
[39e81f7]314const utf8 *
[f6b319c]315wordwrap(in, cols)
[e19eb97]316        const char *in
[f6b319c]317        int cols
318        PREINIT:
319                char *rv = NULL;
320        CODE:
[a695a68]321                rv = owl_text_wordwrap(in, cols);
[f6b319c]322                RETVAL = rv;   
323        OUTPUT:
324                RETVAL
325        CLEANUP:
[3b8a563]326                g_free(rv);
[a695a68]327
[d77e909]328AV*
329all_filters()
330        PREINIT:
[129e609]331                owl_list fl;
[d77e909]332        CODE:
333        {
[129e609]334                owl_list_create(&fl);
335                owl_dict_get_keys(&g.filters, &fl);
336                RETVAL = owl_new_av(&fl, (SV*(*)(const void*))owl_new_sv);
[d77e909]337                sv_2mortal((SV*)RETVAL);
[ddbbcffa]338                owl_list_cleanup(&fl, g_free);
[d77e909]339        }
340        OUTPUT:
341                RETVAL
342
[3ff3d86]343AV*
344all_styles()
345        PREINIT:
346                owl_list l;
347        CODE:
348        {
349                owl_list_create(&l);
350                owl_global_get_style_names(&g, &l);
[e3cbd65]351                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
[3ff3d86]352                sv_2mortal((SV*)RETVAL);
353        }
354        OUTPUT:
355                RETVAL
356        CLEANUP:
[ddbbcffa]357                owl_list_cleanup(&l, g_free);
[3ff3d86]358
359
360AV*
361all_variables()
362        PREINIT:
363                owl_list l;
364        CODE:
365        {
366                owl_list_create(&l);
367                owl_dict_get_keys(owl_global_get_vardict(&g), &l);
[e3cbd65]368                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
[fe7616e]369                sv_2mortal((SV*)RETVAL);
370        }
371        OUTPUT:
372                RETVAL
373        CLEANUP:
[ddbbcffa]374                owl_list_cleanup(&l, g_free);
[fe7616e]375
376
377AV*
378all_keymaps()
379        PREINIT:
380                owl_list l;
381                const owl_keyhandler *kh;
382        CODE:
383        {
384                kh = owl_global_get_keyhandler(&g);
[f25df21]385                owl_list_create(&l);
[fe7616e]386                owl_keyhandler_get_keymap_names(kh, &l);
387                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
[3ff3d86]388                sv_2mortal((SV*)RETVAL);
389        }
390        OUTPUT:
391                RETVAL
392        CLEANUP:
[ddbbcffa]393                owl_list_cleanup(&l, g_free);
[3ff3d86]394
[4df918b]395void
396redisplay()
397        CODE:
398        {
399                owl_messagelist_invalidate_formats(owl_global_get_msglist(&g));
400                owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS);
401                owl_mainwin_redisplay(owl_global_get_mainwin(&g));
402        }
403
[fbadb37]404const char *
[bb79a52]405get_zephyr_variable(name)
[9cb03bf]406        const char *name;
[bb79a52]407        CODE:
[fbadb37]408                RETVAL = owl_zephyr_get_variable(name);
[bb79a52]409        OUTPUT:
410                RETVAL
411
[39e81f7]412const utf8 *
[9e5b5fd]413skiptokens(str, n)
414        const char *str;
415        int n;
416        CODE:
417                RETVAL = skiptokens(str, n);
418        OUTPUT:
419                RETVAL
420
421
[6f0fbe9]422MODULE = BarnOwl                PACKAGE = BarnOwl::Zephyr
423
424int
425have_zephyr()
426        CODE:
427                RETVAL = owl_global_is_havezephyr(&g);
428        OUTPUT:
429                RETVAL
[9e5b5fd]430
[25cccdc]431MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
432
433
434void
435new_command(name, func, summary, usage, description)
436        char *name
437        SV *func
438        char *summary
439        char *usage
440        char *description
441        PREINIT:
442                owl_cmd cmd;
443        CODE:
444        {
445                if(!SV_IS_CODEREF(func)) {
446                        croak("Command function must be a coderef!");
447                }
448                cmd.name = name;
[2fec14b]449                cmd.cmd_perl = newSVsv(func);
[25cccdc]450                cmd.summary = summary;
451                cmd.usage = usage;
452                cmd.description = description;
453                cmd.validctx = OWL_CTX_ANY;
454                cmd.cmd_aliased_to = NULL;
455                cmd.cmd_args_fn = NULL;
456                cmd.cmd_v_fn = NULL;
457                cmd.cmd_i_fn = NULL;
458                cmd.cmd_ctxargs_fn = NULL;
459                cmd.cmd_ctxv_fn = NULL;
460                cmd.cmd_ctxi_fn = NULL;
461                owl_cmddict_add_cmd(owl_global_get_cmddict(&g), &cmd);
462           }
463
464void
465new_variable_string(name, ival, summ, desc)
[e19eb97]466        const char * name
467        const char * ival
468        const char * summ
469        const char * desc
[a695a68]470        CODE:
471        owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
472                                        name,
473                                        summ,
474                                        desc,
475                                        ival);
476
477void
[25cccdc]478new_variable_int(name, ival, summ, desc)
[e19eb97]479        const char * name
[a695a68]480        int ival
[e19eb97]481        const char * summ
482        const char * desc
[a695a68]483        CODE:
484        owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
485                                     name,
486                                     summ,
487                                     desc,
488                                     ival);
489
490void
[25cccdc]491new_variable_bool(name, ival, summ, desc)
[e19eb97]492        const char * name
[a695a68]493        int ival
[e19eb97]494        const char * summ
495        const char * desc
[a695a68]496        CODE:
497        owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
498                                      name,
499                                      summ,
500                                      desc,
501                                      ival);
[1631825]502
[0190c4d]503MODULE = BarnOwl                PACKAGE = BarnOwl::Editwin
504
[77f605d]505int
506replace(count, string)
507        int count;
[e19eb97]508        const char *string;
[38cc669]509        PREINIT:
510                owl_editwin *e;
[77f605d]511        CODE:
[818f19c]512                e = owl_global_current_typwin(&g);
[38cc669]513                if (e) {
514                        RETVAL = owl_editwin_replace(e, count, string);
515                } else {
516                        RETVAL = 0;
517                }
[77f605d]518        OUTPUT:
519                RETVAL
520
521int
522point_move(delta)
523        int delta;
[38cc669]524        PREINIT:
525                owl_editwin *e;
[77f605d]526        CODE:
[818f19c]527                e = owl_global_current_typwin(&g);
[38cc669]528                if (e) {
529                        RETVAL = owl_editwin_point_move(e, delta);
530                } else {
531                        RETVAL = 0;
532                }
[77f605d]533        OUTPUT:
534                RETVAL
[a88f35a]535
536int
537replace_region(string)
[e19eb97]538        const char *string;
[38cc669]539        PREINIT:
540                owl_editwin *e;
[a88f35a]541        CODE:
[818f19c]542                e = owl_global_current_typwin(&g);
[38cc669]543                if (e) {
544                        RETVAL = owl_editwin_replace_region(e, string);
545                } else {
546                        RETVAL = 0;
547                }
[a88f35a]548        OUTPUT:
549                RETVAL
550
[39e81f7]551const utf8 *
[d41294a]552get_region()
553        PREINIT:
554                char *region;
[38cc669]555                owl_editwin *e;
[d41294a]556        CODE:
[818f19c]557                e = owl_global_current_typwin(&g);
[38cc669]558                if (e) {
[818f19c]559                        region = owl_editwin_get_region(owl_global_current_typwin(&g));
[38cc669]560                } else {
561                        region = NULL;
562                }
[d41294a]563                RETVAL = region;
564        OUTPUT:
565                RETVAL
566        CLEANUP:
[ddbbcffa]567                g_free(region);
[d41294a]568
[a88f35a]569SV *
570save_excursion(sub)
571        SV *sub;
572        PROTOTYPE: &
573        PREINIT:
574                int count;
[38cc669]575                owl_editwin *e;
[a88f35a]576                owl_editwin_excursion *x;
577        CODE:
578        {
[818f19c]579                e = owl_global_current_typwin(&g);
[38cc669]580                if(!e)
581                        croak("The edit window is not currently active!");
582
[818f19c]583                x = owl_editwin_begin_excursion(owl_global_current_typwin(&g));
[6dc2d6b]584                PUSHMARK(SP);
[a88f35a]585                count = call_sv(sub, G_SCALAR|G_EVAL|G_NOARGS);
[6dc2d6b]586                SPAGAIN;
[818f19c]587                owl_editwin_end_excursion(owl_global_current_typwin(&g), x);
[a88f35a]588
589                if(SvTRUE(ERRSV)) {
590                        croak(NULL);
591                }
592
593                if(count == 1)
594                        RETVAL = SvREFCNT_inc(POPs);
595                else
596                        XSRETURN_UNDEF;
597
598        }
599        OUTPUT:
600                RETVAL
[d41294a]601
602int
603current_column()
[38cc669]604        PREINIT:
605                owl_editwin *e;
[d41294a]606        CODE:
[818f19c]607                e = owl_global_current_typwin(&g);
[38cc669]608                if (e) {
609                        RETVAL = owl_editwin_current_column(e);
610                } else {
611                        RETVAL = 0;
612                }
[d41294a]613        OUTPUT:
614                RETVAL
615
616int
617point()
[38cc669]618        PREINIT:
619                owl_editwin *e;
[d41294a]620        CODE:
[818f19c]621                e = owl_global_current_typwin(&g);
[38cc669]622                if (e) {
623                        RETVAL = owl_editwin_get_point(e);
624                } else {
625                        RETVAL = 0;
626                }
[d41294a]627        OUTPUT:
628                RETVAL
629
630int
631mark()
[38cc669]632        PREINIT:
633                owl_editwin *e;
[d41294a]634        CODE:
[818f19c]635                e = owl_global_current_typwin(&g);
[38cc669]636                if (e) {
637                        RETVAL = owl_editwin_get_mark(e);
638                } else {
639                        RETVAL = 0;
640                }
[d41294a]641        OUTPUT:
642                RETVAL
Note: See TracBrowser for help on using the repository browser.