[BACK]Return to window-copy.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/window-copy.c between version 1.20 and 1.21

version 1.20, 2009/08/13 22:32:18 version 1.21, 2009/08/18 07:08:26
Line 18 
Line 18 
   
 #include <sys/types.h>  #include <sys/types.h>
   
   #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
 #include "tmux.h"  #include "tmux.h"
Line 26 
Line 27 
 void    window_copy_free(struct window_pane *);  void    window_copy_free(struct window_pane *);
 void    window_copy_resize(struct window_pane *, u_int, u_int);  void    window_copy_resize(struct window_pane *, u_int, u_int);
 void    window_copy_key(struct window_pane *, struct client *, int);  void    window_copy_key(struct window_pane *, struct client *, int);
   int     window_copy_key_input(struct window_pane *, int);
 void    window_copy_mouse(  void    window_copy_mouse(
             struct window_pane *, struct client *, u_char, u_char, u_char);              struct window_pane *, struct client *, u_char, u_char, u_char);
   
Line 36 
Line 38 
 void    window_copy_write_lines(  void    window_copy_write_lines(
             struct window_pane *, struct screen_write_ctx *, u_int, u_int);              struct window_pane *, struct screen_write_ctx *, u_int, u_int);
   
   void    window_copy_scroll_to(struct window_pane *, u_int, u_int);
   int     window_copy_search_compare(
               struct grid *, u_int, u_int, struct grid *, u_int);
   int     window_copy_search_lr(
               struct grid *, struct grid *, u_int *, u_int, u_int, u_int);
   int     window_copy_search_rl(
               struct grid *, struct grid *, u_int *, u_int, u_int, u_int);
   void    window_copy_search_up(struct window_pane *, const char *);
   void    window_copy_search_down(struct window_pane *, const char *);
   void    window_copy_goto_line(struct window_pane *, const char *);
 void    window_copy_update_cursor(struct window_pane *, u_int, u_int);  void    window_copy_update_cursor(struct window_pane *, u_int, u_int);
 void    window_copy_start_selection(struct window_pane *);  void    window_copy_start_selection(struct window_pane *);
 int     window_copy_update_selection(struct window_pane *);  int     window_copy_update_selection(struct window_pane *);
Line 65 
Line 77 
         NULL,          NULL,
 };  };
   
   enum window_copy_input_type {
           WINDOW_COPY_OFF,
           WINDOW_COPY_SEARCHUP,
           WINDOW_COPY_SEARCHDOWN,
           WINDOW_COPY_GOTOLINE,
   };
   
 struct window_copy_mode_data {  struct window_copy_mode_data {
         struct screen   screen;          struct screen   screen;
   
         struct mode_key_data    mdata;          struct mode_key_data mdata;
   
         u_int   oy;          u_int           oy;
   
         u_int   selx;          u_int           selx;
         u_int   sely;          u_int           sely;
   
         u_int   cx;          u_int           cx;
         u_int   cy;          u_int           cy;
   
           enum window_copy_input_type inputtype;
           const char     *inputprompt;
           char           *inputstr;
   
           enum window_copy_input_type searchtype;
           char           *searchstr;
 };  };
   
 struct screen *  struct screen *
Line 93 
Line 119 
         data->cx = wp->base.cx;          data->cx = wp->base.cx;
         data->cy = wp->base.cy;          data->cy = wp->base.cy;
   
           data->inputtype = WINDOW_COPY_OFF;
           data->inputprompt = NULL;
           data->inputstr = xstrdup("");
   
           data->searchtype = WINDOW_COPY_OFF;
           data->searchstr = NULL;
   
         s = &data->screen;          s = &data->screen;
         screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);          screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
         if (options_get_number(&wp->window->options, "mode-mouse"))          if (options_get_number(&wp->window->options, "mode-mouse"))
Line 121 
Line 154 
 {  {
         struct window_copy_mode_data    *data = wp->modedata;          struct window_copy_mode_data    *data = wp->modedata;
   
           if (data->searchstr != NULL)
                   xfree(data->searchstr);
           xfree(data->inputstr);
   
         screen_free(&data->screen);          screen_free(&data->screen);
   
         xfree(data);          xfree(data);
 }  }
   
Line 172 
Line 210 
         struct window_copy_mode_data    *data = wp->modedata;          struct window_copy_mode_data    *data = wp->modedata;
         struct screen                   *s = &data->screen;          struct screen                   *s = &data->screen;
         u_int                            n;          u_int                            n;
           int                              keys;
   
           if (data->inputtype != WINDOW_COPY_OFF) {
                   if (window_copy_key_input(wp, key) != 0)
                           goto input_off;
                   return;
           }
   
         switch (mode_key_lookup(&data->mdata, key)) {          switch (mode_key_lookup(&data->mdata, key)) {
         case MODEKEYCOPY_CANCEL:          case MODEKEYCOPY_CANCEL:
                 window_pane_reset_mode(wp);                  window_pane_reset_mode(wp);
Line 250 
Line 295 
         case MODEKEYCOPY_PREVIOUSWORD:          case MODEKEYCOPY_PREVIOUSWORD:
                 window_copy_cursor_previous_word(wp);                  window_copy_cursor_previous_word(wp);
                 break;                  break;
           case MODEKEYCOPY_SEARCHUP:
                   data->inputtype = WINDOW_COPY_SEARCHUP;
                   data->inputprompt = "Search Up";
                   goto input_on;
           case MODEKEYCOPY_SEARCHDOWN:
                   data->inputtype = WINDOW_COPY_SEARCHDOWN;
                   data->inputprompt = "Search Down";
                   goto input_on;
           case MODEKEYCOPY_SEARCHAGAIN:
                   switch (data->searchtype) {
                   case WINDOW_COPY_OFF:
                   case WINDOW_COPY_GOTOLINE:
                           break;
                   case WINDOW_COPY_SEARCHUP:
                           window_copy_search_up(wp, data->searchstr);
                           break;
                   case WINDOW_COPY_SEARCHDOWN:
                           window_copy_search_down(wp, data->searchstr);
                           break;
                   }
                   break;
           case MODEKEYCOPY_GOTOLINE:
                   data->inputtype = WINDOW_COPY_GOTOLINE;
                   data->inputprompt = "Goto Line";
                   *data->inputstr = '\0';
                   goto input_on;
         default:          default:
                 break;                  break;
         }          }
   
           return;
   
   input_on:
           keys = options_get_number(&wp->window->options, "mode-keys");
           if (keys == MODEKEY_EMACS)
                   mode_key_init(&data->mdata, &mode_key_tree_emacs_edit);
           else
                   mode_key_init(&data->mdata, &mode_key_tree_vi_edit);
   
           window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1);
           return;
   
   input_off:
           keys = options_get_number(&wp->window->options, "mode-keys");
           if (keys == MODEKEY_EMACS)
                   mode_key_init(&data->mdata, &mode_key_tree_emacs_copy);
           else
                   mode_key_init(&data->mdata, &mode_key_tree_vi_copy);
   
           data->inputtype = WINDOW_COPY_OFF;
           data->inputprompt = NULL;
   
           window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1);
 }  }
   
   int
   window_copy_key_input(struct window_pane *wp, int key)
   {
           struct window_copy_mode_data    *data = wp->modedata;
           struct screen                   *s = &data->screen;
           size_t                           inputlen;
   
           switch (mode_key_lookup(&data->mdata, key)) {
           case MODEKEYEDIT_CANCEL:
                   return (-1);
           case MODEKEYEDIT_BACKSPACE:
                   inputlen = strlen(data->inputstr);
                   if (inputlen > 0)
                           data->inputstr[inputlen - 1] = '\0';
                   break;
           case MODEKEYEDIT_ENTER:
                   switch (data->inputtype) {
                   case WINDOW_COPY_OFF:
                           break;
                   case WINDOW_COPY_SEARCHUP:
                           window_copy_search_up(wp, data->inputstr);
                           data->searchtype = data->inputtype;
                           data->searchstr = xstrdup(data->inputstr);
                           break;
                   case WINDOW_COPY_SEARCHDOWN:
                           window_copy_search_down(wp, data->inputstr);
                           data->searchtype = data->inputtype;
                           data->searchstr = xstrdup(data->inputstr);
                           break;
                   case WINDOW_COPY_GOTOLINE:
                           window_copy_goto_line(wp, data->inputstr);
                           *data->inputstr = '\0';
                           break;
                   }
                   return (1);
           case MODEKEY_OTHER:
                   if (key < 32 || key > 126)
                           break;
                   inputlen = strlen(data->inputstr) + 2;
   
                   data->inputstr = xrealloc(data->inputstr, 1, inputlen);
                   data->inputstr[inputlen - 2] = key;
                   data->inputstr[inputlen - 1] = '\0';
                   break;
           default:
                   break;
           }
   
           window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1);
           return (0);
   }
   
 void  void
 window_copy_mouse(struct window_pane *wp,  window_copy_mouse(struct window_pane *wp,
     unused struct client *c, u_char b, u_char x, u_char y)      unused struct client *c, u_char b, u_char x, u_char y)
Line 275 
Line 422 
 }  }
   
 void  void
   window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py)
   {
           struct window_copy_mode_data    *data = wp->modedata;
           struct screen                   *s = &wp->base;
           struct grid                     *gd = s->grid;
           u_int                            offset, gap;
   
           data->cx = px;
   
           gap = gd->sy / 4;
           if (py < gd->sy) {
                   offset = 0;
                   data->cy = py;
           } else if (py > gd->hsize + gd->sy - gap) {
                   offset = gd->hsize;
                   data->cy = py - gd->hsize;
           } else {
                   offset = py + gap - gd->sy;
                   data->cy = py - offset;
           }
           data->oy = gd->hsize - offset;
   
           window_copy_redraw_screen(wp);
   }
   
   int
   window_copy_search_compare(
       struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx)
   {
           const struct grid_cell  *gc, *sgc;
           const struct grid_utf8  *gu, *sgu;
   
           gc = grid_peek_cell(gd, px, py);
           sgc = grid_peek_cell(sgd, spx, 0);
   
           if ((gc->flags & GRID_FLAG_UTF8) != (sgc->flags & GRID_FLAG_UTF8))
                   return (0);
   
           if (gc->flags & GRID_FLAG_UTF8) {
                   gu = grid_peek_utf8(gd, px, py);
                   sgu = grid_peek_utf8(sgd, spx, 0);
                   if (memcmp(gu->data, sgu->data, UTF8_SIZE) == 0)
                           return (1);
           } else {
                   if (gc->data == sgc->data)
                           return (1);
           }
           return (0);
   }
   
   int
   window_copy_search_lr(struct grid *gd,
       struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last)
   {
           u_int   ax, bx, px;
   
           for (ax = first; ax < last; ax++) {
                   if (ax + sgd->sx >= gd->sx)
                           break;
                   for (bx = 0; bx < sgd->sx; bx++) {
                           px = ax + bx;
                           if (!window_copy_search_compare(gd, px, py, sgd, bx))
                                   break;
                   }
                   if (bx == sgd->sx) {
                           *ppx = ax;
                           return (1);
                   }
           }
           return (0);
   }
   
   int
   window_copy_search_rl(struct grid *gd,
       struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last)
   {
           u_int   ax, bx, px;
   
           for (ax = last + 1; ax > first; ax--) {
                   for (bx = 0; bx < sgd->sx; bx++) {
                           px = ax - 1 + bx;
                           if (!window_copy_search_compare(gd, px, py, sgd, bx))
                                   break;
                   }
                   if (bx == sgd->sx) {
                           *ppx = ax - 1;
                           return (1);
                   }
           }
           return (0);
   }
   
   void
   window_copy_search_up(struct window_pane *wp, const char *searchstr)
   {
           struct window_copy_mode_data    *data = wp->modedata;
           struct screen                   *s = &wp->base, ss;
           struct screen_write_ctx          ctx;
           struct grid                     *gd = s->grid, *sgd;
           struct grid_cell                 gc;
           size_t                           searchlen;
           u_int                            i, last, fx, fy, px;
           int                              utf8flag, n, wrapped;
   
           if (*searchstr == '\0')
                   return;
           utf8flag = options_get_number(&wp->window->options, "utf8");
           searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
   
           screen_init(&ss, searchlen, 1, 0);
           screen_write_start(&ctx, NULL, &ss);
           memcpy(&gc, &grid_default_cell, sizeof gc);
           screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
           screen_write_stop(&ctx);
   
           fx = data->cx;
           fy = gd->hsize - data->oy + data->cy;
   
           if (fx == 0) {
                   if (fy == 0)
                           return;
                   fx = gd->sx - 1;
                   fy--;
           } else
                   fx--;
           n = wrapped = 0;
   
   retry:
           sgd = ss.grid;
           for (i = fy + 1; i > 0; i--) {
                   last = screen_size_x(s);
                   if (i == fy + 1)
                           last = fx;
                   n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last);
                   if (n) {
                           window_copy_scroll_to(wp, px, i - 1);
                           break;
                   }
           }
           if (!n && !wrapped) {
                   fx = gd->sx - 1;
                   fy = gd->hsize + gd->sy - 1;
                   wrapped = 1;
                   goto retry;
           }
   
           screen_free(&ss);
   }
   
   void
   window_copy_search_down(struct window_pane *wp, const char *searchstr)
   {
           struct window_copy_mode_data    *data = wp->modedata;
           struct screen                   *s = &wp->base, ss;
           struct screen_write_ctx          ctx;
           struct grid                     *gd = s->grid, *sgd;
           struct grid_cell                 gc;
           size_t                           searchlen;
           u_int                            i, first, fx, fy, px;
           int                              utf8flag, n, wrapped;
   
           if (*searchstr == '\0')
                   return;
           utf8flag = options_get_number(&wp->window->options, "utf8");
           searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
   
           screen_init(&ss, searchlen, 1, 0);
           screen_write_start(&ctx, NULL, &ss);
           memcpy(&gc, &grid_default_cell, sizeof gc);
           screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
           screen_write_stop(&ctx);
           searchlen = strlen(searchstr);
   
           fx = data->cx;
           fy = gd->hsize - data->oy + data->cy;
   
           if (fx == gd->sx - 1) {
                   if (fy == gd->hsize + gd->sy)
                           return;
                   fx = 0;
                   fy++;
           } else
                   fx++;
           n = wrapped = 0;
   
   retry:
           sgd = ss.grid;
           for (i = fy + 1; i < gd->hsize + gd->sy; i++) {
                   first = 0;
                   if (i == fy + 1)
                           first = fx;
                   n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx);
                   if (n) {
                           window_copy_scroll_to(wp, px, i - 1);
                           break;
                   }
           }
           if (!n && !wrapped) {
                   fx = 0;
                   fy = 0;
                   wrapped = 1;
                   goto retry;
           }
   
           screen_free(&ss);
   }
   
   void
   window_copy_goto_line(struct window_pane *wp, const char *linestr)
   {
           struct window_copy_mode_data    *data = wp->modedata;
           const char                      *errstr;
           u_int                            lineno;
   
           lineno = strtonum(linestr, 0, screen_hsize(&wp->base), &errstr);
           if (errstr != NULL)
                   return;
   
           data->oy = lineno;
           window_copy_redraw_screen(wp);
   }
   
   void
 window_copy_write_line(  window_copy_write_line(
     struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)      struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
 {  {
Line 282 
Line 652 
         struct screen                   *s = &data->screen;          struct screen                   *s = &data->screen;
         struct grid_cell                 gc;          struct grid_cell                 gc;
         char                             hdr[32];          char                             hdr[32];
         size_t                           size;          size_t                           last, xoff = 0, size = 0;
   
           memcpy(&gc, &grid_default_cell, sizeof gc);
           gc.fg = options_get_number(&wp->window->options, "mode-fg");
           gc.bg = options_get_number(&wp->window->options, "mode-bg");
           gc.attr |= options_get_number(&wp->window->options, "mode-attr");
   
           last = screen_size_y(s) - 1;
         if (py == 0) {          if (py == 0) {
                 memcpy(&gc, &grid_default_cell, sizeof gc);  
                 size = xsnprintf(hdr, sizeof hdr,                  size = xsnprintf(hdr, sizeof hdr,
                     "[%u/%u]", data->oy, screen_hsize(&wp->base));                      "[%u/%u]", data->oy, screen_hsize(&wp->base));
                 gc.fg = options_get_number(&wp->window->options, "mode-fg");  
                 gc.bg = options_get_number(&wp->window->options, "mode-bg");  
                 gc.attr |= options_get_number(  
                     &wp->window->options, "mode-attr");  
                 screen_write_cursormove(ctx, screen_size_x(s) - size, 0);                  screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
                 screen_write_puts(ctx, &gc, "%s", hdr);                  screen_write_puts(ctx, &gc, "%s", hdr);
           } else if (py == last && data->inputtype != WINDOW_COPY_OFF) {
                   xoff = size = xsnprintf(hdr, sizeof hdr,
                       "%s: %s", data->inputprompt, data->inputstr);
                   screen_write_cursormove(ctx, 0, last);
                   screen_write_puts(ctx, &gc, "%s", hdr);
         } else          } else
                 size = 0;                  size = 0;
   
         screen_write_cursormove(ctx, 0, py);          screen_write_cursormove(ctx, xoff, py);
         screen_write_copy(ctx, &wp->base, 0, (screen_hsize(&wp->base) -          screen_write_copy(ctx, &wp->base, xoff, (screen_hsize(&wp->base) -
             data->oy) + py, screen_size_x(s) - size, 1);              data->oy) + py, screen_size_x(s) - size, 1);
   
         if (py == data->cy && data->cx == screen_size_x(s)) {          if (py == data->cy && data->cx == screen_size_x(s)) {

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.21