Author: ray
Date: Fri Feb 10 13:28:30 2017
New Revision: 313547
URL: https://svnweb.freebsd.org/changeset/base/313547

Log:
  o Reset mouse selection when new lines reach selection lines.
  o Fix how selection handled on display.
  
  Submitted by: hselasky
  Reviewed by:  hselasky, emaste(previous version)
  Todo:         track mouse select direction.

Modified:
  head/sys/dev/vt/vt_buf.c

Modified: head/sys/dev/vt/vt_buf.c
==============================================================================
--- head/sys/dev/vt/vt_buf.c    Fri Feb 10 11:17:45 2017        (r313546)
+++ head/sys/dev/vt/vt_buf.c    Fri Feb 10 13:28:30 2017        (r313547)
@@ -54,6 +54,11 @@ static MALLOC_DEFINE(M_VTBUF, "vtbuf", "
        (d).tp_row = (s).tp_row;        \
 } while (0)
 
+#ifndef SC_NO_CUTPASTE
+static int vtbuf_wth(const struct vt_buf *vb, int row);
+static int vtbuf_in_this_range(int begin, int test, int end, int sz);
+#endif
+static int vtbuf_htw(const struct vt_buf *vb, int row);
 
 /*
  * line4
@@ -122,6 +127,9 @@ vthistory_seek(struct vt_buf *vb, int of
 void
 vthistory_addlines(struct vt_buf *vb, int offset)
 {
+#ifndef SC_NO_CUTPASTE
+       int cur, sz;
+#endif
 
        vb->vb_curroffset += offset;
        if (vb->vb_curroffset < 0)
@@ -132,6 +140,17 @@ vthistory_addlines(struct vt_buf *vb, in
        if ((vb->vb_flags & VBF_SCROLL) == 0) {
                vb->vb_roffset = vb->vb_curroffset;
        }
+
+#ifndef SC_NO_CUTPASTE
+       sz = vb->vb_history_size;
+       cur = vb->vb_roffset + vb->vb_scr_size.tp_row + sz - 1;
+       if (vtbuf_in_this_range(cur, vb->vb_mark_start.tp_row, cur + offset, 
sz) ||
+           vtbuf_in_this_range(cur, vb->vb_mark_end.tp_row, cur + offset, sz)) 
{
+               /* clear screen selection */
+               vb->vb_mark_start.tp_row = vb->vb_mark_end.tp_row;
+               vb->vb_mark_start.tp_col = vb->vb_mark_end.tp_col;
+       }
+#endif
 }
 
 void
@@ -144,11 +163,33 @@ vthistory_getpos(const struct vt_buf *vb
 #ifndef SC_NO_CUTPASTE /* Only mouse support use it now. */
 /* Translate current view row number to history row. */
 static int
-vtbuf_wth(struct vt_buf *vb, int row)
+vtbuf_wth(const struct vt_buf *vb, int row)
 {
 
        return ((vb->vb_roffset + row) % vb->vb_history_size);
 }
+
+/*
+ * Test if an index in a circular buffer is within a range.
+ *
+ * begin - start index
+ * end - end index
+ * test - test index
+ * sz - size of circular buffer when it turns over
+ */
+static int
+vtbuf_in_this_range(int begin, int test, int end, int sz)
+{
+
+       begin %= sz;
+       end %= sz;
+
+       /* check for inversion */
+       if (begin > end)
+               return (test >= begin || test < end);
+       else
+               return (test >= begin && test < end);
+}
 #endif
 
 /* Translate history row to current view row number. */
@@ -169,33 +210,44 @@ vtbuf_htw(const struct vt_buf *vb, int r
 int
 vtbuf_iscursor(const struct vt_buf *vb, int row, int col)
 {
-       int sc, sr, ec, er, tmp;
+#ifndef SC_NO_CUTPASTE
+       int sc, sr, sz, ec, er, tmp;
+#endif
 
        if ((vb->vb_flags & (VBF_CURSOR|VBF_SCROLL)) == VBF_CURSOR &&
            (vb->vb_cursor.tp_row == row) && (vb->vb_cursor.tp_col == col))
                return (1);
 
+#ifndef SC_NO_CUTPASTE
        /* Mark cut/paste region. */
+       if (vb->vb_mark_start.tp_col == vb->vb_mark_end.tp_col &&
+           vb->vb_mark_start.tp_row == vb->vb_mark_end.tp_row)
+               return (0);
 
-       /*
-        * Luckily screen view is not like circular buffer, so we will
-        * calculate in screen coordinates.  Translate first.
-        */
        sc = vb->vb_mark_start.tp_col;
-       sr = vtbuf_htw(vb, vb->vb_mark_start.tp_row);
+       sr = vb->vb_mark_start.tp_row;
        ec = vb->vb_mark_end.tp_col;
-       er = vtbuf_htw(vb, vb->vb_mark_end.tp_row);
+       er = vb->vb_mark_end.tp_row;
 
+       /*
+        * Information about if the selection was made bottom-top or
+        * top-bottom is lost due to modulo arithmetics and needs to
+        * be recovered:
+        */
+       sz = vb->vb_history_size;
+       tmp = (sz + er - sr) % sz;
+       row = vtbuf_wth(vb, row);
 
-       /* Swap start and end if start > end. */
-       if (POS_INDEX(sc, sr) > POS_INDEX(ec, er)) {
+       /* Swap start and end if start > end */
+       if ((2 * tmp) > sz || (tmp == 0 && sc > ec)) {
                tmp = sc; sc = ec; ec = tmp;
                tmp = sr; sr = er; er = tmp;
        }
 
-       if ((POS_INDEX(sc, sr) <= POS_INDEX(col, row)) &&
-           (POS_INDEX(col, row) < POS_INDEX(ec, er)))
+       if (vtbuf_in_this_range(POS_INDEX(sc, sr), POS_INDEX(col, row),
+           POS_INDEX(ec, er), POS_INDEX(0, sz)))
                return (1);
+#endif
 
        return (0);
 }
@@ -627,8 +679,8 @@ vtbuf_flush_mark(struct vt_buf *vb)
        int s, e;
 
        /* Notify renderer to update marked region. */
-       if (vb->vb_mark_start.tp_col || vb->vb_mark_end.tp_col ||
-           vb->vb_mark_start.tp_row || vb->vb_mark_end.tp_row) {
+       if ((vb->vb_mark_start.tp_col != vb->vb_mark_end.tp_col) ||
+           (vb->vb_mark_start.tp_row != vb->vb_mark_end.tp_row)) {
 
                s = vtbuf_htw(vb, vb->vb_mark_start.tp_row);
                e = vtbuf_htw(vb, vb->vb_mark_end.tp_row);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to