… | |
… | |
208 | } |
208 | } |
209 | |
209 | |
210 | bool |
210 | bool |
211 | rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) |
211 | rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) |
212 | { |
212 | { |
213 | if (!perl) |
213 | if (!perl |
|
|
214 | || (!should_invoke [htype] && htype != HOOK_INIT && htype != HOOK_DESTROY)) |
214 | return false; |
215 | return false; |
215 | |
216 | |
216 | if (htype == HOOK_INIT) // first hook ever called |
217 | if (htype == HOOK_INIT) // first hook ever called |
217 | term->self = (void *)newSVptr ((void *)term, "urxvt::term"); |
218 | 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 | |
219 | |
225 | if (!should_invoke [htype]) |
|
|
226 | return false; |
|
|
227 | |
|
|
228 | dSP; |
220 | dSP; |
229 | va_list ap; |
221 | va_list ap; |
230 | |
222 | |
231 | va_start (ap, htype); |
223 | va_start (ap, htype); |
232 | |
224 | |
… | |
… | |
249 | |
241 | |
250 | case DT_LONG: |
242 | case DT_LONG: |
251 | XPUSHs (sv_2mortal (newSViv (va_arg (ap, long)))); |
243 | XPUSHs (sv_2mortal (newSViv (va_arg (ap, long)))); |
252 | break; |
244 | break; |
253 | |
245 | |
|
|
246 | case DT_STRING: |
|
|
247 | XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0))); |
|
|
248 | break; |
|
|
249 | |
254 | case DT_END: |
250 | case DT_END: |
255 | { |
251 | { |
256 | va_end (ap); |
252 | va_end (ap); |
257 | |
253 | |
258 | PUTBACK; |
254 | PUTBACK; |
… | |
… | |
270 | LEAVE; |
266 | LEAVE; |
271 | |
267 | |
272 | if (SvTRUE (ERRSV)) |
268 | if (SvTRUE (ERRSV)) |
273 | rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPV_nolen (ERRSV)); |
269 | rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPV_nolen (ERRSV)); |
274 | |
270 | |
|
|
271 | if (htype == HOOK_DESTROY) |
|
|
272 | { |
|
|
273 | // TODO: clear magic |
|
|
274 | hv_clear ((HV *)SvRV ((SV *)term->self)); |
|
|
275 | SvREFCNT_dec ((SV *)term->self); |
|
|
276 | } |
|
|
277 | |
275 | return count; |
278 | return count; |
276 | } |
279 | } |
277 | |
280 | |
278 | default: |
281 | default: |
279 | rxvt_fatal ("FATAL: unable to pass data type %d\n", dt); |
282 | rxvt_fatal ("FATAL: unable to pass data type %d\n", dt); |
… | |
… | |
289 | |
292 | |
290 | BOOT: |
293 | BOOT: |
291 | { |
294 | { |
292 | # define set_hookname(sym) av_store (hookname, PP_CONCAT(HOOK_, sym), newSVpv (PP_STRINGIFY(sym), 0)) |
295 | # define set_hookname(sym) av_store (hookname, PP_CONCAT(HOOK_, sym), newSVpv (PP_STRINGIFY(sym), 0)) |
293 | AV *hookname = get_av ("urxvt::HOOKNAME", 1); |
296 | AV *hookname = get_av ("urxvt::HOOKNAME", 1); |
294 | set_hookname (LOAD); |
|
|
295 | set_hookname (INIT); |
297 | set_hookname (INIT); |
296 | set_hookname (RESET); |
298 | set_hookname (RESET); |
297 | set_hookname (START); |
299 | set_hookname (START); |
298 | set_hookname (DESTROY); |
300 | set_hookname (DESTROY); |
299 | set_hookname (SEL_BEGIN); |
301 | set_hookname (SEL_BEGIN); |
… | |
… | |
305 | set_hookname (VIEW_CHANGE); |
307 | set_hookname (VIEW_CHANGE); |
306 | set_hookname (SCROLL_BACK); |
308 | set_hookname (SCROLL_BACK); |
307 | set_hookname (TTY_ACTIVITY); |
309 | set_hookname (TTY_ACTIVITY); |
308 | set_hookname (REFRESH_BEGIN); |
310 | set_hookname (REFRESH_BEGIN); |
309 | set_hookname (REFRESH_END); |
311 | set_hookname (REFRESH_END); |
|
|
312 | set_hookname (KEYBOARD_COMMAND); |
310 | |
313 | |
311 | sv_setpv (get_sv ("urxvt::LIBDIR", 1), LIBDIR); |
314 | sv_setpv (get_sv ("urxvt::LIBDIR", 1), LIBDIR); |
312 | } |
315 | } |
313 | |
316 | |
314 | void |
317 | void |
… | |
… | |
323 | |
326 | |
324 | void |
327 | void |
325 | fatal (const char *msg) |
328 | fatal (const char *msg) |
326 | CODE: |
329 | CODE: |
327 | rxvt_fatal ("%s", msg); |
330 | 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 | |
331 | |
340 | NV |
332 | NV |
341 | NOW () |
333 | NOW () |
342 | CODE: |
334 | CODE: |
343 | RETVAL = NOW; |
335 | RETVAL = NOW; |
344 | OUTPUT: |
336 | OUTPUT: |
345 | RETVAL |
337 | RETVAL |
346 | |
338 | |
347 | MODULE = urxvt PACKAGE = urxvt::term |
339 | MODULE = urxvt PACKAGE = urxvt::term |
|
|
340 | |
|
|
341 | int |
|
|
342 | rxvt_term::strwidth (SV *str) |
|
|
343 | CODE: |
|
|
344 | { |
|
|
345 | wchar_t *wstr = sv2wcs (str); |
|
|
346 | |
|
|
347 | rxvt_push_locale (THIS->locale); |
|
|
348 | RETVAL = wcswidth (wstr, wcslen (wstr)); |
|
|
349 | rxvt_pop_locale (); |
|
|
350 | |
|
|
351 | free (wstr); |
|
|
352 | } |
|
|
353 | OUTPUT: |
|
|
354 | RETVAL |
|
|
355 | |
|
|
356 | SV * |
|
|
357 | rxvt_term::locale_encode (SV *str) |
|
|
358 | CODE: |
|
|
359 | { |
|
|
360 | wchar_t *wstr = sv2wcs (str); |
|
|
361 | |
|
|
362 | rxvt_push_locale (THIS->locale); |
|
|
363 | char *mbstr = rxvt_wcstombs (wstr); |
|
|
364 | rxvt_pop_locale (); |
|
|
365 | |
|
|
366 | free (wstr); |
|
|
367 | |
|
|
368 | RETVAL = newSVpv (mbstr, 0); |
|
|
369 | free (mbstr); |
|
|
370 | } |
|
|
371 | OUTPUT: |
|
|
372 | RETVAL |
|
|
373 | |
|
|
374 | SV * |
|
|
375 | rxvt_term::locale_decode (SV *octets) |
|
|
376 | CODE: |
|
|
377 | { |
|
|
378 | STRLEN len; |
|
|
379 | char *data = SvPVbyte (octets, len); |
|
|
380 | |
|
|
381 | rxvt_push_locale (THIS->locale); |
|
|
382 | wchar_t *wstr = rxvt_mbstowcs (data, len); |
|
|
383 | rxvt_pop_locale (); |
|
|
384 | |
|
|
385 | char *str = rxvt_wcstoutf8 (wstr); |
|
|
386 | free (wstr); |
|
|
387 | |
|
|
388 | RETVAL = newSVpv (str, 0); |
|
|
389 | SvUTF8_on (RETVAL); |
|
|
390 | free (str); |
|
|
391 | } |
|
|
392 | OUTPUT: |
|
|
393 | RETVAL |
|
|
394 | |
|
|
395 | void |
|
|
396 | rxvt_term::_resource (char *name, int index, SV *newval = 0) |
|
|
397 | PPCODE: |
|
|
398 | { |
|
|
399 | struct resval { const char *name; int value; } rslist [] = { |
|
|
400 | # define Rs_def(name) { # name, Rs_ ## name }, |
|
|
401 | # define Rs_reserve(name,count) |
|
|
402 | # include "rsinc.h" |
|
|
403 | # undef Rs_def |
|
|
404 | # undef Rs_reserve |
|
|
405 | }; |
|
|
406 | |
|
|
407 | struct resval *rs = rslist + sizeof (rslist) / sizeof (rslist [0]); |
|
|
408 | |
|
|
409 | do { |
|
|
410 | if (rs-- == rslist) |
|
|
411 | croak ("no such resource '%s', requested", name); |
|
|
412 | } while (strcmp (name, rs->name)); |
|
|
413 | |
|
|
414 | index += rs->value; |
|
|
415 | |
|
|
416 | if (!IN_RANGE_EXC (index, 0, NUM_RESOURCES)) |
|
|
417 | croak ("requested out-of-bound resource %s+%d,", name, index - rs->value); |
|
|
418 | |
|
|
419 | if (GIMME_V != G_VOID) |
|
|
420 | XPUSHs (THIS->rs [index] ? sv_2mortal (newSVpv (THIS->rs [index], 0)) : &PL_sv_undef); |
|
|
421 | |
|
|
422 | if (newval) |
|
|
423 | { |
|
|
424 | if (SvOK (newval)) |
|
|
425 | { |
|
|
426 | char *str = strdup (SvPVbyte_nolen (newval)); |
|
|
427 | THIS->rs [index] = str; |
|
|
428 | THIS->allocated.push_back (str); |
|
|
429 | } |
|
|
430 | else |
|
|
431 | THIS->rs [index] = 0; |
|
|
432 | } |
|
|
433 | } |
348 | |
434 | |
349 | void |
435 | void |
350 | rxvt_term::selection_mark (...) |
436 | rxvt_term::selection_mark (...) |
351 | PROTOTYPE: $;$$ |
437 | PROTOTYPE: $;$$ |
352 | ALIAS: |
438 | ALIAS: |
… | |
… | |
418 | wchar_t *wtext = sv2wcs (text); |
504 | wchar_t *wtext = sv2wcs (text); |
419 | THIS->scr_overlay_set (x, y, wtext); |
505 | THIS->scr_overlay_set (x, y, wtext); |
420 | free (wtext); |
506 | free (wtext); |
421 | } |
507 | } |
422 | |
508 | |
|
|
509 | void |
|
|
510 | rxvt_term::tt_write (SV *octets) |
|
|
511 | INIT: |
|
|
512 | STRLEN len; |
|
|
513 | char *str = SvPVbyte (octets, len); |
|
|
514 | C_ARGS: |
|
|
515 | (unsigned char *)str, len |
|
|
516 | |
423 | MODULE = urxvt PACKAGE = urxvt::timer |
517 | MODULE = urxvt PACKAGE = urxvt::timer |
424 | |
518 | |
425 | SV * |
519 | SV * |
426 | timer::new () |
520 | timer::new () |
427 | CODE: |
521 | CODE: |