Robert de Bath's multi-purpose patch, slightly modified.
[u/mdw/putty] / window.c
index e2301d6..fd46be4 100644 (file)
--- a/window.c
+++ b/window.c
@@ -3,11 +3,11 @@
 #include <winsock.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <ctype.h>
 
 #define PUTTY_DO_GLOBALS                      /* actually _define_ globals */
 #include "putty.h"
 #include "win_res.h"
-#include "sizetip.h"
 
 #define IDM_SHOWLOG   0x0010
 #define IDM_NEWSESS   0x0020
@@ -151,7 +151,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
             */
            HANDLE filemap;
            Config *cp;
-           if (sscanf(p+1, "%x", &filemap) == 1 &&
+           if (sscanf(p+1, "%p", &filemap) == 1 &&
                (cp = MapViewOfFile(filemap, FILE_MAP_READ,
                                    0, 0, sizeof(Config))) != NULL) {
                cfg = *cp;
@@ -182,7 +182,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
     }
 
     back = (cfg.protocol == PROT_SSH ? &ssh_backend : 
-                       cfg.protocol == PROT_TELNET ? &telnet_backend : &raw_backend );
+           cfg.protocol == PROT_TELNET ? &telnet_backend :
+           &raw_backend);
+
+    ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
 
     if (!prev) {
        wndclass.style         = 0;
@@ -307,6 +310,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
     inbuf_reap = inbuf_head = 0;
     outbuf_reap = outbuf_head = 0;
 
+    /* 
+     * Choose unscroll method
+     */
+    unscroll_event = US_DISP;
+
     /*
      * Prepare the mouse handler.
      */
@@ -342,9 +350,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
            AppendMenu (p, MF_ENABLED, IDM_TEL_EOR, "End Of Record");
            AppendMenu (p, MF_ENABLED, IDM_TEL_EOF, "End Of File");
            AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) p, "Telnet Command");
-           AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "Show Negotiation");
            AppendMenu (m, MF_SEPARATOR, 0, 0);
        }
+       AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "Event Log");
+       AppendMenu (m, MF_SEPARATOR, 0, 0);
        AppendMenu (m, MF_ENABLED, IDM_NEWSESS, "New Session");
        AppendMenu (m, MF_ENABLED, IDM_DUPSESS, "Duplicate Session");
        s = CreateMenu();
@@ -629,7 +638,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
       case WM_SYSCOMMAND:
        switch (wParam & ~0xF) {       /* low 4 bits reserved to Windows */
          case IDM_SHOWLOG:
-           shownegot(hwnd);
+           showeventlog(hwnd);
            break;
          case IDM_NEWSESS:
          case IDM_DUPSESS:
@@ -668,15 +677,17 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
                            UnmapViewOfFile(p);
                        }
                    }
-                   sprintf(c, "putty &%08x", filemap);
+                   sprintf(c, "putty &%p", filemap);
                    cl = c;
                } else if (wParam == IDM_SAVEDSESS) {
                    char *session = sessions[(lParam - IDM_SAVED_MIN) / 16];
                    cl = malloc(16 + strlen(session)); /* 8, but play safe */
                    if (!cl)
                        cl = NULL;     /* not a very important failure mode */
-                   sprintf(cl, "putty @%s", session);
-                   freecl = TRUE;
+                   else {
+                       sprintf(cl, "putty @%s", session);
+                       freecl = TRUE;
+                   }
                } else
                    cl = NULL;
 
@@ -711,6 +722,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
            und_mode = UND_FONT;
            init_fonts();
            sfree(logpal);
+           ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
            if (pal)
                DeleteObject(pal);
            logpal = NULL;
@@ -1014,7 +1026,9 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
            int len;
 
            len = TranslateKey (wParam, lParam, buf);
-           back->send (buf, len);
+           if (len == -1)
+               return DefWindowProc (hwnd, message, wParam, lParam);
+           ldisc->send (buf, len);
        }
        return 0;
       case WM_KEYUP:
@@ -1054,7 +1068,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
         */
        {
            char c = xlat_kbd2tty((unsigned char)wParam);
-           back->send (&c, 1);
+           ldisc->send (&c, 1);
        }
        return 0;
     }
@@ -1216,6 +1230,14 @@ static int TranslateKey(WPARAM wParam, LPARAM lParam, unsigned char *output) {
     ret = GetKeyboardState(keystate);
 
     /* 
+     * Record that we pressed key so the scroll window can be reset, but
+     * be careful to avoid Shift-UP/Down
+     */
+    if( wParam != VK_SHIFT && wParam != VK_PRIOR && wParam != VK_NEXT ) {
+        seen_key_event = 1; 
+    }
+
+    /* 
      * Windows does not always want to distinguish left and right
      * Alt or Control keys. Thus we keep track of them ourselves.
      * See also the WM_KEYUP handler.
@@ -1243,6 +1265,29 @@ static int TranslateKey(WPARAM wParam, LPARAM lParam, unsigned char *output) {
     }
 
     /*
+     * NetHack keypad mode. This may conflict with Shift-PgUp/PgDn,
+     * so we do it first.
+     */
+    if (cfg.nethack_keypad) {
+       int shift = keystate[VK_SHIFT] & 0x80;
+        /*
+         * NB the shifted versions only work with numlock off.
+         */
+       switch ( (lParam >> 16) & 0x1FF ) {
+         case 0x047: *p++ = shift ? 'Y' : 'y'; return p - output;
+         case 0x048: *p++ = shift ? 'K' : 'k'; return p - output;
+         case 0x049: *p++ = shift ? 'U' : 'u'; return p - output;
+         case 0x04B: *p++ = shift ? 'H' : 'h'; return p - output;
+         case 0x04C: *p++ = '.'; return p - output;
+         case 0x04D: *p++ = shift ? 'L' : 'l'; return p - output;
+         case 0x04F: *p++ = shift ? 'B' : 'b'; return p - output;
+         case 0x050: *p++ = shift ? 'J' : 'j'; return p - output;
+         case 0x051: *p++ = shift ? 'N' : 'n'; return p - output;
+         case 0x053: *p++ = '.'; return p - output;
+       }
+    }
+
+    /*
      * Shift-PgUp, Shift-PgDn, and Alt-F4 all produce window
      * events: we'll deal with those now.
      */
@@ -1254,9 +1299,12 @@ static int TranslateKey(WPARAM wParam, LPARAM lParam, unsigned char *output) {
        SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
        return 0;
     }
-    if ((lParam & 0x20000000) && wParam == VK_F4) {
-       SendMessage (hwnd, WM_CLOSE, 0, 0);
-       return 0;
+    if ((lParam & 0x20000000) && wParam == VK_F4 && cfg.alt_f4) {
+       return -1;
+    }
+    if ((lParam & 0x20000000) && wParam == VK_SPACE && cfg.alt_space) {
+       SendMessage (hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0);
+       return -1;
     }
 
     /*
@@ -1282,12 +1330,12 @@ static int TranslateKey(WPARAM wParam, LPARAM lParam, unsigned char *output) {
        return p - output;
     }
 
-    /*
-     * If we're in applications keypad mode, we have to process it
-     * before char-map translation, because it will pre-empt lots
-     * of stuff, even if NumLock is off.
-     */
     if (app_keypad_keys) {
+       /*
+        * If we're in applications keypad mode, we have to process it
+        * before char-map translation, because it will pre-empt lots
+        * of stuff, even if NumLock is off.
+        */
        if (ret) {
            /*
             * Hack to ensure NumLock doesn't interfere with