]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/blobdiff - terminal.c
Fix breakage of SSH-2 packet decompression by r10070.
[PuTTY_svn.git] / terminal.c
index e7095e0c2db2cf7e7a9e248e699de64ceb944e9d..bd77f2397878d085a6646ca508a80acb1405c448 100644 (file)
@@ -109,9 +109,6 @@ static void scroll(Terminal *, int, int, int, int);
 #ifdef OPTIMISE_SCROLL
 static void scroll_display(Terminal *, int, int, int);
 #endif /* OPTIMISE_SCROLL */
-static void term_resume_pasting(Terminal *term);
-static void term_paste_callback(void *vterm);
-static void term_paste_queue(Terminal *term, int timed);
 
 static termline *newline(Terminal *term, int cols, int bce)
 {
@@ -2383,16 +2380,51 @@ static void insch(Terminal *term, int n)
 {
     int dir = (n < 0 ? -1 : +1);
     int m, j;
-    pos cursplus;
+    pos eol;
     termline *ldata;
 
     n = (n < 0 ? -n : n);
     if (n > term->cols - term->curs.x)
        n = term->cols - term->curs.x;
     m = term->cols - term->curs.x - n;
-    cursplus.y = term->curs.y;
-    cursplus.x = term->curs.x + n;
-    check_selection(term, term->curs, cursplus);
+
+    /*
+     * We must de-highlight the selection if it overlaps any part of
+     * the region affected by this operation, i.e. the region from the
+     * current cursor position to end-of-line, _unless_ the entirety
+     * of the selection is going to be moved to the left or right by
+     * this operation but otherwise unchanged, in which case we can
+     * simply move the highlight with the text.
+     */
+    eol.y = term->curs.y;
+    eol.x = term->cols;
+    if (poslt(term->curs, term->selend) && poslt(term->selstart, eol)) {
+        pos okstart = term->curs;
+        pos okend = eol;
+        if (dir > 0) {
+            /* Insertion: n characters at EOL will be splatted. */
+            okend.x -= n;
+        } else {
+            /* Deletion: n characters at cursor position will be splatted. */
+            okstart.x += n;
+        }
+        if (posle(okstart, term->selstart) && posle(term->selend, okend)) {
+            /* Selection is contained entirely in the interval
+             * [okstart,okend), so we need only adjust the selection
+             * bounds. */
+            term->selstart.x += dir * n;
+            term->selend.x += dir * n;
+            assert(term->selstart.x >= term->curs.x);
+            assert(term->selstart.x < term->cols);
+            assert(term->selend.x > term->curs.x);
+            assert(term->selend.x <= term->cols);
+        } else {
+            /* Selection is not wholly contained in that interval, so
+             * we must unhighlight it. */
+            deselect(term);
+        }
+    }
+
     check_boundary(term, term->curs.x, term->curs.y);
     if (dir < 0)
        check_boundary(term, term->curs.x + n, term->curs.y);
@@ -2969,7 +3001,6 @@ static void term_out(Terminal *term)
                term->curs.x = 0;
                term->wrapnext = FALSE;
                seen_disp_event(term);
-                term_resume_pasting(term);
 
                if (term->crhaslf) {
                    if (term->curs.y == term->marg_b)
@@ -3000,7 +3031,6 @@ static void term_out(Terminal *term)
                    term->curs.x = 0;
                term->wrapnext = FALSE;
                seen_disp_event(term);
-                term_resume_pasting(term);
                if (term->logctx)
                    logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
                break;
@@ -5708,48 +5738,6 @@ static void sel_spread(Terminal *term)
     }
 }
 
-static void term_resume_pasting(Terminal *term)
-{
-    expire_timer_context(&term->paste_timer_ctx);
-    term_paste_queue(term, FALSE);
-}
-
-static void term_paste_timing_callback(void *vterm, unsigned long now)
-{
-    Terminal *term = *(Terminal **)vterm;
-    term_resume_pasting(term);
-}
-
-static void term_paste_queue(Terminal *term, int timed)
-{
-    if (timed) {
-        /*
-         * Delay sending the rest of the paste buffer until we have
-         * seen a newline coming back from the server (indicating that
-         * it's absorbed the data we've sent so far). As a fallback,
-         * continue sending anyway after a longish timeout.
-         *
-         * We use the pointless structure field term->paste_timer_ctx
-         * (which is a Terminal *, and we'll make sure it points
-         * straight back to term) as our timer context, so that it can
-         * be distinguished from term itself. That way, if we see a
-         * reason to continue pasting before the timer goes off, we
-         * can cancel just this timer and none of the other terminal
-         * timers handling display updates, blinking text and cursor,
-         * and visual bells.
-         */
-        term->paste_timer_ctx = term;
-        schedule_timer(450, term_paste_timing_callback,
-                       &term->paste_timer_ctx);
-    } else {
-        /*
-         * Just arrange to call term_paste_callback from the top level
-         * at the next opportunity.
-         */
-        queue_toplevel_callback(term_paste_callback, term);
-    }
-}
-
 static void term_paste_callback(void *vterm)
 {
     Terminal *term = (Terminal *)vterm;
@@ -5768,7 +5756,7 @@ static void term_paste_callback(void *vterm)
        term->paste_pos += n;
 
        if (term->paste_pos < term->paste_len) {
-            term_paste_queue(term, TRUE);
+            queue_toplevel_callback(term_paste_callback, term);
            return;
        }
     }
@@ -5838,7 +5826,7 @@ void term_do_paste(Terminal *term)
     }
     get_clip(term->frontend, NULL, NULL);
 
-    term_paste_queue(term, FALSE);
+    queue_toplevel_callback(term_paste_callback, term);
 }
 
 void term_mouse(Terminal *term, Mouse_Button braw, Mouse_Button bcooked,
@@ -6125,7 +6113,6 @@ void term_nopaste(Terminal *term)
 {
     if (term->paste_len == 0)
        return;
-    expire_timer_context(&term->paste_timer_ctx);
     sfree(term->paste_buffer);
     term->paste_buffer = NULL;
     term->paste_len = 0;