*** empty log message ***
authorroot <root>
Fri, 6 Jan 2006 01:16:58 +0000 (01:16 +0000)
committerroot <root>
Fri, 6 Jan 2006 01:16:58 +0000 (01:16 +0000)
12 files changed:
Changes
MANIFEST
src/command.C
src/hookinc.h
src/keyboard.C
src/main.C
src/perl/example-filter-input [new file with mode: 0644]
src/perl/mark-urls
src/rxvtperl.h
src/rxvtperl.xs
src/screen.C
src/urxvt.pm

diff --git a/Changes b/Changes
index e1cdc08..4efedda 100644 (file)
--- 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
index cd37bf4..0d367e9 100644 (file)
--- 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
index ecff4ec..46fe69f 100644 (file)
@@ -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
index 96769cc..ce29bcc 100644 (file)
@@ -17,7 +17,7 @@
 
   def (VIEW_CHANGE)
   def (SCROLL_BACK)
-  def (TTY_ACTIVITY)
+  def (LINE_UPDATE)
   def (ADD_LINES)
   def (OSC_SEQ)
 
index 81526a3..14bf78c 100644 (file)
@@ -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));
 }
index e79fc1a..03c1e64 100644 (file)
@@ -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 (file)
index 0000000..ce19f2b
--- /dev/null
@@ -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
+}
+
index ce19f2b..c096cae 100644 (file)
@@ -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
+   ()
 }
 
index 1369226..6ef968e 100644 (file)
@@ -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
 
index 017ec85..d3fdf8b 100644 (file)
@@ -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]));
               }
index b452acb..ba26cac 100644 (file)
@@ -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);
index 9b416b1..7502965 100644 (file)
@@ -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}
    )
 }