source: perlglue.xs @ 6b4033f

release-1.8release-1.9
Last change on this file since 6b4033f was f25df21, checked in by David Benjamin <davidben@mit.edu>, 11 years ago
Don't call owl_list_create in owl_dict_get_keys Until we get rid of this owl_list thing altogether, there should be a convention as to who initializes the thing. Otherwise, we leak memory from people initializing it too many times. Whoever reviews this probably wants to look over this very carefully in case I missed one of the owl_list_creates. Also kill the various wrappers over owl_list_cleanup as they are not the inverse of any operation.
  • Property mode set to 100644
File size: 11.6 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                        argv = g_new(const char *, items + 1);
46                        argv[0] = cmd;
47                        for(i = 1; i < items; i++) {
48                                argv[i] = SvPV_nolen(ST(i));
49                        }
50                        rv = owl_function_command_argv(argv, items);
51                        g_free(argv);
52                }
53                RETVAL = rv;
54        }
55        OUTPUT:
56                RETVAL
57        CLEANUP:
58                if (rv) g_free(rv);
59
60SV *
61getcurmsg()
62        CODE:
63                RETVAL = owl_perlconfig_curmessage2hashref();
64        OUTPUT:
65                RETVAL
66
67int
68getnumcols()
69        CODE:
70                RETVAL = owl_global_get_cols(&g);
71        OUTPUT:
72                RETVAL
73               
74time_t
75getidletime()
76        CODE:
77                RETVAL = owl_global_get_idletime(&g);
78        OUTPUT:
79                RETVAL
80
81const utf8 *
82zephyr_getrealm()
83        CODE:
84                RETVAL = owl_zephyr_get_realm();
85        OUTPUT:
86                RETVAL
87
88const utf8 *
89zephyr_getsender()
90        CODE:
91                RETVAL = owl_zephyr_get_sender();
92        OUTPUT:
93                RETVAL
94
95void
96zephyr_zwrite(cmd,msg)
97        const char *cmd
98        const char *msg
99        PREINIT:
100                int i;
101        CODE:
102                i = owl_zwrite_create_and_send_from_line(cmd, msg);
103
104const utf8 *
105ztext_stylestrip(ztext)
106        const char *ztext
107        PREINIT:
108                char *rv = NULL;
109        CODE:
110                rv = owl_function_ztext_stylestrip(ztext);
111                RETVAL = rv;
112        OUTPUT:
113                RETVAL
114        CLEANUP:
115                if (rv) g_free(rv);
116
117const utf8 *
118zephyr_smartstrip_user(in)
119        const char *in
120        PREINIT:
121                char *rv = NULL;
122        CODE:
123        {
124                rv = owl_zephyr_smartstripped_user(in);
125                RETVAL = rv;
126        }
127        OUTPUT:
128                RETVAL
129        CLEANUP:
130                g_free(rv);
131
132const utf8 *
133zephyr_getsubs()
134        PREINIT:
135                char *rv = NULL;
136        CODE:
137                rv = owl_zephyr_getsubs();
138                RETVAL = rv;
139    OUTPUT:
140                RETVAL
141    CLEANUP:
142                if (rv) g_free(rv);
143
144void
145queue_message(msg)
146        SV *msg
147        PREINIT:
148                owl_message *m;
149        CODE:
150        {
151                if(!SvROK(msg) || SvTYPE(SvRV(msg)) != SVt_PVHV) {
152                        croak("Usage: BarnOwl::queue_message($message)");
153                }
154
155                m = owl_perlconfig_hashref2message(msg);
156
157                owl_global_messagequeue_addmsg(&g, m);
158        }
159
160void
161admin_message(header, body)
162        const char *header
163        const char *body
164        CODE:
165        {
166                owl_function_adminmsg(header, body);           
167        }
168
169void
170start_question(line, callback)
171        const char *line
172        SV *callback
173        PREINIT:
174                owl_editwin *e;
175        CODE:
176        {
177                if(!SV_IS_CODEREF(callback))
178                        croak("Callback must be a subref");
179
180                e = owl_function_start_question(line);
181
182                owl_editwin_set_cbdata(e,
183                                       newSVsv(callback),
184                                       owl_perlconfig_dec_refcnt);
185                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
186        }
187
188void
189start_password(line, callback)
190        const char *line
191        SV *callback
192        PREINIT:
193                owl_editwin *e;
194        CODE:
195        {
196                if(!SV_IS_CODEREF(callback))
197                        croak("Callback must be a subref");
198
199                e = owl_function_start_password(line);
200
201                owl_editwin_set_cbdata(e,
202                                       newSVsv(callback),
203                                       owl_perlconfig_dec_refcnt);
204                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
205        }
206
207void
208start_edit_win(line, callback)
209        const char *line
210        SV *callback
211        CODE:
212        {
213                if(!SV_IS_CODEREF(callback))
214                        croak("Callback must be a subref");
215
216                owl_function_start_edit_win(line,
217                                            owl_perlconfig_edit_callback,
218                                            newSVsv(callback),
219                                            owl_perlconfig_dec_refcnt);
220        }
221
222
223const char * 
224get_data_dir ()
225        CODE:
226                RETVAL = owl_get_datadir();
227        OUTPUT:
228        RETVAL
229
230const char * 
231get_config_dir ()
232        CODE:
233                RETVAL = owl_global_get_confdir(&g);
234        OUTPUT:
235        RETVAL 
236
237void
238popless_text(text) 
239        const char *text
240        CODE:
241        {
242                owl_function_popless_text(text);
243        }
244
245void
246popless_ztext(text) 
247        const char *text
248        CODE:
249        {
250                owl_fmtext fm;
251                owl_fmtext_init_null(&fm);
252                owl_fmtext_append_ztext(&fm, text);
253                owl_function_popless_fmtext(&fm);
254                owl_fmtext_cleanup(&fm);
255        }
256
257void
258error(text) 
259        const char *text
260        CODE:
261        {
262                owl_function_error("%s", text);
263        }
264
265void
266debug(text)
267        const char *text
268        CODE:
269        {
270                owl_function_debugmsg("%s", text);
271        }
272
273void
274message(text)
275        const char *text
276        CODE:
277        {
278                owl_function_makemsg("%s", text);
279        }
280
281void
282create_style(name, object)
283     const char *name
284     SV  *object
285     PREINIT:
286                owl_style *s;
287     CODE:
288        {
289                s = g_new(owl_style, 1);
290                owl_style_create_perl(s, name, newSVsv(object));
291                owl_global_add_style(&g, s);
292        }
293
294int
295getnumcolors()
296        CODE:
297                RETVAL = owl_function_get_color_count();
298        OUTPUT:
299                RETVAL
300
301void
302_remove_filter(filterName)
303        const char *filterName
304        CODE:
305        {
306                /* Don't delete the current view, or the 'all' filter */
307                if (strcmp(filterName, owl_view_get_filtname(owl_global_get_current_view(&g)))
308                    && strcmp(filterName, "all")) {
309                        owl_global_remove_filter(&g,filterName);
310                }
311        }
312
313const utf8 *
314wordwrap(in, cols)
315        const char *in
316        int cols
317        PREINIT:
318                char *rv = NULL;
319        CODE:
320                rv = owl_text_wordwrap(in, cols);
321                RETVAL = rv;   
322        OUTPUT:
323                RETVAL
324        CLEANUP:
325                if (rv)
326                        g_free(rv);
327
328void
329remove_io_dispatch(fd)
330        int fd
331        CODE:
332        owl_select_remove_perl_io_dispatch(fd);
333
334AV*
335all_filters()
336        PREINIT:
337                owl_list fl;
338        CODE:
339        {
340                owl_list_create(&fl);
341                owl_dict_get_keys(&g.filters, &fl);
342                RETVAL = owl_new_av(&fl, (SV*(*)(const void*))owl_new_sv);
343                sv_2mortal((SV*)RETVAL);
344                owl_list_cleanup(&fl, g_free);
345        }
346        OUTPUT:
347                RETVAL
348
349AV*
350all_styles()
351        PREINIT:
352                owl_list l;
353        CODE:
354        {
355                owl_list_create(&l);
356                owl_global_get_style_names(&g, &l);
357                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
358                sv_2mortal((SV*)RETVAL);
359        }
360        OUTPUT:
361                RETVAL
362        CLEANUP:
363                owl_list_cleanup(&l, g_free);
364
365
366AV*
367all_variables()
368        PREINIT:
369                owl_list l;
370        CODE:
371        {
372                owl_list_create(&l);
373                owl_dict_get_keys(owl_global_get_vardict(&g), &l);
374                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
375                sv_2mortal((SV*)RETVAL);
376        }
377        OUTPUT:
378                RETVAL
379        CLEANUP:
380                owl_list_cleanup(&l, g_free);
381
382
383AV*
384all_keymaps()
385        PREINIT:
386                owl_list l;
387                const owl_keyhandler *kh;
388        CODE:
389        {
390                kh = owl_global_get_keyhandler(&g);
391                owl_list_create(&l);
392                owl_keyhandler_get_keymap_names(kh, &l);
393                RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
394                sv_2mortal((SV*)RETVAL);
395        }
396        OUTPUT:
397                RETVAL
398        CLEANUP:
399                owl_list_cleanup(&l, g_free);
400
401void
402redisplay()
403        CODE:
404        {
405                owl_messagelist_invalidate_formats(owl_global_get_msglist(&g));
406                owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS);
407                owl_mainwin_redisplay(owl_global_get_mainwin(&g));
408        }
409
410const char *
411get_zephyr_variable(name)
412        const char *name;
413        CODE:
414                RETVAL = owl_zephyr_get_variable(name);
415        OUTPUT:
416                RETVAL
417
418const utf8 *
419skiptokens(str, n)
420        const char *str;
421        int n;
422        CODE:
423                RETVAL = skiptokens(str, n);
424        OUTPUT:
425                RETVAL
426
427
428MODULE = BarnOwl                PACKAGE = BarnOwl::Zephyr
429
430int
431have_zephyr()
432        CODE:
433                RETVAL = owl_global_is_havezephyr(&g);
434        OUTPUT:
435                RETVAL
436
437MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
438
439
440void
441new_command(name, func, summary, usage, description)
442        char *name
443        SV *func
444        char *summary
445        char *usage
446        char *description
447        PREINIT:
448                owl_cmd cmd;
449        CODE:
450        {
451                if(!SV_IS_CODEREF(func)) {
452                        croak("Command function must be a coderef!");
453                }
454                cmd.name = name;
455                cmd.cmd_perl = newSVsv(func);
456                cmd.summary = summary;
457                cmd.usage = usage;
458                cmd.description = description;
459                cmd.validctx = OWL_CTX_ANY;
460                cmd.cmd_aliased_to = NULL;
461                cmd.cmd_args_fn = NULL;
462                cmd.cmd_v_fn = NULL;
463                cmd.cmd_i_fn = NULL;
464                cmd.cmd_ctxargs_fn = NULL;
465                cmd.cmd_ctxv_fn = NULL;
466                cmd.cmd_ctxi_fn = NULL;
467                owl_cmddict_add_cmd(owl_global_get_cmddict(&g), &cmd);
468           }
469
470void
471new_variable_string(name, ival, summ, desc)
472        const char * name
473        const char * ival
474        const char * summ
475        const char * desc
476        CODE:
477        owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
478                                        name,
479                                        summ,
480                                        desc,
481                                        ival);
482
483void
484new_variable_int(name, ival, summ, desc)
485        const char * name
486        int ival
487        const char * summ
488        const char * desc
489        CODE:
490        owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
491                                     name,
492                                     summ,
493                                     desc,
494                                     ival);
495
496void
497new_variable_bool(name, ival, summ, desc)
498        const char * name
499        int ival
500        const char * summ
501        const char * desc
502        CODE:
503        owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
504                                      name,
505                                      summ,
506                                      desc,
507                                      ival);
508
509void
510add_io_dispatch(fd, mode, cb)
511        int fd
512        int mode
513        SV * cb
514        CODE:
515        owl_select_add_perl_io_dispatch(fd, mode, newSVsv(cb));
516
517IV
518add_timer(after, interval, cb, name = NULL)
519        int after
520        int interval
521        SV *cb
522        const char *name
523        PREINIT:
524                SV *ref;
525                owl_timer *t;
526        CODE:
527                ref = sv_rvweaken(newSVsv(cb));
528                t = owl_select_add_timer(name,
529                                         after,
530                                         interval,
531                                         owl_perlconfig_perl_timer,
532                                         owl_perlconfig_perl_timer_destroy,
533                                         ref);
534                owl_function_debugmsg("Created timer %s: %p", t->name ? t->name : "(unnamed)", t);
535        RETVAL = (IV)t;
536        OUTPUT:
537                RETVAL
538
539void
540remove_timer(timer)
541        IV timer
542        PREINIT:
543                owl_timer *t;
544        CODE:
545                t = (owl_timer*)timer;
546                owl_function_debugmsg("Freeing timer %s: %p", t->name ? t->name : "(unnamed)", t);
547                owl_select_remove_timer(t);
548
549MODULE = BarnOwl                PACKAGE = BarnOwl::Editwin
550
551int
552replace(count, string)
553        int count;
554        const char *string;
555        PREINIT:
556                owl_editwin *e;
557        CODE:
558                e = owl_global_current_typwin(&g);
559                if (e) {
560                        RETVAL = owl_editwin_replace(e, count, string);
561                } else {
562                        RETVAL = 0;
563                }
564        OUTPUT:
565                RETVAL
566
567int
568point_move(delta)
569        int delta;
570        PREINIT:
571                owl_editwin *e;
572        CODE:
573                e = owl_global_current_typwin(&g);
574                if (e) {
575                        RETVAL = owl_editwin_point_move(e, delta);
576                } else {
577                        RETVAL = 0;
578                }
579        OUTPUT:
580                RETVAL
581
582int
583replace_region(string)
584        const char *string;
585        PREINIT:
586                owl_editwin *e;
587        CODE:
588                e = owl_global_current_typwin(&g);
589                if (e) {
590                        RETVAL = owl_editwin_replace_region(e, string);
591                } else {
592                        RETVAL = 0;
593                }
594        OUTPUT:
595                RETVAL
596
597const utf8 *
598get_region()
599        PREINIT:
600                char *region;
601                owl_editwin *e;
602        CODE:
603                e = owl_global_current_typwin(&g);
604                if (e) {
605                        region = owl_editwin_get_region(owl_global_current_typwin(&g));
606                } else {
607                        region = NULL;
608                }
609                RETVAL = region;
610        OUTPUT:
611                RETVAL
612        CLEANUP:
613                g_free(region);
614
615SV *
616save_excursion(sub)
617        SV *sub;
618        PROTOTYPE: &
619        PREINIT:
620                int count;
621                owl_editwin *e;
622                owl_editwin_excursion *x;
623        CODE:
624        {
625                e = owl_global_current_typwin(&g);
626                if(!e)
627                        croak("The edit window is not currently active!");
628
629                x = owl_editwin_begin_excursion(owl_global_current_typwin(&g));
630                PUSHMARK(SP);
631                count = call_sv(sub, G_SCALAR|G_EVAL|G_NOARGS);
632                SPAGAIN;
633                owl_editwin_end_excursion(owl_global_current_typwin(&g), x);
634
635                if(SvTRUE(ERRSV)) {
636                        croak(NULL);
637                }
638
639                if(count == 1)
640                        RETVAL = SvREFCNT_inc(POPs);
641                else
642                        XSRETURN_UNDEF;
643
644        }
645        OUTPUT:
646                RETVAL
647
648int
649current_column()
650        PREINIT:
651                owl_editwin *e;
652        CODE:
653                e = owl_global_current_typwin(&g);
654                if (e) {
655                        RETVAL = owl_editwin_current_column(e);
656                } else {
657                        RETVAL = 0;
658                }
659        OUTPUT:
660                RETVAL
661
662int
663point()
664        PREINIT:
665                owl_editwin *e;
666        CODE:
667                e = owl_global_current_typwin(&g);
668                if (e) {
669                        RETVAL = owl_editwin_get_point(e);
670                } else {
671                        RETVAL = 0;
672                }
673        OUTPUT:
674                RETVAL
675
676int
677mark()
678        PREINIT:
679                owl_editwin *e;
680        CODE:
681                e = owl_global_current_typwin(&g);
682                if (e) {
683                        RETVAL = owl_editwin_get_mark(e);
684                } else {
685                        RETVAL = 0;
686                }
687        OUTPUT:
688                RETVAL
Note: See TracBrowser for help on using the repository browser.