Make memory management uniform: _everything_ now goes through the
[u/mdw/putty] / window.c
index 98dd9a5..1568617 100644 (file)
--- a/window.c
+++ b/window.c
@@ -40,6 +40,7 @@
 #define IDM_TEL_EOF   0x0130
 #define IDM_ABOUT     0x0140
 #define IDM_SAVEDSESS 0x0150
+#define IDM_COPYALL   0x0160
 
 #define IDM_SAVED_MIN 0x1000
 #define IDM_SAVED_MAX 0x2000
@@ -102,6 +103,8 @@ static char *window_name, *icon_name;
 
 static Ldisc *real_ldisc;
 
+static int compose_state = 0;
+
 void begin_session(void) {
     ldisc = real_ldisc;
 }
@@ -365,14 +368,15 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
 
     {
        int winmode = WS_OVERLAPPEDWINDOW|WS_VSCROLL;
-       if (!cfg.scrollbar) winmode &= ~(WS_VSCROLL);
-       if (cfg.locksize)   winmode &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX);
-       hwnd = CreateWindow (appname, appname,
-                            winmode,
-                            CW_USEDEFAULT, CW_USEDEFAULT,
-                            guess_width, guess_height,
-                            NULL, NULL, inst, NULL);
-    }
+        int exwinmode = 0;
+       if (!cfg.scrollbar)  winmode &= ~(WS_VSCROLL);
+       if (cfg.locksize)    winmode &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX);
+        if (cfg.alwaysontop) exwinmode = WS_EX_TOPMOST;
+        hwnd = CreateWindowEx (exwinmode, appname, appname,
+                              winmode, CW_USEDEFAULT, CW_USEDEFAULT,
+                              guess_width, guess_height,
+                              NULL, NULL, inst, NULL);
+     }
 
     /*
      * Initialise the fonts, simultaneously correcting the guesses
@@ -409,9 +413,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
     {
         char *bits;
         int size = (font_width+15)/16 * 2 * font_height; 
-        bits = calloc(size, 1);
+        bits = smalloc(size);
+        memset(bits, 0, size);
         caretbm = CreateBitmap(font_width, font_height, 1, 1, bits);
-        free(bits);
+        sfree(bits);
     }
 
     /*
@@ -510,6 +515,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
        AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) s, "Sa&ved Sessions");
        AppendMenu (m, MF_ENABLED, IDM_RECONF, "Chan&ge Settings...");
        AppendMenu (m, MF_SEPARATOR, 0, 0);
+       AppendMenu (m, MF_ENABLED, IDM_COPYALL, "C&opy All to Clipboard");
        AppendMenu (m, MF_ENABLED, IDM_CLRSB, "C&lear Scrollback");
        AppendMenu (m, MF_ENABLED, IDM_RESET, "Rese&t Terminal");
        AppendMenu (m, MF_SEPARATOR, 0, 0);
@@ -589,7 +595,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
            if (!has_focus)
               timer_id = SetTimer(hwnd, 1, 59500, NULL);
            else
-              timer_id = SetTimer(hwnd, 1, 250, NULL);
+              timer_id = SetTimer(hwnd, 1, 100, NULL);
            long_timer = 1;
        
            /* There's no point rescanning everything in the message queue
@@ -1125,7 +1131,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
                    cl = c;
                } else if (wParam == IDM_SAVEDSESS) {
                    char *session = sessions[(lParam - IDM_SAVED_MIN) / 16];
-                   cl = malloc(16 + strlen(session)); /* 8, but play safe */
+                   cl = smalloc(16 + strlen(session)); /* 8, but play safe */
                    if (!cl)
                        cl = NULL;     /* not a very important failure mode */
                    else {
@@ -1149,82 +1155,109 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
                if (filemap)
                    CloseHandle(filemap);
                if (freecl)
-                   free(cl);
+                   sfree(cl);
            }
            break;
-         case IDM_RECONF:
-           if (!do_reconfig(hwnd))
-               break;
-           just_reconfigged = TRUE;
-           {
-               int i;
-               for (i=0; i<8; i++)
-                   if (fonts[i])
-                       DeleteObject(fonts[i]);
-           }
-           bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT;
-           und_mode = UND_FONT;
-           init_fonts(0);
-           sfree(logpal);
-           /* Telnet will change local echo -> remote if the remote asks */
-           if (cfg.protocol != PROT_TELNET)
-               ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
-           if (pal)
-               DeleteObject(pal);
-           logpal = NULL;
-           pal = NULL;
-           cfgtopalette();
-           init_palette();
-
-           /* Enable or disable the scroll bar, etc */
-           {
-               LONG nflg, flag = GetWindowLong(hwnd, GWL_STYLE);
-
-               nflg = flag;
-               if (cfg.scrollbar) nflg |=  WS_VSCROLL;
-               else               nflg &= ~WS_VSCROLL;
-               if (cfg.locksize) 
-                  nflg &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX);
-               else              
-                  nflg |= (WS_THICKFRAME|WS_MAXIMIZEBOX);
-
-               if (nflg != flag)
-               {
-                   RECT cr, wr;
-
-                   SetWindowLong(hwnd, GWL_STYLE, nflg);
-                   SendMessage (hwnd, WM_IGNORE_SIZE, 0, 0);
-                   SetWindowPos(hwnd, NULL, 0,0,0,0,
-                        SWP_NOACTIVATE|SWP_NOCOPYBITS|
-                        SWP_NOMOVE|SWP_NOSIZE| SWP_NOZORDER|
-                        SWP_FRAMECHANGED);
-
-                   GetWindowRect (hwnd, &wr);
-                   GetClientRect (hwnd, &cr);
-                   extra_width = wr.right - wr.left - cr.right + cr.left;
-                   extra_height = wr.bottom - wr.top - cr.bottom + cr.top;
-               }
-           }
+          case IDM_RECONF:
+            {
+                int prev_alwaysontop = cfg.alwaysontop;
+                if (!do_reconfig(hwnd))
+                    break;
+                just_reconfigged = TRUE;
+                {
+                    int i;
+                    for (i=0; i<8; i++)
+                        if (fonts[i])
+                            DeleteObject(fonts[i]);
+                }
+                bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT;
+                und_mode = UND_FONT;
+                init_fonts(0);
+                sfree(logpal);
+                /*
+                 * Telnet will change local echo -> remote if the
+                 * remote asks.
+                 */
+                if (cfg.protocol != PROT_TELNET)
+                    ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
+                if (pal)
+                    DeleteObject(pal);
+                logpal = NULL;
+                pal = NULL;
+                cfgtopalette();
+                init_palette();
+
+                /* Enable or disable the scroll bar, etc */
+                {
+                    LONG nflg, flag = GetWindowLong(hwnd, GWL_STYLE);
+                    LONG nexflag, exflag = GetWindowLong(hwnd, GWL_EXSTYLE);
+
+                    nexflag = exflag;
+                    if (cfg.alwaysontop != prev_alwaysontop) {
+                        if (cfg.alwaysontop) {
+                            nexflag = WS_EX_TOPMOST;
+                            SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
+                                         SWP_NOMOVE | SWP_NOSIZE);
+                        } else {
+                            nexflag = 0;
+                            SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
+                                         SWP_NOMOVE | SWP_NOSIZE);
+                        }
+                    }
+
+                    nflg = flag;
+                    if (cfg.scrollbar) nflg |=  WS_VSCROLL;
+                    else               nflg &= ~WS_VSCROLL;
+                    if (cfg.locksize)
+                        nflg &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX);
+                    else
+                        nflg |= (WS_THICKFRAME|WS_MAXIMIZEBOX);
+
+                    if (nflg != flag || nexflag != exflag)
+                    {
+                        RECT cr, wr;
+
+                        if (nflg != flag)
+                            SetWindowLong(hwnd, GWL_STYLE, nflg);
+                        if (nexflag != exflag)
+                            SetWindowLong(hwnd, GWL_EXSTYLE, nexflag);
+
+                        SendMessage (hwnd, WM_IGNORE_SIZE, 0, 0);
+                        SetWindowPos(hwnd, NULL, 0,0,0,0,
+                                     SWP_NOACTIVATE|SWP_NOCOPYBITS|
+                                     SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|
+                                     SWP_FRAMECHANGED);
+
+                        GetWindowRect (hwnd, &wr);
+                        GetClientRect (hwnd, &cr);
+                        extra_width = wr.right - wr.left - cr.right + cr.left;
+                        extra_height = wr.bottom - wr.top - cr.bottom + cr.top;
+                    }
+                }
 
-           term_size(cfg.height, cfg.width, cfg.savelines);
-           InvalidateRect(hwnd, NULL, TRUE);
-           SetWindowPos (hwnd, NULL, 0, 0,
-                         extra_width + font_width * cfg.width,
-                         extra_height + font_height * cfg.height,
-                         SWP_NOACTIVATE | SWP_NOCOPYBITS |
-                         SWP_NOMOVE | SWP_NOZORDER);
-           if (IsIconic(hwnd)) {
-               SetWindowText (hwnd,
-                              cfg.win_name_always ? window_name : icon_name);
-           }
-           break;
-         case IDM_CLRSB:
-           term_clrsb();
-           break;
-         case IDM_RESET:
-           term_pwron();
+                term_size(cfg.height, cfg.width, cfg.savelines);
+                InvalidateRect(hwnd, NULL, TRUE);
+                SetWindowPos (hwnd, NULL, 0, 0,
+                              extra_width + font_width * cfg.width,
+                              extra_height + font_height * cfg.height,
+                              SWP_NOACTIVATE | SWP_NOCOPYBITS |
+                              SWP_NOMOVE | SWP_NOZORDER);
+                if (IsIconic(hwnd)) {
+                    SetWindowText (hwnd,
+                                   cfg.win_name_always ? window_name : icon_name);
+                }
+            }
+            break;
+         case IDM_COPYALL:
+           term_copyall();
            break;
-         case IDM_TEL_AYT: back->special (TS_AYT); break;
+          case IDM_CLRSB:
+            term_clrsb();
+            break;
+          case IDM_RESET:
+            term_pwron();
+            break;
+          case IDM_TEL_AYT: back->special (TS_AYT); break;
          case IDM_TEL_BRK: back->special (TS_BRK); break;
          case IDM_TEL_SYNCH: back->special (TS_SYNCH); break;
          case IDM_TEL_EC: back->special (TS_EC); break;
@@ -1348,6 +1381,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
        has_focus = TRUE;
         CreateCaret(hwnd, caretbm, 0, 0);
         ShowCaret(hwnd);
+        compose_state = 0;
        term_out();
        term_update();
        break;
@@ -1813,7 +1847,6 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
     unsigned char * p = output;
 
     static WORD keys[3];
-    static int compose_state = 0;
     static int compose_char = 0;
     static WPARAM compose_key = 0;
 
@@ -1904,7 +1937,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
        /* Nastyness with NUMLock - Shift-NUMLock is left alone though */
        if ( (cfg.funky_type == 3 ||
-              (cfg.funky_type <= 1 && app_keypad_keys && !cfg.no_applic))
+              (cfg.funky_type <= 1 && app_keypad_keys && !cfg.no_applic_k))
              && wParam==VK_NUMLOCK && !(keystate[VK_SHIFT]&0x80)) {
 
            wParam = VK_EXECUTE;
@@ -1949,7 +1982,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
     if (compose_state>1 && left_alt) compose_state = 0;
 
     /* Sanitize the number pad if not using a PC NumPad */
-    if( left_alt || (app_keypad_keys && !cfg.no_applic && cfg.funky_type != 2)
+    if( left_alt || (app_keypad_keys && !cfg.no_applic_k
+                     && cfg.funky_type != 2)
        || cfg.funky_type == 3 || cfg.nethack_keypad || compose_state )
     {
        if ((HIWORD(lParam)&KF_EXTENDED) == 0)
@@ -2001,7 +2035,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
             return -1;
        }
        if (left_alt && wParam == VK_SPACE && cfg.alt_space) {
-            
+            PostMessage(hwnd, WM_CHAR, ' ', 0);
             SendMessage (hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0);
             return -1;
        }
@@ -2032,13 +2066,13 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
           if ( cfg.funky_type == 3 ||
              ( cfg.funky_type <= 1 &&
-               app_keypad_keys && !cfg.no_applic)) switch(wParam) {
+               app_keypad_keys && !cfg.no_applic_k)) switch(wParam) {
               case VK_EXECUTE: xkey = 'P'; break;
               case VK_DIVIDE:  xkey = 'Q'; break;
               case VK_MULTIPLY:xkey = 'R'; break;
               case VK_SUBTRACT:xkey = 'S'; break;
           }
-          if(app_keypad_keys && !cfg.no_applic) switch(wParam) {
+          if(app_keypad_keys && !cfg.no_applic_k) switch(wParam) {
               case VK_NUMPAD0: xkey = 'p'; break;
               case VK_NUMPAD1: xkey = 'q'; break;
               case VK_NUMPAD2: xkey = 'r'; break;
@@ -2200,7 +2234,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
            {
                if (vt52_mode)
                    p += sprintf((char *)p, "\x1B%c", xkey);
-               else if (app_cursor_keys && !cfg.no_applic)
+               else if (app_cursor_keys && !cfg.no_applic_c)
                    p += sprintf((char *)p, "\x1BO%c", xkey);
                else
                    p += sprintf((char *)p, "\x1B[%c", xkey);
@@ -2274,9 +2308,17 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
        }
     }
 
-    /* This stops ALT press-release doing a 'COMMAND MENU' function */
-    if (!cfg.alt_only) {
-       if (message == WM_SYSKEYUP && wParam == VK_MENU) 
+    /* ALT alone may or may not want to bring up the System menu */
+    if (wParam == VK_MENU) {
+        if (cfg.alt_only) {
+            static int alt_state = 0;
+            if (message == WM_SYSKEYDOWN)
+                alt_state = 1;
+            else if (message == WM_SYSKEYUP && alt_state)
+                PostMessage(hwnd, WM_CHAR, ' ', 0);
+            if (message == WM_SYSKEYUP)
+                alt_state = 0;
+        } else
            return 0;
     }