Justin Bradford's patch for increased proxy robustness.
[u/mdw/putty] / terminal.c
index b286efe..dc1793c 100644 (file)
@@ -328,10 +328,9 @@ void term_update(void)
     ctx = get_ctx();
     if (ctx) {
        int need_sbar_update = seen_disp_event;
-       if ((seen_key_event && (cfg.scroll_on_key)) ||
-           (seen_disp_event && (cfg.scroll_on_disp))) {
+       if (seen_disp_event && cfg.scroll_on_disp) {
            disptop = 0;               /* return to main screen */
-           seen_disp_event = seen_key_event = 0;
+           seen_disp_event = 0;
            need_sbar_update = TRUE;
        }
        if (need_sbar_update)
@@ -343,6 +342,37 @@ void term_update(void)
 }
 
 /*
+ * Called from front end when a keypress occurs, to trigger
+ * anything magical that needs to happen in that situation.
+ */
+void term_seen_key_event(void)
+{
+    /*
+     * On any keypress, clear the bell overload mechanism
+     * completely, on the grounds that large numbers of
+     * beeps coming from deliberate key action are likely
+     * to be intended (e.g. beeps from filename completion
+     * blocking repeatedly).
+     */
+    beep_overloaded = FALSE;
+    while (beephead) {
+       struct beeptime *tmp = beephead;
+       beephead = tmp->next;
+       sfree(tmp);
+    }
+    beeptail = NULL;
+    nbeeps = 0;
+
+    /*
+     * Reset the scrollback on keypress, if we're doing that.
+     */
+    if (cfg.scroll_on_key) {
+       disptop = 0;                   /* return to main screen */
+       seen_disp_event = 1;
+    }
+}
+
+/*
  * Same as power_on(), but an external function.
  */
 void term_pwron(void)
@@ -1042,6 +1072,9 @@ static void term_print_finish(void)
     int len, size;
     char c;
 
+    if (!printing && !only_printing)
+       return;                        /* we need do nothing */
+
     term_print_flush();
     while ((size = bufchain_size(&printer_buf)) > 0) {
        bufchain_prefix(&printer_buf, &data, &len);
@@ -1072,6 +1105,7 @@ void term_out(void)
 
     unget = -1;
 
+    chars = NULL;                     /* placate compiler warnings */
     while (nchars > 0 || bufchain_size(&inbuf) > 0) {
        if (unget == -1) {
            if (nchars == 0) {
@@ -1129,7 +1163,6 @@ void term_out(void)
                else
                    print_state = 0;
                if (print_state == 4) {
-                   printing = only_printing = FALSE;
                    term_print_finish();
                }
                continue;
@@ -1373,12 +1406,12 @@ void term_out(void)
                     * Perform an actual beep if we're not overloaded.
                     */
                    if (!cfg.bellovl || !beep_overloaded) {
-                       beep(cfg.beep);
                        if (cfg.beep == BELL_VISUAL) {
                            in_vbell = TRUE;
                            vbell_startpoint = ticks;
                            term_update();
-                       }
+                       } else
+                           beep(cfg.beep);
                    }
                    disptop = 0;
                }
@@ -1911,8 +1944,6 @@ void term_out(void)
                                print_state = 0;
                                term_print_setup();
                            } else if (esc_args[0] == 4 && printing) {
-                               printing = FALSE;
-                               only_printing = FALSE;
                                term_print_finish();
                            }
                        }
@@ -2994,8 +3025,8 @@ void term_blink(int flg)
     now = GETTICKCOUNT();
     blink_diff = now - last_tblink;
 
-    /* Make sure the text blinks no more than 2Hz */
-    if (blink_diff < 0 || blink_diff > 450) {
+    /* Make sure the text blinks no more than 2Hz; we'll use 0.45 s period. */
+    if (blink_diff < 0 || blink_diff > (TICKSPERSEC * 9 / 20)) {
        last_tblink = now;
        tblinker = !tblinker;
     }
@@ -3176,16 +3207,14 @@ static void clipme(pos top, pos bottom, int rect)
                    unsigned char buf[4];
                    WCHAR wbuf[4];
                    int rv;
-                   if (IsDBCSLeadByteEx(font_codepage, (BYTE) c)) {
+                   if (is_dbcs_leadbyte(font_codepage, (BYTE) c)) {
                        buf[0] = c;
                        buf[1] = (unsigned char) ldata[top.x + 1];
-                       rv = MultiByteToWideChar(font_codepage,
-                                                0, buf, 2, wbuf, 4);
+                       rv = mb_to_wc(font_codepage, 0, buf, 2, wbuf, 4);
                        top.x++;
                    } else {
                        buf[0] = c;
-                       rv = MultiByteToWideChar(font_codepage,
-                                                0, buf, 1, wbuf, 4);
+                       rv = mb_to_wc(font_codepage, 0, buf, 1, wbuf, 4);
                    }
 
                    if (rv > 0) {
@@ -3219,8 +3248,10 @@ static void clipme(pos top, pos bottom, int rect)
        top.y++;
        top.x = rect ? old_top_x : 0;
     }
+#if SELECTION_NUL_TERMINATED
     wblen++;
     *wbptr++ = 0;
+#endif
     write_clip(workbuf, wblen, FALSE); /* transfer to clipboard */
     if (buflen > 0)                   /* indicates we allocated this buffer */
        sfree(workbuf);
@@ -3449,9 +3480,11 @@ void term_do_paste(void)
     int len;
 
     get_clip(&data, &len);
-    if (data) {
+    if (data && len > 0) {
         wchar_t *p, *q;
 
+       term_seen_key_event();         /* pasted data counts */
+
         if (paste_buffer)
             sfree(paste_buffer);
         paste_pos = paste_hold = paste_len = 0;
@@ -3684,8 +3717,12 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
        } else
            selstate = NO_SELECTION;
     } else if (b == MBT_PASTE
-              && (a == MA_CLICK || a == MA_2CLK || a == MA_3CLK)) {
-        term_do_paste();
+              && (a == MA_CLICK
+#if MULTICLICK_ONLY_EVENT
+                  || a == MA_2CLK || a == MA_3CLK
+#endif
+                  )) {
+       request_paste();
     }
 
     term_update();
@@ -3700,6 +3737,11 @@ void term_nopaste()
     paste_len = 0;
 }
 
+int term_paste_pending(void)
+{
+    return paste_len != 0;
+}
+
 void term_paste()
 {
     static long last_paste = 0;