Put the \001 prefix back on scp error messages when they're sent to
[u/mdw/putty] / window.c
index f724275..62e4be7 100644 (file)
--- a/window.c
+++ b/window.c
@@ -1,6 +1,7 @@
 #include <windows.h>
 #include <imm.h>
 #include <commctrl.h>
+#include <mmsystem.h>
 #ifndef AUTO_WINSOCK
 #ifdef WINSOCK_TWO
 #include <winsock2.h>
@@ -42,6 +43,9 @@
 #define IDM_SAVEDSESS 0x0150
 #define IDM_COPYALL   0x0160
 
+#define IDM_SESSLGP   0x0250  /* log type printable */
+#define IDM_SESSLGA   0x0260  /* log type all chars */
+#define IDM_SESSLGE   0x0270  /* log end */
 #define IDM_SAVED_MIN 0x1000
 #define IDM_SAVED_MAX 0x2000
 
@@ -441,7 +445,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
 
        error = back->init (cfg.host, cfg.port, &realhost);
        if (error) {
-           sprintf(msg, "Unable to open connection:\n%s", error);
+           sprintf(msg, "Unable to open connection to\n"
+                   "%.800s\n"
+                   "%s", cfg.host, error);
            MessageBox(NULL, msg, "PuTTY Error", MB_ICONERROR | MB_OK);
            return 0;
        }
@@ -595,14 +601,17 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
                term_out();
            term_update();
             ShowCaret(hwnd);
-           if (!has_focus)
+           if (in_vbell)
+              /* Hmm, term_update didn't want to do an update too soon ... */
+              timer_id = SetTimer(hwnd, 1, 50, NULL);
+           else if (!has_focus)
               timer_id = SetTimer(hwnd, 1, 59500, NULL);
            else
               timer_id = SetTimer(hwnd, 1, 100, NULL);
            long_timer = 1;
        
            /* There's no point rescanning everything in the message queue
-            * so we do an apperently unneccesary wait here 
+            * so we do an apparently unnecessary wait here
             */
            WaitMessage();
            if (GetMessage (&msg, NULL, 0, 0) != 1)
@@ -1656,7 +1665,8 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
  * have one.)
  */
 void sys_cursor(int x, int y) {
-    SetCaretPos(x * font_width, y * font_height);
+    if (has_focus)
+       SetCaretPos(x * font_width, y * font_height);
 }
 
 /*
@@ -1726,7 +1736,7 @@ void do_text (Context ctx, int x, int y, char *text, int len,
 #endif
                /* This is CP437 ... junk translation */
                static const unsigned char oemhighhalf[] = {
-                   0xff, 0xad, 0x9b, 0x9c, 0x6f, 0x9d, 0x7c, 0x15,
+                   0x20, 0xad, 0x9b, 0x9c, 0x6f, 0x9d, 0x7c, 0x15,
                    0x22, 0x43, 0xa6, 0xae, 0xaa, 0x2d, 0x52, 0xc4,
                    0xf8, 0xf1, 0xfd, 0x33, 0x27, 0xe6, 0x14, 0xfa,
                    0x2c, 0x31, 0xa7, 0xaf, 0xac, 0xab, 0x2f, 0xa8,
@@ -2018,29 +2028,6 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
            keystate[VK_RMENU] = keystate[VK_MENU];
        }
 
-       /* Note if AltGr was pressed and if it was used as a compose key */
-       if (cfg.compose_key) {
-           if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED))
-           {
-               if (!compose_state) compose_key = wParam;
-           }
-           if (wParam == VK_APPS && !compose_state)
-               compose_key = wParam;
-
-           if (wParam == compose_key)
-           {
-               if (compose_state == 0 && (HIWORD(lParam)&(KF_UP|KF_REPEAT))==0)
-                   compose_state = 1;
-               else if (compose_state == 1 && (HIWORD(lParam)&KF_UP))
-                   compose_state = 2;
-               else
-                   compose_state = 0;
-           }
-           else if (compose_state==1 && wParam != VK_CONTROL)
-               compose_state = 0;
-       } else {
-           compose_state = 0;
-       }
 
        /* Nastyness with NUMLock - Shift-NUMLock is left alone though */
        if ( (cfg.funky_type == 3 ||
@@ -2067,14 +2054,43 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
     key_down = ((HIWORD(lParam)&KF_UP)==0);
 
-    /* Make sure Ctrl-ALT is not the same as AltGr for ToAscii */
-    if (left_alt && (keystate[VK_CONTROL]&0x80))
-       keystate[VK_MENU] = 0;
+    /* Make sure Ctrl-ALT is not the same as AltGr for ToAscii unless told. */
+    if (left_alt && (keystate[VK_CONTROL]&0x80)) {
+       if (cfg.ctrlaltkeys)
+           keystate[VK_MENU] = 0;
+       else {
+           keystate[VK_RMENU] = 0x80;
+           left_alt = 0;
+       }
+    }
 
     scan = (HIWORD(lParam) & (KF_UP | KF_EXTENDED | 0xFF));
     shift_state = ((keystate[VK_SHIFT]&0x80)!=0)
                 + ((keystate[VK_CONTROL]&0x80)!=0)*2;
 
+    /* Note if AltGr was pressed and if it was used as a compose key */
+    if (!compose_state) {
+       compose_key = 0x100;
+       if (cfg.compose_key) {
+           if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED))
+               compose_key = wParam;
+       }
+       if (wParam == VK_APPS)
+           compose_key = wParam;
+    }
+
+    if (wParam == compose_key)
+    {
+       if (compose_state == 0 && (HIWORD(lParam)&(KF_UP|KF_REPEAT))==0)
+           compose_state = 1;
+       else if (compose_state == 1 && (HIWORD(lParam)&KF_UP))
+           compose_state = 2;
+       else
+           compose_state = 0;
+    }
+    else if (compose_state==1 && wParam != VK_CONTROL)
+       compose_state = 0;
+
     /* 
      * Record that we pressed key so the scroll window can be reset, but
      * be careful to avoid Shift-UP/Down
@@ -2245,6 +2261,10 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
        {
            *p++ = 3; return p - output;
        }
+       if (wParam == VK_PAUSE)                         /* Break/Pause */
+       {
+           *p++ = 26; *p++ = 0; return -2;
+       }
        /* Control-2 to Control-8 are special */
        if (shift_state == 2 && wParam >= '2' && wParam <= '8')
        {
@@ -2305,6 +2325,24 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
        /* Reorder edit keys to physical order */
        if (cfg.funky_type == 3 && code <= 6 ) code = "\0\2\1\4\5\3\6"[code];
 
+       if (vt52_mode && code > 0 && code <= 6) {
+           p += sprintf((char *)p, "\x1B%c", " HLMEIG"[code]);
+           return p - output;
+       }
+
+       if (cfg.funky_type == 5 && code >= 11 && code <= 24) {
+           p += sprintf((char *)p, "\x1B[%c", code + 'M' - 11);
+           return p - output;
+       }
+       if ((vt52_mode || cfg.funky_type == 4) && code >= 11 && code <= 24) {
+           int offt = 0;
+           if (code>15) offt++; if (code>21) offt++;
+           if (vt52_mode)
+               p += sprintf((char *)p, "\x1B%c", code + 'P' - 11 - offt);
+           else
+               p += sprintf((char *)p, "\x1BO%c", code + 'P' - 11 - offt);
+           return p - output;
+       }
        if (cfg.funky_type == 1 && code >= 11 && code <= 15) {
            p += sprintf((char *)p, "\x1B[[%c", code + 'A' - 11);
            return p - output;
@@ -2414,6 +2452,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
            return p-output;
        }
+       /* If we're definitly not building up an ALT-54321 then clear it */
+       if (!left_alt) keys[0] = 0;
     }
 
     /* ALT alone may or may not want to bring up the System menu */
@@ -2428,6 +2468,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
         } else
            return 0;
     }
+    else alt_state = 0;
 
     return -1;
 }
@@ -2622,21 +2663,30 @@ void fatalbox(char *fmt, ...) {
 /*
  * Beep.
  */
-void beep(int errorbeep) {
-    static long last_beep = 0;
-    long now, beep_diff;
-
-    now = GetTickCount();
-    beep_diff = now-last_beep;
-
-    /* Make sure we only respond to one beep per packet or so */
-    if (beep_diff>=0 && beep_diff<50)
-        return;
-
-    if(errorbeep)
-       MessageBeep(MB_ICONHAND);
-    else
-       MessageBeep(MB_OK);
-
-    last_beep = GetTickCount();
+void beep(int mode) {
+    if (mode == BELL_DEFAULT) {
+       /*
+        * For MessageBeep style bells, we want to be careful of
+        * timing, because they don't have the nice property of
+        * PlaySound bells that each one cancels the previous
+        * active one. So we limit the rate to one per 50ms or so.
+        */
+       static long lastbeep = 0;
+       long now, beepdiff;
+
+       now = GetTickCount();
+       beepdiff = now - lastbeep;
+       if (beepdiff >= 0 && beepdiff < 50)
+           return;
+       MessageBeep(MB_OK);
+       lastbeep = now;
+    } else if (mode == BELL_WAVEFILE) {
+       if (!PlaySound(cfg.bell_wavefile, NULL, SND_ASYNC | SND_FILENAME)) {
+           char buf[sizeof(cfg.bell_wavefile)+80];
+           sprintf(buf, "Unable to play sound file\n%s\n"
+                   "Using default sound instead", cfg.bell_wavefile);
+           MessageBox(hwnd, buf, "PuTTY Sound Error", MB_OK | MB_ICONEXCLAMATION);
+           cfg.beep = BELL_DEFAULT;
+       }
+    }
 }