… | |
… | |
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 | } |
… | |
… | |
402 | perl_environ = rxvt_environ; |
417 | perl_environ = rxvt_environ; |
403 | swap (perl_environ, environ); |
418 | swap (perl_environ, environ); |
404 | |
419 | |
405 | char *argv[] = { |
420 | char *argv[] = { |
406 | "", |
421 | "", |
407 | "-edo '" LIBDIR "/urxvt.pm' or ($@ and die $@) or exit 1", |
422 | "-e" |
|
|
423 | "BEGIN {" |
|
|
424 | " urxvt->bootstrap;" |
|
|
425 | " unshift @INC, '" LIBDIR "';" |
|
|
426 | "}" |
|
|
427 | "" |
|
|
428 | "use urxvt;" |
408 | }; |
429 | }; |
409 | |
430 | |
410 | perl = perl_alloc (); |
431 | perl = perl_alloc (); |
411 | perl_construct (perl); |
432 | perl_construct (perl); |
412 | |
433 | |
… | |
… | |
427 | |
448 | |
428 | if (perl) |
449 | if (perl) |
429 | { |
450 | { |
430 | // runs outside of perls ENV |
451 | // runs outside of perls ENV |
431 | term->perl.self = (void *)newSVptr ((void *)term, "urxvt::term"); |
452 | term->perl.self = (void *)newSVptr ((void *)term, "urxvt::term"); |
432 | 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); |
433 | } |
454 | } |
434 | } |
455 | } |
435 | |
456 | |
436 | static void |
457 | static void |
437 | ungrab (rxvt_term *THIS) |
458 | ungrab (rxvt_term *THIS) |
… | |
… | |
442 | XUngrabPointer (THIS->display->display, THIS->perl.grabtime); |
463 | XUngrabPointer (THIS->display->display, THIS->perl.grabtime); |
443 | THIS->perl.grabtime = 0; |
464 | THIS->perl.grabtime = 0; |
444 | } |
465 | } |
445 | } |
466 | } |
446 | |
467 | |
447 | static void |
|
|
448 | swap_overlays (rxvt_term *term) |
|
|
449 | { |
|
|
450 | HV *hv = (HV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, 0)); |
|
|
451 | |
|
|
452 | if (HvKEYS (hv)) |
|
|
453 | { |
|
|
454 | hv_iterinit (hv); |
|
|
455 | |
|
|
456 | while (HE *he = hv_iternext (hv)) |
|
|
457 | ((overlay *)SvIV (hv_iterval (hv, he)))->swap (); |
|
|
458 | } |
|
|
459 | } |
|
|
460 | |
|
|
461 | bool |
468 | bool |
462 | rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) |
469 | rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) |
463 | { |
470 | { |
464 | if (!perl || !term->perl.self) |
471 | if (!perl || !term->perl.self) |
465 | return false; |
472 | return false; |
466 | |
473 | |
467 | // pre-handling of some events |
474 | // pre-handling of some events |
468 | if (htype == HOOK_REFRESH_END) |
475 | if (htype == HOOK_REFRESH_END) |
469 | 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 | } |
470 | |
482 | |
471 | swap (perl_environ, environ); |
483 | swap (perl_environ, environ); |
472 | |
484 | |
473 | bool event_consumed; |
485 | bool event_consumed; |
474 | |
486 | |
… | |
… | |
529 | XEvent *xe = va_arg (ap, XEvent *); |
541 | XEvent *xe = va_arg (ap, XEvent *); |
530 | HV *hv = newHV (); |
542 | HV *hv = newHV (); |
531 | |
543 | |
532 | # define set(name, sv) hv_store (hv, # name, sizeof (# name) - 1, sv, 0) |
544 | # define set(name, sv) hv_store (hv, # name, sizeof (# name) - 1, sv, 0) |
533 | # define setiv(name, val) hv_store (hv, # name, sizeof (# name) - 1, newSViv (val), 0) |
545 | # define setiv(name, val) hv_store (hv, # name, sizeof (# name) - 1, newSViv (val), 0) |
|
|
546 | # define setuv(name, val) hv_store (hv, # name, sizeof (# name) - 1, newSVuv (val), 0) |
534 | # undef set |
547 | # undef set |
535 | |
548 | |
536 | setiv (type, xe->type); |
549 | setiv (type, xe->type); |
537 | setiv (send_event, xe->xany.send_event); |
550 | setiv (send_event, xe->xany.send_event); |
538 | setiv (serial, xe->xany.serial); |
551 | setiv (serial, xe->xany.serial); |
… | |
… | |
542 | case KeyPress: |
555 | case KeyPress: |
543 | case KeyRelease: |
556 | case KeyRelease: |
544 | case ButtonPress: |
557 | case ButtonPress: |
545 | case ButtonRelease: |
558 | case ButtonRelease: |
546 | case MotionNotify: |
559 | case MotionNotify: |
|
|
560 | setuv (window, xe->xmotion.window); |
|
|
561 | setuv (root, xe->xmotion.root); |
|
|
562 | setuv (subwindow, xe->xmotion.subwindow); |
547 | setiv (time, xe->xmotion.time); |
563 | setuv (time, xe->xmotion.time); |
548 | setiv (x, xe->xmotion.x); |
564 | setiv (x, xe->xmotion.x); |
549 | setiv (y, xe->xmotion.y); |
565 | setiv (y, xe->xmotion.y); |
550 | setiv (row, xe->xmotion.y / term->fheight); |
566 | setiv (row, xe->xmotion.y / term->fheight); |
551 | setiv (col, xe->xmotion.x / term->fwidth); |
567 | setiv (col, xe->xmotion.x / term->fwidth); |
552 | setiv (x_root, xe->xmotion.x_root); |
568 | setiv (x_root, xe->xmotion.x_root); |
553 | setiv (y_root, xe->xmotion.y_root); |
569 | setiv (y_root, xe->xmotion.y_root); |
554 | setiv (state, xe->xmotion.state); |
570 | setuv (state, xe->xmotion.state); |
|
|
571 | |
|
|
572 | switch (xe->type) |
|
|
573 | { |
|
|
574 | case KeyPress: |
|
|
575 | case KeyRelease: |
|
|
576 | setuv (keycode, xe->xkey.keycode); |
|
|
577 | break; |
|
|
578 | |
|
|
579 | case ButtonPress: |
|
|
580 | case ButtonRelease: |
|
|
581 | setuv (button, xe->xbutton.button); |
|
|
582 | break; |
|
|
583 | |
|
|
584 | case MotionNotify: |
|
|
585 | setiv (is_hint, xe->xmotion.is_hint); |
|
|
586 | break; |
|
|
587 | } |
|
|
588 | |
555 | break; |
589 | break; |
556 | } |
|
|
557 | |
590 | |
|
|
591 | case MapNotify: |
|
|
592 | case UnmapNotify: |
|
|
593 | case ConfigureNotify: |
|
|
594 | setuv (event, xe->xconfigure.event); |
|
|
595 | setuv (window, xe->xconfigure.window); |
|
|
596 | |
558 | switch (xe->type) |
597 | switch (xe->type) |
559 | { |
598 | { |
560 | case KeyPress: |
599 | case ConfigureNotify: |
561 | case KeyRelease: |
600 | setiv (x, xe->xconfigure.x); |
562 | setiv (keycode, xe->xkey.keycode); |
601 | setiv (y, xe->xconfigure.y); |
|
|
602 | setiv (width, xe->xconfigure.width); |
|
|
603 | setiv (height, xe->xconfigure.height); |
|
|
604 | setuv (above, xe->xconfigure.above); |
563 | break; |
605 | break; |
564 | |
|
|
565 | case ButtonPress: |
|
|
566 | case ButtonRelease: |
|
|
567 | setiv (button, xe->xbutton.button); |
|
|
568 | break; |
606 | } |
569 | |
607 | |
570 | case MotionNotify: |
|
|
571 | setiv (is_hint, xe->xmotion.is_hint); |
|
|
572 | break; |
608 | break; |
573 | } |
609 | } |
574 | |
610 | |
575 | XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); |
611 | XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); |
576 | } |
612 | } |
… | |
… | |
617 | else |
653 | else |
618 | event_consumed = false; |
654 | event_consumed = false; |
619 | |
655 | |
620 | // post-handling of some events |
656 | // post-handling of some events |
621 | if (htype == HOOK_REFRESH_BEGIN) |
657 | if (htype == HOOK_REFRESH_BEGIN) |
622 | 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 | } |
623 | else if (htype == HOOK_DESTROY) |
664 | else if (htype == HOOK_DESTROY) |
624 | { |
665 | { |
625 | clearSVptr ((SV *)term->perl.self); |
666 | clearSVptr ((SV *)term->perl.self); |
626 | SvREFCNT_dec ((SV *)term->perl.self); |
667 | SvREFCNT_dec ((SV *)term->perl.self); |
627 | } |
668 | } |
… | |
… | |
841 | |
882 | |
842 | for (int i = 1; i < items; i++) |
883 | for (int i = 1; i < items; i++) |
843 | term->argv->push_back (strdup (SvPVbyte_nolen (ST (i)))); |
884 | term->argv->push_back (strdup (SvPVbyte_nolen (ST (i)))); |
844 | |
885 | |
845 | AV *envv = (AV *)SvRV (ST (0)); |
886 | AV *envv = (AV *)SvRV (ST (0)); |
846 | for (int i = av_len (envv) + 1; i--; ) |
887 | for (int i = AvFILL (envv) + 1; i--; ) |
847 | 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)))); |
848 | |
889 | |
849 | term->envv->push_back (0); |
890 | term->envv->push_back (0); |
850 | |
891 | |
851 | bool success; |
892 | bool success; |
… | |
… | |
1274 | { |
1315 | { |
1275 | if (!SvROK (new_rend) || SvTYPE (SvRV (new_rend)) != SVt_PVAV) |
1316 | if (!SvROK (new_rend) || SvTYPE (SvRV (new_rend)) != SVt_PVAV) |
1276 | croak ("new_rend must be arrayref"); |
1317 | croak ("new_rend must be arrayref"); |
1277 | |
1318 | |
1278 | AV *av = (AV *)SvRV (new_rend); |
1319 | AV *av = (AV *)SvRV (new_rend); |
1279 | int len = min (av_len (av) + 1 - start_ofs, max_len); |
1320 | int len = min (AvFILL (av) + 1 - start_ofs, max_len); |
1280 | |
1321 | |
1281 | if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len)) |
1322 | if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len)) |
1282 | croak ("new_rend array extends beyond horizontal margins"); |
1323 | croak ("new_rend array extends beyond horizontal margins"); |
1283 | |
1324 | |
1284 | for (int col = start_col; col < start_col + len; col++) |
1325 | for (int col = start_col; col < start_col + len; col++) |
… | |
… | |
1451 | if (set) |
1492 | if (set) |
1452 | THIS->options |= optval; |
1493 | THIS->options |= optval; |
1453 | else |
1494 | else |
1454 | THIS->options &= ~optval; |
1495 | THIS->options &= ~optval; |
1455 | |
1496 | |
|
|
1497 | if (THIS->check_ev.is_active ()) // avoid doing this before START |
1456 | switch (optval) |
1498 | switch (optval) |
1457 | { |
1499 | { |
1458 | case Opt_skipBuiltinGlyphs: |
1500 | case Opt_skipBuiltinGlyphs: |
1459 | THIS->set_fonts (); |
1501 | THIS->set_fonts (); |
1460 | THIS->scr_remap_chars (); |
1502 | THIS->scr_remap_chars (); |
1461 | THIS->scr_touch (true); |
1503 | THIS->scr_touch (true); |
1462 | THIS->want_refresh = 1; |
1504 | THIS->want_refresh = 1; |
1463 | break; |
1505 | break; |
1464 | |
1506 | |
1465 | case Opt_cursorUnderline: |
1507 | case Opt_cursorUnderline: |
1466 | THIS->want_refresh = 1; |
1508 | THIS->want_refresh = 1; |
1467 | break; |
1509 | break; |
1468 | |
1510 | |
1469 | # case Opt_scrollBar_floating: |
1511 | # case Opt_scrollBar_floating: |
1470 | # case Opt_scrollBar_right: |
1512 | # case Opt_scrollBar_right: |
1471 | # THIS->resize_all_windows (THIS->width, THIS->height, 1); |
1513 | # THIS->resize_all_windows (THIS->width, THIS->height, 1); |
1472 | # break; |
1514 | # break; |
1473 | } |
1515 | } |
1474 | } |
1516 | } |
1475 | } |
1517 | } |
1476 | OUTPUT: |
1518 | OUTPUT: |
1477 | RETVAL |
1519 | RETVAL |
1478 | |
1520 | |
… | |
… | |
1506 | PUSHs (sv_2mortal (newSViv (rc.col))); |
1548 | PUSHs (sv_2mortal (newSViv (rc.col))); |
1507 | } |
1549 | } |
1508 | |
1550 | |
1509 | if (items == 3) |
1551 | if (items == 3) |
1510 | { |
1552 | { |
|
|
1553 | rc.row = SvIV (ST (1)); |
|
|
1554 | rc.col = SvIV (ST (2)); |
|
|
1555 | |
|
|
1556 | if (ix == 2 && rc.col == 0) |
|
|
1557 | { |
|
|
1558 | rc.row--; |
|
|
1559 | rc.col = THIS->ncol; |
|
|
1560 | } |
|
|
1561 | |
|
|
1562 | clamp_it (rc.col, 0, THIS->ncol); |
1511 | rc.row = clamp (SvIV (ST (1)), THIS->top_row, THIS->nrow - 1); |
1563 | clamp_it (rc.row, THIS->top_row, THIS->nrow - 1); |
1512 | rc.col = clamp (SvIV (ST (2)), 0, THIS->ncol - 1); |
|
|
1513 | |
1564 | |
1514 | if (ix) |
1565 | if (ix) |
1515 | THIS->want_refresh = 1; |
1566 | THIS->want_refresh = 1; |
1516 | } |
1567 | } |
1517 | } |
1568 | } |
… | |
… | |
1676 | RETVAL = THIS; |
1727 | RETVAL = THIS; |
1677 | OUTPUT: |
1728 | OUTPUT: |
1678 | RETVAL |
1729 | RETVAL |
1679 | |
1730 | |
1680 | timer * |
1731 | timer * |
|
|
1732 | timer::after (NV delay) |
|
|
1733 | CODE: |
|
|
1734 | THIS->start (NOW + delay); |
|
|
1735 | RETVAL = THIS; |
|
|
1736 | OUTPUT: |
|
|
1737 | RETVAL |
|
|
1738 | |
|
|
1739 | timer * |
1681 | timer::stop () |
1740 | timer::stop () |
1682 | CODE: |
1741 | CODE: |
1683 | THIS->stop (); |
1742 | THIS->stop (); |
1684 | RETVAL = THIS; |
1743 | RETVAL = THIS; |
1685 | OUTPUT: |
1744 | OUTPUT: |