source: perlglue.xs @ bd25f30

release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since bd25f30 was 747d6a5, checked in by Nelson Elhage <nelhage@mit.edu>, 12 years ago
Implement BarnOwl::message in XS to fix stupid quoting issues.
  • Property mode set to 100644
File size: 9.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"
9SV *owl_perlconfig_curmessage2hashref(void);
10
11#define SV_IS_CODEREF(sv) (SvROK((sv)) && SvTYPE(SvRV((sv))) == SVt_PVCV)
12
13        /*************************************************************
14         * NOTE
15         *************************************************************
16         * These functions, when they are intended to be user-visible,
17         * are documented in perl/lib/BarnOwl.pm. If you add functions
18         * to this file, add the appropriate documentation there!
19         *
20         * If the function is simple enough, we simply define its
21         * entire functionality here in XS. If, however, it needs
22         * complex argument processing or something, we define a
23         * simple version here that takes arguments in as flat a
24         * manner as possible, to simplify the XS code, put it in
25         * BarnOwl::Intenal::, and write a perl wrapper in BarnOwl.pm
26         * that munges the arguments as appropriate and calls the
27         * internal version.
28         */
29
30MODULE = BarnOwl                PACKAGE = BarnOwl
31
32char *
33command(cmd, ...)
34        char *cmd
35        PREINIT:
36                char *rv = NULL;
37                char **argv;
38                int i;
39        CODE:
40        {
41                if (items == 1) {
42                        rv = owl_function_command(cmd);
43                } else {
44                        argv = owl_malloc((items + 1) * sizeof *argv);
45                        argv[0] = cmd;
46                        for(i = 1; i < items; i++) {
47                                argv[i] = SvPV_nolen(ST(i));
48                        }
49                        rv = owl_function_command_argv(argv, items);
50                        owl_free(argv);
51                }
52                RETVAL = rv;
53        }
54        OUTPUT:
55                RETVAL
56        CLEANUP:
57                if (rv) owl_free(rv);
58
59SV *
60getcurmsg()
61        CODE:
62                RETVAL = owl_perlconfig_curmessage2hashref();
63        OUTPUT:
64                RETVAL
65
66int
67getnumcols()
68        CODE:
69                RETVAL = owl_global_get_cols(&g);
70        OUTPUT:
71                RETVAL
72               
73time_t
74getidletime()
75        CODE:
76                RETVAL = owl_global_get_idletime(&g);
77        OUTPUT:
78                RETVAL
79
80const char *
81zephyr_getrealm()
82        CODE:
83                RETVAL = owl_zephyr_get_realm();
84        OUTPUT:
85                RETVAL
86
87char *
88zephyr_getsender()
89        CODE:
90                RETVAL = owl_zephyr_get_sender();
91        OUTPUT:
92                RETVAL
93
94void
95zephyr_zwrite(cmd,msg)
96        char *cmd
97        char *msg
98        PREINIT:
99                int i;
100        CODE:
101                i = owl_zwrite_create_and_send_from_line(cmd, msg);
102
103char *
104ztext_stylestrip(ztext)
105        char *ztext
106        PREINIT:
107                char *rv = NULL;
108        CODE:
109                rv = owl_function_ztext_stylestrip(ztext);
110                RETVAL = rv;
111        OUTPUT:
112                RETVAL
113        CLEANUP:
114                if (rv) owl_free(rv);
115
116char *
117zephyr_smartstrip_user(in)
118        char *in
119        PREINIT:
120                char *rv = NULL;
121        CODE:
122        {
123                rv = owl_zephyr_smartstripped_user(in);
124                RETVAL = rv;
125        }
126        OUTPUT:
127                RETVAL
128        CLEANUP:
129                owl_free(rv);
130
131char *
132zephyr_getsubs()
133        PREINIT:
134                char *rv = NULL;
135        CODE:
136                rv = owl_zephyr_getsubs();
137                RETVAL = rv;
138    OUTPUT:
139                RETVAL
140    CLEANUP:
141                if (rv) owl_free(rv);
142
143void queue_message(msg) 
144        SV *msg
145        PREINIT:
146                owl_message *m;
147        CODE:
148        {
149                if(!SvROK(msg) || SvTYPE(SvRV(msg)) != SVt_PVHV) {
150                        croak("Usage: BarnOwl::queue_message($message)");
151                }
152
153                m = owl_perlconfig_hashref2message(msg);
154
155                owl_global_messagequeue_addmsg(&g, m);
156        }
157
158void admin_message(header, body) 
159        char *header
160        char *body
161        CODE:
162        {
163                owl_function_adminmsg(header, body);           
164        }
165
166void start_question(line, callback)
167        char *line
168        SV *callback
169        PREINIT:
170        CODE:
171        {
172                if(!SV_IS_CODEREF(callback))
173                        croak("Callback must be a subref");
174
175                owl_function_start_question(line);
176
177                SvREFCNT_inc(callback);
178                owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
179                owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
180        }
181
182void start_password(line, callback)
183        char *line
184        SV *callback
185        PREINIT:
186        CODE:
187        {
188                if(!SV_IS_CODEREF(callback))
189                        croak("Callback must be a subref");
190
191                owl_function_start_password(line);
192
193                SvREFCNT_inc(callback);
194                owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
195                owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
196        }
197
198void start_edit_win(line, callback)
199        char *line
200        SV *callback
201        PREINIT:
202                owl_editwin * e;
203                char buff[1024];
204        CODE:
205        {
206                if(!SV_IS_CODEREF(callback))
207                        croak("Callback must be a subref");
208
209                e = owl_global_get_typwin(&g);
210                owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE,
211                                      owl_global_get_msg_history(&g));
212                owl_editwin_clear(e);
213                owl_editwin_set_dotsend(e);
214                snprintf(buff, 1023, "----> %s\n", line);
215                owl_editwin_set_locktext(e, buff);
216
217                owl_global_set_typwin_active(&g);
218
219                SvREFCNT_inc(callback);
220                owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
221                owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
222        }
223
224
225char * 
226get_data_dir ()
227        CODE:
228                RETVAL = owl_get_datadir();
229        OUTPUT:
230        RETVAL
231
232char * 
233get_config_dir ()
234        CODE:
235                RETVAL = owl_global_get_confdir(&g);
236        OUTPUT:
237        RETVAL 
238
239void
240popless_text(text) 
241        char *text
242        CODE:
243        {
244                owl_function_popless_text(text);
245        }
246
247void
248popless_ztext(text) 
249        char *text
250        CODE:
251        {
252                owl_fmtext fm;
253                owl_fmtext_init_null(&fm);
254                owl_fmtext_append_ztext(&fm, text);
255                owl_function_popless_fmtext(&fm);
256                owl_fmtext_free(&fm);
257        }
258
259void
260error(text) 
261        char *text
262        CODE:
263        {
264                owl_function_error("%s", text);
265        }
266
267void
268debug(text)
269        char *text
270        CODE:
271        {
272                owl_function_debugmsg("%s", text);
273        }
274
275void
276message(text)
277        char *text
278        CODE:
279        {
280                owl_function_makemsg("%s", text);
281        }
282
283void
284create_style(name, object)
285     char *name
286     SV  *object
287     PREINIT:
288                owl_style *s;
289     CODE:
290        {
291                s = owl_malloc(sizeof(owl_style));
292                owl_style_create_perl(s, name, object);
293                owl_global_add_style(&g, s);
294        }
295
296int
297getnumcolors()
298        CODE:
299                RETVAL = owl_function_get_color_count();
300        OUTPUT:
301                RETVAL
302
303void
304_remove_filter(filterName)
305        char *filterName
306        CODE:
307        {
308                /* Don't delete the current view, or the 'all' filter */
309                if (strcmp(filterName, owl_view_get_filtname(owl_global_get_current_view(&g)))
310                    && strcmp(filterName, "all")) {
311                        owl_global_remove_filter(&g,filterName);
312                }
313        }
314
315char *
316wordwrap(in, cols)
317        char *in
318        int cols
319        PREINIT:
320                char *rv = NULL;
321        CODE:
322                rv = owl_text_wordwrap(in, cols);
323                RETVAL = rv;   
324        OUTPUT:
325                RETVAL
326        CLEANUP:
327                if (rv) owl_free(rv);
328
329void
330add_dispatch(fd, cb)
331        int fd
332        SV * cb
333        CODE:
334        SvREFCNT_inc(cb);
335        owl_select_add_perl_dispatch(fd, cb);
336
337void
338remove_dispatch(fd)
339        int fd
340        CODE:
341        owl_select_remove_perl_dispatch(fd);
342
343
344AV*
345all_filters()
346        PREINIT:
347                AV *filters;
348                owl_list *fl;
349                owl_filter *f;
350                int i;
351        CODE:
352        {
353                fl = owl_global_get_filterlist(&g);
354                filters = newAV();
355                for(i=0;i<owl_list_get_size(fl);i++) {
356                        f = owl_list_get_element(fl, i);
357                        av_push(filters, newSVpv(owl_filter_get_name(f), 0));
358                }
359                RETVAL = filters;
360                sv_2mortal((SV*)RETVAL);
361        }
362        OUTPUT:
363                RETVAL
364
365MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
366
367
368void
369new_command(name, func, summary, usage, description)
370        char *name
371        SV *func
372        char *summary
373        char *usage
374        char *description
375        PREINIT:
376                owl_cmd cmd;
377        CODE:
378        {
379                if(!SV_IS_CODEREF(func)) {
380                        croak("Command function must be a coderef!");
381                }
382                SvREFCNT_inc(func);
383                cmd.name = name;
384                cmd.cmd_perl = func;
385                cmd.summary = summary;
386                cmd.usage = usage;
387                cmd.description = description;
388                cmd.validctx = OWL_CTX_ANY;
389                cmd.cmd_aliased_to = NULL;
390                cmd.cmd_args_fn = NULL;
391                cmd.cmd_v_fn = NULL;
392                cmd.cmd_i_fn = NULL;
393                cmd.cmd_ctxargs_fn = NULL;
394                cmd.cmd_ctxv_fn = NULL;
395                cmd.cmd_ctxi_fn = NULL;
396                owl_cmddict_add_cmd(owl_global_get_cmddict(&g), &cmd);
397           }
398
399void
400new_variable_string(name, ival, summ, desc)
401        char * name
402        char * ival
403        char * summ
404        char * desc
405        CODE:
406        owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
407                                        name,
408                                        summ,
409                                        desc,
410                                        ival);
411
412void
413new_variable_int(name, ival, summ, desc)
414        char * name
415        int ival
416        char * summ
417        char * desc
418        CODE:
419        owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
420                                     name,
421                                     summ,
422                                     desc,
423                                     ival);
424
425void
426new_variable_bool(name, ival, summ, desc)
427        char * name
428        int ival
429        char * summ
430        char * desc
431        CODE:
432        owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
433                                      name,
434                                      summ,
435                                      desc,
436                                      ival);
437
438IV
439add_timer(after, interval, cb)
440        int after
441        int interval
442        SV *cb
443        PREINIT:
444                SV *ref;
445                owl_timer *t;
446        CODE:
447                ref = sv_rvweaken(newSVsv(cb));
448                t = owl_select_add_timer(after,
449                                         interval,
450                                         owl_perlconfig_perl_timer,
451                                         owl_perlconfig_perl_timer_destroy,
452                                         ref);
453        owl_function_debugmsg("Created timer %p", t);
454        RETVAL = (IV)t;
455        OUTPUT:
456                RETVAL
457
458void
459remove_timer(timer)
460        IV timer
461        PREINIT:
462                owl_timer *t;
463        CODE:
464                t = (owl_timer*)timer;
465                owl_function_debugmsg("Freeing timer %p", t);
466                                owl_select_remove_timer(t);
467
468MODULE = BarnOwl                PACKAGE = BarnOwl::Editwin
469
470int
471replace(count, string)
472        int count;
473        char *string;
474        CODE:
475                RETVAL = owl_editwin_replace(owl_global_get_typwin(&g), count, string);
476        OUTPUT:
477                RETVAL
478
479int
480point_move(delta)
481        int delta;
482        CODE:
483                RETVAL = owl_editwin_point_move(owl_global_get_typwin(&g), delta);
484        OUTPUT:
485                RETVAL
486
487int
488replace_region(string)
489        char *string;
490        CODE:
491                RETVAL = owl_editwin_replace_region(owl_global_get_typwin(&g), string);
492        OUTPUT:
493                RETVAL
494
495char *
496get_region()
497        PREINIT:
498                char *region;
499        CODE:
500                region = owl_editwin_get_region(owl_global_get_typwin(&g));
501                RETVAL = region;
502        OUTPUT:
503                RETVAL
504        CLEANUP:
505                owl_free(region);
506
507SV *
508save_excursion(sub)
509        SV *sub;
510        PROTOTYPE: &
511        PREINIT:
512                int count;
513                owl_editwin_excursion *x;
514        CODE:
515        {
516                x = owl_editwin_begin_excursion(owl_global_get_typwin(&g));
517                PUSHMARK(SP);
518                count = call_sv(sub, G_SCALAR|G_EVAL|G_NOARGS);
519                SPAGAIN;
520                owl_editwin_end_excursion(owl_global_get_typwin(&g), x);
521
522                if(SvTRUE(ERRSV)) {
523                        croak(NULL);
524                }
525
526                if(count == 1)
527                        RETVAL = SvREFCNT_inc(POPs);
528                else
529                        XSRETURN_UNDEF;
530
531        }
532        OUTPUT:
533                RETVAL
534
535int
536current_column()
537        CODE:
538                RETVAL = owl_editwin_current_column(owl_global_get_typwin(&g));
539        OUTPUT:
540                RETVAL
541
542int
543point()
544        CODE:
545                RETVAL = owl_editwin_get_point(owl_global_get_typwin(&g));
546        OUTPUT:
547                RETVAL
548
549int
550mark()
551        CODE:
552                RETVAL = owl_editwin_get_mark(owl_global_get_typwin(&g));
553        OUTPUT:
554                RETVAL
Note: See TracBrowser for help on using the repository browser.