source: perlglue.xs @ 7ed9bc6

release-1.8release-1.9
Last change on this file since 7ed9bc6 was bcde7926, checked in by David Benjamin <davidben@mit.edu>, 10 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
Line 
1/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2#ifdef HAVE_LIBZEPHYR
3#include <zephyr/zephyr.h>
4#endif
5#include <EXTERN.h>
6
7#define OWL_PERL
8#include "owl.h"
9
10#define SV_IS_CODEREF(sv) (SvROK((sv)) && SvTYPE(SvRV((sv))) == SVt_PVCV)
11
12typedef char utf8;
13
14        /*************************************************************
15         * NOTE
16         *************************************************************
17         * These functions, when they are intended to be user-visible,
18         * are documented in perl/lib/BarnOwl.pm. If you add functions
19         * to this file, add the appropriate documentation there!
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
25         * manner as possible, to simplify the XS code, put it in
26         * BarnOwl::Internal::, and write a perl wrapper in BarnOwl.pm
27         * that munges the arguments as appropriate and calls the
28         * internal version.
29         */
30
31MODULE = BarnOwl                PACKAGE = BarnOwl
32
33const utf8 *
34command(cmd, ...)
35        const char *cmd
36        PREINIT:
37                char *rv = NULL;
38                const char **argv;
39                int i;
40        CODE:
41        {
42                if (items == 1) {
43                        rv = owl_function_command(cmd);
44                } else {
45                        /* Ensure this is NULL-terminated. */
46                        argv = g_new0(const char *, items + 1);
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);
52                        g_free(argv);
53                }
54                RETVAL = rv;
55        }
56        OUTPUT:
57                RETVAL
58        CLEANUP:
59                g_free(rv);
60
61SV *
62getcurmsg()
63        CODE:
64                RETVAL = owl_perlconfig_curmessage2hashref();
65        OUTPUT:
66                RETVAL
67
68int
69getnumcols()
70        CODE:
71                RETVAL = owl_global_get_cols(&g);
72        OUTPUT:
73                RETVAL
74               
75time_t
76getidletime()
77        CODE:
78                RETVAL = owl_global_get_idletime(&g);
79        OUTPUT:
80                RETVAL
81
82const utf8 *
83zephyr_getrealm()
84        CODE:
85                RETVAL = owl_zephyr_get_realm();
86        OUTPUT:
87                RETVAL
88
89const utf8 *
90zephyr_getsender()
91        CODE:
92                RETVAL = owl_zephyr_get_sender();
93        OUTPUT:
94                RETVAL
95
96void
97zephyr_zwrite(cmd,msg)
98        const char *cmd
99        const char *msg
100        PREINIT:
101                int i;
102        CODE:
103                i = owl_zwrite_create_and_send_from_line(cmd, msg);
104
105const utf8 *
106ztext_stylestrip(ztext)
107        const char *ztext
108        PREINIT:
109                char *rv = NULL;
110        CODE:
111                rv = owl_function_ztext_stylestrip(ztext);
112                RETVAL = rv;
113        OUTPUT:
114                RETVAL
115        CLEANUP:
116                g_free(rv);
117
118const utf8 *
119zephyr_smartstrip_user(in)
120        const char *in
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:
131                g_free(rv);
132
133const utf8 *
134zephyr_getsubs()
135        PREINIT:
136                char *rv = NULL;
137        CODE:
138                rv = owl_zephyr_getsubs();
139                RETVAL = rv;
140    OUTPUT:
141                RETVAL
142    CLEANUP:
143                g_free(rv);
144
145void
146queue_message(msg)
147        SV *msg
148        PREINIT:
149                owl_message *m;
150        CODE:
151        {
152                if(!SvROK(msg) || SvTYPE(SvRV(msg)) != SVt_PVHV) {
153                        croak("Usage: BarnOwl::queue_message($message)");
154                }
155
156                m = owl_perlconfig_hashref2message(msg);
157
158                owl_global_messagequeue_addmsg(&g, m);
159        }
160
161void
162admin_message(header, body)
163        const char *header
164        const char *body
165        CODE:
166        {
167                owl_function_adminmsg(header, body);           
168        }
169
170void
171start_question(line, callback)
172        const char *line
173        SV *callback
174        PREINIT:
175                owl_editwin *e;
176        CODE:
177        {
178                if(!SV_IS_CODEREF(callback))
179                        croak("Callback must be a subref");
180
181                e = owl_function_start_question(line);
182
183                owl_editwin_set_cbdata(e,
184                                       newSVsv(callback),
185                                       owl_perlconfig_dec_refcnt);
186                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
187        }
188
189void
190start_password(line, callback)
191        const char *line
192        SV *callback
193        PREINIT:
194                owl_editwin *e;
195        CODE:
196        {
197                if(!SV_IS_CODEREF(callback))
198                        croak("Callback must be a subref");
199
200                e = owl_function_start_password(line);
201
202                owl_editwin_set_cbdata(e,
203                                       newSVsv(callback),
204                                       owl_perlconfig_dec_refcnt);
205                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
206        }
207
208void
209start_edit_win(line, callback)
210        const char *line
211        SV *callback
212        CODE:
213        {
214                if(!SV_IS_CODEREF(callback))
215                        croak("Callback must be a subref");
216
217                owl_function_start_edit_win(line,
218                                            owl_perlconfig_edit_callback,
219                                            newSVsv(callback),
220                                            owl_perlconfig_dec_refcnt);
221        }
222
223
224const char * 
225get_data_dir ()
226        CODE:
227                RETVAL = owl_get_datadir();
228        OUTPUT:
229        RETVAL
230
231const char * 
232get_config_dir ()
233        CODE:
234                RETVAL = owl_global_get_confdir(&g);
235        OUTPUT:
236        RETVAL 
237
238void
239popless_text(text) 
240        const char *text
241        CODE:
242        {
243                owl_function_popless_text(text);
244        }
245
246void
247popless_ztext(text) 
248        const char *text
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);
255                owl_fmtext_cleanup(&fm);
256        }
257
258void
259error(text) 
260        const char *text
261        CODE:
262        {
263                owl_function_error("%s", text);
264        }
265
266void
267debug(text)
268        const char *text
269        CODE:
270        {
271                owl_function_debugmsg("%s", text);
272        }
273
274void
275message(text)
276        const char *text
277        CODE:
278        {
279                owl_function_makemsg("%s", text);
280        }
281
282void
283create_style(name, object)
284     const char *name
285     SV  *object
286     PREINIT:
287                owl_style *s;
288     CODE:
289        {
290                s = g_new(owl_style, 1);
291                owl_style_create_perl(s, name, newSVsv(object));
292                owl_global_add_style(&g, s);
293        }
294
295int
296getnumcolors()
297        CODE:
298                RETVAL = owl_function_get_color_count();
299        OUTPUT:
300                RETVAL
301
302void
303_remove_filter(filterName)
304        const char *filterName
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        }
313
314const utf8 *
315wordwrap(in, cols)
316        const char *in
317        int cols
318        PREINIT:
319                char *rv = NULL;
320        CODE:
321                rv = owl_text_wordwrap(in, cols);
322                RETVAL = rv;   
323        OUTPUT:
324                RETVAL
325        CLEANUP:
326                g_free(rv);
327
328AV*
329all_filters()
330        PREINIT:
331                owl_list fl;
332        CODE:
333        {
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);
337                sv_2mortal((SV*)RETVAL);
338                owl_list_cleanup(&fl, g_free);
339        }
340        OUTPUT:
341                RETVAL
342
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);
351                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
352                sv_2mortal((SV*)RETVAL);
353        }
354        OUTPUT:
355                RETVAL
356        CLEANUP:
357                owl_list_cleanup(&l, g_free);
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);
368                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
369                sv_2mortal((SV*)RETVAL);
370        }
371        OUTPUT:
372                RETVAL
373        CLEANUP:
374                owl_list_cleanup(&l, g_free);
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);
385                owl_list_create(&l);
386                owl_keyhandler_get_keymap_names(kh, &l);
387                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
388                sv_2mortal((SV*)RETVAL);
389        }
390        OUTPUT:
391                RETVAL
392        CLEANUP:
393                owl_list_cleanup(&l, g_free);
394
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
404const char *
405get_zephyr_variable(name)
406        const char *name;
407        CODE:
408                RETVAL = owl_zephyr_get_variable(name);
409        OUTPUT:
410                RETVAL
411
412const utf8 *
413skiptokens(str, n)
414        const char *str;
415        int n;
416        CODE:
417                RETVAL = skiptokens(str, n);
418        OUTPUT:
419                RETVAL
420
421
422MODULE = BarnOwl                PACKAGE = BarnOwl::Zephyr
423
424int
425have_zephyr()
426        CODE:
427                RETVAL = owl_global_is_havezephyr(&g);
428        OUTPUT:
429                RETVAL
430
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;
449                cmd.cmd_perl = newSVsv(func);
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)
466        const char * name
467        const char * ival
468        const char * summ
469        const char * desc
470        CODE:
471        owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
472                                        name,
473                                        summ,
474                                        desc,
475                                        ival);
476
477void
478new_variable_int(name, ival, summ, desc)
479        const char * name
480        int ival
481        const char * summ
482        const char * desc
483        CODE:
484        owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
485                                     name,
486                                     summ,
487                                     desc,
488                                     ival);
489
490void
491new_variable_bool(name, ival, summ, desc)
492        const char * name
493        int ival
494        const char * summ
495        const char * desc
496        CODE:
497        owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
498                                      name,
499                                      summ,
500                                      desc,
501                                      ival);
502
503MODULE = BarnOwl                PACKAGE = BarnOwl::Editwin
504
505int
506replace(count, string)
507        int count;
508        const char *string;
509        PREINIT:
510                owl_editwin *e;
511        CODE:
512                e = owl_global_current_typwin(&g);
513                if (e) {
514                        RETVAL = owl_editwin_replace(e, count, string);
515                } else {
516                        RETVAL = 0;
517                }
518        OUTPUT:
519                RETVAL
520
521int
522point_move(delta)
523        int delta;
524        PREINIT:
525                owl_editwin *e;
526        CODE:
527                e = owl_global_current_typwin(&g);
528                if (e) {
529                        RETVAL = owl_editwin_point_move(e, delta);
530                } else {
531                        RETVAL = 0;
532                }
533        OUTPUT:
534                RETVAL
535
536int
537replace_region(string)
538        const char *string;
539        PREINIT:
540                owl_editwin *e;
541        CODE:
542                e = owl_global_current_typwin(&g);
543                if (e) {
544                        RETVAL = owl_editwin_replace_region(e, string);
545                } else {
546                        RETVAL = 0;
547                }
548        OUTPUT:
549                RETVAL
550
551const utf8 *
552get_region()
553        PREINIT:
554                char *region;
555                owl_editwin *e;
556        CODE:
557                e = owl_global_current_typwin(&g);
558                if (e) {
559                        region = owl_editwin_get_region(owl_global_current_typwin(&g));
560                } else {
561                        region = NULL;
562                }
563                RETVAL = region;
564        OUTPUT:
565                RETVAL
566        CLEANUP:
567                g_free(region);
568
569SV *
570save_excursion(sub)
571        SV *sub;
572        PROTOTYPE: &
573        PREINIT:
574                int count;
575                owl_editwin *e;
576                owl_editwin_excursion *x;
577        CODE:
578        {
579                e = owl_global_current_typwin(&g);
580                if(!e)
581                        croak("The edit window is not currently active!");
582
583                x = owl_editwin_begin_excursion(owl_global_current_typwin(&g));
584                PUSHMARK(SP);
585                count = call_sv(sub, G_SCALAR|G_EVAL|G_NOARGS);
586                SPAGAIN;
587                owl_editwin_end_excursion(owl_global_current_typwin(&g), x);
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
601
602int
603current_column()
604        PREINIT:
605                owl_editwin *e;
606        CODE:
607                e = owl_global_current_typwin(&g);
608                if (e) {
609                        RETVAL = owl_editwin_current_column(e);
610                } else {
611                        RETVAL = 0;
612                }
613        OUTPUT:
614                RETVAL
615
616int
617point()
618        PREINIT:
619                owl_editwin *e;
620        CODE:
621                e = owl_global_current_typwin(&g);
622                if (e) {
623                        RETVAL = owl_editwin_get_point(e);
624                } else {
625                        RETVAL = 0;
626                }
627        OUTPUT:
628                RETVAL
629
630int
631mark()
632        PREINIT:
633                owl_editwin *e;
634        CODE:
635                e = owl_global_current_typwin(&g);
636                if (e) {
637                        RETVAL = owl_editwin_get_mark(e);
638                } else {
639                        RETVAL = 0;
640                }
641        OUTPUT:
642                RETVAL
Note: See TracBrowser for help on using the repository browser.