--- rxvt-unicode/src/rxvtperl.xs 2006/07/05 23:34:14 1.101 +++ rxvt-unicode/src/rxvtperl.xs 2008/07/31 03:24:08 1.124 @@ -3,7 +3,7 @@ *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. - * Copyright (c) 2005-2006 Marc Lehmann + * Copyright (c) 2005-2008 Marc Lehmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ #include "unistd.h" -#include "iom.h" +#include "ev_cpp.h" #include "rxvt.h" #include "keyboard.h" #include "rxvtutil.h" @@ -41,19 +41,13 @@ #include "perlxsi.c" -#ifdef HAVE_SCROLLBARS -# define GRAB_CURSOR THIS->leftptr_cursor -#else -# define GRAB_CURSOR None -#endif +#define GRAB_CURSOR THIS->scrollBar.leftptr_cursor #undef LINENO #define LINENO(n) MOD (THIS->term_start + int(n), THIS->total_rows) #undef ROW #define ROW(n) THIS->row_buf [LINENO (n)] -typedef int CHAINED UNUSED; - ///////////////////////////////////////////////////////////////////////////// static wchar_t * @@ -77,12 +71,6 @@ } static SV * -new_ref (HV *hv, const char *klass) -{ - return sv_bless (newRV ((SV *)hv), gv_stashpv (klass, 1)); -} - -static SV * newSVptr (void *ptr, const char *klass) { HV *hv = newHV (); @@ -119,130 +107,6 @@ ///////////////////////////////////////////////////////////////////////////// -#define SvWATCHER(sv) (perl_watcher *)SvPTR (sv, "urxvt::watcher") - -struct perl_watcher -{ - SV *cbsv; - HV *self; - - perl_watcher () - : cbsv (0) - { - } - - ~perl_watcher () - { - SvREFCNT_dec (cbsv); - } - - void cb (SV *cb) - { - SvREFCNT_dec (cbsv); - cbsv = newSVsv (cb); - } - - void invoke (const char *type, SV *self, int arg = -1); -}; - -void -perl_watcher::invoke (const char *type, SV *self, int arg) -{ - dSP; - - ENTER; - SAVETMPS; - - PUSHMARK (SP); - - XPUSHs (sv_2mortal (self)); - - if (arg >= 0) - XPUSHs (sv_2mortal (newSViv (arg))); - - PUTBACK; - call_sv (cbsv, G_VOID | G_EVAL | G_DISCARD); - SPAGAIN; - - PUTBACK; - FREETMPS; - LEAVE; - - if (SvTRUE (ERRSV)) - rxvt_warn ("%s callback evaluation error: %s", type, SvPV_nolen (ERRSV)); -} - -#define newSVtimer(timer) new_ref ((timer)->self, "urxvt::timer") -#define SvTIMER(sv) (timer *)(perl_watcher *)SvPTR ((sv), "urxvt::timer") - -struct timer : perl_watcher, time_watcher -{ - tstamp interval; - - timer () - : time_watcher (this, &timer::execute) - { - } - - void execute (time_watcher &w) - { - if (interval) - start (at + interval); - - invoke ("urxvt::timer", newSVtimer (this)); - } -}; - -#define newSViow(iow) new_ref ((iow)->self, "urxvt::iow") -#define SvIOW(sv) (iow *)(perl_watcher *)SvPTR ((sv), "urxvt::iow") - -struct iow : perl_watcher, io_watcher -{ - iow () - : io_watcher (this, &iow::execute) - { - } - - void execute (io_watcher &w, short revents) - { - invoke ("urxvt::iow", newSViow (this), revents); - } -}; - -#define newSViw(iw) new_ref ((iw)->self, "urxvt::iw") -#define SvIW(sv) (iw *)(perl_watcher *)SvPTR ((sv), "urxvt::iw") - -struct iw : perl_watcher, idle_watcher -{ - iw () - : idle_watcher (this, &iw::execute) - { - } - - void execute (idle_watcher &w) - { - invoke ("urxvt::iw", newSViw (this)); - } -}; - -#define newSVpw(pw) new_ref ((pw)->self, "urxvt::pw") -#define SvPW(sv) (pw *)(perl_watcher *)SvPTR ((sv), "urxvt::pw") - -struct pw : perl_watcher, child_watcher -{ - pw () - : child_watcher (this, &pw::execute) - { - } - - void execute (child_watcher &w, int status) - { - invoke ("urxvt::pw", newSVpw (this), status); - } -}; - -///////////////////////////////////////////////////////////////////////////// - #define SvOVERLAY(sv) (overlay *)SvPTR (sv, "urxvt::overlay") class overlay { @@ -270,6 +134,9 @@ overlay::overlay (rxvt_term *THIS, int x_, int y_, int w_, int h_, rend_t rstyle, int border) : THIS(THIS), x(x_), y(y_), w(w_), h(h_), border(border == 2), overlay_av (0) { + if (w < 0) w = 0; + if (h < 0) h = 0; + if (border == 2) { w += 2; @@ -345,6 +212,7 @@ av_push (overlay_av, newSViv ((long)this)); THIS->want_refresh = 1; + THIS->refresh_check (); } void @@ -368,6 +236,7 @@ overlay_av = 0; THIS->want_refresh = 1; + THIS->refresh_check (); } void overlay::swap () @@ -422,8 +291,14 @@ } THIS->want_refresh = 1; + THIS->refresh_check (); } +///////////////////////////////////////////////////////////////////////////// + +#define IOM_CLASS "urxvt" +#define IOM_WARN rxvt_warn +#include "iom_perl.h" ///////////////////////////////////////////////////////////////////////////// @@ -508,7 +383,7 @@ if (htype == HOOK_REFRESH_END) { AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, 0)); - + for (int i = 0; i <= AvFILL (av); i++) ((overlay *)SvIV (*av_fetch (av, i, 0)))->swap (); } @@ -717,7 +592,7 @@ if (htype == HOOK_REFRESH_BEGIN) { AV *av = (AV *)SvRV (*hv_fetch ((HV *)SvRV ((SV *)term->perl.self), "_overlay", 8, 0)); - + for (int i = AvFILL (av); i >= 0; i--) ((overlay *)SvIV (*av_fetch (av, i, 0)))->swap (); } @@ -725,7 +600,7 @@ { clearSVptr ((SV *)term->perl.self); SvREFCNT_dec ((SV *)term->perl.self); - + // don't allow further calls term->perl.self = 0; } @@ -766,6 +641,7 @@ IV iv; } *civ, const_iv[] = { # define const_iv(name) { # name, (IV)name } + const_iv (NUM_RESOURCES), const_iv (DEFAULT_RSTYLE), const_iv (OVERLAY_RSTYLE), const_iv (RS_Bold), @@ -790,9 +666,9 @@ const_iv (Button5Mask), const_iv (AnyModifier), - const_iv (EVENT_NONE), - const_iv (EVENT_READ), - const_iv (EVENT_WRITE), + const_iv (NoSymbol), + const_iv (GrabModeSync), + const_iv (GrabModeAsync), const_iv (NoEventMask), const_iv (KeyPressMask), @@ -901,7 +777,7 @@ NV NOW () CODE: - RETVAL = NOW; + RETVAL = ev::now (); OUTPUT: RETVAL @@ -936,7 +812,7 @@ int GET_CUSTOM (int rend) CODE: - RETVAL = (rend && RS_customMask) >> RS_customShift; + RETVAL = (rend & RS_customMask) >> RS_customShift; OUTPUT: RETVAL @@ -983,19 +859,12 @@ envv->push_back (0); - bool success; - try { - success = term->init (argv, envv); + term->init (argv, envv); } catch (const class rxvt_failure_exception &e) { - success = false; - } - - if (!success) - { term->destroy (); croak ("error while initializing new terminal instance"); } @@ -1014,31 +883,35 @@ CODE: THIS->perl.should_invoke [htype] += inc; -void +int rxvt_term::grab_button (int button, U32 modifiers, Window window = THIS->vt) CODE: - XGrabButton (THIS->dpy, button, modifiers, window, 1, - ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask, - GrabModeSync, GrabModeSync, None, GRAB_CURSOR); + RETVAL = XGrabButton (THIS->dpy, button, modifiers, window, 1, + ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask, + GrabModeSync, GrabModeSync, None, GRAB_CURSOR); + OUTPUT: RETVAL -void +int rxvt_term::ungrab_button (int button, U32 modifiers, Window window = THIS->vt) CODE: - XUngrabButton (THIS->dpy, button, modifiers, window); - -#if 0 + RETVAL = XUngrabButton (THIS->dpy, button, modifiers, window); + OUTPUT: RETVAL void -XGrabKey (rxvt_term *THIS, int keycode, U32 modifiers, Window window = THIS->vt) - C_ARGS: - THIS->dpy, keycode, modifiers, window, 1, - GrabModeSync, GrabModeSync +rxvt_term::XGrabKey (int keycode, U32 modifiers, Window window = THIS->vt, \ + int owner_events = 1, int pointer_mode = GrabModeAsync, int keyboard_mode = GrabModeAsync) + CODE: + XGrabKey (THIS->dpy, keycode, modifiers, window, owner_events, pointer_mode, keyboard_mode); void -XUngrabKey (rxvt_term *THIS, int keycode, U32 modifiers, Window window = THIS->vt) - C_ARGS: THIS->dpy, keycode, modifiers, window +rxvt_term::XUngrabKey (int keycode, U32 modifiers, Window window = THIS->vt) + CODE: + XUngrabKey (THIS->dpy, keycode, modifiers, window); -#endif +void +rxvt_term::XUngrabKeyboard (Time eventtime) + CODE: + XUngrabKeyboard (THIS->dpy, eventtime); bool rxvt_term::grab (Time eventtime, int sync = 0) @@ -1083,13 +956,44 @@ ungrab (THIS); int +rxvt_term::XStringToKeysym (char *string) + CODE: + RETVAL = XStringToKeysym (string); + OUTPUT: RETVAL + +char * +rxvt_term::XKeysymToString (int sym) + CODE: + RETVAL = XKeysymToString (sym); + OUTPUT: RETVAL + +int +rxvt_term::XKeysymToKeycode (int sym) + CODE: + RETVAL = XKeysymToKeycode (THIS->dpy, sym); + OUTPUT: RETVAL + +int +rxvt_term::XKeycodeToKeysym (int code, int index) + CODE: + RETVAL = XKeycodeToKeysym (THIS->dpy, code, index); + OUTPUT: RETVAL + +int rxvt_term::strwidth (SV *str) CODE: { wchar_t *wstr = sv2wcs (str); rxvt_push_locale (THIS->locale); - RETVAL = wcswidth (wstr, wcslen (wstr)); + RETVAL = 0; + for (wchar_t *wc = wstr; *wc; wc++) + { + int w = WCWIDTH (*wc); + + if (w) + RETVAL += max (w, 1); + } rxvt_pop_locale (); free (wstr); @@ -1132,6 +1036,13 @@ OUTPUT: RETVAL +char * +rxvt_term::locale () + CODE: + RETVAL = THIS->locale; + OUTPUT: + RETVAL + #define TERM_OFFSET(sym) offsetof (TermWin_t, sym) #define TERM_OFFSET_width TERM_OFFSET(width) @@ -1188,7 +1099,9 @@ case 1: RETVAL = THIS->ModMetaMask; break; case 2: RETVAL = THIS->ModNumLockMask; break; case 3: RETVAL = THIS->current_screen; break; +#ifdef CURSOR_BLINK case 4: RETVAL = THIS->hidden_cursor; break; +#endif } OUTPUT: RETVAL @@ -1223,10 +1136,10 @@ } int -rxvt_term::pty_ev_events (int events = EVENT_UNDEF) +rxvt_term::pty_ev_events (int events = ev::UNDEF) CODE: RETVAL = THIS->pty_ev.events; - if (events != EVENT_UNDEF) + if (events != ev::UNDEF) THIS->pty_ev.set (events); OUTPUT: RETVAL @@ -1315,6 +1228,7 @@ rxvt_term::want_refresh () CODE: THIS->want_refresh = 1; + THIS->refresh_check (); void rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0, int start_ofs = 0, int max_len = MAX_COLS) @@ -1479,7 +1393,6 @@ CODE: { wchar_t *wstr = sv2wcs (text); - int wlen = wcslen (wstr); int dlen = 0; // find length @@ -1522,12 +1435,20 @@ rs = rslist + sizeof (rslist) / sizeof (rslist [0]); - do { - if (rs-- == rslist) - croak ("no such resource '%s', requested", name); - } while (strcmp (name, rs->name)); + if (*name) + { + do { + if (rs-- == rslist) + croak ("no such resource '%s', requested", name); + } while (strcmp (name, rs->name)); - index += rs->value; + index += rs->value; + } + else + { + --rs; + name = ""; + } if (!IN_RANGE_EXC (index, 0, NUM_RESOURCES)) croak ("requested out-of-bound resource %s+%d,", name, index - rs->value); @@ -1552,19 +1473,16 @@ rxvt_term::x_resource (const char *name) bool -rxvt_term::option (U32 optval, int set = -1) +rxvt_term::option (U8 optval, int set = -1) CODE: { - RETVAL = THIS->options & optval; + RETVAL = THIS->option (optval); if (set >= 0) { - if (set) - THIS->options |= optval; - else - THIS->options &= ~optval; + THIS->set_option (optval, set); - if (THIS->check_ev.is_active ()) // avoid doing this before START + if (THIS->env_colorfgbg [0]) // avoid doing this before START switch (optval) { case Opt_skipBuiltinGlyphs: @@ -1572,10 +1490,12 @@ THIS->scr_remap_chars (); THIS->scr_touch (true); THIS->want_refresh = 1; + THIS->refresh_check (); break; case Opt_cursorUnderline: THIS->want_refresh = 1; + THIS->refresh_check (); break; # case Opt_scrollBar_floating: @@ -1643,7 +1563,10 @@ clamp_it (rc.row, THIS->top_row, THIS->nrow - 1); if (ix) - THIS->want_refresh = 1; + { + THIS->want_refresh = 1; + THIS->refresh_check (); + } } } @@ -1760,7 +1683,7 @@ EXTEND (SP, count); while (count--) PUSHs (newSVuv ((U32)props [count])); - + XFree (props); } @@ -1793,7 +1716,7 @@ } void -rxvt_term::XChangeWindowProperty (Window window, Atom property, Atom type, int format, SV *data) +rxvt_term::XChangeProperty (Window window, Atom property, Atom type, int format, SV *data) CODE: { STRLEN len; @@ -1899,188 +1822,5 @@ void overlay::DESTROY () -############################################################################# -# urxvt::watcher -############################################################################# - -MODULE = urxvt PACKAGE = urxvt::watcher - -CHAINED -perl_watcher::cb (SV *cb) - CODE: - THIS->cb (cb); - OUTPUT: - RETVAL - -############################################################################# -# urxvt::timer -############################################################################# - -MODULE = urxvt PACKAGE = urxvt::timer - -SV * -timer::new () - CODE: - timer *w = new timer; - w->start (NOW); - RETVAL = newSVptr ((void *)(perl_watcher *)w, "urxvt::timer"); - w->self = (HV *)SvRV (RETVAL); - OUTPUT: - RETVAL - -NV -timer::at () - CODE: - RETVAL = THIS->at; - OUTPUT: - RETVAL - -CHAINED -timer::interval (NV interval) - CODE: - THIS->interval = interval; - OUTPUT: - RETVAL - -CHAINED -timer::set (NV tstamp) - CODE: - THIS->set (tstamp); - OUTPUT: - RETVAL - -CHAINED -timer::start (NV tstamp = THIS->at) - CODE: - THIS->start (tstamp); - OUTPUT: - RETVAL - -CHAINED -timer::after (NV delay) - CODE: - THIS->start (NOW + delay); - OUTPUT: - RETVAL - -CHAINED -timer::stop () - CODE: - THIS->stop (); - OUTPUT: - RETVAL - -void -timer::DESTROY () - -############################################################################# -# urxvt::iow -############################################################################# - -MODULE = urxvt PACKAGE = urxvt::iow - -SV * -iow::new () - CODE: - iow *w = new iow; - RETVAL = newSVptr ((void *)(perl_watcher *)w, "urxvt::iow"); - w->self = (HV *)SvRV (RETVAL); - OUTPUT: - RETVAL - -CHAINED -iow::fd (int fd) - CODE: - THIS->fd = fd; - OUTPUT: - RETVAL - -CHAINED -iow::events (short events) - CODE: - THIS->events = events; - OUTPUT: - RETVAL - -CHAINED -iow::start () - CODE: - THIS->start (); - OUTPUT: - RETVAL - -CHAINED -iow::stop () - CODE: - THIS->stop (); - OUTPUT: - RETVAL - -void -iow::DESTROY () - -############################################################################# -# urxvt::iw -############################################################################# - -MODULE = urxvt PACKAGE = urxvt::iw - -SV * -iw::new () - CODE: - iw *w = new iw; - RETVAL = newSVptr ((void *)(perl_watcher *)w, "urxvt::iw"); - w->self = (HV *)SvRV (RETVAL); - OUTPUT: - RETVAL - -CHAINED -iw::start () - CODE: - THIS->start (); - OUTPUT: - RETVAL - -CHAINED -iw::stop () - CODE: - THIS->stop (); - OUTPUT: - RETVAL - -void -iw::DESTROY () - -############################################################################# -# urxvt::pw -############################################################################# - -MODULE = urxvt PACKAGE = urxvt::pw - -SV * -pw::new () - CODE: - pw *w = new pw; - RETVAL = newSVptr ((void *)(perl_watcher *)w, "urxvt::pw"); - w->self = (HV *)SvRV (RETVAL); - OUTPUT: - RETVAL - -CHAINED -pw::start (int pid) - CODE: - THIS->start (pid); - OUTPUT: - RETVAL - -CHAINED -pw::stop () - CODE: - THIS->stop (); - OUTPUT: - RETVAL - -void -pw::DESTROY () - +INCLUDE: $PERL