… | |
… | |
35 | #include "rxvtutil.h" |
35 | #include "rxvtutil.h" |
36 | #include "rxvtperl.h" |
36 | #include "rxvtperl.h" |
37 | |
37 | |
38 | #include "perlxsi.c" |
38 | #include "perlxsi.c" |
39 | |
39 | |
|
|
40 | #undef LINENO |
|
|
41 | #define LINENO(n) MOD (THIS->term_start + int(n), THIS->total_rows) |
|
|
42 | #undef ROW |
|
|
43 | #define ROW(n) THIS->row_buf [LINENO (n)] |
|
|
44 | |
40 | ///////////////////////////////////////////////////////////////////////////// |
45 | ///////////////////////////////////////////////////////////////////////////// |
41 | |
46 | |
42 | static wchar_t * |
47 | static wchar_t * |
43 | sv2wcs (SV *sv) |
48 | sv2wcs (SV *sv) |
44 | { |
49 | { |
… | |
… | |
208 | } |
213 | } |
209 | |
214 | |
210 | bool |
215 | bool |
211 | rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) |
216 | rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) |
212 | { |
217 | { |
213 | if (!perl) |
218 | if (!perl |
|
|
219 | || (!should_invoke [htype] && htype != HOOK_INIT && htype != HOOK_DESTROY)) |
214 | return false; |
220 | return false; |
215 | |
221 | |
216 | if (htype == HOOK_INIT) // first hook ever called |
222 | if (htype == HOOK_INIT) // first hook ever called |
217 | term->self = (void *)newSVptr ((void *)term, "urxvt::term"); |
223 | term->self = (void *)newSVptr ((void *)term, "urxvt::term"); |
218 | else if (htype == HOOK_DESTROY) |
|
|
219 | { |
|
|
220 | // TODO: clear magic |
|
|
221 | hv_clear ((HV *)SvRV ((SV *)term->self)); |
|
|
222 | SvREFCNT_dec ((SV *)term->self); |
|
|
223 | } |
|
|
224 | |
224 | |
225 | if (!should_invoke [htype]) |
|
|
226 | return false; |
|
|
227 | |
|
|
228 | dSP; |
225 | dSP; |
229 | va_list ap; |
226 | va_list ap; |
230 | |
227 | |
231 | va_start (ap, htype); |
228 | va_start (ap, htype); |
232 | |
229 | |
… | |
… | |
249 | |
246 | |
250 | case DT_LONG: |
247 | case DT_LONG: |
251 | XPUSHs (sv_2mortal (newSViv (va_arg (ap, long)))); |
248 | XPUSHs (sv_2mortal (newSViv (va_arg (ap, long)))); |
252 | break; |
249 | break; |
253 | |
250 | |
|
|
251 | case DT_STRING: |
|
|
252 | XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0))); |
|
|
253 | break; |
|
|
254 | |
254 | case DT_END: |
255 | case DT_END: |
255 | { |
256 | { |
256 | va_end (ap); |
257 | va_end (ap); |
257 | |
258 | |
258 | PUTBACK; |
259 | PUTBACK; |
… | |
… | |
270 | LEAVE; |
271 | LEAVE; |
271 | |
272 | |
272 | if (SvTRUE (ERRSV)) |
273 | if (SvTRUE (ERRSV)) |
273 | rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPV_nolen (ERRSV)); |
274 | rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPV_nolen (ERRSV)); |
274 | |
275 | |
|
|
276 | if (htype == HOOK_DESTROY) |
|
|
277 | { |
|
|
278 | // TODO: clear magic |
|
|
279 | hv_clear ((HV *)SvRV ((SV *)term->self)); |
|
|
280 | SvREFCNT_dec ((SV *)term->self); |
|
|
281 | } |
|
|
282 | |
275 | return count; |
283 | return count; |
276 | } |
284 | } |
277 | |
285 | |
278 | default: |
286 | default: |
279 | rxvt_fatal ("FATAL: unable to pass data type %d\n", dt); |
287 | rxvt_fatal ("FATAL: unable to pass data type %d\n", dt); |
… | |
… | |
288 | PROTOTYPES: ENABLE |
296 | PROTOTYPES: ENABLE |
289 | |
297 | |
290 | BOOT: |
298 | BOOT: |
291 | { |
299 | { |
292 | # define set_hookname(sym) av_store (hookname, PP_CONCAT(HOOK_, sym), newSVpv (PP_STRINGIFY(sym), 0)) |
300 | # define set_hookname(sym) av_store (hookname, PP_CONCAT(HOOK_, sym), newSVpv (PP_STRINGIFY(sym), 0)) |
|
|
301 | # define export_const(name) newCONSTSUB (gv_stashpv ("urxvt", 1), #name, newSViv (name)); |
293 | AV *hookname = get_av ("urxvt::HOOKNAME", 1); |
302 | AV *hookname = get_av ("urxvt::HOOKNAME", 1); |
294 | set_hookname (LOAD); |
|
|
295 | set_hookname (INIT); |
303 | set_hookname (INIT); |
296 | set_hookname (RESET); |
304 | set_hookname (RESET); |
297 | set_hookname (START); |
305 | set_hookname (START); |
298 | set_hookname (DESTROY); |
306 | set_hookname (DESTROY); |
299 | set_hookname (SEL_BEGIN); |
307 | set_hookname (SEL_BEGIN); |
… | |
… | |
305 | set_hookname (VIEW_CHANGE); |
313 | set_hookname (VIEW_CHANGE); |
306 | set_hookname (SCROLL_BACK); |
314 | set_hookname (SCROLL_BACK); |
307 | set_hookname (TTY_ACTIVITY); |
315 | set_hookname (TTY_ACTIVITY); |
308 | set_hookname (REFRESH_BEGIN); |
316 | set_hookname (REFRESH_BEGIN); |
309 | set_hookname (REFRESH_END); |
317 | set_hookname (REFRESH_END); |
|
|
318 | set_hookname (KEYBOARD_COMMAND); |
|
|
319 | |
|
|
320 | export_const (DEFAULT_RSTYLE); |
|
|
321 | export_const (OVERLAY_RSTYLE); |
|
|
322 | export_const (RS_Bold); |
|
|
323 | export_const (RS_Italic); |
|
|
324 | export_const (RS_Blink); |
|
|
325 | export_const (RS_RVid); |
|
|
326 | export_const (RS_Uline); |
310 | |
327 | |
311 | sv_setpv (get_sv ("urxvt::LIBDIR", 1), LIBDIR); |
328 | sv_setpv (get_sv ("urxvt::LIBDIR", 1), LIBDIR); |
312 | } |
329 | } |
313 | |
330 | |
314 | void |
331 | void |
… | |
… | |
323 | |
340 | |
324 | void |
341 | void |
325 | fatal (const char *msg) |
342 | fatal (const char *msg) |
326 | CODE: |
343 | CODE: |
327 | rxvt_fatal ("%s", msg); |
344 | rxvt_fatal ("%s", msg); |
328 | |
|
|
329 | int |
|
|
330 | wcswidth (SV *str) |
|
|
331 | CODE: |
|
|
332 | { |
|
|
333 | wchar_t *wstr = sv2wcs (str); |
|
|
334 | RETVAL = wcswidth (wstr, wcslen (wstr)); |
|
|
335 | free (wstr); |
|
|
336 | } |
|
|
337 | OUTPUT: |
|
|
338 | RETVAL |
|
|
339 | |
345 | |
340 | NV |
346 | NV |
341 | NOW () |
347 | NOW () |
342 | CODE: |
348 | CODE: |
343 | RETVAL = NOW; |
349 | RETVAL = NOW; |
344 | OUTPUT: |
350 | OUTPUT: |
345 | RETVAL |
351 | RETVAL |
346 | |
352 | |
|
|
353 | int |
|
|
354 | GET_BASEFG (int rend) |
|
|
355 | CODE: |
|
|
356 | RETVAL = GET_BASEFG (rend); |
|
|
357 | OUTPUT: |
|
|
358 | RETVAL |
|
|
359 | |
|
|
360 | int |
|
|
361 | GET_BASEBG (int rend) |
|
|
362 | CODE: |
|
|
363 | RETVAL = GET_BASEBG (rend); |
|
|
364 | OUTPUT: |
|
|
365 | RETVAL |
|
|
366 | |
|
|
367 | int |
|
|
368 | SET_FGCOLOR (int rend, int new_color) |
|
|
369 | CODE: |
|
|
370 | RETVAL = SET_FGCOLOR (rend, new_color); |
|
|
371 | OUTPUT: |
|
|
372 | RETVAL |
|
|
373 | |
|
|
374 | int |
|
|
375 | SET_BGCOLOR (int rend, int new_color) |
|
|
376 | CODE: |
|
|
377 | RETVAL = SET_BGCOLOR (rend, new_color); |
|
|
378 | OUTPUT: |
|
|
379 | RETVAL |
|
|
380 | |
|
|
381 | int |
|
|
382 | GET_CUSTOM (int rend) |
|
|
383 | CODE: |
|
|
384 | RETVAL = (rend && RS_customMask) >> RS_customShift; |
|
|
385 | OUTPUT: |
|
|
386 | RETVAL |
|
|
387 | |
|
|
388 | int |
|
|
389 | SET_CUSTOM (int rend, int new_value) |
|
|
390 | CODE: |
|
|
391 | { |
|
|
392 | if (!IN_RANGE_EXC (new_value, 0, RS_customCount)) |
|
|
393 | croak ("custom value out of range, must be 0..%d", RS_customCount - 1); |
|
|
394 | |
|
|
395 | RETVAL = (rend & ~RS_customMask) |
|
|
396 | | ((new_value << RS_customShift) & RS_customMask); |
|
|
397 | } |
|
|
398 | OUTPUT: |
|
|
399 | RETVAL |
|
|
400 | |
347 | MODULE = urxvt PACKAGE = urxvt::term |
401 | MODULE = urxvt PACKAGE = urxvt::term |
|
|
402 | |
|
|
403 | int |
|
|
404 | rxvt_term::strwidth (SV *str) |
|
|
405 | CODE: |
|
|
406 | { |
|
|
407 | wchar_t *wstr = sv2wcs (str); |
|
|
408 | |
|
|
409 | rxvt_push_locale (THIS->locale); |
|
|
410 | RETVAL = wcswidth (wstr, wcslen (wstr)); |
|
|
411 | rxvt_pop_locale (); |
|
|
412 | |
|
|
413 | free (wstr); |
|
|
414 | } |
|
|
415 | OUTPUT: |
|
|
416 | RETVAL |
|
|
417 | |
|
|
418 | SV * |
|
|
419 | rxvt_term::locale_encode (SV *str) |
|
|
420 | CODE: |
|
|
421 | { |
|
|
422 | wchar_t *wstr = sv2wcs (str); |
|
|
423 | |
|
|
424 | rxvt_push_locale (THIS->locale); |
|
|
425 | char *mbstr = rxvt_wcstombs (wstr); |
|
|
426 | rxvt_pop_locale (); |
|
|
427 | |
|
|
428 | free (wstr); |
|
|
429 | |
|
|
430 | RETVAL = newSVpv (mbstr, 0); |
|
|
431 | free (mbstr); |
|
|
432 | } |
|
|
433 | OUTPUT: |
|
|
434 | RETVAL |
|
|
435 | |
|
|
436 | SV * |
|
|
437 | rxvt_term::locale_decode (SV *octets) |
|
|
438 | CODE: |
|
|
439 | { |
|
|
440 | STRLEN len; |
|
|
441 | char *data = SvPVbyte (octets, len); |
|
|
442 | |
|
|
443 | rxvt_push_locale (THIS->locale); |
|
|
444 | wchar_t *wstr = rxvt_mbstowcs (data, len); |
|
|
445 | rxvt_pop_locale (); |
|
|
446 | |
|
|
447 | char *str = rxvt_wcstoutf8 (wstr); |
|
|
448 | free (wstr); |
|
|
449 | |
|
|
450 | RETVAL = newSVpv (str, 0); |
|
|
451 | SvUTF8_on (RETVAL); |
|
|
452 | free (str); |
|
|
453 | } |
|
|
454 | OUTPUT: |
|
|
455 | RETVAL |
|
|
456 | |
|
|
457 | int |
|
|
458 | rxvt_term::nsaved () |
|
|
459 | CODE: |
|
|
460 | RETVAL = THIS->nsaved; |
|
|
461 | OUTPUT: |
|
|
462 | RETVAL |
|
|
463 | |
|
|
464 | int |
|
|
465 | rxvt_term::view_start (int newval = -1) |
|
|
466 | CODE: |
|
|
467 | { |
|
|
468 | RETVAL = THIS->view_start; |
|
|
469 | |
|
|
470 | if (newval >= 0) |
|
|
471 | { |
|
|
472 | THIS->view_start = min (newval, THIS->nsaved); |
|
|
473 | THIS->scr_changeview (RETVAL); |
|
|
474 | } |
|
|
475 | } |
|
|
476 | OUTPUT: |
|
|
477 | RETVAL |
|
|
478 | |
|
|
479 | int |
|
|
480 | rxvt_term::nrow () |
|
|
481 | CODE: |
|
|
482 | RETVAL = THIS->nrow; |
|
|
483 | OUTPUT: |
|
|
484 | RETVAL |
|
|
485 | |
|
|
486 | int |
|
|
487 | rxvt_term::ncol () |
|
|
488 | CODE: |
|
|
489 | RETVAL = THIS->ncol; |
|
|
490 | OUTPUT: |
|
|
491 | RETVAL |
|
|
492 | |
|
|
493 | void |
|
|
494 | rxvt_term::want_refresh () |
|
|
495 | CODE: |
|
|
496 | THIS->want_refresh = 1; |
|
|
497 | |
|
|
498 | void |
|
|
499 | rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0) |
|
|
500 | PPCODE: |
|
|
501 | { |
|
|
502 | if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow)) |
|
|
503 | croak ("row_number number of out range"); |
|
|
504 | |
|
|
505 | line_t &l = ROW(row_number); |
|
|
506 | |
|
|
507 | if (GIMME_V != G_VOID) |
|
|
508 | { |
|
|
509 | wchar_t *wstr = new wchar_t [THIS->ncol]; |
|
|
510 | |
|
|
511 | for (int col = 0; col <THIS->ncol; col++) |
|
|
512 | wstr [col] = l.t [col]; |
|
|
513 | |
|
|
514 | char *str = rxvt_wcstoutf8 (wstr, THIS->ncol); |
|
|
515 | free (wstr); |
|
|
516 | |
|
|
517 | SV *sv = newSVpv (str, 0); |
|
|
518 | SvUTF8_on (sv); |
|
|
519 | XPUSHs (sv_2mortal (sv)); |
|
|
520 | free (str); |
|
|
521 | } |
|
|
522 | |
|
|
523 | if (new_text) |
|
|
524 | { |
|
|
525 | STRLEN slen; |
|
|
526 | char *str = SvPVutf8 (new_text, slen); |
|
|
527 | wchar_t *wstr = rxvt_utf8towcs (str, slen); |
|
|
528 | |
|
|
529 | int len = wcslen (wstr); |
|
|
530 | |
|
|
531 | if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len)) |
|
|
532 | { |
|
|
533 | free (wstr); |
|
|
534 | croak ("new_text extends beyond horizontal margins"); |
|
|
535 | } |
|
|
536 | |
|
|
537 | for (int col = start_col; col < start_col + len; col++) |
|
|
538 | { |
|
|
539 | l.t [col] = wstr [col - start_col]; |
|
|
540 | l.r [col] = SET_FONT (l.r [col], THIS->fontset [GET_STYLE (l.r [col])]->find_font (l.t [col])); |
|
|
541 | } |
|
|
542 | |
|
|
543 | free (wstr); |
|
|
544 | } |
|
|
545 | } |
|
|
546 | |
|
|
547 | void |
|
|
548 | rxvt_term::ROW_r (int row_number, SV *new_rend = 0, int start_col = 0) |
|
|
549 | PPCODE: |
|
|
550 | { |
|
|
551 | if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow)) |
|
|
552 | croak ("row_number number of out range"); |
|
|
553 | |
|
|
554 | line_t &l = ROW(row_number); |
|
|
555 | |
|
|
556 | if (GIMME_V != G_VOID) |
|
|
557 | { |
|
|
558 | AV *av = newAV (); |
|
|
559 | |
|
|
560 | av_extend (av, THIS->ncol - 1); |
|
|
561 | for (int col = 0; col < THIS->ncol; col++) |
|
|
562 | av_store (av, col, newSViv (l.r [col])); |
|
|
563 | |
|
|
564 | XPUSHs (sv_2mortal (newRV_noinc ((SV *)av))); |
|
|
565 | } |
|
|
566 | |
|
|
567 | if (new_rend) |
|
|
568 | { |
|
|
569 | if (!SvROK (new_rend) || SvTYPE (SvRV (new_rend)) != SVt_PVAV) |
|
|
570 | croak ("new_rend must be arrayref"); |
|
|
571 | |
|
|
572 | AV *av = (AV *)SvRV (new_rend); |
|
|
573 | int len = av_len (av) + 1; |
|
|
574 | |
|
|
575 | if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len)) |
|
|
576 | croak ("new_rend array extends beyond horizontal margins"); |
|
|
577 | |
|
|
578 | for (int col = start_col; col < start_col + len; col++) |
|
|
579 | { |
|
|
580 | rend_t r = SvIV (*av_fetch (av, col - start_col, 1)) & ~RS_fontMask; |
|
|
581 | |
|
|
582 | l.r [col] = SET_FONT (r, THIS->fontset [GET_STYLE (r)]->find_font (l.t [col])); |
|
|
583 | } |
|
|
584 | } |
|
|
585 | } |
|
|
586 | |
|
|
587 | int |
|
|
588 | rxvt_term::ROW_l (int row_number, int new_length = -2) |
|
|
589 | CODE: |
|
|
590 | { |
|
|
591 | if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow)) |
|
|
592 | croak ("row_number number of out range"); |
|
|
593 | |
|
|
594 | line_t &l = ROW(row_number); |
|
|
595 | RETVAL = l.l; |
|
|
596 | |
|
|
597 | if (new_length >= -1) |
|
|
598 | l.l = new_length; |
|
|
599 | } |
|
|
600 | OUTPUT: |
|
|
601 | RETVAL |
|
|
602 | |
|
|
603 | SV * |
|
|
604 | rxvt_term::special_encode (SV *str) |
|
|
605 | CODE: |
|
|
606 | abort ();//TODO |
|
|
607 | |
|
|
608 | SV * |
|
|
609 | rxvt_term::special_decode (SV *str) |
|
|
610 | CODE: |
|
|
611 | abort ();//TODO |
|
|
612 | |
|
|
613 | void |
|
|
614 | rxvt_term::_resource (char *name, int index, SV *newval = 0) |
|
|
615 | PPCODE: |
|
|
616 | { |
|
|
617 | struct resval { const char *name; int value; } rslist [] = { |
|
|
618 | # define Rs_def(name) { # name, Rs_ ## name }, |
|
|
619 | # define Rs_reserve(name,count) |
|
|
620 | # include "rsinc.h" |
|
|
621 | # undef Rs_def |
|
|
622 | # undef Rs_reserve |
|
|
623 | }; |
|
|
624 | |
|
|
625 | struct resval *rs = rslist + sizeof (rslist) / sizeof (rslist [0]); |
|
|
626 | |
|
|
627 | do { |
|
|
628 | if (rs-- == rslist) |
|
|
629 | croak ("no such resource '%s', requested", name); |
|
|
630 | } while (strcmp (name, rs->name)); |
|
|
631 | |
|
|
632 | index += rs->value; |
|
|
633 | |
|
|
634 | if (!IN_RANGE_EXC (index, 0, NUM_RESOURCES)) |
|
|
635 | croak ("requested out-of-bound resource %s+%d,", name, index - rs->value); |
|
|
636 | |
|
|
637 | if (GIMME_V != G_VOID) |
|
|
638 | XPUSHs (THIS->rs [index] ? sv_2mortal (newSVpv (THIS->rs [index], 0)) : &PL_sv_undef); |
|
|
639 | |
|
|
640 | if (newval) |
|
|
641 | { |
|
|
642 | if (SvOK (newval)) |
|
|
643 | { |
|
|
644 | char *str = strdup (SvPVbyte_nolen (newval)); |
|
|
645 | THIS->rs [index] = str; |
|
|
646 | THIS->allocated.push_back (str); |
|
|
647 | } |
|
|
648 | else |
|
|
649 | THIS->rs [index] = 0; |
|
|
650 | } |
|
|
651 | } |
348 | |
652 | |
349 | void |
653 | void |
350 | rxvt_term::selection_mark (...) |
654 | rxvt_term::selection_mark (...) |
351 | PROTOTYPE: $;$$ |
655 | PROTOTYPE: $;$$ |
352 | ALIAS: |
656 | ALIAS: |
… | |
… | |
418 | wchar_t *wtext = sv2wcs (text); |
722 | wchar_t *wtext = sv2wcs (text); |
419 | THIS->scr_overlay_set (x, y, wtext); |
723 | THIS->scr_overlay_set (x, y, wtext); |
420 | free (wtext); |
724 | free (wtext); |
421 | } |
725 | } |
422 | |
726 | |
|
|
727 | void |
|
|
728 | rxvt_term::tt_write (SV *octets) |
|
|
729 | INIT: |
|
|
730 | STRLEN len; |
|
|
731 | char *str = SvPVbyte (octets, len); |
|
|
732 | C_ARGS: |
|
|
733 | (unsigned char *)str, len |
|
|
734 | |
423 | MODULE = urxvt PACKAGE = urxvt::timer |
735 | MODULE = urxvt PACKAGE = urxvt::timer |
424 | |
736 | |
425 | SV * |
737 | SV * |
426 | timer::new () |
738 | timer::new () |
427 | CODE: |
739 | CODE: |