… | |
… | |
211 | |
211 | |
212 | #define SvOVERLAY(sv) (overlay *)SvPTR (sv, "urxvt::overlay") |
212 | #define SvOVERLAY(sv) (overlay *)SvPTR (sv, "urxvt::overlay") |
213 | |
213 | |
214 | struct overlay { |
214 | struct overlay { |
215 | HV *self; |
215 | HV *self; |
|
|
216 | bool visible; |
216 | rxvt_term *THIS; |
217 | rxvt_term *THIS; |
217 | int x, y, w, h; |
218 | int x, y, w, h; |
218 | int border; |
219 | int border; |
219 | text_t **text; |
220 | text_t **text; |
220 | rend_t **rend; |
221 | rend_t **rend; |
… | |
… | |
229 | |
230 | |
230 | void set (int x, int y, SV *str, SV *rend); |
231 | void set (int x, int y, SV *str, SV *rend); |
231 | }; |
232 | }; |
232 | |
233 | |
233 | overlay::overlay (rxvt_term *THIS, int x_, int y_, int w_, int h_, rend_t rstyle, int border) |
234 | overlay::overlay (rxvt_term *THIS, int x_, int y_, int w_, int h_, rend_t rstyle, int border) |
234 | : THIS(THIS), x(x_), y(y_), w(w_), h(h_), border(border == 2) |
235 | : THIS(THIS), x(x_), y(y_), w(w_), h(h_), border(border == 2), visible(false) |
235 | { |
236 | { |
236 | if (border == 2) |
237 | if (border == 2) |
237 | { |
238 | { |
238 | w += 2; |
239 | w += 2; |
239 | h += 2; |
240 | h += 2; |
… | |
… | |
300 | } |
301 | } |
301 | |
302 | |
302 | void |
303 | void |
303 | overlay::show () |
304 | overlay::show () |
304 | { |
305 | { |
305 | char key[33]; sprintf (key, "%32lx", (long)this); |
306 | if (visible) |
|
|
307 | return; |
306 | |
308 | |
|
|
309 | visible = true; |
|
|
310 | |
307 | HV *hv = (HV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)THIS->perl.self), "_overlay", 8, 0)); |
311 | AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)THIS->perl.self), "_overlay", 8, 0)); |
308 | hv_store (hv, key, 32, newSViv ((long)this), 0); |
312 | av_push (av, newSViv ((long)this)); |
309 | } |
313 | } |
310 | |
314 | |
311 | void |
315 | void |
312 | overlay::hide () |
316 | overlay::hide () |
313 | { |
317 | { |
|
|
318 | if (!visible) |
|
|
319 | return; |
|
|
320 | |
|
|
321 | visible = false; |
|
|
322 | |
314 | SV **ovs = hv_fetch ((HV *)SvRV ((SV *)THIS->perl.self), "_overlay", 8, 0); |
323 | AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)THIS->perl.self), "_overlay", 8, 0)); |
315 | |
324 | |
316 | if (ovs) |
325 | int i; |
|
|
326 | |
|
|
327 | for (i = AvFILL (av); i >= 0; i--) |
|
|
328 | if (SvIV (*av_fetch (av, i, 1)) == (long)this) |
317 | { |
329 | { |
318 | char key[33]; sprintf (key, "%32lx", (long)this); |
|
|
319 | |
|
|
320 | HV *hv = (HV *)SvRV (*ovs); |
|
|
321 | hv_delete (hv, key, 32, G_DISCARD); |
330 | av_delete (av, i, G_DISCARD); |
|
|
331 | break; |
322 | } |
332 | } |
|
|
333 | |
|
|
334 | for (; i < AvFILL (av); i++) |
|
|
335 | av_store (av, i, SvREFCNT_inc (*av_fetch (av, i + 1, 0))); |
|
|
336 | |
|
|
337 | av_pop (av); |
323 | } |
338 | } |
324 | |
339 | |
325 | void overlay::swap () |
340 | void overlay::swap () |
326 | { |
341 | { |
327 | int ov_x = max (0, min (MOD (x, THIS->ncol), THIS->ncol - w)); |
342 | int ov_x = max (0, min (MOD (x, THIS->ncol), THIS->ncol - w)); |
… | |
… | |
367 | if (!SvROK (rend) || SvTYPE (SvRV (rend)) != SVt_PVAV) |
382 | if (!SvROK (rend) || SvTYPE (SvRV (rend)) != SVt_PVAV) |
368 | croak ("rend must be arrayref"); |
383 | croak ("rend must be arrayref"); |
369 | |
384 | |
370 | AV *av = (AV *)SvRV (rend); |
385 | AV *av = (AV *)SvRV (rend); |
371 | |
386 | |
372 | for (int col = min (av_len (av) + 1, w - x - border); col--; ) |
387 | for (int col = min (AvFILL (av) + 1, w - x - border); col--; ) |
373 | this->rend [y][x + col] = SvIV (*av_fetch (av, col, 1)); |
388 | this->rend [y][x + col] = SvIV (*av_fetch (av, col, 1)); |
374 | } |
389 | } |
375 | |
390 | |
376 | THIS->want_refresh = 1; |
391 | THIS->want_refresh = 1; |
377 | } |
392 | } |
… | |
… | |
433 | |
448 | |
434 | if (perl) |
449 | if (perl) |
435 | { |
450 | { |
436 | // runs outside of perls ENV |
451 | // runs outside of perls ENV |
437 | term->perl.self = (void *)newSVptr ((void *)term, "urxvt::term"); |
452 | term->perl.self = (void *)newSVptr ((void *)term, "urxvt::term"); |
438 | hv_store ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, newRV_noinc ((SV *)newHV ()), 0); |
453 | hv_store ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, newRV_noinc ((SV *)newAV ()), 0); |
439 | } |
454 | } |
440 | } |
455 | } |
441 | |
456 | |
442 | static void |
457 | static void |
443 | ungrab (rxvt_term *THIS) |
458 | ungrab (rxvt_term *THIS) |
… | |
… | |
448 | XUngrabPointer (THIS->display->display, THIS->perl.grabtime); |
463 | XUngrabPointer (THIS->display->display, THIS->perl.grabtime); |
449 | THIS->perl.grabtime = 0; |
464 | THIS->perl.grabtime = 0; |
450 | } |
465 | } |
451 | } |
466 | } |
452 | |
467 | |
453 | static void |
|
|
454 | swap_overlays (rxvt_term *term) |
|
|
455 | { |
|
|
456 | HV *hv = (HV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, 0)); |
|
|
457 | |
|
|
458 | if (HvKEYS (hv)) |
|
|
459 | { |
|
|
460 | hv_iterinit (hv); |
|
|
461 | |
|
|
462 | while (HE *he = hv_iternext (hv)) |
|
|
463 | ((overlay *)SvIV (hv_iterval (hv, he)))->swap (); |
|
|
464 | } |
|
|
465 | } |
|
|
466 | |
|
|
467 | bool |
468 | bool |
468 | rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) |
469 | rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) |
469 | { |
470 | { |
470 | if (!perl || !term->perl.self) |
471 | if (!perl || !term->perl.self) |
471 | return false; |
472 | return false; |
472 | |
473 | |
473 | // pre-handling of some events |
474 | // pre-handling of some events |
474 | if (htype == HOOK_REFRESH_END) |
475 | if (htype == HOOK_REFRESH_END) |
475 | swap_overlays (term); |
476 | { |
|
|
477 | AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, 0)); |
|
|
478 | |
|
|
479 | for (int i = 0; i <= AvFILL (av); i++) |
|
|
480 | ((overlay *)SvIV (*av_fetch (av, i, 0)))->swap (); |
|
|
481 | } |
476 | |
482 | |
477 | swap (perl_environ, environ); |
483 | swap (perl_environ, environ); |
478 | |
484 | |
479 | bool event_consumed; |
485 | bool event_consumed; |
480 | |
486 | |
… | |
… | |
647 | else |
653 | else |
648 | event_consumed = false; |
654 | event_consumed = false; |
649 | |
655 | |
650 | // post-handling of some events |
656 | // post-handling of some events |
651 | if (htype == HOOK_REFRESH_BEGIN) |
657 | if (htype == HOOK_REFRESH_BEGIN) |
652 | swap_overlays (term); |
658 | { |
|
|
659 | AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, 0)); |
|
|
660 | |
|
|
661 | for (int i = AvFILL (av); i >= 0; i--) |
|
|
662 | ((overlay *)SvIV (*av_fetch (av, i, 0)))->swap (); |
|
|
663 | } |
653 | else if (htype == HOOK_DESTROY) |
664 | else if (htype == HOOK_DESTROY) |
654 | { |
665 | { |
655 | clearSVptr ((SV *)term->perl.self); |
666 | clearSVptr ((SV *)term->perl.self); |
656 | SvREFCNT_dec ((SV *)term->perl.self); |
667 | SvREFCNT_dec ((SV *)term->perl.self); |
657 | } |
668 | } |
… | |
… | |
871 | |
882 | |
872 | for (int i = 1; i < items; i++) |
883 | for (int i = 1; i < items; i++) |
873 | term->argv->push_back (strdup (SvPVbyte_nolen (ST (i)))); |
884 | term->argv->push_back (strdup (SvPVbyte_nolen (ST (i)))); |
874 | |
885 | |
875 | AV *envv = (AV *)SvRV (ST (0)); |
886 | AV *envv = (AV *)SvRV (ST (0)); |
876 | for (int i = av_len (envv) + 1; i--; ) |
887 | for (int i = AvFILL (envv) + 1; i--; ) |
877 | term->envv->push_back (strdup (SvPVbyte_nolen (*av_fetch (envv, i, 1)))); |
888 | term->envv->push_back (strdup (SvPVbyte_nolen (*av_fetch (envv, i, 1)))); |
878 | |
889 | |
879 | term->envv->push_back (0); |
890 | term->envv->push_back (0); |
880 | |
891 | |
881 | bool success; |
892 | bool success; |
… | |
… | |
1304 | { |
1315 | { |
1305 | if (!SvROK (new_rend) || SvTYPE (SvRV (new_rend)) != SVt_PVAV) |
1316 | if (!SvROK (new_rend) || SvTYPE (SvRV (new_rend)) != SVt_PVAV) |
1306 | croak ("new_rend must be arrayref"); |
1317 | croak ("new_rend must be arrayref"); |
1307 | |
1318 | |
1308 | AV *av = (AV *)SvRV (new_rend); |
1319 | AV *av = (AV *)SvRV (new_rend); |
1309 | int len = min (av_len (av) + 1 - start_ofs, max_len); |
1320 | int len = min (AvFILL (av) + 1 - start_ofs, max_len); |
1310 | |
1321 | |
1311 | if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len)) |
1322 | if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len)) |
1312 | croak ("new_rend array extends beyond horizontal margins"); |
1323 | croak ("new_rend array extends beyond horizontal margins"); |
1313 | |
1324 | |
1314 | for (int col = start_col; col < start_col + len; col++) |
1325 | for (int col = start_col; col < start_col + len; col++) |
… | |
… | |
1715 | RETVAL = THIS; |
1726 | RETVAL = THIS; |
1716 | OUTPUT: |
1727 | OUTPUT: |
1717 | RETVAL |
1728 | RETVAL |
1718 | |
1729 | |
1719 | timer * |
1730 | timer * |
|
|
1731 | timer::after (NV delay) |
|
|
1732 | CODE: |
|
|
1733 | THIS->start (NOW + delay); |
|
|
1734 | RETVAL = THIS; |
|
|
1735 | OUTPUT: |
|
|
1736 | RETVAL |
|
|
1737 | |
|
|
1738 | timer * |
1720 | timer::stop () |
1739 | timer::stop () |
1721 | CODE: |
1740 | CODE: |
1722 | THIS->stop (); |
1741 | THIS->stop (); |
1723 | RETVAL = THIS; |
1742 | RETVAL = THIS; |
1724 | OUTPUT: |
1743 | OUTPUT: |