From: root Date: Fri, 6 Jan 2006 01:16:58 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=8efe0566175f438492c3bea4d1722aa3fd409406;p=dana%2Furxvt.git *** empty log message *** --- diff --git a/Changes b/Changes index e1cdc081..4efedda7 100644 --- a/Changes +++ b/Changes @@ -9,6 +9,9 @@ WISH: OnTheSpot editing, or maybe switch to miiiiiiif WISH: just for fun, do shade and tint with XRender. WISH: support tex fonts + - perl: implement additional hook: line_update, add_lines. + - perl: urxvt::line now can set via ->t and ->r. + 6.3 Wed Jan 4 22:37:10 CET 2006 - SECURITY FIX: on systems using openpty, permissions were not correctly updated on the tty device and were left as diff --git a/MANIFEST b/MANIFEST index cd37bf47..0d367e93 100644 --- a/MANIFEST +++ b/MANIFEST @@ -171,6 +171,7 @@ src/rxvtperl.h src/rxvtperl.xs src/perl/example-refresh-hooks +src/perl/example-filter-input src/perl/digital-clock src/perl/selection src/perl/mark-urls diff --git a/src/command.C b/src/command.C index ecff4ec0..46fe69f7 100644 --- a/src/command.C +++ b/src/command.C @@ -969,6 +969,45 @@ rxvt_term::flush () if (want_refresh) { + if (SHOULD_INVOKE (HOOK_LINE_UPDATE)) + { + int row = -view_start; + + while (row > -nsaved && ROW (row - 1).is_longer ()) + --row; + + while (row < -view_start + nrow) + { + int start_row = row; + line_t *l; + + do + { + l = &ROW (row); + + if (!(l->f & LINE_FILTERED)) + { + // line not filtered, mark it as filtered + l->f |= LINE_FILTERED; + while (l->is_longer ()) + { + l = &ROW (++row); + l->f |= LINE_FILTERED; + } + + // and filter it + HOOK_INVOKE ((this, HOOK_LINE_UPDATE, DT_INT, start_row, DT_END)); + + break; + } + } + while (l->is_longer ()); + + row++; + } + + } + scr_refresh (refresh_type); scrollbar_show (1); #ifdef USE_XIM @@ -1704,7 +1743,7 @@ rxvt_term::focus_in () focus = 1; want_refresh = 1; - PERL_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); + HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); #if USE_XIM if (Input_Context != NULL) @@ -1735,7 +1774,7 @@ rxvt_term::focus_out () focus = 0; want_refresh = 1; - PERL_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); + HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); #if ENABLE_FRILLS || ISO_14755 if (iso14755buf) @@ -1857,7 +1896,7 @@ rxvt_term::button_press (XButtonEvent &ev) if (ev.button != MEvent.button) MEvent.clicks = 0; - if (!PERL_INVOKE ((this, HOOK_MOUSE_CLICK, DT_XEVENT, &ev, DT_END))) + if (!HOOK_INVOKE ((this, HOOK_MOUSE_CLICK, DT_XEVENT, &ev, DT_END))) switch (ev.button) { case Button1: @@ -2735,7 +2774,7 @@ rxvt_term::cmd_parse () // scr_add_lines only works for nlines <= nrow - 1. if (nlines >= nrow - 1) { - if (!PERL_INVOKE ((this, HOOK_ADD_LINES, DT_USTRING_LEN, buf, str - buf, DT_END))) + if (!HOOK_INVOKE ((this, HOOK_ADD_LINES, DT_USTRING_LEN, buf, str - buf, DT_END))) scr_add_lines (buf, nlines, str - buf); nlines = 0; @@ -2760,7 +2799,7 @@ rxvt_term::cmd_parse () ch = next_char (); } - if (!PERL_INVOKE ((this, HOOK_ADD_LINES, DT_USTRING_LEN, buf, str - buf, DT_END))) + if (!HOOK_INVOKE ((this, HOOK_ADD_LINES, DT_USTRING_LEN, buf, str - buf, DT_END))) scr_add_lines (buf, nlines, str - buf); /* @@ -3977,7 +4016,7 @@ rxvt_term::process_xterm_seq (int op, const char *str, char resp) #if ENABLE_PERL case URxvt_perl: - if (PERL_INVOKE ((this, HOOK_OSC_SEQ, DT_STRING, str, DT_END))) + if (HOOK_INVOKE ((this, HOOK_OSC_SEQ, DT_STRING, str, DT_END))) ; // no responses yet break; #endif diff --git a/src/hookinc.h b/src/hookinc.h index 96769cc6..ce29bccc 100644 --- a/src/hookinc.h +++ b/src/hookinc.h @@ -17,7 +17,7 @@ def (VIEW_CHANGE) def (SCROLL_BACK) - def (TTY_ACTIVITY) + def (LINE_UPDATE) def (ADD_LINES) def (OSC_SEQ) diff --git a/src/keyboard.C b/src/keyboard.C index 81526a3f..14bf78c8 100644 --- a/src/keyboard.C +++ b/src/keyboard.C @@ -76,7 +76,7 @@ output_string (rxvt_term *rt, const char *str) if (strncmp (str, "command:", 8) == 0) rt->cmd_write (str + 8, strlen (str) - 8); else if (strncmp (str, "perl:", 5) == 0) - PERL_INVOKE((rt, HOOK_KEYBOARD_COMMAND, DT_STRING, str + 5, DT_END)); + HOOK_INVOKE((rt, HOOK_KEYBOARD_COMMAND, DT_STRING, str + 5, DT_END)); else rt->tt_write (str, strlen (str)); } diff --git a/src/main.C b/src/main.C index e79fc1a0..03c1e64a 100644 --- a/src/main.C +++ b/src/main.C @@ -208,7 +208,7 @@ void rxvt_term::emergency_cleanup () rxvt_term::~rxvt_term () { - PERL_INVOKE ((this, HOOK_DESTROY, DT_END)); + HOOK_INVOKE ((this, HOOK_DESTROY, DT_END)); termlist.erase (find (termlist.begin (), termlist.end(), this)); @@ -494,7 +494,7 @@ rxvt_term::init (int argc, const char *const *argv) || (rs[Rs_perl_eval] && *rs[Rs_perl_eval])) { rxvt_perl.init (); - PERL_INVOKE ((this, HOOK_INIT, DT_END)); + HOOK_INVOKE ((this, HOOK_INIT, DT_END)); } #endif @@ -540,7 +540,7 @@ rxvt_term::init (int argc, const char *const *argv) check_ev.start (); - PERL_INVOKE ((this, HOOK_START, DT_END)); + HOOK_INVOKE ((this, HOOK_START, DT_END)); return true; } diff --git a/src/perl/example-filter-input b/src/perl/example-filter-input new file mode 100644 index 00000000..ce19f2bc --- /dev/null +++ b/src/perl/example-filter-input @@ -0,0 +1,29 @@ +#! perl + +# same url as used in "selection" +my $url = + qr{( + (?:https?|ftp|news|mailto|file)://[ab-zA-Z0-9\-\@;\/?:&=%\$_.+!*\x27(),~]+ + [ab-zA-Z0-9\-\@;\/?:&=%\$_+!*\x27(),~] # do not include a trailing dot, its wrong too often + )}x; + +sub on_add_lines { + my ($term, $str) = @_; + + while ($str =~ $url) { + # found a url, first output preceding text + $term->scr_add_lines (substr $str, 0, $-[1], ""); + # then toggle underline + $term->rstyle ($term->rstyle ^ urxvt::RS_Uline); + # now output the url + $term->scr_add_lines (substr $str, 0, $+[1] - $-[1], ""); + # toggle undelrine again + $term->rstyle ($term->rstyle ^ urxvt::RS_Uline); + } + + # output trailing text + $term->scr_add_lines ($str); + + 1 +} + diff --git a/src/perl/mark-urls b/src/perl/mark-urls index ce19f2bc..c096caef 100644 --- a/src/perl/mark-urls +++ b/src/perl/mark-urls @@ -7,23 +7,25 @@ my $url = [ab-zA-Z0-9\-\@;\/?:&=%\$_+!*\x27(),~] # do not include a trailing dot, its wrong too often )}x; -sub on_add_lines { - my ($term, $str) = @_; - - while ($str =~ $url) { - # found a url, first output preceding text - $term->scr_add_lines (substr $str, 0, $-[1], ""); - # then toggle underline - $term->rstyle ($term->rstyle ^ urxvt::RS_Uline); - # now output the url - $term->scr_add_lines (substr $str, 0, $+[1] - $-[1], ""); - # toggle undelrine again - $term->rstyle ($term->rstyle ^ urxvt::RS_Uline); - } +sub on_line_update { + my ($term, $row) = @_; + + # fetch the line that has changed + my $line = $term->line ($row); + my $text = $line->t; + + # find all urls (if any) + while ($text =~ /$url/g) { + my $rend = $line->r; - # output trailing text - $term->scr_add_lines ($str); + # mark all characters as underlined. we _must_ not toggle underline, + # as we might get called on an already-marked url. + $_ |= urxvt::RS_Uline + for @{$rend}[ $-[1] .. $+[1] - 1]; + + $line->r ($rend); + } - 1 + () } diff --git a/src/rxvtperl.h b/src/rxvtperl.h index 13692262..6ef968e2 100644 --- a/src/rxvtperl.h +++ b/src/rxvtperl.h @@ -6,11 +6,11 @@ #define RXVTPERL_H_ #if ENABLE_PERL +# define SHOULD_INVOKE(htype) rxvt_perl.should_invoke [htype] +# define HOOK_INVOKE(args) rxvt_perl.invoke args #include "rxvt.h" -#define PERL_INVOKE(args) rxvt_perl.invoke args - enum data_type { DT_END, DT_INT, @@ -36,11 +36,13 @@ struct rxvt_perl_interp void init (); bool invoke (rxvt_term *term, hook_type htype, ...); + void line_update (rxvt_term *term); }; extern struct rxvt_perl_interp rxvt_perl; #else +# define SHOULD_INVOKE(htype) false # define PERL_INVOKE(args) false #endif diff --git a/src/rxvtperl.xs b/src/rxvtperl.xs index 017ec85a..d3fdf8b3 100644 --- a/src/rxvtperl.xs +++ b/src/rxvtperl.xs @@ -735,7 +735,7 @@ rxvt_term::want_refresh () THIS->want_refresh = 1; void -rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0) +rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0, int start_ofs = 0, int max_len = MAX_COLS) PPCODE: { if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow)) @@ -759,7 +759,7 @@ rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0) { wchar_t *wstr = sv2wcs (new_text); - int len = wcslen (wstr); + int len = min (wcslen (wstr) - start_ofs, max_len); if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len)) { @@ -769,7 +769,7 @@ rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0) for (int col = start_col; col < start_col + len; col++) { - l.t [col] = wstr [col - start_col]; + l.t [col] = wstr [start_ofs + col - start_col]; l.r [col] = SET_FONT (l.r [col], THIS->fontset [GET_STYLE (l.r [col])]->find_font (l.t [col])); } @@ -778,7 +778,7 @@ rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0) } void -rxvt_term::ROW_r (int row_number, SV *new_rend = 0, int start_col = 0) +rxvt_term::ROW_r (int row_number, SV *new_rend = 0, int start_col = 0, int start_ofs = 0, int max_len = MAX_COLS) PPCODE: { if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow)) @@ -803,14 +803,14 @@ rxvt_term::ROW_r (int row_number, SV *new_rend = 0, int start_col = 0) croak ("new_rend must be arrayref"); AV *av = (AV *)SvRV (new_rend); - int len = av_len (av) + 1; + int len = min (av_len (av) + 1 - start_ofs, max_len); if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len)) croak ("new_rend array extends beyond horizontal margins"); for (int col = start_col; col < start_col + len; col++) { - rend_t r = SvIV (*av_fetch (av, col - start_col, 1)) & ~RS_fontMask; + rend_t r = SvIV (*av_fetch (av, start_ofs + col - start_col, 1)) & ~RS_fontMask; l.r [col] = SET_FONT (r, THIS->fontset [GET_STYLE (r)]->find_font (l.t [col])); } diff --git a/src/screen.C b/src/screen.C index b452acbb..ba26cac1 100644 --- a/src/screen.C +++ b/src/screen.C @@ -416,7 +416,7 @@ rxvt_term::scr_reset () tt_winch (); - PERL_INVOKE ((this, HOOK_RESET, DT_END)); + HOOK_INVOKE ((this, HOOK_RESET, DT_END)); } /* ------------------------------------------------------------------------- */ @@ -620,7 +620,7 @@ rxvt_term::scr_scroll_text (int row1, int row2, int count) { nsaved = min (nsaved + count, saveLines); - PERL_INVOKE ((this, HOOK_SCROLL_BACK, DT_INT, count, DT_INT, nsaved, DT_END)); + HOOK_INVOKE ((this, HOOK_SCROLL_BACK, DT_INT, count, DT_INT, nsaved, DT_END)); term_start = (term_start + count) % total_rows; @@ -1835,7 +1835,7 @@ rxvt_term::scr_changeview (unsigned int oldviewstart) { if (view_start != oldviewstart) { - PERL_INVOKE ((this, HOOK_VIEW_CHANGE, DT_INT, view_start, DT_END)); + HOOK_INVOKE ((this, HOOK_VIEW_CHANGE, DT_INT, view_start, DT_END)); want_refresh = 1; num_scr -= (view_start - oldviewstart); @@ -2055,7 +2055,7 @@ rxvt_term::scr_refresh (unsigned char refresh_type) } } - PERL_INVOKE ((this, HOOK_REFRESH_BEGIN, DT_END)); + HOOK_INVOKE ((this, HOOK_REFRESH_BEGIN, DT_END)); #if ENABLE_OVERLAY scr_swap_overlay (); #endif @@ -2328,7 +2328,7 @@ rxvt_term::scr_refresh (unsigned char refresh_type) #if ENABLE_OVERLAY scr_swap_overlay (); #endif - PERL_INVOKE ((this, HOOK_REFRESH_END, DT_END)); + HOOK_INVOKE ((this, HOOK_REFRESH_END, DT_END)); /* * G: cleanup cursor and display outline cursor if necessary @@ -2892,7 +2892,7 @@ rxvt_term::selection_make (Time tm) if (selection.clicks == 4) return; /* nothing selected, go away */ - if (PERL_INVOKE ((this, HOOK_SEL_MAKE, DT_LONG, (long)tm, DT_END))) + if (HOOK_INVOKE ((this, HOOK_SEL_MAKE, DT_LONG, (long)tm, DT_END))) return; i = (selection.end.row - selection.beg.row + 1) * (ncol + 1); @@ -2987,7 +2987,7 @@ rxvt_term::selection_make (Time tm) selection.len = ofs; selection.text = (wchar_t *)rxvt_realloc (new_selection_text, (ofs + 1) * sizeof (wchar_t)); - if (PERL_INVOKE ((this, HOOK_SEL_GRAB, DT_LONG, (long)tm, DT_END))) + if (HOOK_INVOKE ((this, HOOK_SEL_GRAB, DT_LONG, (long)tm, DT_END))) return; selection_grab (tm); @@ -3333,7 +3333,7 @@ rxvt_term::selection_extend_colrow (int32_t col, int32_t row, int button3, int b if (ROWCOL_IS_AFTER (selection.end, selection.beg)) selection.end.col--; - if (!PERL_INVOKE ((this, HOOK_SEL_EXTEND, DT_END))) + if (!HOOK_INVOKE ((this, HOOK_SEL_EXTEND, DT_END))) { selection_delimit_word (UP, &selection.beg, &selection.beg); selection_delimit_word (DN, &selection.end, &selection.end); diff --git a/src/urxvt.pm b/src/urxvt.pm index 9b416b1a..75029658 100644 --- a/src/urxvt.pm +++ b/src/urxvt.pm @@ -782,6 +782,7 @@ sub urxvt::term::line { term => $self, beg => $beg, end => $end, + ncol => $self->ncol, len => ($end - $beg) * $self->ncol + $self->ROW_l ($end), }, urxvt::line:: } @@ -789,18 +790,35 @@ sub urxvt::term::line { sub urxvt::line::t { my ($self) = @_; - substr +(join "", map $self->{term}->ROW_t ($_), $self->{beg} .. $self->{end}), - 0, $self->{len} + if (@_ > 1) + { + $self->{term}->ROW_t ($_, $_[1], 0, ($_ - $self->{beg}) * $self->{ncol}, $self->{ncol}) + for $self->{beg} .. $self->{end}; + } + + defined wantarray && + substr +(join "", map $self->{term}->ROW_t ($_), $self->{beg} .. $self->{end}), + 0, $self->{len} } sub urxvt::line::r { my ($self) = @_; - my $rend = [ - map @{ $self->{term}->ROW_r ($_) }, $self->{beg} .. $self->{end} - ]; - $#$rend = $self->{len} - 1; - $rend + if (@_ > 1) + { + $self->{term}->ROW_r ($_, $_[1], 0, ($_ - $self->{beg}) * $self->{ncol}, $self->{ncol}) + for $self->{beg} .. $self->{end}; + } + + if (defined wantarray) { + my $rend = [ + map @{ $self->{term}->ROW_r ($_) }, $self->{beg} .. $self->{end} + ]; + $#$rend = $self->{len} - 1; + return $rend; + } + + () } sub urxvt::line::beg { $_[0]{beg} } @@ -810,7 +828,7 @@ sub urxvt::line::l { $_[0]{len} } sub urxvt::line::offset_of { my ($self, $row, $col) = @_; - ($row - $self->{beg}) * $self->{term}->ncol + $col + ($row - $self->{beg}) * $self->{ncol} + $col } sub urxvt::line::coord_of { @@ -819,8 +837,8 @@ sub urxvt::line::coord_of { use integer; ( - $offset / $self->{term}->ncol + $self->{beg}, - $offset % $self->{term}->ncol + $offset / $self->{ncol} + $self->{beg}, + $offset % $self->{ncol} ) }