Jan Holmen Holsten's patch for drag-selects to scroll the scrollback.
[u/mdw/putty] / terminal.c
index aeadc77..5b8a183 100644 (file)
@@ -254,6 +254,7 @@ unsigned long *lineptr(int y, int lineno)
     if (newline != line) {
        delpos234(whichtree, treeindex);
        addpos234(whichtree, newline, treeindex);
+        line = newline;
     }
 
     return line + 1;
@@ -933,15 +934,18 @@ void term_out(void)
 {
     int c, inbuf_reap;
 
+    /*
+     * Optionally log the session traffic to a file. Useful for
+     * debugging and possibly also useful for actual logging.
+     */
+    if (cfg.logtype == LGTYP_DEBUG)
+       for (inbuf_reap = 0; inbuf_reap < inbuf_head; inbuf_reap++) {
+           logtraffic((unsigned char) inbuf[inbuf_reap], LGTYP_DEBUG);
+       }
+
     for (inbuf_reap = 0; inbuf_reap < inbuf_head; inbuf_reap++) {
        c = inbuf[inbuf_reap];
 
-       /*
-        * Optionally log the session traffic to a file. Useful for
-        * debugging and possibly also useful for actual logging.
-        */
-       logtraffic((unsigned char) c, LGTYP_DEBUG);
-
        /* Note only VT220+ are 8-bit VT102 is seven bit, it shouldn't even
         * be able to display 8-bit characters, but I'll let that go 'cause
         * of i18n.
@@ -984,9 +988,9 @@ void term_out(void)
                  case 4:
                  case 5:
                    if ((c & 0xC0) != 0x80) {
-                       inbuf_reap--;  /* This causes the faulting character */
-                       c = UCSERR;    /* to be logged twice - not really a */
-                       utf_state = 0; /* serious problem. */
+                       inbuf_reap--;
+                       c = UCSERR;
+                       utf_state = 0;
                        break;
                    }
                    utf_char = (utf_char << 6) | (c & 0x3f);
@@ -1948,6 +1952,21 @@ void term_out(void)
                            }
                        }
                        break;
+                     case 'Z':         /* BackTab for xterm */
+                       compatibility(OTHER);
+                       {
+                           int i = def(esc_args[0], 1);
+                           pos old_curs = curs;
+
+                           for(;i>0 && curs.x>0; i--) {
+                               do {
+                                   curs.x--;
+                               } while (curs.x >0 && !tabs[curs.x]);
+                           }
+                           fix_cpos;
+                           check_selection(old_curs, curs);
+                       }
+                       break;
                      case ANSI('L', '='):
                        compatibility(OTHER);
                        use_bce = (esc_args[0] <= 0);
@@ -3063,11 +3082,18 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
 {
     pos selpoint;
     unsigned long *ldata;
+    int raw_mouse = xterm_mouse && !(cfg.mouse_override && shift);
 
-    if (y < 0)
+    if (y < 0) {
        y = 0;
-    if (y >= rows)
+       if (a == MA_DRAG && !raw_mouse)
+           term_scroll(0, -1);
+    }
+    if (y >= rows) {
        y = rows - 1;
+       if (a == MA_DRAG && !raw_mouse)
+           term_scroll(0, +1);
+    }
     if (x < 0) {
        if (y > 0) {
            x = cols - 1;
@@ -3084,7 +3110,7 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
     if ((ldata[cols] & LATTR_MODE) != LATTR_NORM)
        selpoint.x /= 2;
 
-    if (xterm_mouse) {
+    if (raw_mouse) {
        int encstate = 0, r, c;
        char abuf[16];
        static int is_down = 0;
@@ -3265,13 +3291,33 @@ int term_ldisc(int option)
 /*
  * from_backend(), to get data from the backend for the terminal.
  */
-void from_backend(int is_stderr, char *data, int len)
+int from_backend(int is_stderr, char *data, int len)
 {
     while (len--) {
        if (inbuf_head >= INBUF_SIZE)
            term_out();
        inbuf[inbuf_head++] = *data++;
     }
+
+    /*
+     * We process all stdout/stderr data immediately we receive it,
+     * and don't return until it's all gone. Therefore, there's no
+     * reason at all to return anything other than zero from this
+     * function.
+     * 
+     * This is a slightly suboptimal way to deal with SSH2 - in
+     * principle, the window mechanism would allow us to continue
+     * to accept data on forwarded ports and X connections even
+     * while the terminal processing was going slowly - but we
+     * can't do the 100% right thing without moving the terminal
+     * processing into a separate thread, and that might hurt
+     * portability. So we manage stdout buffering the old SSH1 way:
+     * if the terminal processing goes slowly, the whole SSH
+     * connection stops accepting data until it's ready.
+     * 
+     * In practice, I can't imagine this causing serious trouble.
+     */
+    return 0;
 }
 
 /*