ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtperl.xs
Revision: 1.13
Committed: Tue Jan 3 04:18:47 2006 UTC (18 years, 5 months ago) by root
Branch: MAIN
Changes since 1.12: +201 -24 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*----------------------------------------------------------------------*
2 * File: rxvtperl.xs
3 *----------------------------------------------------------------------*
4 *
5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 2005-2005 Marc Lehmann <pcg@goof.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *----------------------------------------------------------------------*/
22
23 #define line_t perl_line_t
24 #include <EXTERN.h>
25 #include <perl.h>
26 #include <XSUB.h>
27 #undef line_t
28
29 #include "../config.h"
30
31 #include <cstdarg>
32
33 #include "rxvt.h"
34 #include "iom.h"
35 #include "rxvtutil.h"
36 #include "rxvtperl.h"
37
38 #include "perlxsi.c"
39
40 #undef LINENO
41 #define LINENO(n) MOD (THIS->term_start + int(n), THIS->total_rows)
42 #undef ROW
43 #define ROW(n) THIS->row_buf [LINENO (n)]
44
45 /////////////////////////////////////////////////////////////////////////////
46
47 static wchar_t *
48 sv2wcs (SV *sv)
49 {
50 STRLEN len;
51 char *str = SvPVutf8 (sv, len);
52 return rxvt_utf8towcs (str, len);
53 }
54
55 static SV *
56 new_ref (HV *hv, const char *klass)
57 {
58 return sv_bless (newRV ((SV *)hv), gv_stashpv (klass, 1));
59 }
60
61 //TODO: use magic
62 static SV *
63 newSVptr (void *ptr, const char *klass)
64 {
65 HV *hv = newHV ();
66 hv_store (hv, "_ptr", 4, newSViv ((long)ptr), 0);
67 return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
68 }
69
70 static long
71 SvPTR (SV *sv, const char *klass)
72 {
73 if (!sv_derived_from (sv, klass))
74 croak ("object of type %s expected", klass);
75
76 IV iv = SvIV (*hv_fetch ((HV *)SvRV (sv), "_ptr", 4, 1));
77
78 if (!iv)
79 croak ("perl code used %s object, but C++ object is already destroyed, caught", klass);
80
81 return (long)iv;
82 }
83
84 #define newSVterm(term) SvREFCNT_inc ((SV *)term->self)
85 #define SvTERM(sv) (rxvt_term *)SvPTR (sv, "urxvt::term")
86
87 /////////////////////////////////////////////////////////////////////////////
88
89 struct perl_watcher
90 {
91 SV *cbsv;
92 HV *self;
93
94 perl_watcher ()
95 : cbsv (newSV (0))
96 {
97 }
98
99 ~perl_watcher ()
100 {
101 SvREFCNT_dec (cbsv);
102 }
103
104 void cb (SV *cb)
105 {
106 sv_setsv (cbsv, cb);
107 }
108
109 void invoke (const char *type, SV *self, int arg = -1);
110 };
111
112 void
113 perl_watcher::invoke (const char *type, SV *self, int arg)
114 {
115 dSP;
116
117 ENTER;
118 SAVETMPS;
119
120 PUSHMARK (SP);
121
122 XPUSHs (sv_2mortal (self));
123
124 if (arg >= 0)
125 XPUSHs (sv_2mortal (newSViv (arg)));
126
127 PUTBACK;
128 call_sv (cbsv, G_VOID | G_EVAL | G_DISCARD);
129 SPAGAIN;
130
131 PUTBACK;
132 FREETMPS;
133 LEAVE;
134
135 if (SvTRUE (ERRSV))
136 rxvt_warn ("%s callback evaluation error: %s", type, SvPV_nolen (ERRSV));
137 }
138
139 #define newSVtimer(timer) new_ref (timer->self, "urxvt::timer")
140 #define SvTIMER(sv) (timer *)SvPTR (sv, "urxvt::timer")
141
142 struct timer : time_watcher, perl_watcher
143 {
144 tstamp interval;
145
146 timer ()
147 : time_watcher (this, &timer::execute)
148 {
149 }
150
151 void execute (time_watcher &w)
152 {
153 if (interval)
154 start (at + interval);
155
156 invoke ("urxvt::timer", newSVtimer (this));
157 }
158 };
159
160 #define newSViow(iow) new_ref (iow->self, "urxvt::iow")
161 #define SvIOW(sv) (iow *)SvPTR (sv, "urxvt::iow")
162
163 struct iow : io_watcher, perl_watcher
164 {
165 iow ()
166 : io_watcher (this, &iow::execute)
167 {
168 }
169
170 void execute (io_watcher &w, short revents)
171 {
172 invoke ("urxvt::iow", newSViow (this), revents);
173 }
174 };
175
176 /////////////////////////////////////////////////////////////////////////////
177
178 #define SvOVERLAY(sv) (overlay *)SvPTR (sv, "urxvt::overlay")
179
180 struct overlay {
181 HV *self;
182 rxvt_term *THIS;
183 int x, y, w, h;
184 int border;
185 text_t **text;
186 rend_t **rend;
187
188 overlay (rxvt_term *THIS, int x_, int y_, int w_, int h_, rend_t rstyle, int border);
189 ~overlay ();
190
191 void swap ();
192
193 void set (int x, int y, SV *str, SV *rend);
194 };
195
196 overlay::overlay (rxvt_term *THIS, int x_, int y_, int w_, int h_, rend_t rstyle, int border)
197 : THIS(THIS), x(x_), y(y_), w(w_), h(h_), border(border == 2)
198 {
199 if (border == 2)
200 {
201 w += 2;
202 h += 2;
203 }
204
205 text = new text_t *[h];
206 rend = new rend_t *[h];
207
208 for (int y = 0; y < h; y++)
209 {
210 text_t *tp = text[y] = new text_t[w];
211 rend_t *rp = rend[y] = new rend_t[w];
212
213 text_t t0, t1, t2;
214 rend_t r = rstyle;
215
216 if (border == 2)
217 {
218 if (y == 0)
219 t0 = 0x2554, t1 = 0x2550, t2 = 0x2557;
220 else if (y < h - 1)
221 t0 = 0x2551, t1 = 0x0020, t2 = 0x2551;
222 else
223 t0 = 0x255a, t1 = 0x2550, t2 = 0x255d;
224
225 *tp++ = t0;
226 *rp++ = r;
227
228 for (int x = w - 2; x-- > 0; )
229 {
230 *tp++ = t1;
231 *rp++ = r;
232 }
233
234 *tp = t2;
235 *rp = r;
236 }
237 else
238 for (int x = w; x-- > 0; )
239 {
240 *tp++ = 0x0020;
241 *rp++ = r;
242 }
243 }
244
245 THIS->want_refresh = 1;
246 }
247
248 overlay::~overlay ()
249 {
250 for (int y = h; y--; )
251 {
252 delete [] text[y];
253 delete [] rend[y];
254 }
255
256 delete [] text;
257 delete [] rend;
258
259 THIS->want_refresh = 1;
260 }
261
262 void overlay::swap ()
263 {
264 int ov_x = max (0, min (MOD (x, THIS->ncol), THIS->ncol - w));
265 int ov_y = max (0, min (MOD (y, THIS->nrow), THIS->nrow - h));
266
267 int ov_w = min (w, THIS->ncol - ov_x);
268 int ov_h = min (h, THIS->nrow - ov_y);
269
270 for (int y = ov_h; y--; )
271 {
272 text_t *t1 = text [y];
273 rend_t *r1 = rend [y];
274
275 text_t *t2 = ROW(y + ov_y - THIS->view_start).t + ov_x;
276 rend_t *r2 = ROW(y + ov_y - THIS->view_start).r + ov_x;
277
278 for (int x = ov_w; x--; )
279 {
280 text_t t = *t1; *t1++ = *t2; *t2++ = t;
281 rend_t r = *r1; *r1++ = *r2; *r2++ = SET_FONT (r, THIS->fontset [GET_STYLE (r)]->find_font (t));
282 }
283 }
284
285 }
286
287 void overlay::set (int x, int y, SV *str, SV *rend)
288 {
289 x += border;
290 y += border;
291
292 if (!IN_RANGE_EXC (y, 0, h - border))
293 return;
294
295 wchar_t *wstr = sv2wcs (str);
296
297 for (int col = min (wcslen (wstr), w - x - border); col--; )
298 text [y][x + col] = wstr [col];
299
300 free (wstr);
301
302 THIS->want_refresh = 1;
303 }
304
305
306 /////////////////////////////////////////////////////////////////////////////
307
308 struct rxvt_perl_interp rxvt_perl;
309
310 static PerlInterpreter *perl;
311
312 rxvt_perl_interp::rxvt_perl_interp ()
313 {
314 }
315
316 rxvt_perl_interp::~rxvt_perl_interp ()
317 {
318 if (perl)
319 {
320 perl_destruct (perl);
321 perl_free (perl);
322 }
323 }
324
325 void
326 rxvt_perl_interp::init ()
327 {
328 if (!perl)
329 {
330 char *argv[] = {
331 "",
332 "-edo '" LIBDIR "/urxvt.pm' or ($@ and die $@) or exit 1",
333 };
334
335 perl = perl_alloc ();
336 perl_construct (perl);
337
338 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL)
339 || perl_run (perl))
340 {
341 rxvt_warn ("unable to initialize perl-interpreter, continuing without.\n");
342
343 perl_destruct (perl);
344 perl_free (perl);
345 perl = 0;
346 }
347 }
348 }
349
350 bool
351 rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...)
352 {
353 if (!perl)
354 return false;
355
356 if (htype == HOOK_INIT) // first hook ever called
357 {
358 term->self = (void *)newSVptr ((void *)term, "urxvt::term");
359 hv_store ((HV *)SvRV ((SV *)term->self), "_overlay", 8, newRV_noinc ((SV *)newHV ()), 0);
360 }
361 else if (htype == HOOK_DESTROY)
362 {
363 // handled later
364 }
365 else if (htype == HOOK_REFRESH_BEGIN || htype == HOOK_REFRESH_END)
366 {
367 HV *hv = (HV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->self), "_overlay", 8, 0));
368
369 if (HvKEYS (hv))
370 {
371 hv_iterinit (hv);
372
373 while (HE *he = hv_iternext (hv))
374 ((overlay *)SvIV (hv_iterval (hv, he)))->swap ();
375 }
376 }
377 else if (!should_invoke [htype])
378 return false;
379
380 dSP;
381 va_list ap;
382
383 va_start (ap, htype);
384
385 ENTER;
386 SAVETMPS;
387
388 PUSHMARK (SP);
389
390 XPUSHs (sv_2mortal (newSVterm (term)));
391 XPUSHs (sv_2mortal (newSViv (htype)));
392
393 for (;;) {
394 data_type dt = (data_type)va_arg (ap, int);
395
396 switch (dt)
397 {
398 case DT_INT:
399 XPUSHs (sv_2mortal (newSViv (va_arg (ap, int))));
400 break;
401
402 case DT_LONG:
403 XPUSHs (sv_2mortal (newSViv (va_arg (ap, long))));
404 break;
405
406 case DT_STRING:
407 XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
408 break;
409
410 case DT_END:
411 {
412 va_end (ap);
413
414 PUTBACK;
415 int count = call_pv ("urxvt::invoke", G_ARRAY | G_EVAL);
416 SPAGAIN;
417
418 if (count)
419 {
420 SV *status = POPs;
421 count = SvTRUE (status);
422 }
423
424 PUTBACK;
425 FREETMPS;
426 LEAVE;
427
428 if (SvTRUE (ERRSV))
429 rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPV_nolen (ERRSV));
430
431 if (htype == HOOK_DESTROY)
432 {
433 // TODO: clear magic
434 hv_clear ((HV *)SvRV ((SV *)term->self));
435 SvREFCNT_dec ((SV *)term->self);
436 }
437
438 return count;
439 }
440
441 default:
442 rxvt_fatal ("FATAL: unable to pass data type %d\n", dt);
443 }
444 }
445 }
446
447 /////////////////////////////////////////////////////////////////////////////
448
449 MODULE = urxvt PACKAGE = urxvt
450
451 PROTOTYPES: ENABLE
452
453 BOOT:
454 {
455 # define set_hookname(sym) av_store (hookname, PP_CONCAT(HOOK_, sym), newSVpv (PP_STRINGIFY(sym), 0))
456 # define export_const(name) newCONSTSUB (gv_stashpv ("urxvt", 1), #name, newSViv (name));
457 AV *hookname = get_av ("urxvt::HOOKNAME", 1);
458 set_hookname (INIT);
459 set_hookname (RESET);
460 set_hookname (START);
461 set_hookname (DESTROY);
462 set_hookname (SEL_BEGIN);
463 set_hookname (SEL_EXTEND);
464 set_hookname (SEL_MAKE);
465 set_hookname (SEL_GRAB);
466 set_hookname (FOCUS_IN);
467 set_hookname (FOCUS_OUT);
468 set_hookname (VIEW_CHANGE);
469 set_hookname (SCROLL_BACK);
470 set_hookname (TTY_ACTIVITY);
471 set_hookname (REFRESH_BEGIN);
472 set_hookname (REFRESH_END);
473 set_hookname (KEYBOARD_COMMAND);
474
475 export_const (DEFAULT_RSTYLE);
476 export_const (OVERLAY_RSTYLE);
477 export_const (RS_Bold);
478 export_const (RS_Italic);
479 export_const (RS_Blink);
480 export_const (RS_RVid);
481 export_const (RS_Uline);
482
483 sv_setpv (get_sv ("urxvt::LIBDIR", 1), LIBDIR);
484 }
485
486 void
487 set_should_invoke (int htype, int value)
488 CODE:
489 rxvt_perl.should_invoke [htype] = value;
490
491 void
492 warn (const char *msg)
493 CODE:
494 rxvt_warn ("%s", msg);
495
496 void
497 fatal (const char *msg)
498 CODE:
499 rxvt_fatal ("%s", msg);
500
501 NV
502 NOW ()
503 CODE:
504 RETVAL = NOW;
505 OUTPUT:
506 RETVAL
507
508 int
509 GET_BASEFG (int rend)
510 CODE:
511 RETVAL = GET_BASEFG (rend);
512 OUTPUT:
513 RETVAL
514
515 int
516 GET_BASEBG (int rend)
517 CODE:
518 RETVAL = GET_BASEBG (rend);
519 OUTPUT:
520 RETVAL
521
522 int
523 SET_FGCOLOR (int rend, int new_color)
524 CODE:
525 RETVAL = SET_FGCOLOR (rend, new_color);
526 OUTPUT:
527 RETVAL
528
529 int
530 SET_BGCOLOR (int rend, int new_color)
531 CODE:
532 RETVAL = SET_BGCOLOR (rend, new_color);
533 OUTPUT:
534 RETVAL
535
536 int
537 GET_CUSTOM (int rend)
538 CODE:
539 RETVAL = (rend && RS_customMask) >> RS_customShift;
540 OUTPUT:
541 RETVAL
542
543 int
544 SET_CUSTOM (int rend, int new_value)
545 CODE:
546 {
547 if (!IN_RANGE_EXC (new_value, 0, RS_customCount))
548 croak ("custom value out of range, must be 0..%d", RS_customCount - 1);
549
550 RETVAL = (rend & ~RS_customMask)
551 | ((new_value << RS_customShift) & RS_customMask);
552 }
553 OUTPUT:
554 RETVAL
555
556 MODULE = urxvt PACKAGE = urxvt::term
557
558 int
559 rxvt_term::strwidth (SV *str)
560 CODE:
561 {
562 wchar_t *wstr = sv2wcs (str);
563
564 rxvt_push_locale (THIS->locale);
565 RETVAL = wcswidth (wstr, wcslen (wstr));
566 rxvt_pop_locale ();
567
568 free (wstr);
569 }
570 OUTPUT:
571 RETVAL
572
573 SV *
574 rxvt_term::locale_encode (SV *str)
575 CODE:
576 {
577 wchar_t *wstr = sv2wcs (str);
578
579 rxvt_push_locale (THIS->locale);
580 char *mbstr = rxvt_wcstombs (wstr);
581 rxvt_pop_locale ();
582
583 free (wstr);
584
585 RETVAL = newSVpv (mbstr, 0);
586 free (mbstr);
587 }
588 OUTPUT:
589 RETVAL
590
591 SV *
592 rxvt_term::locale_decode (SV *octets)
593 CODE:
594 {
595 STRLEN len;
596 char *data = SvPVbyte (octets, len);
597
598 rxvt_push_locale (THIS->locale);
599 wchar_t *wstr = rxvt_mbstowcs (data, len);
600 rxvt_pop_locale ();
601
602 char *str = rxvt_wcstoutf8 (wstr);
603 free (wstr);
604
605 RETVAL = newSVpv (str, 0);
606 SvUTF8_on (RETVAL);
607 free (str);
608 }
609 OUTPUT:
610 RETVAL
611
612 int
613 rxvt_term::nsaved ()
614 CODE:
615 RETVAL = THIS->nsaved;
616 OUTPUT:
617 RETVAL
618
619 int
620 rxvt_term::view_start (int newval = -1)
621 CODE:
622 {
623 RETVAL = THIS->view_start;
624
625 if (newval >= 0)
626 {
627 THIS->view_start = min (newval, THIS->nsaved);
628 THIS->scr_changeview (RETVAL);
629 }
630 }
631 OUTPUT:
632 RETVAL
633
634 int
635 rxvt_term::nrow ()
636 CODE:
637 RETVAL = THIS->nrow;
638 OUTPUT:
639 RETVAL
640
641 int
642 rxvt_term::ncol ()
643 CODE:
644 RETVAL = THIS->ncol;
645 OUTPUT:
646 RETVAL
647
648 void
649 rxvt_term::want_refresh ()
650 CODE:
651 THIS->want_refresh = 1;
652
653 void
654 rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0)
655 PPCODE:
656 {
657 if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow))
658 croak ("row_number number of out range");
659
660 line_t &l = ROW(row_number);
661
662 if (GIMME_V != G_VOID)
663 {
664 wchar_t *wstr = new wchar_t [THIS->ncol];
665
666 for (int col = 0; col <THIS->ncol; col++)
667 wstr [col] = l.t [col];
668
669 char *str = rxvt_wcstoutf8 (wstr, THIS->ncol);
670 free (wstr);
671
672 SV *sv = newSVpv (str, 0);
673 SvUTF8_on (sv);
674 XPUSHs (sv_2mortal (sv));
675 free (str);
676 }
677
678 if (new_text)
679 {
680 wchar_t *wstr = sv2wcs (new_text);
681
682 int len = wcslen (wstr);
683
684 if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len))
685 {
686 free (wstr);
687 croak ("new_text extends beyond horizontal margins");
688 }
689
690 for (int col = start_col; col < start_col + len; col++)
691 {
692 l.t [col] = wstr [col - start_col];
693 l.r [col] = SET_FONT (l.r [col], THIS->fontset [GET_STYLE (l.r [col])]->find_font (l.t [col]));
694 }
695
696 free (wstr);
697 }
698 }
699
700 void
701 rxvt_term::ROW_r (int row_number, SV *new_rend = 0, int start_col = 0)
702 PPCODE:
703 {
704 if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow))
705 croak ("row_number number of out range");
706
707 line_t &l = ROW(row_number);
708
709 if (GIMME_V != G_VOID)
710 {
711 AV *av = newAV ();
712
713 av_extend (av, THIS->ncol - 1);
714 for (int col = 0; col < THIS->ncol; col++)
715 av_store (av, col, newSViv (l.r [col]));
716
717 XPUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
718 }
719
720 if (new_rend)
721 {
722 if (!SvROK (new_rend) || SvTYPE (SvRV (new_rend)) != SVt_PVAV)
723 croak ("new_rend must be arrayref");
724
725 AV *av = (AV *)SvRV (new_rend);
726 int len = av_len (av) + 1;
727
728 if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len))
729 croak ("new_rend array extends beyond horizontal margins");
730
731 for (int col = start_col; col < start_col + len; col++)
732 {
733 rend_t r = SvIV (*av_fetch (av, col - start_col, 1)) & ~RS_fontMask;
734
735 l.r [col] = SET_FONT (r, THIS->fontset [GET_STYLE (r)]->find_font (l.t [col]));
736 }
737 }
738 }
739
740 int
741 rxvt_term::ROW_l (int row_number, int new_length = -2)
742 CODE:
743 {
744 if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow))
745 croak ("row_number number of out range");
746
747 line_t &l = ROW(row_number);
748 RETVAL = l.l;
749
750 if (new_length >= -1)
751 l.l = new_length;
752 }
753 OUTPUT:
754 RETVAL
755
756 SV *
757 rxvt_term::special_encode (SV *str)
758 CODE:
759 abort ();//TODO
760
761 SV *
762 rxvt_term::special_decode (SV *str)
763 CODE:
764 abort ();//TODO
765
766 void
767 rxvt_term::_resource (char *name, int index, SV *newval = 0)
768 PPCODE:
769 {
770 struct resval { const char *name; int value; } rslist [] = {
771 # define Rs_def(name) { # name, Rs_ ## name },
772 # define Rs_reserve(name,count)
773 # include "rsinc.h"
774 # undef Rs_def
775 # undef Rs_reserve
776 };
777
778 struct resval *rs = rslist + sizeof (rslist) / sizeof (rslist [0]);
779
780 do {
781 if (rs-- == rslist)
782 croak ("no such resource '%s', requested", name);
783 } while (strcmp (name, rs->name));
784
785 index += rs->value;
786
787 if (!IN_RANGE_EXC (index, 0, NUM_RESOURCES))
788 croak ("requested out-of-bound resource %s+%d,", name, index - rs->value);
789
790 if (GIMME_V != G_VOID)
791 XPUSHs (THIS->rs [index] ? sv_2mortal (newSVpv (THIS->rs [index], 0)) : &PL_sv_undef);
792
793 if (newval)
794 {
795 if (SvOK (newval))
796 {
797 char *str = strdup (SvPVbyte_nolen (newval));
798 THIS->rs [index] = str;
799 THIS->allocated.push_back (str);
800 }
801 else
802 THIS->rs [index] = 0;
803 }
804 }
805
806 void
807 rxvt_term::selection_mark (...)
808 PROTOTYPE: $;$$
809 ALIAS:
810 selection_beg = 1
811 selection_end = 2
812 PPCODE:
813 {
814 row_col_t &sel = ix == 1 ? THIS->selection.beg
815 : ix == 2 ? THIS->selection.end
816 : THIS->selection.mark;
817
818 if (GIMME_V != G_VOID)
819 {
820 EXTEND (SP, 2);
821 PUSHs (sv_2mortal (newSViv (sel.row)));
822 PUSHs (sv_2mortal (newSViv (sel.col)));
823 }
824
825 if (items == 3)
826 {
827 sel.row = clamp (SvIV (ST (1)), -THIS->nsaved, THIS->nrow - 1);
828 sel.col = clamp (SvIV (ST (2)), 0, THIS->ncol - 1);
829
830 if (ix)
831 THIS->want_refresh = 1;
832 }
833 }
834
835 int
836 rxvt_term::selection_grab (int eventtime)
837
838 void
839 rxvt_term::selection (SV *newtext = 0)
840 PPCODE:
841 {
842 if (GIMME_V != G_VOID)
843 {
844 char *sel = rxvt_wcstoutf8 (THIS->selection.text, THIS->selection.len);
845 SV *sv = newSVpv (sel, 0);
846 SvUTF8_on (sv);
847 free (sel);
848 XPUSHs (sv_2mortal (sv));
849 }
850
851 if (newtext)
852 {
853 free (THIS->selection.text);
854
855 THIS->selection.text = sv2wcs (newtext);
856 THIS->selection.len = wcslen (THIS->selection.text);
857 }
858 }
859
860 void
861 rxvt_term::tt_write (SV *octets)
862 INIT:
863 STRLEN len;
864 char *str = SvPVbyte (octets, len);
865 C_ARGS:
866 (unsigned char *)str, len
867
868 SV *
869 rxvt_term::overlay (int x, int y, int w, int h, int rstyle = OVERLAY_RSTYLE, int border = 2)
870 CODE:
871 {
872 overlay *o = new overlay (THIS, x, y, w, h, rstyle, border);
873 RETVAL = newSVptr ((void *)o, "urxvt::overlay");
874 o->self = (HV *)SvRV (RETVAL);
875
876 HV *hv = (HV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)THIS->self), "_overlay", 8, 0));
877 char key[33]; sprintf (key, "%32lx", (long)o);
878 hv_store (hv, key, 32, newSViv ((long)o), 0);
879 }
880 OUTPUT:
881 RETVAL
882
883 MODULE = urxvt PACKAGE = urxvt::overlay
884
885 void
886 overlay::set (int x, int y, SV *text, SV *rend = 0)
887
888 void
889 overlay::DESTROY ()
890 CODE:
891 {
892 SV **ovs = hv_fetch ((HV *)SvRV ((SV *)THIS->THIS->self), "_overlay", 8, 0);
893 if (ovs)
894 {
895 HV *hv = (HV *)SvRV (*ovs);
896 char key[33]; sprintf (key, "%32lx", (long)THIS);
897 hv_delete (hv, key, 32, G_DISCARD);
898 }
899
900 delete THIS;
901 }
902
903 MODULE = urxvt PACKAGE = urxvt::timer
904
905 SV *
906 timer::new ()
907 CODE:
908 timer *w = new timer;
909 w->start (NOW);
910 RETVAL = newSVptr ((void *)w, "urxvt::timer");
911 w->self = (HV *)SvRV (RETVAL);
912 OUTPUT:
913 RETVAL
914
915 timer *
916 timer::cb (SV *cb)
917 CODE:
918 THIS->cb (cb);
919 RETVAL = THIS;
920 OUTPUT:
921 RETVAL
922
923 NV
924 timer::at ()
925 CODE:
926 RETVAL = THIS->at;
927 OUTPUT:
928 RETVAL
929
930 timer *
931 timer::interval (NV interval)
932 CODE:
933 THIS->interval = interval;
934 RETVAL = THIS;
935 OUTPUT:
936 RETVAL
937
938 timer *
939 timer::set (NV tstamp)
940 CODE:
941 THIS->set (tstamp);
942 RETVAL = THIS;
943 OUTPUT:
944 RETVAL
945
946 timer *
947 timer::start (NV tstamp = THIS->at)
948 CODE:
949 THIS->start (tstamp);
950 RETVAL = THIS;
951 OUTPUT:
952 RETVAL
953
954 timer *
955 timer::stop ()
956 CODE:
957 THIS->stop ();
958 RETVAL = THIS;
959 OUTPUT:
960 RETVAL
961
962 void
963 timer::DESTROY ()
964
965 MODULE = urxvt PACKAGE = urxvt::iow
966
967 SV *
968 iow::new ()
969 CODE:
970 iow *w = new iow;
971 RETVAL = newSVptr ((void *)w, "urxvt::iow");
972 w->self = (HV *)SvRV (RETVAL);
973 OUTPUT:
974 RETVAL
975
976 iow *
977 iow::cb (SV *cb)
978 CODE:
979 THIS->cb (cb);
980 RETVAL = THIS;
981 OUTPUT:
982 RETVAL
983
984 iow *
985 iow::fd (int fd)
986 CODE:
987 THIS->fd = fd;
988 RETVAL = THIS;
989 OUTPUT:
990 RETVAL
991
992 iow *
993 iow::events (short events)
994 CODE:
995 THIS->events = events;
996 RETVAL = THIS;
997 OUTPUT:
998 RETVAL
999
1000 iow *
1001 iow::start ()
1002 CODE:
1003 THIS->start ();
1004 RETVAL = THIS;
1005 OUTPUT:
1006 RETVAL
1007
1008 iow *
1009 iow::stop ()
1010 CODE:
1011 THIS->stop ();
1012 RETVAL = THIS;
1013 OUTPUT:
1014 RETVAL
1015
1016 void
1017 iow::DESTROY ()
1018
1019