ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtperl.xs
Revision: 1.257
Committed: Fri Dec 30 16:51:59 2022 UTC (18 months ago) by root
Branch: MAIN
Changes since 1.256: +84 -6 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /*----------------------------------------------------------------------*
2     * File: rxvtperl.xs
3     *----------------------------------------------------------------------*
4     *
5     * All portions of code are copyright by their respective author/s.
6 sf-exg 1.235 * Copyright (c) 2005-2014 Marc Lehmann <schmorp@schmorp.de>
7 root 1.1 *
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 root 1.224 * the Free Software Foundation; either version 3 of the License, or
11 root 1.1 * (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 root 1.151 #undef bool // perl defines it's own bool type, except with g++... what a trap
29 root 1.1
30     #include "../config.h"
31    
32 sf-exg 1.152 #include <stddef.h>
33     #include <stdarg.h>
34 root 1.1
35 root 1.257 #include <unistd.h>
36    
37     #include <X11/extensions/shape.h>
38    
39     // support old includes (https://bugs.freedesktop.org/show_bug.cgi?id=2799, https://lists.x.org/archives/xorg-arch/2005-March/000004.html)
40     #ifndef ShapeInput
41     # define ShapeInput 2
42     #endif
43 root 1.59
44 root 1.116 #include "ev_cpp.h"
45 root 1.1 #include "rxvt.h"
46 root 1.50 #include "keyboard.h"
47 root 1.1 #include "rxvtutil.h"
48     #include "rxvtperl.h"
49    
50     #include "perlxsi.c"
51    
52 ayin 1.121 #define GRAB_CURSOR THIS->scrollBar.leftptr_cursor
53 root 1.41
54 root 1.8 #undef LINENO
55     #define LINENO(n) MOD (THIS->term_start + int(n), THIS->total_rows)
56     #undef ROW
57     #define ROW(n) THIS->row_buf [LINENO (n)]
58    
59 root 1.1 /////////////////////////////////////////////////////////////////////////////
60    
61 root 1.155 typedef char * octet_string;
62     typedef char * utf8_string;
63    
64 root 1.167 typedef int render_repeat_mode;
65    
66 sf-exg 1.188 #if HAVE_PIXBUF
67 root 1.155 typedef GdkPixbuf * urxvt__pixbuf;
68 sf-exg 1.188 #endif
69 sf-exg 1.207 #if HAVE_IMG
70 root 1.155 typedef rxvt_img * urxvt__img;
71 root 1.197 typedef rxvt_img::nv rxvt_img__nv;
72 root 1.155
73     /////////////////////////////////////////////////////////////////////////////
74    
75 root 1.194 static rgba
76     parse_rgba (SV *sv, rxvt_screen *s = 0)
77 root 1.156 {
78 root 1.194 rgba c;
79    
80 root 1.198 if (SvROK (sv))
81 root 1.194 {
82 root 1.198 AV *av = (AV *)SvRV (sv);
83    
84 root 1.194 if (SvTYPE ((SV *)av) != SVt_PVAV)
85     croak ("colour must be either a colour string, or an array,");
86    
87     int len = av_len (av) + 1;
88    
89     if (len != 1 && len != 3 && len != 4)
90     croak ("component colour array must have 1, 3 or 4 components,");
91    
92     c.a = rgba::MAX_CC;
93    
94 root 1.246 c.r = c.g = c.b = float_to_component (SvNV (*av_fetch (av, 0, 0)));
95 root 1.194
96     if (len >= 3)
97     {
98 root 1.246 c.g = float_to_component (SvNV (*av_fetch (av, 1, 0)));
99     c.b = float_to_component (SvNV (*av_fetch (av, 2, 0)));
100 root 1.194
101     if (len >= 4)
102 root 1.246 c.a = float_to_component (SvNV (*av_fetch (av, 3, 0)));
103 root 1.194 }
104     }
105     else if (s)
106     {
107     rxvt_color rc;
108     rc.set (s, SvPVbyte_nolen (sv));
109     rc.get (c);
110     }
111 root 1.195 else
112     croak ("unable to parse colour,");
113 root 1.194
114     return c;
115 root 1.156 }
116    
117     /////////////////////////////////////////////////////////////////////////////
118 sf-exg 1.207 #endif
119 root 1.156
120 root 1.1 static wchar_t *
121     sv2wcs (SV *sv)
122     {
123     STRLEN len;
124     char *str = SvPVutf8 (sv, len);
125     return rxvt_utf8towcs (str, len);
126     }
127    
128     static SV *
129 root 1.25 wcs2sv (wchar_t *wstr, int len = -1)
130     {
131     char *str = rxvt_wcstoutf8 (wstr, len);
132    
133     SV *sv = newSVpv (str, 0);
134     SvUTF8_on (sv);
135     free (str);
136    
137     return sv;
138     }
139    
140     static SV *
141 root 1.1 newSVptr (void *ptr, const char *klass)
142     {
143     HV *hv = newHV ();
144 root 1.18 sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0);
145 root 1.1 return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
146     }
147    
148 root 1.18 static void
149     clearSVptr (SV *sv)
150     {
151     if (SvROK (sv))
152     sv = SvRV (sv);
153    
154     hv_clear ((HV *)sv);
155     sv_unmagic (sv, PERL_MAGIC_ext);
156     }
157    
158 root 1.1 static long
159     SvPTR (SV *sv, const char *klass)
160     {
161     if (!sv_derived_from (sv, klass))
162     croak ("object of type %s expected", klass);
163    
164 root 1.18 MAGIC *mg = mg_find (SvRV (sv), PERL_MAGIC_ext);
165 root 1.1
166 root 1.18 if (!mg)
167 root 1.1 croak ("perl code used %s object, but C++ object is already destroyed, caught", klass);
168    
169 root 1.18 return (long)mg->mg_ptr;
170 root 1.1 }
171    
172 root 1.95 #define newSVterm(term) SvREFCNT_inc ((SV *)(term)->perl.self)
173     #define SvTERM(sv) (rxvt_term *)SvPTR ((sv), "urxvt::term")
174 root 1.1
175     /////////////////////////////////////////////////////////////////////////////
176    
177 root 1.13 #define SvOVERLAY(sv) (overlay *)SvPTR (sv, "urxvt::overlay")
178    
179 root 1.126 class overlay : overlay_base
180     {
181 root 1.13 rxvt_term *THIS;
182 root 1.93 AV *overlay_av;
183 root 1.13 int border;
184    
185 root 1.93 public:
186     HV *self;
187    
188 root 1.13 overlay (rxvt_term *THIS, int x_, int y_, int w_, int h_, rend_t rstyle, int border);
189     ~overlay ();
190    
191 root 1.18 void show ();
192     void hide ();
193    
194 root 1.13 void swap ();
195    
196     void set (int x, int y, SV *str, SV *rend);
197     };
198    
199     overlay::overlay (rxvt_term *THIS, int x_, int y_, int w_, int h_, rend_t rstyle, int border)
200 root 1.126 : THIS(THIS), border(border == 2), overlay_av (0)
201 root 1.13 {
202 root 1.126 x = x_;
203     y = y_;
204     w = w_;
205     h = h_;
206    
207 root 1.103 if (w < 0) w = 0;
208     if (h < 0) h = 0;
209    
210 root 1.13 if (border == 2)
211     {
212     w += 2;
213     h += 2;
214     }
215    
216     text = new text_t *[h];
217     rend = new rend_t *[h];
218 root 1.24
219 root 1.13 for (int y = 0; y < h; y++)
220 root 1.24 {
221 root 1.13 text_t *tp = text[y] = new text_t[w];
222     rend_t *rp = rend[y] = new rend_t[w];
223 root 1.24
224 root 1.13 text_t t0, t1, t2;
225     rend_t r = rstyle;
226 root 1.24
227 root 1.13 if (border == 2)
228     {
229     if (y == 0)
230     t0 = 0x2554, t1 = 0x2550, t2 = 0x2557;
231     else if (y < h - 1)
232     t0 = 0x2551, t1 = 0x0020, t2 = 0x2551;
233     else
234     t0 = 0x255a, t1 = 0x2550, t2 = 0x255d;
235 root 1.24
236     *tp++ = t0;
237 root 1.13 *rp++ = r;
238 root 1.24
239 root 1.13 for (int x = w - 2; x-- > 0; )
240     {
241     *tp++ = t1;
242     *rp++ = r;
243 root 1.24 }
244 root 1.13
245     *tp = t2;
246 root 1.24 *rp = r;
247 root 1.13 }
248     else
249     for (int x = w; x-- > 0; )
250     {
251     *tp++ = 0x0020;
252     *rp++ = r;
253 root 1.24 }
254     }
255 root 1.13
256 root 1.18 show ();
257 root 1.13 }
258    
259     overlay::~overlay ()
260     {
261 root 1.18 hide ();
262    
263 root 1.13 for (int y = h; y--; )
264     {
265     delete [] text[y];
266     delete [] rend[y];
267     }
268    
269     delete [] text;
270     delete [] rend;
271     }
272    
273 root 1.18 void
274     overlay::show ()
275     {
276 root 1.93 if (overlay_av)
277 root 1.76 return;
278    
279 root 1.93 overlay_av = (AV *)SvREFCNT_inc (SvRV (
280     *hv_fetch ((HV *)SvRV ((SV *)THIS->perl.self), "_overlay", 8, 0)
281     ));
282     av_push (overlay_av, newSViv ((long)this));
283 root 1.18
284 root 1.93 THIS->want_refresh = 1;
285 root 1.118 THIS->refresh_check ();
286 root 1.18 }
287    
288     void
289     overlay::hide ()
290     {
291 root 1.93 if (!overlay_av)
292 root 1.76 return;
293    
294     int i;
295 root 1.18
296 root 1.93 for (i = AvFILL (overlay_av); i >= 0; i--)
297     if (SvIV (*av_fetch (overlay_av, i, 1)) == (long)this)
298 root 1.101 break;
299 root 1.76
300 root 1.93 for (; i < AvFILL (overlay_av); i++)
301     av_store (overlay_av, i, SvREFCNT_inc (*av_fetch (overlay_av, i + 1, 0)));
302    
303 sf-exg 1.239 SvREFCNT_dec (av_pop (overlay_av));
304 root 1.18
305 root 1.93 SvREFCNT_dec (overlay_av);
306     overlay_av = 0;
307    
308     THIS->want_refresh = 1;
309 root 1.118 THIS->refresh_check ();
310 root 1.18 }
311    
312 root 1.13 void overlay::swap ()
313     {
314     int ov_x = max (0, min (MOD (x, THIS->ncol), THIS->ncol - w));
315     int ov_y = max (0, min (MOD (y, THIS->nrow), THIS->nrow - h));
316    
317     int ov_w = min (w, THIS->ncol - ov_x);
318     int ov_h = min (h, THIS->nrow - ov_y);
319    
320 root 1.126 // hide cursor if it is within the overlay area
321     if (IN_RANGE_EXC (THIS->screen.cur.col - ov_x, 0, ov_w)
322     && IN_RANGE_EXC (THIS->screen.cur.row - ov_y, 0, ov_h))
323     THIS->screen.flags &= ~Screen_VisibleCursor;
324    
325 root 1.13 for (int y = ov_h; y--; )
326     {
327     text_t *t1 = text [y];
328     rend_t *r1 = rend [y];
329 root 1.24
330 root 1.67 text_t *t2 = ROW(y + ov_y + THIS->view_start).t + ov_x;
331     rend_t *r2 = ROW(y + ov_y + THIS->view_start).r + ov_x;
332 root 1.13
333     for (int x = ov_w; x--; )
334 root 1.24 {
335 root 1.13 text_t t = *t1; *t1++ = *t2; *t2++ = t;
336     rend_t r = *r1; *r1++ = *r2; *r2++ = SET_FONT (r, THIS->fontset [GET_STYLE (r)]->find_font (t));
337     }
338     }
339    
340     }
341    
342 root 1.14 void overlay::set (int x, int y, SV *text, SV *rend)
343 root 1.13 {
344     x += border;
345     y += border;
346    
347     if (!IN_RANGE_EXC (y, 0, h - border))
348     return;
349    
350 root 1.14 wchar_t *wtext = sv2wcs (text);
351 root 1.13
352 root 1.14 for (int col = min (wcslen (wtext), w - x - border); col--; )
353     this->text [y][x + col] = wtext [col];
354 root 1.24
355 root 1.14 free (wtext);
356    
357     if (rend)
358     {
359     if (!SvROK (rend) || SvTYPE (SvRV (rend)) != SVt_PVAV)
360     croak ("rend must be arrayref");
361    
362     AV *av = (AV *)SvRV (rend);
363    
364 root 1.76 for (int col = min (AvFILL (av) + 1, w - x - border); col--; )
365 root 1.14 this->rend [y][x + col] = SvIV (*av_fetch (av, col, 1));
366     }
367 root 1.13
368     THIS->want_refresh = 1;
369 root 1.118 THIS->refresh_check ();
370 root 1.13 }
371    
372 root 1.109 /////////////////////////////////////////////////////////////////////////////
373    
374 ayin 1.119 #include "iom_perl.h"
375 root 1.13
376     /////////////////////////////////////////////////////////////////////////////
377    
378 root 1.1 struct rxvt_perl_interp rxvt_perl;
379    
380     static PerlInterpreter *perl;
381    
382 root 1.247 #if 0 /* we are not a library anymore, so doing this is just not worth it */
383     /*THINK/TODO: this has the side effect of, of course, not calling destructors. */
384     /* but therse are not guaranteed anyway... */
385 root 1.1 rxvt_perl_interp::~rxvt_perl_interp ()
386     {
387     if (perl)
388     {
389 root 1.249 localise_env set_environ (perl_environ);
390 root 1.1 perl_destruct (perl);
391     perl_free (perl);
392 root 1.125 PERL_SYS_TERM ();
393 root 1.1 }
394     }
395 root 1.247 #endif
396 root 1.1
397     void
398 root 1.192 rxvt_perl_interp::init ()
399 root 1.1 {
400     if (!perl)
401     {
402 root 1.68 rxvt_push_locale (""); // perl init destroys current locale
403    
404 root 1.134 {
405     perl_environ = rxvt_environ;
406     localise_env set_environ (perl_environ);
407 root 1.56
408 root 1.244 const char *args[] = {
409 root 1.134 "",
410     "-e"
411     "BEGIN {"
412     " urxvt->bootstrap;"
413     " unshift @INC, '" LIBDIR "';"
414     "}"
415     ""
416 root 1.243 "use urxvt;",
417     0
418 root 1.134 };
419 root 1.243 int argc = ecb_array_length (args) - 1;
420 root 1.244 char **argv = (char **)args;
421 root 1.1
422 root 1.134 PERL_SYS_INIT3 (&argc, &argv, &environ);
423     perl = perl_alloc ();
424     perl_construct (perl);
425 root 1.1
426 root 1.134 if (perl_parse (perl, xs_init, argc, argv, (char **)NULL)
427     || perl_run (perl))
428     {
429     rxvt_warn ("unable to initialize perl-interpreter, continuing without.\n");
430 root 1.57
431 root 1.134 perl_destruct (perl);
432     perl_free (perl);
433     perl = 0;
434     }
435     }
436 root 1.68
437     rxvt_pop_locale ();
438 root 1.1 }
439 root 1.192 }
440    
441     void
442     rxvt_perl_interp::init (rxvt_term *term)
443     {
444     init ();
445 root 1.68
446 root 1.182 if (perl && !term->perl.self)
447 root 1.70 {
448     // runs outside of perls ENV
449     term->perl.self = (void *)newSVptr ((void *)term, "urxvt::term");
450 root 1.76 hv_store ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, newRV_noinc ((SV *)newAV ()), 0);
451 sf-exg 1.142 hv_store ((HV *)SvRV ((SV *)term->perl.self), "_selection", 10, newRV_noinc ((SV *)newAV ()), 0);
452 root 1.70 }
453 root 1.1 }
454    
455 root 1.170 void
456 root 1.192 rxvt_perl_interp::eval (const char *str)
457     {
458     eval_pv (str, 1);
459     }
460    
461     void
462 root 1.171 rxvt_perl_interp::usage (rxvt_term *term, int type)
463 root 1.170 {
464     localise_env set_environ (perl_environ);
465    
466     ENTER;
467     SAVETMPS;
468    
469     dSP;
470 root 1.174 PUSHMARK (SP);
471 root 1.171 EXTEND (SP, 2);
472     PUSHs (sv_2mortal (newSVterm (term)));
473     PUSHs (sv_2mortal (newSViv (type)));
474 root 1.170 PUTBACK;
475 root 1.173 call_pv ("urxvt::usage", G_VOID | G_DISCARD);
476 root 1.170
477     FREETMPS;
478     LEAVE;
479     }
480    
481     uint8_t
482 root 1.173 rxvt_perl_interp::parse_resource (rxvt_term *term, const char *name, bool arg, bool longopt, bool flag, const char *value)
483 root 1.170 {
484     localise_env set_environ (perl_environ);
485    
486     ENTER;
487     SAVETMPS;
488    
489     dSP;
490 root 1.174 PUSHMARK (SP);
491 root 1.170 EXTEND (SP, 6);
492     PUSHs (sv_2mortal (newSVterm (term)));
493     PUSHs (sv_2mortal (newSVpv (name, 0)));
494     PUSHs (arg ? &PL_sv_yes : &PL_sv_no);
495     PUSHs (longopt ? &PL_sv_yes : &PL_sv_no);
496     PUSHs (flag ? &PL_sv_yes : &PL_sv_no);
497     PUSHs (value ? sv_2mortal (newSVpv (value, 0)) : &PL_sv_undef);
498     PUTBACK;
499 root 1.173 call_pv ("urxvt::parse_resource", G_SCALAR);
500     SPAGAIN;
501 root 1.170
502     uint8_t ret = POPi;
503    
504     FREETMPS;
505     LEAVE;
506    
507     return ret;
508     }
509    
510 root 1.45 static void
511 root 1.223 _keysym_resource_push (rxvt_term *term, const char *k, const char *v)
512     {
513 sf-exg 1.227 unsigned int state;
514    
515     if (term->parse_keysym (k, state) == -1)
516     return;
517    
518 root 1.223 dSP;
519     XPUSHs (sv_2mortal (newSVpv (v, 0)));
520     PUTBACK;
521     }
522    
523     static void
524     _keysym_resources (rxvt_term *term)
525     {
526     term->enumerate_keysym_resources (_keysym_resource_push);
527     }
528    
529     static void
530 root 1.45 ungrab (rxvt_term *THIS)
531     {
532     if (THIS->perl.grabtime)
533     {
534 root 1.96 XUngrabKeyboard (THIS->dpy, THIS->perl.grabtime);
535     XUngrabPointer (THIS->dpy, THIS->perl.grabtime);
536 root 1.45 THIS->perl.grabtime = 0;
537     }
538     }
539    
540 root 1.1 bool
541 root 1.255 rxvt_perl_interp::invoke (rxvt_term *term, int htype, ...)
542 root 1.1 {
543 root 1.68 if (!perl || !term->perl.self)
544 root 1.1 return false;
545 root 1.24
546 root 1.134 localise_env set_environ (perl_environ);
547    
548 root 1.68 // pre-handling of some events
549     if (htype == HOOK_REFRESH_END)
550 root 1.76 {
551     AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, 0));
552 ayin 1.115
553 root 1.76 for (int i = 0; i <= AvFILL (av); i++)
554     ((overlay *)SvIV (*av_fetch (av, i, 0)))->swap ();
555     }
556 sf-exg 1.142 else if (htype == HOOK_DESTROY)
557     {
558     AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_selection", 10, 0));
559    
560     for (int i = AvFILL (av); i >= 0; i--)
561     {
562     rxvt_selection *req = (rxvt_selection *)SvIV (*av_fetch (av, i, 0));
563     delete req;
564     }
565     }
566 root 1.1
567 root 1.68 bool event_consumed;
568 root 1.1
569 root 1.170 if (term->perl.should_invoke [htype])
570 root 1.134 {
571     dSP;
572     va_list ap;
573    
574     va_start (ap, htype);
575 root 1.1
576 root 1.134 ENTER;
577     SAVETMPS;
578 root 1.1
579 root 1.134 PUSHMARK (SP);
580 root 1.1
581 root 1.138 EXTEND (SP, 2);
582     PUSHs (sv_2mortal (newSVterm (term)));
583     PUSHs (sv_2mortal (newSViv (htype)));
584 root 1.1
585 root 1.134 for (;;) {
586     data_type dt = (data_type)va_arg (ap, int);
587 root 1.1
588 root 1.134 switch (dt)
589     {
590     case DT_INT:
591     XPUSHs (sv_2mortal (newSViv (va_arg (ap, int))));
592     break;
593 root 1.1
594 root 1.134 case DT_LONG:
595     XPUSHs (sv_2mortal (newSViv (va_arg (ap, long))));
596     break;
597 root 1.68
598 root 1.134 case DT_STR:
599     XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
600     break;
601 root 1.68
602 root 1.134 case DT_STR_LEN:
603     {
604     char *str = va_arg (ap, char *);
605     int len = va_arg (ap, int);
606 root 1.68
607 root 1.134 XPUSHs (sv_2mortal (newSVpvn (str, len)));
608     }
609     break;
610 root 1.68
611 root 1.134 case DT_WCS_LEN:
612     {
613     wchar_t *wstr = va_arg (ap, wchar_t *);
614     int wlen = va_arg (ap, int);
615 root 1.68
616 root 1.134 XPUSHs (sv_2mortal (wcs2sv (wstr, wlen)));
617     }
618     break;
619 root 1.68
620 root 1.134 case DT_LCS_LEN:
621     {
622     long *lstr = va_arg (ap, long *);
623     int llen = va_arg (ap, int);
624 root 1.68
625 root 1.134 XPUSHs (sv_2mortal (newSVpvn ((char *)lstr, llen * sizeof (long))));
626     }
627     break;
628 root 1.91
629 root 1.134 case DT_XEVENT:
630     {
631     XEvent *xe = va_arg (ap, XEvent *);
632     HV *hv = newHV ();
633 root 1.91
634 root 1.134 # define set(name, sv) hv_store (hv, # name, sizeof (# name) - 1, sv, 0)
635     # define setiv(name, val) hv_store (hv, # name, sizeof (# name) - 1, newSViv (val), 0)
636     # define setuv(name, val) hv_store (hv, # name, sizeof (# name) - 1, newSVuv (val), 0)
637     # undef set
638    
639     setiv (type, xe->type);
640     setiv (send_event, xe->xany.send_event);
641     setiv (serial, xe->xany.serial);
642 root 1.29
643 root 1.134 switch (xe->type)
644     {
645     case KeyPress:
646     case KeyRelease:
647     case ButtonPress:
648     case ButtonRelease:
649     case MotionNotify:
650     setuv (window, xe->xmotion.window);
651     setuv (root, xe->xmotion.root);
652     setuv (subwindow, xe->xmotion.subwindow);
653     setuv (time, xe->xmotion.time);
654     setiv (x, xe->xmotion.x);
655     setiv (y, xe->xmotion.y);
656     setiv (row, xe->xmotion.y / term->fheight + term->view_start);
657     setiv (col, xe->xmotion.x / term->fwidth);
658     setiv (x_root, xe->xmotion.x_root);
659     setiv (y_root, xe->xmotion.y_root);
660     setuv (state, xe->xmotion.state);
661    
662     switch (xe->type)
663     {
664     case KeyPress:
665     case KeyRelease:
666     setuv (keycode, xe->xkey.keycode);
667     break;
668    
669     case ButtonPress:
670     case ButtonRelease:
671     setuv (button, xe->xbutton.button);
672     break;
673    
674     case MotionNotify:
675     setiv (is_hint, xe->xmotion.is_hint);
676     break;
677     }
678    
679     break;
680    
681     case MapNotify:
682     case UnmapNotify:
683     case ConfigureNotify:
684     setuv (event, xe->xconfigure.event);
685     setuv (window, xe->xconfigure.window);
686    
687     switch (xe->type)
688     {
689     case ConfigureNotify:
690     setiv (x, xe->xconfigure.x);
691     setiv (y, xe->xconfigure.y);
692     setiv (width, xe->xconfigure.width);
693     setiv (height, xe->xconfigure.height);
694     setuv (above, xe->xconfigure.above);
695     break;
696     }
697    
698     break;
699    
700     case PropertyNotify:
701     setuv (window, xe->xproperty.window);
702     setuv (atom, xe->xproperty.atom);
703     setuv (time, xe->xproperty.time);
704     setiv (state, xe->xproperty.state);
705     break;
706    
707     case ClientMessage:
708     setuv (window, xe->xclient.window);
709     setuv (message_type, xe->xclient.message_type);
710     setuv (format, xe->xclient.format);
711     setuv (l0, xe->xclient.data.l[0]);
712     setuv (l1, xe->xclient.data.l[1]);
713     setuv (l2, xe->xclient.data.l[2]);
714     setuv (l3, xe->xclient.data.l[3]);
715     setuv (l4, xe->xclient.data.l[4]);
716     break;
717     }
718 root 1.68
719 root 1.134 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
720     }
721     break;
722 root 1.68
723 root 1.134 case DT_END:
724     goto call;
725 root 1.68
726 root 1.134 default:
727     rxvt_fatal ("FATAL: unable to pass data type %d\n", dt);
728     }
729     }
730 root 1.29
731 root 1.134 call:
732     va_end (ap);
733 root 1.29
734 root 1.134 PUTBACK;
735     int count = call_pv ("urxvt::invoke", G_ARRAY | G_EVAL);
736     SPAGAIN;
737 root 1.29
738 root 1.134 if (count)
739     {
740     SV *status = POPs;
741     count = SvTRUE (status);
742     }
743 root 1.29
744 root 1.134 PUTBACK;
745     FREETMPS;
746     LEAVE;
747 root 1.29
748 root 1.134 if (SvTRUE (ERRSV))
749     {
750 root 1.138 rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPVbyte_nolen (ERRSV));
751 root 1.134 ungrab (term); // better lose the grab than the session
752     }
753 root 1.68
754 root 1.134 event_consumed = !!count;
755     }
756 root 1.68 else
757     event_consumed = false;
758    
759     // post-handling of some events
760     if (htype == HOOK_REFRESH_BEGIN)
761 root 1.76 {
762     AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, 0));
763 ayin 1.115
764 root 1.76 for (int i = AvFILL (av); i >= 0; i--)
765     ((overlay *)SvIV (*av_fetch (av, i, 0)))->swap ();
766     }
767 root 1.68 else if (htype == HOOK_DESTROY)
768 root 1.57 {
769 root 1.68 clearSVptr ((SV *)term->perl.self);
770     SvREFCNT_dec ((SV *)term->perl.self);
771 ayin 1.115
772 root 1.91 // don't allow further calls
773     term->perl.self = 0;
774 root 1.57 }
775 root 1.68
776     return event_consumed;
777 root 1.1 }
778    
779 root 1.138 void
780     rxvt_perl_interp::selection_finish (rxvt_selection *sel, char *data, unsigned int len)
781     {
782     localise_env set_environ (perl_environ);
783    
784     ENTER;
785     SAVETMPS;
786    
787     dSP;
788     XPUSHs (sv_2mortal (newSVpvn (data, len)));
789 root 1.170 PUTBACK;
790 root 1.138 call_sv ((SV *)sel->cb_sv, G_VOID | G_DISCARD | G_EVAL);
791    
792     if (SvTRUE (ERRSV))
793     rxvt_warn ("perl selection callback evaluation error: %s", SvPVbyte_nolen (ERRSV));
794    
795     FREETMPS;
796     LEAVE;
797     }
798    
799 root 1.1 /////////////////////////////////////////////////////////////////////////////
800    
801     MODULE = urxvt PACKAGE = urxvt
802    
803     PROTOTYPES: ENABLE
804    
805     BOOT:
806     {
807 root 1.52 sv_setsv (get_sv ("urxvt::LIBDIR", 1), newSVpvn (LIBDIR, sizeof (LIBDIR) - 1));
808     sv_setsv (get_sv ("urxvt::RESNAME", 1), newSVpvn (RESNAME, sizeof (RESNAME) - 1));
809     sv_setsv (get_sv ("urxvt::RESCLASS", 1), newSVpvn (RESCLASS, sizeof (RESCLASS) - 1));
810     sv_setsv (get_sv ("urxvt::RXVTNAME", 1), newSVpvn (RXVTNAME, sizeof (RXVTNAME) - 1));
811 root 1.37
812 root 1.1 AV *hookname = get_av ("urxvt::HOOKNAME", 1);
813 root 1.21 # define def(sym) av_store (hookname, HOOK_ ## sym, newSVpv (# sym, 0));
814     # include "hookinc.h"
815     # undef def
816 root 1.1
817 root 1.39 HV *option = get_hv ("urxvt::OPTION", 1);
818 root 1.133 # define def(name) hv_store (option, # name, sizeof (# name) - 1, newSVuv (Opt_ ## name), 0);
819 root 1.39 # define nodef(name)
820     # include "optinc.h"
821     # undef nodef
822     # undef def
823    
824     HV *stash = gv_stashpv ("urxvt", 1);
825 root 1.97 static const struct {
826 root 1.62 const char *name;
827     IV iv;
828     } *civ, const_iv[] = {
829     # define const_iv(name) { # name, (IV)name }
830 root 1.218 const_iv (HOOK_INIT),
831     const_iv (HOOK_DESTROY),
832 root 1.222 const_iv (HOOK_ACTION),
833 root 1.253 const_iv (HOOK_OSC_SEQ),
834     const_iv (HOOK_OSC_SEQ_PERL),
835 root 1.218
836 root 1.123 const_iv (NUM_RESOURCES),
837 root 1.62 const_iv (DEFAULT_RSTYLE),
838     const_iv (OVERLAY_RSTYLE),
839 root 1.131 const_iv (Color_Bits),
840     const_iv (RS_bgShift), const_iv (RS_bgMask),
841     const_iv (RS_fgShift), const_iv (RS_fgMask),
842     const_iv (RS_Careful),
843     const_iv (RS_fontCount),
844     const_iv (RS_fontShift),
845     const_iv (RS_fontMask),
846     const_iv (RS_baseattrMask),
847     const_iv (RS_attrMask),
848     const_iv (RS_redraw),
849     const_iv (RS_Sel),
850 root 1.62 const_iv (RS_Bold),
851     const_iv (RS_Italic),
852     const_iv (RS_Blink),
853     const_iv (RS_RVid),
854     const_iv (RS_Uline),
855    
856 root 1.216 // TODO: should support all colour constants, create colorinc.h &c
857     const_iv (Color_fg),
858     const_iv (Color_bg),
859 root 1.257 # if OFF_FOCUS_FADING
860 root 1.216 const_iv (Color_fade),
861 root 1.257 # endif
862 root 1.216 const_iv (Color_pointer_fg),
863     const_iv (Color_pointer_bg),
864     const_iv (Color_border),
865     const_iv (NRS_COLORS),
866     const_iv (TOTAL_COLORS),
867    
868 root 1.62 const_iv (CurrentTime),
869     const_iv (ShiftMask),
870     const_iv (LockMask),
871     const_iv (ControlMask),
872     const_iv (Mod1Mask),
873     const_iv (Mod2Mask),
874     const_iv (Mod3Mask),
875     const_iv (Mod4Mask),
876     const_iv (Mod5Mask),
877     const_iv (Button1Mask),
878     const_iv (Button2Mask),
879     const_iv (Button3Mask),
880     const_iv (Button4Mask),
881     const_iv (Button5Mask),
882     const_iv (AnyModifier),
883    
884 root 1.102 const_iv (NoSymbol),
885     const_iv (GrabModeSync),
886     const_iv (GrabModeAsync),
887    
888 root 1.62 const_iv (NoEventMask),
889     const_iv (KeyPressMask),
890     const_iv (KeyReleaseMask),
891     const_iv (ButtonPressMask),
892     const_iv (ButtonReleaseMask),
893     const_iv (EnterWindowMask),
894     const_iv (LeaveWindowMask),
895     const_iv (PointerMotionMask),
896     const_iv (PointerMotionHintMask),
897     const_iv (Button1MotionMask),
898     const_iv (Button2MotionMask),
899     const_iv (Button3MotionMask),
900     const_iv (Button4MotionMask),
901     const_iv (Button5MotionMask),
902     const_iv (ButtonMotionMask),
903     const_iv (KeymapStateMask),
904     const_iv (ExposureMask),
905     const_iv (VisibilityChangeMask),
906     const_iv (StructureNotifyMask),
907     const_iv (ResizeRedirectMask),
908     const_iv (SubstructureNotifyMask),
909     const_iv (SubstructureRedirectMask),
910     const_iv (FocusChangeMask),
911     const_iv (PropertyChangeMask),
912     const_iv (ColormapChangeMask),
913     const_iv (OwnerGrabButtonMask),
914    
915     const_iv (KeyPress),
916     const_iv (KeyRelease),
917     const_iv (ButtonPress),
918     const_iv (ButtonRelease),
919     const_iv (MotionNotify),
920     const_iv (EnterNotify),
921     const_iv (LeaveNotify),
922     const_iv (FocusIn),
923     const_iv (FocusOut),
924     const_iv (KeymapNotify),
925     const_iv (Expose),
926     const_iv (GraphicsExpose),
927     const_iv (NoExpose),
928     const_iv (VisibilityNotify),
929     const_iv (CreateNotify),
930     const_iv (DestroyNotify),
931     const_iv (UnmapNotify),
932     const_iv (MapNotify),
933     const_iv (MapRequest),
934     const_iv (ReparentNotify),
935     const_iv (ConfigureNotify),
936     const_iv (ConfigureRequest),
937     const_iv (GravityNotify),
938     const_iv (ResizeRequest),
939     const_iv (CirculateNotify),
940     const_iv (CirculateRequest),
941     const_iv (PropertyNotify),
942     const_iv (SelectionClear),
943     const_iv (SelectionRequest),
944     const_iv (SelectionNotify),
945     const_iv (ColormapNotify),
946     const_iv (ClientMessage),
947     const_iv (MappingNotify),
948 root 1.257
949     // shape extension
950     const_iv (ShapeSet),
951     const_iv (ShapeUnion),
952     const_iv (ShapeIntersect),
953     const_iv (ShapeSubtract),
954     const_iv (ShapeInvert),
955    
956     const_iv (ShapeBounding),
957     const_iv (ShapeClip),
958     const_iv (ShapeInput),
959    
960     // XIM
961 root 1.91 # if ENABLE_XIM_ONTHESPOT
962     const_iv (XIMReverse),
963     const_iv (XIMUnderline),
964     const_iv (XIMHighlight),
965     const_iv (XIMPrimary),
966     const_iv (XIMSecondary),
967     const_iv (XIMTertiary),
968     const_iv (XIMVisibleToForward),
969     const_iv (XIMVisibleToBackword),
970     const_iv (XIMVisibleToCenter),
971 root 1.257 # endif
972     # if XRENDER
973 root 1.158 const_iv (PictStandardARGB32),
974     const_iv (PictStandardRGB24),
975     const_iv (PictStandardA8),
976     const_iv (PictStandardA4),
977     const_iv (PictStandardA1),
978 root 1.159 const_iv (RepeatNone),
979     const_iv (RepeatNormal),
980     const_iv (RepeatPad),
981     const_iv (RepeatReflect),
982 root 1.198 // all versions
983     const_iv (PictOpClear),
984     const_iv (PictOpSrc),
985     const_iv (PictOpDst),
986     const_iv (PictOpOver),
987     const_iv (PictOpOverReverse),
988     const_iv (PictOpIn),
989     const_iv (PictOpInReverse),
990     const_iv (PictOpOut),
991     const_iv (PictOpOutReverse),
992     const_iv (PictOpAtop),
993     const_iv (PictOpAtopReverse),
994     const_iv (PictOpXor),
995     const_iv (PictOpAdd),
996     const_iv (PictOpSaturate),
997     // 0.2+
998     const_iv (PictOpDisjointClear),
999     const_iv (PictOpDisjointSrc),
1000     const_iv (PictOpDisjointDst),
1001     const_iv (PictOpDisjointOver),
1002     const_iv (PictOpDisjointOverReverse),
1003     const_iv (PictOpDisjointIn),
1004     const_iv (PictOpDisjointInReverse),
1005     const_iv (PictOpDisjointOut),
1006     const_iv (PictOpDisjointOutReverse),
1007     const_iv (PictOpDisjointAtop),
1008     const_iv (PictOpDisjointAtopReverse),
1009     const_iv (PictOpDisjointXor),
1010     const_iv (PictOpConjointClear),
1011     const_iv (PictOpConjointSrc),
1012     const_iv (PictOpConjointDst),
1013     const_iv (PictOpConjointOver),
1014     const_iv (PictOpConjointOverReverse),
1015     const_iv (PictOpConjointIn),
1016     const_iv (PictOpConjointInReverse),
1017     const_iv (PictOpConjointOut),
1018     const_iv (PictOpConjointOutReverse),
1019     const_iv (PictOpConjointAtop),
1020     const_iv (PictOpConjointAtopReverse),
1021     const_iv (PictOpConjointXor),
1022     // 0.11+
1023     const_iv (PictOpMultiply),
1024     const_iv (PictOpScreen),
1025     const_iv (PictOpOverlay),
1026     const_iv (PictOpDarken),
1027     const_iv (PictOpLighten),
1028     const_iv (PictOpColorDodge),
1029     const_iv (PictOpColorBurn),
1030     const_iv (PictOpHardLight),
1031     const_iv (PictOpSoftLight),
1032     const_iv (PictOpDifference),
1033     const_iv (PictOpExclusion),
1034     const_iv (PictOpHSLHue),
1035     const_iv (PictOpHSLSaturation),
1036     const_iv (PictOpHSLColor),
1037     const_iv (PictOpHSLLuminosity),
1038 root 1.257 # endif
1039 root 1.92 # if 0
1040 root 1.91 const_iv (XIMForwardChar),
1041     const_iv (XIMBackwardChar),
1042     const_iv (XIMForwardWord),
1043     const_iv (XIMBackwardWord),
1044     const_iv (XIMCaretUp),
1045     const_iv (XIMCaretDown),
1046     const_iv (XIMNextLine),
1047     const_iv (XIMPreviousLine),
1048     const_iv (XIMLineStart),
1049     const_iv (XIMLineEnd),
1050     const_iv (XIMAbsolutePosition),
1051     const_iv (XIMDontChange),
1052     # endif
1053 root 1.241
1054     /* DEC private modes */
1055     const_iv (PrivMode_132),
1056     const_iv (PrivMode_132OK),
1057     const_iv (PrivMode_rVideo),
1058     const_iv (PrivMode_relOrigin),
1059     const_iv (PrivMode_Screen),
1060     const_iv (PrivMode_Autowrap),
1061     const_iv (PrivMode_aplCUR),
1062     const_iv (PrivMode_aplKP),
1063     const_iv (PrivMode_HaveBackSpace),
1064     const_iv (PrivMode_BackSpace),
1065     const_iv (PrivMode_ShiftKeys),
1066     const_iv (PrivMode_VisibleCursor),
1067     const_iv (PrivMode_MouseX10),
1068     const_iv (PrivMode_MouseX11),
1069     const_iv (PrivMode_scrollBar),
1070     const_iv (PrivMode_TtyOutputInh),
1071     const_iv (PrivMode_Keypress),
1072     const_iv (PrivMode_smoothScroll),
1073     const_iv (PrivMode_vt52),
1074     const_iv (PrivMode_LFNL),
1075     const_iv (PrivMode_MouseBtnEvent),
1076     const_iv (PrivMode_MouseAnyEvent),
1077     const_iv (PrivMode_BracketPaste),
1078 sf-exg 1.248 const_iv (PrivMode_ExtMouseUTF8),
1079     const_iv (PrivMode_ExtMouseUrxvt),
1080 root 1.241 const_iv (PrivMode_BlinkingCursor),
1081     const_iv (PrivMode_mouse_report),
1082     const_iv (PrivMode_Default),
1083 root 1.62 };
1084    
1085 root 1.143 for (civ = const_iv + ecb_array_length (const_iv); civ > const_iv; civ--)
1086     newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
1087 root 1.1 }
1088    
1089     void
1090 root 1.232 log (utf8_string msg)
1091 root 1.171 CODE:
1092     rxvt_log ("%s", msg);
1093    
1094     void
1095 root 1.232 warn (utf8_string msg)
1096 root 1.1 CODE:
1097     rxvt_warn ("%s", msg);
1098    
1099     void
1100 root 1.232 fatal (utf8_string msg)
1101 root 1.1 CODE:
1102     rxvt_fatal ("%s", msg);
1103    
1104 root 1.59 void
1105     _exit (int status)
1106    
1107 root 1.167 void
1108     catch_fatal (SV *block)
1109     PROTOTYPE: &
1110     CODE:
1111     try
1112     {
1113     PUSHMARK (SP);
1114     PUTBACK;
1115     call_sv (block, G_VOID | G_DISCARD);
1116     SPAGAIN;
1117     }
1118     catch (const rxvt_failure_exception &e)
1119     {
1120     croak ("rxvt_fatal exception caught, trying to continue.");
1121     }
1122    
1123 root 1.3 NV
1124     NOW ()
1125     CODE:
1126 root 1.116 RETVAL = ev::now ();
1127 root 1.3 OUTPUT:
1128     RETVAL
1129    
1130 root 1.11 int
1131     GET_BASEFG (int rend)
1132     CODE:
1133     RETVAL = GET_BASEFG (rend);
1134     OUTPUT:
1135     RETVAL
1136    
1137     int
1138     GET_BASEBG (int rend)
1139     CODE:
1140     RETVAL = GET_BASEBG (rend);
1141     OUTPUT:
1142     RETVAL
1143    
1144     int
1145 root 1.12 SET_FGCOLOR (int rend, int new_color)
1146 root 1.11 CODE:
1147 root 1.98 RETVAL = SET_FGCOLOR (rend, clamp (new_color, 0, TOTAL_COLORS - 1));
1148 root 1.11 OUTPUT:
1149     RETVAL
1150    
1151     int
1152 root 1.12 SET_BGCOLOR (int rend, int new_color)
1153 root 1.11 CODE:
1154 root 1.98 RETVAL = SET_BGCOLOR (rend, clamp (new_color, 0, TOTAL_COLORS - 1));
1155 root 1.12 OUTPUT:
1156     RETVAL
1157    
1158     int
1159     GET_CUSTOM (int rend)
1160     CODE:
1161 root 1.108 RETVAL = (rend & RS_customMask) >> RS_customShift;
1162 root 1.12 OUTPUT:
1163     RETVAL
1164    
1165     int
1166     SET_CUSTOM (int rend, int new_value)
1167     CODE:
1168     {
1169     if (!IN_RANGE_EXC (new_value, 0, RS_customCount))
1170 sf-exg 1.256 croak ("custom value out of range, must be 0..%lu", RS_customCount - 1);
1171 root 1.12
1172     RETVAL = (rend & ~RS_customMask)
1173     | ((new_value << RS_customShift) & RS_customMask);
1174     }
1175 root 1.11 OUTPUT:
1176     RETVAL
1177    
1178 root 1.95 void
1179     termlist ()
1180     PPCODE:
1181     {
1182     EXTEND (SP, rxvt_term::termlist.size ());
1183    
1184     for (rxvt_term **t = rxvt_term::termlist.begin (); t < rxvt_term::termlist.end (); t++)
1185     if ((*t)->perl.self)
1186     PUSHs (sv_2mortal (newSVterm (*t)));
1187     }
1188    
1189 root 1.139 IV
1190     _new_selection_request (rxvt_term *term, int selnum, Time tm, Window win, Atom prop, SV *cb)
1191     CODE:
1192     rxvt_selection *req = new rxvt_selection (term->display, selnum, tm, win, prop, term);
1193     req->cb_sv = newSVsv (cb);
1194 sf-exg 1.142 AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_selection", 10, 0));
1195     av_push (av, newSViv ((IV)req));
1196 root 1.139 RETVAL = (IV)req;
1197     OUTPUT:
1198     RETVAL
1199    
1200     void
1201     _delete_selection_request (IV req_)
1202     CODE:
1203     rxvt_selection *req = (rxvt_selection *)req_;
1204 sf-exg 1.142 AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)req->term->perl.self), "_selection", 10, 0));
1205     int i;
1206    
1207     for (i = AvFILL (av); i >= 0; i--)
1208     if (SvIV (*av_fetch (av, i, 1)) == req_)
1209     break;
1210    
1211     for (; i < AvFILL (av); i++)
1212     av_store (av, i, SvREFCNT_inc (*av_fetch (av, i + 1, 0)));
1213    
1214     av_pop (av);
1215    
1216 root 1.139 delete req;
1217    
1218 root 1.3 MODULE = urxvt PACKAGE = urxvt::term
1219    
1220 root 1.54 SV *
1221 root 1.95 _new (AV *env, AV *arg)
1222 root 1.54 CODE:
1223     {
1224     rxvt_term *term = new rxvt_term;
1225    
1226 root 1.88 stringvec *argv = new stringvec;
1227 root 1.95 for (int i = 0; i <= AvFILL (arg); i++)
1228     argv->push_back (strdup (SvPVbyte_nolen (*av_fetch (arg, i, 1))));
1229 root 1.54
1230 root 1.148 stringvec *envv = new stringvec;
1231 root 1.88 for (int i = AvFILL (env) + 1; i--; )
1232     envv->push_back (strdup (SvPVbyte_nolen (*av_fetch (env, i, 1))));
1233 root 1.54
1234     try
1235     {
1236 root 1.117 term->init (argv, envv);
1237 root 1.54 }
1238     catch (const class rxvt_failure_exception &e)
1239     {
1240     term->destroy ();
1241     croak ("error while initializing new terminal instance");
1242     }
1243    
1244     RETVAL = term && term->perl.self
1245     ? newSVterm (term) : &PL_sv_undef;
1246     }
1247     OUTPUT:
1248     RETVAL
1249    
1250 root 1.28 void
1251     rxvt_term::destroy ()
1252    
1253 root 1.35 void
1254 root 1.62 rxvt_term::set_should_invoke (int htype, int inc)
1255     CODE:
1256 root 1.166 uint8_t &count = THIS->perl.should_invoke [htype];
1257     uint8_t prev = count;
1258     count += inc;
1259     if (!prev != !count)
1260     {
1261     // hook status changed, react
1262     switch (htype)
1263     {
1264     case HOOK_POSITION_CHANGE:
1265     if (count)
1266     THIS->get_window_origin (THIS->parent_x, THIS->parent_y);
1267     }
1268     }
1269 root 1.62
1270 root 1.173 void
1271     rxvt_term::put_option_db (octet_string specifier, octet_string value)
1272     CODE:
1273     XrmPutStringResource (&THIS->option_db, specifier, value);
1274    
1275 root 1.223 void
1276     rxvt_term::_keysym_resources ()
1277     PPCODE:
1278     PUTBACK;
1279     _keysym_resources (THIS);
1280     SPAGAIN;
1281    
1282 root 1.102 int
1283 root 1.95 rxvt_term::grab_button (int button, U32 modifiers, Window window = THIS->vt)
1284 root 1.36 CODE:
1285 root 1.102 RETVAL = XGrabButton (THIS->dpy, button, modifiers, window, 1,
1286     ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1287     GrabModeSync, GrabModeSync, None, GRAB_CURSOR);
1288     OUTPUT: RETVAL
1289 root 1.36
1290 root 1.102 int
1291 root 1.95 rxvt_term::ungrab_button (int button, U32 modifiers, Window window = THIS->vt)
1292     CODE:
1293 root 1.102 RETVAL = XUngrabButton (THIS->dpy, button, modifiers, window);
1294     OUTPUT: RETVAL
1295 root 1.95
1296 root 1.102 void
1297     rxvt_term::XGrabKey (int keycode, U32 modifiers, Window window = THIS->vt, \
1298     int owner_events = 1, int pointer_mode = GrabModeAsync, int keyboard_mode = GrabModeAsync)
1299     CODE:
1300     XGrabKey (THIS->dpy, keycode, modifiers, window, owner_events, pointer_mode, keyboard_mode);
1301 root 1.95
1302     void
1303 root 1.102 rxvt_term::XUngrabKey (int keycode, U32 modifiers, Window window = THIS->vt)
1304     CODE:
1305     XUngrabKey (THIS->dpy, keycode, modifiers, window);
1306 root 1.95
1307 root 1.36 bool
1308 root 1.79 rxvt_term::grab (Time eventtime, int sync = 0)
1309 root 1.35 CODE:
1310     {
1311 root 1.36 int mode = sync ? GrabModeSync : GrabModeAsync;
1312    
1313     THIS->perl.grabtime = 0;
1314    
1315 root 1.96 if (!XGrabPointer (THIS->dpy, THIS->vt, 0,
1316 root 1.36 ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1317 root 1.41 mode, mode, None, GRAB_CURSOR, eventtime))
1318 root 1.96 if (!XGrabKeyboard (THIS->dpy, THIS->vt, 0, mode, mode, eventtime))
1319 root 1.36 THIS->perl.grabtime = eventtime;
1320     else
1321 root 1.96 XUngrabPointer (THIS->dpy, eventtime);
1322 root 1.36
1323     RETVAL = !!THIS->perl.grabtime;
1324 root 1.35 }
1325 root 1.36 OUTPUT:
1326     RETVAL
1327    
1328     void
1329 root 1.44 rxvt_term::allow_events_async ()
1330 root 1.36 CODE:
1331 root 1.96 XAllowEvents (THIS->dpy, AsyncBoth, THIS->perl.grabtime);
1332 root 1.36
1333     void
1334 root 1.44 rxvt_term::allow_events_sync ()
1335 root 1.36 CODE:
1336 root 1.96 XAllowEvents (THIS->dpy, SyncBoth, THIS->perl.grabtime);
1337 root 1.36
1338     void
1339 root 1.44 rxvt_term::allow_events_replay ()
1340 root 1.36 CODE:
1341 root 1.96 XAllowEvents (THIS->dpy, ReplayPointer, THIS->perl.grabtime);
1342     XAllowEvents (THIS->dpy, ReplayKeyboard, THIS->perl.grabtime);
1343 root 1.36
1344     void
1345 root 1.44 rxvt_term::ungrab ()
1346 root 1.36 CODE:
1347 root 1.45 ungrab (THIS);
1348 root 1.35
1349 root 1.1 int
1350 root 1.232 rxvt_term::XStringToKeysym (octet_string string)
1351 root 1.102 CODE:
1352     RETVAL = XStringToKeysym (string);
1353     OUTPUT: RETVAL
1354    
1355     char *
1356     rxvt_term::XKeysymToString (int sym)
1357     CODE:
1358     RETVAL = XKeysymToString (sym);
1359     OUTPUT: RETVAL
1360    
1361     int
1362     rxvt_term::XKeysymToKeycode (int sym)
1363     CODE:
1364     RETVAL = XKeysymToKeycode (THIS->dpy, sym);
1365     OUTPUT: RETVAL
1366    
1367     int
1368     rxvt_term::XKeycodeToKeysym (int code, int index)
1369     CODE:
1370 sf-exg 1.228 RETVAL = rxvt_XKeycodeToKeysym (THIS->dpy, code, index);
1371 root 1.102 OUTPUT: RETVAL
1372    
1373     int
1374 root 1.3 rxvt_term::strwidth (SV *str)
1375 root 1.1 CODE:
1376     {
1377     wchar_t *wstr = sv2wcs (str);
1378 root 1.3
1379     rxvt_push_locale (THIS->locale);
1380 root 1.105 RETVAL = 0;
1381     for (wchar_t *wc = wstr; *wc; wc++)
1382     {
1383     int w = WCWIDTH (*wc);
1384    
1385     if (w)
1386 root 1.107 RETVAL += max (w, 1);
1387 root 1.105 }
1388 root 1.3 rxvt_pop_locale ();
1389    
1390 root 1.1 free (wstr);
1391     }
1392     OUTPUT:
1393     RETVAL
1394    
1395 root 1.3 SV *
1396     rxvt_term::locale_encode (SV *str)
1397 root 1.1 CODE:
1398 root 1.3 {
1399 root 1.254 if (!SvOK (str))
1400     XSRETURN_UNDEF;
1401    
1402 root 1.3 wchar_t *wstr = sv2wcs (str);
1403    
1404     rxvt_push_locale (THIS->locale);
1405     char *mbstr = rxvt_wcstombs (wstr);
1406     rxvt_pop_locale ();
1407    
1408     free (wstr);
1409    
1410 root 1.71 RETVAL = newSVpv (mbstr, 0);
1411 root 1.3 free (mbstr);
1412     }
1413     OUTPUT:
1414 root 1.1 RETVAL
1415    
1416 root 1.3 SV *
1417     rxvt_term::locale_decode (SV *octets)
1418     CODE:
1419     {
1420 root 1.254 if (!SvOK (octets))
1421     XSRETURN_UNDEF;
1422    
1423 root 1.3 STRLEN len;
1424     char *data = SvPVbyte (octets, len);
1425    
1426     rxvt_push_locale (THIS->locale);
1427     wchar_t *wstr = rxvt_mbstowcs (data, len);
1428     rxvt_pop_locale ();
1429    
1430 root 1.71 RETVAL = wcs2sv (wstr);
1431 root 1.3 free (wstr);
1432     }
1433     OUTPUT:
1434     RETVAL
1435 root 1.1
1436 root 1.38 #define TERM_OFFSET(sym) offsetof (TermWin_t, sym)
1437 root 1.24
1438 root 1.127 #define TERM_OFFSET_width TERM_OFFSET(width)
1439     #define TERM_OFFSET_height TERM_OFFSET(height)
1440     #define TERM_OFFSET_fwidth TERM_OFFSET(fwidth)
1441     #define TERM_OFFSET_fheight TERM_OFFSET(fheight)
1442     #define TERM_OFFSET_fbase TERM_OFFSET(fbase)
1443     #define TERM_OFFSET_nrow TERM_OFFSET(nrow)
1444     #define TERM_OFFSET_ncol TERM_OFFSET(ncol)
1445     #define TERM_OFFSET_focus TERM_OFFSET(focus)
1446     #define TERM_OFFSET_mapped TERM_OFFSET(mapped)
1447     #define TERM_OFFSET_int_bwidth TERM_OFFSET(int_bwidth)
1448     #define TERM_OFFSET_ext_bwidth TERM_OFFSET(ext_bwidth)
1449     #define TERM_OFFSET_lineSpace TERM_OFFSET(lineSpace)
1450     #define TERM_OFFSET_letterSpace TERM_OFFSET(letterSpace)
1451     #define TERM_OFFSET_saveLines TERM_OFFSET(saveLines)
1452     #define TERM_OFFSET_total_rows TERM_OFFSET(total_rows)
1453     #define TERM_OFFSET_top_row TERM_OFFSET(top_row)
1454 root 1.24
1455     int
1456 root 1.237 rxvt_term::width (int new_value = NO_INIT)
1457 root 1.24 ALIAS:
1458 root 1.127 width = TERM_OFFSET_width
1459     height = TERM_OFFSET_height
1460     fwidth = TERM_OFFSET_fwidth
1461     fheight = TERM_OFFSET_fheight
1462     fbase = TERM_OFFSET_fbase
1463     nrow = TERM_OFFSET_nrow
1464     ncol = TERM_OFFSET_ncol
1465     focus = TERM_OFFSET_focus
1466     mapped = TERM_OFFSET_mapped
1467     int_bwidth = TERM_OFFSET_int_bwidth
1468     ext_bwidth = TERM_OFFSET_ext_bwidth
1469     lineSpace = TERM_OFFSET_lineSpace
1470     letterSpace = TERM_OFFSET_letterSpace
1471     saveLines = TERM_OFFSET_saveLines
1472     total_rows = TERM_OFFSET_total_rows
1473     top_row = TERM_OFFSET_top_row
1474 root 1.24 CODE:
1475     RETVAL = *(int *)((char *)THIS + ix);
1476 root 1.237 if (items > 1)
1477     *(int *)((char *)THIS + ix) = new_value;
1478 root 1.24 OUTPUT:
1479     RETVAL
1480    
1481 root 1.38 unsigned int
1482     rxvt_term::ModLevel3Mask ()
1483     ALIAS:
1484     ModLevel3Mask = 0
1485     ModMetaMask = 1
1486     ModNumLockMask = 2
1487 root 1.86 current_screen = 3
1488 root 1.87 hidden_cursor = 4
1489 root 1.241 priv_modes = 5
1490 root 1.38 CODE:
1491     switch (ix)
1492     {
1493 root 1.87 case 0: RETVAL = THIS->ModLevel3Mask; break;
1494     case 1: RETVAL = THIS->ModMetaMask; break;
1495     case 2: RETVAL = THIS->ModNumLockMask; break;
1496     case 3: RETVAL = THIS->current_screen; break;
1497 root 1.124 #ifdef CURSOR_BLINK
1498 root 1.87 case 4: RETVAL = THIS->hidden_cursor; break;
1499 root 1.240 #else
1500     case 4: RETVAL = 0; break;
1501 root 1.124 #endif
1502 root 1.241 case 5: RETVAL = THIS->priv_modes; break;
1503 root 1.38 }
1504     OUTPUT:
1505     RETVAL
1506    
1507 root 1.48 char *
1508     rxvt_term::display_id ()
1509 root 1.49 ALIAS:
1510     display_id = 0
1511     locale = 1
1512 root 1.48 CODE:
1513 root 1.49 switch (ix)
1514     {
1515     case 0: RETVAL = THIS->display->id; break;
1516     case 1: RETVAL = THIS->locale; break;
1517     }
1518 root 1.48 OUTPUT:
1519     RETVAL
1520    
1521 root 1.54 SV *
1522 root 1.100 rxvt_term::envv ()
1523     ALIAS:
1524     argv = 1
1525     PPCODE:
1526 root 1.54 {
1527 root 1.100 stringvec *vec = ix ? THIS->argv : THIS->envv;
1528 root 1.54
1529 root 1.100 EXTEND (SP, vec->size ());
1530 root 1.54
1531 root 1.100 for (char **i = vec->begin (); i != vec->end (); ++i)
1532     if (*i)
1533     PUSHs (sv_2mortal (newSVpv (*i, 0)));
1534 root 1.54 }
1535    
1536 root 1.50 int
1537 root 1.116 rxvt_term::pty_ev_events (int events = ev::UNDEF)
1538 root 1.50 CODE:
1539     RETVAL = THIS->pty_ev.events;
1540 root 1.116 if (events != ev::UNDEF)
1541 root 1.50 THIS->pty_ev.set (events);
1542     OUTPUT:
1543     RETVAL
1544    
1545 root 1.90 int
1546     rxvt_term::pty_fd ()
1547     CODE:
1548     RETVAL = THIS->pty->pty;
1549     OUTPUT:
1550     RETVAL
1551    
1552 root 1.79 Window
1553 root 1.31 rxvt_term::parent ()
1554     CODE:
1555 sf-exg 1.140 RETVAL = THIS->parent;
1556 root 1.31 OUTPUT:
1557     RETVAL
1558    
1559 root 1.166 int
1560     rxvt_term::parent_x ()
1561     CODE:
1562     RETVAL = THIS->parent_x;
1563     OUTPUT:
1564     RETVAL
1565    
1566     int
1567     rxvt_term::parent_y ()
1568 root 1.30 CODE:
1569 root 1.166 RETVAL = THIS->parent_y;
1570 root 1.30 OUTPUT:
1571     RETVAL
1572    
1573 sf-exg 1.202 Window
1574     rxvt_term::vt ()
1575     CODE:
1576     RETVAL = THIS->vt;
1577     OUTPUT:
1578     RETVAL
1579    
1580 root 1.62 void
1581     rxvt_term::vt_emask_add (U32 emask)
1582     CODE:
1583     THIS->vt_emask_perl |= emask;
1584     THIS->vt_select_input ();
1585    
1586 root 1.30 U32
1587 root 1.25 rxvt_term::rstyle (U32 new_rstyle = THIS->rstyle)
1588 root 1.7 CODE:
1589 root 1.25 RETVAL = THIS->rstyle;
1590     THIS->rstyle = new_rstyle;
1591 root 1.7 OUTPUT:
1592 root 1.24 RETVAL
1593 root 1.7
1594     int
1595 root 1.252 rxvt_term::view_start (int newval = 0)
1596 root 1.61 PROTOTYPE: $;$
1597 root 1.7 CODE:
1598     {
1599     RETVAL = THIS->view_start;
1600 sf-exg 1.251 if (items > 1)
1601     THIS->scr_changeview (newval);
1602 root 1.7 }
1603     OUTPUT:
1604     RETVAL
1605    
1606 root 1.8 void
1607 sf-exg 1.146 rxvt_term::set_urgency (bool enable)
1608    
1609     void
1610 root 1.83 rxvt_term::focus_in ()
1611    
1612     void
1613     rxvt_term::focus_out ()
1614    
1615     void
1616 root 1.98 rxvt_term::key_press (unsigned int state, unsigned int keycode, Time time = CurrentTime)
1617     ALIAS:
1618     key_release = 1
1619     CODE:
1620     {
1621     XKeyEvent xkey;
1622    
1623     memset (&xkey, 0, sizeof (xkey));
1624    
1625     xkey.time = time;
1626     xkey.state = state;
1627     xkey.keycode = keycode;
1628    
1629     xkey.type = ix ? KeyRelease : KeyPress;
1630     xkey.display = THIS->dpy;
1631     xkey.window = THIS->vt;
1632     xkey.root = THIS->display->root;
1633     xkey.subwindow = THIS->vt;
1634    
1635     if (ix)
1636     THIS->key_release (xkey);
1637     else
1638     THIS->key_press (xkey);
1639     }
1640    
1641     void
1642 root 1.9 rxvt_term::want_refresh ()
1643     CODE:
1644     THIS->want_refresh = 1;
1645 root 1.118 THIS->refresh_check ();
1646 root 1.9
1647     void
1648 sf-exg 1.234 rxvt_term::refresh_check ()
1649    
1650     void
1651 root 1.27 rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0, int start_ofs = 0, int max_len = MAX_COLS)
1652 root 1.8 PPCODE:
1653     {
1654 root 1.67 if (!IN_RANGE_EXC (row_number, THIS->top_row, THIS->nrow))
1655 root 1.19 XSRETURN_EMPTY;
1656 root 1.8
1657     line_t &l = ROW(row_number);
1658    
1659     if (GIMME_V != G_VOID)
1660     {
1661 root 1.91 wchar_t *wstr = rxvt_temp_buf<wchar_t> (THIS->ncol);
1662 root 1.8
1663 root 1.33 for (int col = 0; col < THIS->ncol; col++)
1664 root 1.8 wstr [col] = l.t [col];
1665    
1666 root 1.71 XPUSHs (sv_2mortal (wcs2sv (wstr, THIS->ncol)));
1667 root 1.8 }
1668    
1669     if (new_text)
1670     {
1671 root 1.13 wchar_t *wstr = sv2wcs (new_text);
1672 root 1.8
1673 root 1.27 int len = min (wcslen (wstr) - start_ofs, max_len);
1674 root 1.8
1675 root 1.83 if (start_col < 0 || start_col + len > THIS->ncol)
1676 root 1.8 {
1677     free (wstr);
1678 root 1.10 croak ("new_text extends beyond horizontal margins");
1679 root 1.8 }
1680    
1681     for (int col = start_col; col < start_col + len; col++)
1682     {
1683 root 1.27 l.t [col] = wstr [start_ofs + col - start_col];
1684 root 1.8 l.r [col] = SET_FONT (l.r [col], THIS->fontset [GET_STYLE (l.r [col])]->find_font (l.t [col]));
1685     }
1686 root 1.9
1687     free (wstr);
1688 root 1.8 }
1689     }
1690    
1691     void
1692 root 1.27 rxvt_term::ROW_r (int row_number, SV *new_rend = 0, int start_col = 0, int start_ofs = 0, int max_len = MAX_COLS)
1693 root 1.8 PPCODE:
1694     {
1695 root 1.67 if (!IN_RANGE_EXC (row_number, THIS->top_row, THIS->nrow))
1696 root 1.19 XSRETURN_EMPTY;
1697 root 1.8
1698     line_t &l = ROW(row_number);
1699    
1700     if (GIMME_V != G_VOID)
1701     {
1702     AV *av = newAV ();
1703    
1704     av_extend (av, THIS->ncol - 1);
1705     for (int col = 0; col < THIS->ncol; col++)
1706     av_store (av, col, newSViv (l.r [col]));
1707    
1708     XPUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
1709     }
1710    
1711     if (new_rend)
1712     {
1713     if (!SvROK (new_rend) || SvTYPE (SvRV (new_rend)) != SVt_PVAV)
1714     croak ("new_rend must be arrayref");
1715    
1716     AV *av = (AV *)SvRV (new_rend);
1717 root 1.76 int len = min (AvFILL (av) + 1 - start_ofs, max_len);
1718 root 1.8
1719 root 1.83 if (start_col < 0 || start_col + len > THIS->ncol)
1720 root 1.10 croak ("new_rend array extends beyond horizontal margins");
1721 root 1.8
1722     for (int col = start_col; col < start_col + len; col++)
1723     {
1724 root 1.27 rend_t r = SvIV (*av_fetch (av, start_ofs + col - start_col, 1)) & ~RS_fontMask;
1725 root 1.8
1726     l.r [col] = SET_FONT (r, THIS->fontset [GET_STYLE (r)]->find_font (l.t [col]));
1727     }
1728     }
1729     }
1730    
1731     int
1732 root 1.26 rxvt_term::ROW_l (int row_number, int new_length = -1)
1733 root 1.8 CODE:
1734     {
1735 root 1.67 if (!IN_RANGE_EXC (row_number, THIS->top_row, THIS->nrow))
1736 root 1.19 XSRETURN_EMPTY;
1737 root 1.8
1738     line_t &l = ROW(row_number);
1739 root 1.26 RETVAL = l.l;
1740 root 1.8
1741 root 1.26 if (new_length >= 0)
1742 root 1.8 l.l = new_length;
1743     }
1744     OUTPUT:
1745     RETVAL
1746    
1747 root 1.19 bool
1748 root 1.26 rxvt_term::ROW_is_longer (int row_number, int new_is_longer = -1)
1749 root 1.19 CODE:
1750     {
1751 root 1.67 if (!IN_RANGE_EXC (row_number, THIS->top_row, THIS->nrow))
1752 root 1.19 XSRETURN_EMPTY;
1753    
1754     line_t &l = ROW(row_number);
1755 root 1.26 RETVAL = l.is_longer ();
1756    
1757     if (new_is_longer >= 0)
1758     l.is_longer (new_is_longer);
1759 root 1.19 }
1760     OUTPUT:
1761     RETVAL
1762    
1763 root 1.8 SV *
1764 root 1.33 rxvt_term::special_encode (SV *string)
1765 root 1.8 CODE:
1766 root 1.33 {
1767     wchar_t *wstr = sv2wcs (string);
1768     int wlen = wcslen (wstr);
1769 root 1.91 wchar_t *rstr = rxvt_temp_buf<wchar_t> (wlen * 2); // cannot become longer
1770 root 1.33
1771     rxvt_push_locale (THIS->locale);
1772    
1773     wchar_t *r = rstr;
1774     for (wchar_t *s = wstr; *s; s++)
1775 root 1.91 {
1776     int w = WCWIDTH (*s);
1777    
1778     if (w == 0)
1779     {
1780     if (r == rstr)
1781     croak ("leading combining character unencodable");
1782 root 1.33
1783 root 1.91 unicode_t n = rxvt_compose (r[-1], *s);
1784     if (n == NOCHAR)
1785     n = rxvt_composite.compose (r[-1], *s);
1786    
1787     r[-1] = n;
1788     }
1789 root 1.33 #if !UNICODE_3
1790 root 1.91 else if (*s >= 0x10000)
1791     *r++ = rxvt_composite.compose (*s);
1792 root 1.33 #endif
1793 root 1.91 else
1794     *r++ = *s;
1795    
1796     // the *2 above only allows wcwidth <= 2
1797     if (w > 1)
1798     *r++ = NOCHAR;
1799     }
1800 root 1.33
1801     rxvt_pop_locale ();
1802    
1803 sf-exg 1.230 free (wstr);
1804 root 1.71 RETVAL = wcs2sv (rstr, r - rstr);
1805 root 1.33 }
1806     OUTPUT:
1807     RETVAL
1808 root 1.8
1809     SV *
1810 root 1.33 rxvt_term::special_decode (SV *text)
1811 root 1.8 CODE:
1812 root 1.33 {
1813     wchar_t *wstr = sv2wcs (text);
1814     int dlen = 0;
1815    
1816     // find length
1817     for (wchar_t *s = wstr; *s; s++)
1818     if (*s == NOCHAR)
1819     ;
1820     else if (IS_COMPOSE (*s))
1821 root 1.250 dlen += rxvt_composite.expand (*s);
1822 root 1.33 else
1823     dlen++;
1824    
1825 root 1.91 wchar_t *rstr = rxvt_temp_buf<wchar_t> (dlen);
1826 root 1.33
1827     // decode
1828     wchar_t *r = rstr;
1829     for (wchar_t *s = wstr; *s; s++)
1830     if (*s == NOCHAR)
1831     ;
1832     else if (IS_COMPOSE (*s))
1833     r += rxvt_composite.expand (*s, r);
1834     else
1835     *r++ = *s;
1836    
1837 sf-exg 1.230 free (wstr);
1838 root 1.71 RETVAL = wcs2sv (rstr, r - rstr);
1839 root 1.33 }
1840     OUTPUT:
1841     RETVAL
1842 root 1.8
1843 root 1.1 void
1844 root 1.232 rxvt_term::_resource (octet_string name, int index, SV *newval = 0)
1845 root 1.2 PPCODE:
1846     {
1847 root 1.97 static const struct resval { const char *name; int value; } *rs, rslist [] = {
1848 root 1.21 # define def(name) { # name, Rs_ ## name },
1849     # define reserve(name,count)
1850 root 1.2 # include "rsinc.h"
1851 root 1.21 # undef def
1852     # undef reserve
1853 root 1.2 };
1854    
1855 sf-exg 1.141 rs = rslist + ecb_array_length (rslist);
1856 root 1.2
1857 root 1.123 if (*name)
1858     {
1859     do {
1860     if (rs-- == rslist)
1861     croak ("no such resource '%s', requested", name);
1862     } while (strcmp (name, rs->name));
1863 root 1.2
1864 root 1.123 index += rs->value;
1865     }
1866     else
1867     {
1868     --rs;
1869 root 1.244 name = (octet_string)"";
1870 root 1.123 }
1871 root 1.2
1872     if (!IN_RANGE_EXC (index, 0, NUM_RESOURCES))
1873     croak ("requested out-of-bound resource %s+%d,", name, index - rs->value);
1874    
1875     if (GIMME_V != G_VOID)
1876 root 1.71 XPUSHs (THIS->rs [index] ? sv_2mortal (newSVpv (THIS->rs [index], 0)) : &PL_sv_undef);
1877 root 1.2
1878     if (newval)
1879     {
1880     if (SvOK (newval))
1881     {
1882     char *str = strdup (SvPVbyte_nolen (newval));
1883     THIS->rs [index] = str;
1884     THIS->allocated.push_back (str);
1885     }
1886     else
1887     THIS->rs [index] = 0;
1888     }
1889     }
1890    
1891 root 1.55 const char *
1892 root 1.232 rxvt_term::x_resource (octet_string name)
1893 root 1.55
1894 root 1.40 bool
1895 ayin 1.113 rxvt_term::option (U8 optval, int set = -1)
1896 root 1.40 CODE:
1897     {
1898 ayin 1.113 RETVAL = THIS->option (optval);
1899 root 1.40
1900     if (set >= 0)
1901     {
1902 ayin 1.113 THIS->set_option (optval, set);
1903 root 1.40
1904 sf-exg 1.150 if (THIS->init_done) // avoid doing this before START
1905 root 1.78 switch (optval)
1906     {
1907     case Opt_skipBuiltinGlyphs:
1908     THIS->set_fonts ();
1909     THIS->scr_remap_chars ();
1910     THIS->scr_touch (true);
1911     THIS->want_refresh = 1;
1912 root 1.118 THIS->refresh_check ();
1913 root 1.78 break;
1914 sf-exg 1.153 #ifdef CURSOR_BLINK
1915     case Opt_cursorBlink:
1916     THIS->cursor_blink_reset ();
1917     break;
1918     #endif
1919    
1920 root 1.78 case Opt_cursorUnderline:
1921 sf-exg 1.225 THIS->cursor_type = set ? 1 : 0;
1922 root 1.78 THIS->want_refresh = 1;
1923 root 1.118 THIS->refresh_check ();
1924 root 1.78 break;
1925 root 1.40
1926     # case Opt_scrollBar_floating:
1927     # case Opt_scrollBar_right:
1928     # THIS->resize_all_windows (THIS->width, THIS->height, 1);
1929     # break;
1930 root 1.78 }
1931 root 1.40 }
1932     }
1933     OUTPUT:
1934     RETVAL
1935    
1936 sf-exg 1.236 SV *
1937     rxvt_term::lookup_keysym (int keysym, unsigned int state)
1938     CODE:
1939     {
1940     keysym_t *key = THIS->keyboard->lookup_keysym (THIS, keysym, state);
1941     RETVAL = key ? sv_2mortal (newSVpv (key->str, 0)) : &PL_sv_undef;
1942     }
1943     OUTPUT:
1944     RETVAL
1945    
1946 root 1.50 bool
1947 root 1.233 rxvt_term::bind_action (octet_string keysym, octet_string action)
1948 sf-exg 1.219 ALIAS:
1949     parse_keysym = 1
1950 root 1.50 CODE:
1951 root 1.232 RETVAL = 0 < THIS->bind_action (keysym, action);
1952 root 1.50 THIS->keyboard->register_done ();
1953     OUTPUT:
1954     RETVAL
1955    
1956 root 1.2 void
1957 sf-exg 1.229 rxvt_term::register_command (int keysym, unsigned int state, SV *str)
1958     CODE:
1959     wchar_t *wstr = sv2wcs (str);
1960     THIS->keyboard->register_action (keysym, state, wstr);
1961     free (wstr);
1962    
1963     void
1964 root 1.46 rxvt_term::screen_cur (...)
1965 root 1.1 PROTOTYPE: $;$$
1966     ALIAS:
1967 root 1.24 screen_cur = 0
1968     selection_beg = 1
1969     selection_end = 2
1970     selection_mark = 3
1971 root 1.1 PPCODE:
1972     {
1973 root 1.24 row_col_t &rc = ix == 0 ? THIS->screen.cur
1974     : ix == 1 ? THIS->selection.beg
1975     : ix == 2 ? THIS->selection.end
1976     : THIS->selection.mark;
1977 root 1.1
1978     if (GIMME_V != G_VOID)
1979     {
1980     EXTEND (SP, 2);
1981 root 1.24 PUSHs (sv_2mortal (newSViv (rc.row)));
1982     PUSHs (sv_2mortal (newSViv (rc.col)));
1983 root 1.1 }
1984    
1985 root 1.128 if (items >= 3)
1986 root 1.1 {
1987 root 1.73 rc.row = SvIV (ST (1));
1988     rc.col = SvIV (ST (2));
1989    
1990 root 1.89 if (ix == 2)
1991 root 1.73 {
1992 root 1.89 if (rc.col == 0)
1993     {
1994     // col == 0 means end of previous line
1995     rc.row--;
1996     rc.col = THIS->ncol;
1997     }
1998     else if (IN_RANGE_EXC (rc.row, THIS->top_row, THIS->nrow)
1999     && rc.col > ROW(rc.row).l)
2000     {
2001     // col >= length means while line and add newline
2002     rc.col = THIS->ncol;
2003     }
2004 root 1.73 }
2005    
2006     clamp_it (rc.col, 0, THIS->ncol);
2007     clamp_it (rc.row, THIS->top_row, THIS->nrow - 1);
2008 root 1.1
2009     if (ix)
2010 root 1.118 {
2011 root 1.128 THIS->selection.screen = THIS->current_screen;
2012    
2013 root 1.213 THIS->selection_changed ();
2014 root 1.118 THIS->refresh_check ();
2015     }
2016 root 1.1 }
2017     }
2018    
2019 root 1.128 int
2020     rxvt_term::selection_screen (int screen = -1)
2021 root 1.53 CODE:
2022 root 1.128 RETVAL = THIS->selection.screen;
2023     if (screen >= 0)
2024     THIS->selection.screen = screen;
2025     OUTPUT:
2026 root 1.53 RETVAL
2027    
2028 root 1.93 void
2029 sf-exg 1.215 rxvt_term::selection_request (Time tm, int selnum)
2030    
2031     void
2032 sf-exg 1.129 rxvt_term::selection_clear (bool clipboard = false)
2033    
2034     void
2035 root 1.79 rxvt_term::selection_make (Time eventtime, bool rect = false)
2036 root 1.60 CODE:
2037     THIS->selection.op = SELECTION_CONT;
2038     THIS->selection.rect = rect;
2039     THIS->selection_make (eventtime);
2040    
2041 root 1.1 int
2042 sf-exg 1.129 rxvt_term::selection_grab (Time eventtime, bool clipboard = false)
2043 root 1.1
2044     void
2045 sf-exg 1.130 rxvt_term::selection (SV *newtext = 0, bool clipboard = false)
2046 root 1.1 PPCODE:
2047     {
2048 sf-exg 1.130 wchar_t * &text = clipboard ? THIS->selection.clip_text : THIS->selection.text;
2049     unsigned int &len = clipboard ? THIS->selection.clip_len : THIS->selection.len;
2050    
2051 root 1.1 if (GIMME_V != G_VOID)
2052 sf-exg 1.130 XPUSHs (text
2053     ? sv_2mortal (wcs2sv (text, len))
2054 root 1.45 : &PL_sv_undef);
2055 root 1.1
2056     if (newtext)
2057     {
2058 sf-exg 1.130 free (text);
2059 root 1.1
2060 sf-exg 1.130 text = sv2wcs (newtext);
2061     len = wcslen (text);
2062 root 1.1 }
2063     }
2064 root 1.24
2065 root 1.128 char
2066     rxvt_term::cur_charset ()
2067     CODE:
2068     RETVAL = THIS->charsets [THIS->screen.charset];
2069     OUTPUT:
2070     RETVAL
2071    
2072 root 1.1 void
2073 root 1.51 rxvt_term::scr_xor_rect (int beg_row, int beg_col, int end_row, int end_col, U32 rstyle1 = RS_RVid, U32 rstyle2 = RS_RVid | RS_Uline)
2074    
2075     void
2076     rxvt_term::scr_xor_span (int beg_row, int beg_col, int end_row, int end_col, U32 rstyle = RS_RVid)
2077    
2078     void
2079 root 1.50 rxvt_term::scr_bell ()
2080    
2081     void
2082 root 1.231 rxvt_term::scr_recolor (bool refresh = true);
2083 root 1.161
2084     void
2085 root 1.86 rxvt_term::scr_change_screen (int screen)
2086    
2087     void
2088 root 1.25 rxvt_term::scr_add_lines (SV *string)
2089     CODE:
2090     {
2091     wchar_t *wstr = sv2wcs (string);
2092 root 1.32 THIS->scr_add_lines (wstr, wcslen (wstr));
2093 root 1.25 free (wstr);
2094     }
2095    
2096     void
2097 sf-exg 1.221 rxvt_term::tt_write_user_input (SV *octets)
2098     INIT:
2099     STRLEN len;
2100     char *str = SvPVbyte (octets, len);
2101     C_ARGS:
2102     str, len
2103    
2104     void
2105 root 1.13 rxvt_term::tt_write (SV *octets)
2106     INIT:
2107     STRLEN len;
2108     char *str = SvPVbyte (octets, len);
2109     C_ARGS:
2110 root 1.23 str, len
2111 root 1.13
2112 root 1.28 void
2113 sf-exg 1.132 rxvt_term::tt_paste (SV *octets)
2114     INIT:
2115     STRLEN len;
2116     char *str = SvPVbyte (octets, len);
2117     C_ARGS:
2118     str, len
2119    
2120     void
2121 root 1.28 rxvt_term::cmd_parse (SV *octets)
2122     CODE:
2123     {
2124     STRLEN len;
2125     char *str = SvPVbyte (octets, len);
2126    
2127     char *old_cmdbuf_ptr = THIS->cmdbuf_ptr;
2128     char *old_cmdbuf_endp = THIS->cmdbuf_endp;
2129    
2130     THIS->cmdbuf_ptr = str;
2131     THIS->cmdbuf_endp = str + len;
2132    
2133 root 1.35 rxvt_push_locale (THIS->locale);
2134 root 1.28 THIS->cmd_parse ();
2135 root 1.35 rxvt_pop_locale ();
2136 root 1.28
2137     THIS->cmdbuf_ptr = old_cmdbuf_ptr;
2138     THIS->cmdbuf_endp = old_cmdbuf_endp;
2139     }
2140    
2141 root 1.13 SV *
2142     rxvt_term::overlay (int x, int y, int w, int h, int rstyle = OVERLAY_RSTYLE, int border = 2)
2143     CODE:
2144     {
2145     overlay *o = new overlay (THIS, x, y, w, h, rstyle, border);
2146     RETVAL = newSVptr ((void *)o, "urxvt::overlay");
2147     o->self = (HV *)SvRV (RETVAL);
2148     }
2149     OUTPUT:
2150     RETVAL
2151    
2152 root 1.79 #############################################################################
2153     # Various X Utility Functions
2154     #############################################################################
2155    
2156     void
2157     rxvt_term::XListProperties (Window window)
2158     PPCODE:
2159     {
2160     int count;
2161 root 1.96 Atom *props = XListProperties (THIS->dpy, window, &count);
2162 root 1.79
2163     EXTEND (SP, count);
2164     while (count--)
2165     PUSHs (newSVuv ((U32)props [count]));
2166 ayin 1.115
2167 root 1.79 XFree (props);
2168     }
2169    
2170     void
2171     rxvt_term::XGetWindowProperty (Window window, Atom property)
2172     PPCODE:
2173     {
2174     Atom type;
2175     int format;
2176     unsigned long nitems;
2177     unsigned long bytes_after;
2178     unsigned char *prop;
2179 root 1.81
2180 root 1.96 XGetWindowProperty (THIS->dpy, window, property,
2181 root 1.81 0, 1<<24, 0, AnyPropertyType,
2182 root 1.79 &type, &format, &nitems, &bytes_after, &prop);
2183 root 1.81
2184 root 1.79 if (type != None)
2185     {
2186 root 1.81 int elemsize = format == 16 ? sizeof (short)
2187     : format == 32 ? sizeof (long)
2188     : 1;
2189    
2190 root 1.79 EXTEND (SP, 3);
2191     PUSHs (newSVuv ((U32)type));
2192     PUSHs (newSViv (format));
2193 root 1.81 PUSHs (newSVpvn ((char *)prop, nitems * elemsize));
2194 root 1.79 XFree (prop);
2195     }
2196     }
2197    
2198     void
2199 root 1.122 rxvt_term::XChangeProperty (Window window, Atom property, Atom type, int format, SV *data)
2200 root 1.79 CODE:
2201     {
2202     STRLEN len;
2203     char *data_ = SvPVbyte (data, len);
2204    
2205 root 1.81 int elemsize = format == 16 ? sizeof (short)
2206     : format == 32 ? sizeof (long)
2207     : 1;
2208    
2209 root 1.96 XChangeProperty (THIS->dpy, window, property,
2210 root 1.79 type, format, PropModeReplace,
2211 root 1.81 (unsigned char *)data_, len / elemsize);
2212 root 1.79 }
2213    
2214 root 1.81 Atom
2215 root 1.159 XInternAtom (rxvt_term *term, octet_string atom_name, int only_if_exists = FALSE)
2216 root 1.96 C_ARGS: term->dpy, atom_name, only_if_exists
2217 root 1.81
2218     char *
2219     XGetAtomName (rxvt_term *term, Atom atom)
2220 root 1.96 C_ARGS: term->dpy, atom
2221 root 1.81 CLEANUP:
2222     XFree (RETVAL);
2223    
2224 root 1.79 void
2225     XDeleteProperty (rxvt_term *term, Window window, Atom property)
2226 root 1.159 C_ARGS: term->dpy, window, property
2227 root 1.79
2228 root 1.257 Region
2229     XCreateRegion ()
2230    
2231     int
2232     XUnionRectWithRegion (int x, int y, int w, int h, Region src, Region dst)
2233     CODE:
2234     XRectangle rect;
2235     rect.x = x;
2236     rect.y = y;
2237     rect.width = w;
2238     rect.height = h;
2239     RETVAL = XUnionRectWithRegion (&rect, src, dst);
2240     OUTPUT: RETVAL
2241    
2242     int
2243     XIntersectRegion (Region src1, Region src2, Region res)
2244    
2245     int
2246     XUnionRegion (Region src1, Region src2, Region res)
2247    
2248     int
2249     XSubtractRegion (Region src1, Region src2, Region res)
2250    
2251     int
2252     XXorRegion (Region src1, Region src2, Region res)
2253    
2254     int
2255     XOffsetRegion (Region r, int dx, int dy)
2256    
2257     int
2258     XShrinkRegion (Region r, int dx, int dy)
2259    
2260     int
2261     XDestroyRegion (Region r)
2262    
2263     void
2264     rxvt_term::XShapeQueryVersion ()
2265     PPCODE:
2266     int major, minor;
2267     EXTEND (SP, 2);
2268     if (XShapeQueryVersion (THIS->display->dpy, &major, &minor))
2269     {
2270     PUSHs (sv_2mortal (newSViv (major)));
2271     PUSHs (sv_2mortal (newSViv (minor)));
2272     }
2273    
2274     void
2275     XShapeCombineRegion (rxvt_term *term, Window dest, int destKind, int xOff, int yOff, Region r, int op)
2276     C_ARGS: term->display->dpy, dest, destKind, xOff, yOff, r, op
2277    
2278     void
2279     XShapeCombineMask (rxvt_term *term, XID dest, int destKind, int xOff, int yOff, Pixmap src, int op)
2280     C_ARGS: term->display->dpy, dest, destKind, xOff, yOff, src, op
2281    
2282     void
2283     XShapeCombineShape (rxvt_term *term, XID dest, int destKind, int xOff, int yOff, Pixmap src, int srcKind, int op)
2284     C_ARGS: term->display->dpy, dest, destKind, xOff, yOff, src, srcKind, op
2285    
2286 root 1.79 Window
2287     rxvt_term::DefaultRootWindow ()
2288     CODE:
2289     RETVAL = THIS->display->root;
2290     OUTPUT:
2291     RETVAL
2292    
2293 root 1.81 #if 0
2294    
2295 root 1.79 Window
2296     XCreateSimpleWindow (rxvt_term *term, Window parent, int x, int y, unsigned int width, unsigned int height)
2297 root 1.96 C_ARGS: term->dpy, (Window)parent,
2298 root 1.79 x, y, width, height, 0,
2299     term->pix_colors_focused[Color_border],
2300     term->pix_colors_focused[Color_border]
2301    
2302 root 1.81 #endif
2303    
2304 root 1.79 void
2305     XReparentWindow (rxvt_term *term, Window window, Window parent, int x = 0, int y = 0)
2306 root 1.96 C_ARGS: term->dpy, window, parent, x, y
2307 root 1.79
2308     void
2309     XMapWindow (rxvt_term *term, Window window)
2310 root 1.96 C_ARGS: term->dpy, window
2311 root 1.79
2312     void
2313     XUnmapWindow (rxvt_term *term, Window window)
2314 root 1.96 C_ARGS: term->dpy, window
2315 root 1.79
2316     void
2317     XMoveResizeWindow (rxvt_term *term, Window window, int x, int y, unsigned int width, unsigned int height)
2318 root 1.96 C_ARGS: term->dpy, window, x, y, width, height
2319 root 1.84
2320     void
2321     rxvt_term::XChangeInput (Window window, U32 add_events, U32 del_events = 0)
2322     CODE:
2323     {
2324     XWindowAttributes attr;
2325 root 1.96 XGetWindowAttributes (THIS->dpy, window, &attr);
2326     XSelectInput (THIS->dpy, window, attr.your_event_mask | add_events & ~del_events);
2327 root 1.84 }
2328 root 1.79
2329 root 1.82 void
2330     rxvt_term::XTranslateCoordinates (Window src, Window dst, int x, int y)
2331     PPCODE:
2332     {
2333     int dx, dy;
2334     Window child;
2335    
2336 root 1.96 if (XTranslateCoordinates (THIS->dpy, src, dst, x, y, &dx, &dy, &child))
2337 root 1.82 {
2338     EXTEND (SP, 3);
2339     PUSHs (newSViv (dx));
2340     PUSHs (newSViv (dy));
2341     PUSHs (newSVuv (child));
2342     }
2343     }
2344    
2345 root 1.79 #############################################################################
2346 root 1.158 # fancy bg bloatstuff (TODO: should be moved up somewhere)
2347    
2348 root 1.191 bool
2349     rxvt_term::has_render ()
2350     CODE:
2351     RETVAL = THIS->display->flags & DISPLAY_HAS_RENDER;
2352     OUTPUT:
2353     RETVAL
2354    
2355 root 1.165 void
2356 root 1.181 rxvt_term::background_geometry (bool border = false)
2357 root 1.165 PPCODE:
2358     EXTEND (SP, 4);
2359 root 1.181 PUSHs (sv_2mortal (newSViv (THIS->parent_x + (border ? THIS->window_vt_x : 0))));
2360     PUSHs (sv_2mortal (newSViv (THIS->parent_y + (border ? THIS->window_vt_y : 0))));
2361     PUSHs (sv_2mortal (newSViv (border ? THIS->vt_width : THIS->szHint.width )));
2362     PUSHs (sv_2mortal (newSViv (border ? THIS->vt_height : THIS->szHint.height)));
2363 root 1.165
2364 root 1.162 #if HAVE_IMG
2365    
2366     rxvt_img *
2367 root 1.199 rxvt_term::new_img (SV *format = &PL_sv_undef, int x = 0, int y = 0, int width = 1, int height = 1)
2368 root 1.162 CODE:
2369     XRenderPictFormat *f = SvOK (format)
2370 sf-exg 1.168 ? XRenderFindStandardFormat (THIS->dpy, SvIV (format))
2371     : XRenderFindVisualFormat (THIS->dpy, THIS->visual);
2372 root 1.196 RETVAL = new rxvt_img (THIS, f, x, y, width, height);
2373 root 1.189 RETVAL->alloc ();
2374 root 1.162 OUTPUT:
2375     RETVAL
2376    
2377 root 1.160 #if ENABLE_TRANSPARENCY
2378 root 1.158
2379 root 1.159 rxvt_img *
2380     rxvt_term::new_img_from_root ()
2381     CODE:
2382     RETVAL = rxvt_img::new_from_root (THIS);
2383     OUTPUT:
2384     RETVAL
2385    
2386     #endif
2387 root 1.158
2388     #if HAVE_PIXBUF
2389    
2390 root 1.159 rxvt_img *
2391     rxvt_term::new_img_from_file (octet_string filename)
2392     CODE:
2393     try
2394     {
2395     RETVAL = rxvt_img::new_from_file (THIS, filename);
2396     }
2397     catch (const class rxvt_failure_exception &e)
2398     {
2399     croak ("new_img_from_file failed");
2400     }
2401     OUTPUT:
2402     RETVAL
2403    
2404 root 1.158 #endif
2405    
2406 root 1.161 void
2407 root 1.245 rxvt_term::clr_background ()
2408     CODE:
2409     delete THIS->bg_img;
2410     THIS->bg_img = 0;
2411     THIS->bg_flags = rxvt_term::BG_NEEDS_REFRESH;
2412    
2413     void
2414 root 1.180 rxvt_term::set_background (rxvt_img *img, bool border = false)
2415 root 1.161 CODE:
2416 sf-exg 1.210 delete THIS->bg_img;
2417     THIS->bg_img = 0;
2418 root 1.245 THIS->bg_flags = rxvt_term::BG_NEEDS_REFRESH;
2419 root 1.161
2420 root 1.245 //if (img) // TODO: cannot be false, maybe allow and get rid of clr_background?
2421 root 1.161 {
2422 root 1.183 img = img->clone (); // own the img
2423    
2424     if (img->repeat != RepeatNormal) // X11 only supports RepeatNormal as bg pixmap
2425 root 1.206 img->sub_rect (0, 0,
2426     border ? THIS->vt_width : THIS->szHint.width,
2427     border ? THIS->vt_height : THIS->szHint.height)
2428     ->replace (img);
2429 root 1.187
2430     // just in case, should usually be a nop
2431     img->reify ()
2432     ->replace (img);
2433    
2434     img->convert_format (XRenderFindVisualFormat (THIS->dpy, THIS->visual), THIS->pix_colors [Color_bg])
2435     ->replace (img);
2436 root 1.186
2437 sf-exg 1.190 THIS->bg_img = img;
2438 root 1.180
2439     if (!border)
2440     THIS->bg_flags |= rxvt_term::BG_IS_TRANSPARENT;
2441 root 1.161 }
2442    
2443     #endif
2444    
2445 root 1.158 #############################################################################
2446 root 1.79 # urxvt::overlay
2447     #############################################################################
2448    
2449 root 1.13 MODULE = urxvt PACKAGE = urxvt::overlay
2450 root 1.1
2451     void
2452 root 1.13 overlay::set (int x, int y, SV *text, SV *rend = 0)
2453 root 1.1
2454     void
2455 root 1.18 overlay::show ()
2456    
2457     void
2458     overlay::hide ()
2459    
2460     void
2461 root 1.13 overlay::DESTROY ()
2462 root 1.1
2463 root 1.109 INCLUDE: $PERL <iom_perl.xs -pe s/IOM_MODULE/urxvt/g,s/IOM_CLASS/urxvt/g |
2464 root 1.1
2465 root 1.155 MODULE = urxvt PACKAGE = urxvt::pixbuf PREFIX = gdk_pixbuf_
2466    
2467 root 1.156 #if HAVE_PIXBUF
2468    
2469     urxvt::pixbuf gdk_pixbuf_new_from_file (SV *klass, octet_string filename)
2470     C_ARGS: filename, 0
2471 root 1.155
2472     void
2473     DESTROY (urxvt::pixbuf self)
2474     CODE:
2475 sf-exg 1.201 g_object_unref (self);
2476 root 1.155
2477 root 1.156 #endif
2478    
2479     MODULE = urxvt PACKAGE = urxvt::img
2480    
2481     #if HAVE_IMG
2482    
2483 root 1.158 # rxvt_img *new (rxvt_screen *screen, XRenderPictFormat *format, int width, int height)
2484     # rxvt_img *rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap);
2485 root 1.156
2486 root 1.196 void
2487     rxvt_img::geometry ()
2488     PPCODE:
2489     EXTEND (SP, 4);
2490     PUSHs (sv_2mortal (newSViv (THIS->x)));
2491     PUSHs (sv_2mortal (newSViv (THIS->y)));
2492     PUSHs (sv_2mortal (newSViv (THIS->w)));
2493     PUSHs (sv_2mortal (newSViv (THIS->h)));
2494    
2495     int
2496     rxvt_img::x ()
2497 root 1.200 ALIAS:
2498     x = 0
2499     y = 1
2500     w = 2
2501     h = 3
2502     CODE:
2503     switch (ix)
2504     {
2505     case 0: RETVAL = THIS->x; break;
2506     case 1: RETVAL = THIS->y; break;
2507     case 2: RETVAL = THIS->w; break;
2508     case 3: RETVAL = THIS->h; break;
2509     }
2510 root 1.162 OUTPUT:
2511     RETVAL
2512    
2513     Pixmap
2514     rxvt_img::pm ()
2515     CODE:
2516     RETVAL = THIS->pm;
2517     OUTPUT:
2518     RETVAL
2519    
2520 root 1.158 void
2521 root 1.204 rxvt_img::fill (SV *c, int x = 0, int y = 0, int w = THIS->w, int h = THIS->h)
2522     PROTOTYPE: $;$$$$
2523 root 1.158 INIT:
2524 sf-exg 1.242 rxvt_screen screen;
2525     screen.set (THIS->d);
2526     rgba cc = parse_rgba (c, &screen);
2527 root 1.204 C_ARGS: cc, x, y, w, h
2528 root 1.156
2529 root 1.158 void
2530 root 1.159 rxvt_img::DESTROY ()
2531     CODE:
2532     delete THIS;
2533    
2534 root 1.176 void
2535 root 1.200 rxvt_img::add_alpha ()
2536    
2537     void
2538 root 1.176 rxvt_img::unshare ()
2539    
2540 root 1.200 void
2541 root 1.183 rxvt_img::repeat_mode (render_repeat_mode repeat = 0)
2542 root 1.200 PPCODE:
2543 root 1.183 if (items >= 2)
2544     THIS->repeat_mode (repeat);
2545     if (GIMME_V != G_VOID)
2546     XPUSHs (sv_2mortal (newSViv (THIS->repeat)));
2547 root 1.176
2548     void
2549     rxvt_img::move (int dx, int dy)
2550 root 1.156
2551 root 1.158 void
2552 root 1.197 rxvt_img::brightness (rxvt_img::nv r, rxvt_img::nv g, rxvt_img::nv b, rxvt_img::nv a = 1.)
2553 root 1.159
2554     void
2555 root 1.197 rxvt_img::contrast (rxvt_img::nv r, rxvt_img::nv g, rxvt_img::nv b, rxvt_img::nv a = 1.)
2556 root 1.156
2557 root 1.199 void
2558     rxvt_img::draw (rxvt_img *img, int op = PictOpOver, rxvt_img::nv mask = 1.);
2559    
2560 root 1.176 rxvt_img *
2561     rxvt_img::clone ()
2562 root 1.156
2563 root 1.158 rxvt_img *
2564 root 1.178 rxvt_img::reify ()
2565    
2566     rxvt_img *
2567 root 1.176 rxvt_img::sub_rect (int x, int y, int width, int height)
2568 root 1.156
2569 root 1.158 rxvt_img *
2570 root 1.176 rxvt_img::blur (int rh, int rv)
2571 root 1.167
2572     rxvt_img *
2573 root 1.205 rxvt_img::muladd (rxvt_img::nv mul, rxvt_img::nv add)
2574    
2575     rxvt_img *
2576 root 1.197 rxvt_img::transform (rxvt_img::nv p11, rxvt_img::nv p12, rxvt_img::nv p13, rxvt_img::nv p21, rxvt_img::nv p22, rxvt_img::nv p23, rxvt_img::nv p31, rxvt_img::nv p32, rxvt_img::nv p33)
2577 root 1.159 INIT:
2578 root 1.197 rxvt_img::nv matrix[3][3] = {
2579 root 1.193 { p11, p12, p13 },
2580     { p21, p22, p23 },
2581     { p31, p32, p33 }
2582 root 1.159 };
2583 root 1.193 C_ARGS: matrix
2584 root 1.156
2585 root 1.164 rxvt_img *
2586     rxvt_img::scale (int new_width, int new_height)
2587    
2588     rxvt_img *
2589 root 1.197 rxvt_img::rotate (int x, int y, rxvt_img::nv phi)
2590 root 1.164
2591 root 1.203 rxvt_img *
2592 root 1.200 rxvt_img::tint (SV *c)
2593     INIT:
2594 sf-exg 1.242 rxvt_screen screen;
2595     screen.set (THIS->d);
2596     rgba cc = parse_rgba (c, &screen);
2597 root 1.200 C_ARGS: cc
2598    
2599     rxvt_img *
2600 sf-exg 1.212 rxvt_img::shade (rxvt_img::nv factor)
2601    
2602     rxvt_img *
2603 root 1.200 rxvt_img::filter (octet_string name, SV *params = &PL_sv_undef)
2604     CODE:
2605     rxvt_img::nv *vparams = 0;
2606     int nparams = 0;
2607    
2608     if (SvOK (params))
2609     {
2610     if (!SvROK (params) || SvTYPE (SvRV (params)) != SVt_PVAV)
2611     croak ("rxvt_img::filter: params must be an array reference with parameter values");
2612    
2613     nparams = av_len ((AV *)SvRV (params)) + 1;
2614 sf-exg 1.214 vparams = (rxvt_img::nv *)malloc (nparams * sizeof (rxvt_img::nv));
2615 root 1.200
2616     for (int i = 0; i < nparams; ++i)
2617     vparams [i] = SvNV (*av_fetch ((AV *)SvRV (params), i, 1));
2618     }
2619    
2620     RETVAL = THIS->filter (name, nparams, vparams);
2621 sf-exg 1.214 free (vparams);
2622 root 1.200 OUTPUT:
2623     RETVAL
2624    
2625 root 1.156 #endif
2626