Rethink the whole line discipline architecture. Instead of having
[u/mdw/putty] / window.c
index 99b374d..cef6825 100644 (file)
--- a/window.c
+++ b/window.c
@@ -101,13 +101,10 @@ static Mouse_Button lastbtn;
 
 static char *window_name, *icon_name;
 
-static Ldisc *real_ldisc;
-
 static int compose_state = 0;
 
-void begin_session(void) {
-    ldisc = real_ldisc;
-}
+/* Dummy routine, only required in plink. */
+void ldisc_update(int echo, int edit) {}
 
 int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
     static char appname[] = "PuTTY";
@@ -318,11 +315,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
         return 1;
     }
 
-    real_ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
-    /* To start with, we use the simple line discipline, so we can
-     * type passwords etc without fear of them being echoed... */
-    ldisc = &ldisc_simple;
-
     if (!prev) {
        wndclass.style         = 0;
        wndclass.lpfnWndProc   = WndProc;
@@ -564,7 +556,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
            }
            if(!timer_id)
                timer_id = SetTimer(hwnd, 1, 20, NULL);
-           DispatchMessage (&msg);
+            if (!(IsWindow(logbox) && IsDialogMessage(logbox, &msg)))
+                DispatchMessage (&msg);
 
            /* Make sure we blink everything that needs it. */
            term_blink(0);
@@ -1054,6 +1047,17 @@ static void click (Mouse_Button b, int x, int y) {
     lasttime = thistime;
 }
 
+static void show_mouseptr(int show) {
+    static int cursor_visible = 1;
+    if (!cfg.hide_mouseptr)            /* override if this feature disabled */
+        show = 1;
+    if (cursor_visible && !show)
+        ShowCursor(FALSE);
+    else if (!cursor_visible && show)
+        ShowCursor(TRUE);
+    cursor_visible = show;
+}
+
 static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
                                  WPARAM wParam, LPARAM lParam) {
     HDC hdc;
@@ -1077,7 +1081,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
         {
            time_t now;
            time(&now);
-           if (now-last_movement > cfg.ping_interval * 60 - 10)
+           if (now-last_movement > cfg.ping_interval)
            {
               back->special(TS_PING);
               last_movement = now;
@@ -1087,6 +1091,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
       case WM_CREATE:
        break;
       case WM_CLOSE:
+        show_mouseptr(1);
        if (!cfg.warn_on_close || session_closed ||
            MessageBox(hwnd, "Are you sure you want to close this session?",
                       "PuTTY Exit Confirmation",
@@ -1094,6 +1099,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
            DestroyWindow(hwnd);
        return 0;
       case WM_DESTROY:
+        show_mouseptr(1);
        PostQuitMessage (0);
        return 0;
       case WM_SYSCOMMAND:
@@ -1183,6 +1189,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
                cfg.height = rows;
                old_fwidth = font_width;
                old_fheight = font_height;
+                GetWindowText(hwnd, cfg.wintitle, sizeof(cfg.wintitle));
 
                 if (!do_reconfig(hwnd))
                     break;
@@ -1205,11 +1212,10 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
                 init_fonts(0);
                 sfree(logpal);
                 /*
-                 * Telnet will change local echo -> remote if the
-                 * remote asks.
+                 * Flush the line discipline's edit buffer in the
+                 * case where local editing has just been disabled.
                  */
-                if (cfg.protocol != PROT_TELNET)
-                    ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
+                ldisc_send(NULL, 0);
                 if (pal)
                     DeleteObject(pal);
                 logpal = NULL;
@@ -1282,6 +1288,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
                                  SWP_NOACTIVATE | SWP_NOCOPYBITS |
                                  SWP_NOMOVE | SWP_NOZORDER);
                }
+                set_title(cfg.wintitle);
                 if (IsIconic(hwnd)) {
                     SetWindowText (hwnd,
                                    cfg.win_name_always ? window_name : icon_name);
@@ -1327,40 +1334,47 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
 #define TO_CHR_Y(y) (((y)<0 ? (y)-font_height+1: (y)) / font_height)
 
       case WM_LBUTTONDOWN:
+        show_mouseptr(1);
        click (MB_SELECT, TO_CHR_X(X_POS(lParam)),
               TO_CHR_Y(Y_POS(lParam)));
         SetCapture(hwnd);
        return 0;
       case WM_LBUTTONUP:
+        show_mouseptr(1);
        term_mouse (MB_SELECT, MA_RELEASE, TO_CHR_X(X_POS(lParam)),
                    TO_CHR_Y(Y_POS(lParam)));
         ReleaseCapture();
        return 0;
       case WM_MBUTTONDOWN:
+        show_mouseptr(1);
         SetCapture(hwnd);
        click (cfg.mouse_is_xterm ? MB_PASTE : MB_EXTEND,
               TO_CHR_X(X_POS(lParam)),
               TO_CHR_Y(Y_POS(lParam)));
        return 0;
       case WM_MBUTTONUP:
+        show_mouseptr(1);
        term_mouse (cfg.mouse_is_xterm ? MB_PASTE : MB_EXTEND,
                    MA_RELEASE, TO_CHR_X(X_POS(lParam)),
                    TO_CHR_Y(Y_POS(lParam)));
         ReleaseCapture();
        return 0;
       case WM_RBUTTONDOWN:
+        show_mouseptr(1);
         SetCapture(hwnd);
        click (cfg.mouse_is_xterm ? MB_EXTEND : MB_PASTE,
               TO_CHR_X(X_POS(lParam)),
               TO_CHR_Y(Y_POS(lParam)));
        return 0;
       case WM_RBUTTONUP:
+        show_mouseptr(1);
        term_mouse (cfg.mouse_is_xterm ? MB_EXTEND : MB_PASTE,
                    MA_RELEASE, TO_CHR_X(X_POS(lParam)),
                    TO_CHR_Y(Y_POS(lParam)));
         ReleaseCapture();
        return 0;
       case WM_MOUSEMOVE:
+        show_mouseptr(1);
        /*
         * Add the mouse position and message time to the random
         * number noise.
@@ -1426,6 +1440,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
        term_update();
        break;
       case WM_KILLFOCUS:
+        show_mouseptr(1);
        has_focus = FALSE;
         DestroyCaret();
        term_out();
@@ -1591,7 +1606,10 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
                len = TranslateKey (message, wParam, lParam, buf);
                if (len == -1)
                    return DefWindowProc (hwnd, message, wParam, lParam);
-               ldisc->send (buf, len);
+               ldisc_send (buf, len);
+
+                if (len > 0)
+                    show_mouseptr(0);
            }
        }
        return 0;
@@ -1601,7 +1619,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
 
            buf[1] = wParam;
            buf[0] = wParam >> 8;
-           ldisc->send (buf, 2);
+           ldisc_send (buf, 2);
        }
       case WM_CHAR:
       case WM_SYSCHAR:
@@ -1613,7 +1631,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
         */
        {
            char c = xlat_kbd2tty((unsigned char)wParam);
-           ldisc->send (&c, 1);
+           ldisc_send (&c, 1);
        }
        return 0;
     }
@@ -1661,7 +1679,7 @@ void do_text (Context ctx, int x, int y, char *text, int len,
     x *= fnt_width;
     y *= font_height;
 
-    if (attr & ATTR_ACTCURS) {
+    if ((attr & ATTR_ACTCURS) && cfg.cursor_type == 0) {
        attr &= (bold_mode == BOLD_COLOURS ? 0x300200 : 0x300300);
        attr ^= ATTR_CUR_XOR;
     }
@@ -1822,7 +1840,7 @@ void do_text (Context ctx, int x, int y, char *text, int len,
         oldpen = SelectObject (hdc, oldpen);
         DeleteObject (oldpen);
     }
-    if (attr & ATTR_PASCURS) {
+    if ((attr & ATTR_PASCURS) && cfg.cursor_type == 0) {
        POINT pts[5];
         HPEN oldpen;
        pts[0].x = pts[1].x = pts[4].x = x;
@@ -1834,6 +1852,34 @@ void do_text (Context ctx, int x, int y, char *text, int len,
         oldpen = SelectObject (hdc, oldpen);
         DeleteObject (oldpen);
     }
+    if ((attr & (ATTR_ACTCURS | ATTR_PASCURS)) && cfg.cursor_type != 0) {
+        int startx, starty, dx, dy, length, i;
+       if (cfg.cursor_type == 1) {
+            startx = x; starty = y+descent;
+            dx = 1; dy = 0; length = fnt_width;
+        } else {
+           int xadjust = 0;
+           if (attr & ATTR_RIGHTCURS)
+               xadjust = fnt_width-1;
+            startx = x+xadjust; starty = y;
+            dx = 0; dy = 1; length = font_height;
+       }
+        if (attr & ATTR_ACTCURS) {
+            HPEN oldpen;
+            oldpen = SelectObject (hdc, CreatePen(PS_SOLID, 0, colours[23]));
+            MoveToEx (hdc, startx, starty, NULL);
+            LineTo (hdc, startx+dx*length, starty+dy*length);
+            oldpen = SelectObject (hdc, oldpen);
+            DeleteObject (oldpen);
+        } else {
+            for (i = 0; i < length; i++) {
+                if (i % 2 == 0) {
+                    SetPixel(hdc, startx, starty, colours[23]);
+                }
+                startx += dx; starty += dy;
+            }
+        }
+    }
 }
 
 static int check_compose(int first, int second) {