]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - window.c
Fiddly things involving pruning .svn directories, not mentioning
[PuTTY.git] / window.c
index 4cb6003071940e5cbde793b17a5e72f4c2cecc8a..4fb18d39cef79579adf4089d39b8c8f0fdfd67fc 100644 (file)
--- a/window.c
+++ b/window.c
@@ -111,6 +111,7 @@ static struct unicode_data ucsdata;
 static int session_closed;
 
 static const struct telnet_special *specials;
+static int n_specials;
 
 static struct {
     HMENU menu;
@@ -525,7 +526,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 
        /* See if host is of the form user@host */
        if (cfg.host[0] != '\0') {
-           char *atsign = strchr(cfg.host, '@');
+           char *atsign = strrchr(cfg.host, '@');
            /* Make sure we're not overflowing the user field */
            if (atsign) {
                if (atsign - cfg.host < sizeof cfg.username) {
@@ -686,8 +687,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        SetScrollInfo(hwnd, SB_VERT, &si, FALSE);
     }
 
-    start_backend();
-
     /*
      * Prepare the mouse handler.
      */
@@ -742,7 +741,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        }
     }
 
-    update_specials_menu(NULL);
+    start_backend();
 
     /*
      * Set up the initial input locale.
@@ -917,20 +916,48 @@ void update_specials_menu(void *frontend)
        specials = NULL;
 
     if (specials) {
-       p = CreateMenu();
-       for (i = 0; specials[i].name; i++) {
+       /* We can't use Windows to provide a stack for submenus, so
+        * here's a lame "stack" that will do for now. */
+       HMENU saved_menu = NULL;
+       int nesting = 1;
+       p = CreatePopupMenu();
+       for (i = 0; nesting > 0; i++) {
            assert(IDM_SPECIAL_MIN + 0x10 * i < IDM_SPECIAL_MAX);
-           if (*specials[i].name)
+           switch (specials[i].code) {
+             case TS_SEP:
+               AppendMenu(p, MF_SEPARATOR, 0, 0);
+               break;
+             case TS_SUBMENU:
+               assert(nesting < 2);
+               nesting++;
+               saved_menu = p; /* XXX lame stacking */
+               p = CreatePopupMenu();
+               AppendMenu(saved_menu, MF_POPUP | MF_ENABLED,
+                          (UINT) p, specials[i].name);
+               break;
+             case TS_EXITMENU:
+               nesting--;
+               if (nesting) {
+                   p = saved_menu; /* XXX lame stacking */
+                   saved_menu = NULL;
+               }
+               break;
+             default:
                AppendMenu(p, MF_ENABLED, IDM_SPECIAL_MIN + 0x10 * i,
                           specials[i].name);
-           else
-               AppendMenu(p, MF_SEPARATOR, 0, 0);
+               break;
+           }
        }
-    } else
+       /* Squirrel the highest special. */
+       n_specials = i - 1;
+    } else {
        p = NULL;
+       n_specials = 0;
+    }
 
     for (j = 0; j < lenof(popup_menus); j++) {
        if (menu_already_exists) {
+           /* XXX does this free up all submenus? */
            DeleteMenu(popup_menus[j].menu,
                       popup_menus[j].specials_submenu_pos,
                       MF_BYPOSITION);
@@ -945,7 +972,7 @@ void update_specials_menu(void *frontend)
            InsertMenu(popup_menus[j].menu,
                       popup_menus[j].specials_submenu_pos,
                       MF_BYPOSITION | MF_POPUP | MF_ENABLED,
-                      (UINT) p, "Special Command");
+                      (UINT) p, "S&pecial Command");
        }
     }
 }
@@ -1128,36 +1155,6 @@ static void init_palette(void)
                             defpal[i].rgbtGreen, defpal[i].rgbtBlue);
 }
 
-/*
- * This is a wrapper to ExtTextOut() to force Windows to display
- * the precise glyphs we give it. Otherwise it would do its own
- * bidi and Arabic shaping, and we would end up uncertain which
- * characters it had put where.
- */
-static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc,
-                         unsigned short *lpString, UINT cbCount,
-                         CONST INT *lpDx)
-{
-
-    GCP_RESULTSW gcpr;
-    char *buffer = snewn(cbCount*2+2, char);
-    char *classbuffer = snewn(cbCount, char);
-    memset(&gcpr, 0, sizeof(gcpr));
-    memset(buffer, 0, cbCount*2+2);
-    memset(classbuffer, GCPCLASS_NEUTRAL, cbCount);
-
-    gcpr.lStructSize = sizeof(gcpr);
-    gcpr.lpGlyphs = (void *)buffer;
-    gcpr.lpClass = classbuffer;
-    gcpr.nGlyphs = cbCount;
-
-    GetCharacterPlacementW(hdc, lpString, cbCount, 0, &gcpr,
-                          FLI_MASK | GCP_CLASSIN);
-
-    ExtTextOut(hdc, x, y, ETO_GLYPH_INDEX | ETO_CLIPPED | ETO_OPAQUE, lprc,
-              buffer, cbCount, lpDx);
-}
-
 /*
  * Initialise all the fonts we will need initially. There may be as many as
  * three or as few as one.  The other (poentially) twentyone fonts are done
@@ -2089,20 +2086,16 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            }
            if (wParam >= IDM_SPECIAL_MIN && wParam <= IDM_SPECIAL_MAX) {
                int i = (wParam - IDM_SPECIAL_MIN) / 0x10;
-               int j;
                /*
                 * Ensure we haven't been sent a bogus SYSCOMMAND
                 * which would cause us to reference invalid memory
                 * and crash. Perhaps I'm just too paranoid here.
                 */
-               for (j = 0; j < i; j++)
-                   if (!specials || !specials[j].name)
-                       break;
-               if (j == i) {
-                   if (back)
-                       back->special(backhandle, specials[i].code);
-                   net_pending_errors();
-               }
+               if (i >= n_specials)
+                   break;
+               if (back)
+                   back->special(backhandle, specials[i].code);
+               net_pending_errors();
            }
        }
        break;
@@ -2188,7 +2181,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                            mi.rcMonitor.top == pt.y) {
                            mouse_on_hotspot = 1;
                        }
-                       CloseHandle(mon);
                    }
                }
 #else
@@ -2767,6 +2759,16 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            return TRUE;
        }
        break;
+      case WM_SYSCOLORCHANGE:
+       if (cfg.system_colour) {
+           /* Refresh palette from system colours. */
+           /* XXX actually this zaps the entire palette. */
+           systopalette();
+           init_palette();
+           /* Force a repaint of the terminal window. */
+           term_invalidate(term);
+       }
+       break;
       case WM_AGENT_CALLBACK:
        {
            struct agent_callback *c = (struct agent_callback *)lParam;
@@ -3108,13 +3110,9 @@ void do_text(Context ctx, int x, int y, char *text, int len,
        for (i = 0; i < len; i++)
            wbuf[i] = (WCHAR) ((attr & CSET_MASK) + (text[i] & CHAR_MASK));
 
-       /* print Glyphs as they are, without Windows' Shaping*/
-       exact_textout(hdc, x, y - font_height * (lattr == LATTR_BOT) + text_adjust,
-                     &line_box, wbuf, len, IpDx);
-/*     ExtTextOutW(hdc, x,
+       ExtTextOutW(hdc, x,
                    y - font_height * (lattr == LATTR_BOT) + text_adjust,
                    ETO_CLIPPED | ETO_OPAQUE, &line_box, wbuf, len, IpDx);
- */
 
        /* And the shadow bold hack. */
        if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
@@ -3383,8 +3381,8 @@ 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 && term->app_keypad_keys &&
+       if ((cfg.funky_type == FUNKY_VT400 ||
+            (cfg.funky_type <= FUNKY_LINUX && term->app_keypad_keys &&
              !cfg.no_applic_k))
            && wParam == VK_NUMLOCK && !(keystate[VK_SHIFT] & 0x80)) {
 
@@ -3450,8 +3448,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
     /* Sanitize the number pad if not using a PC NumPad */
     if (left_alt || (term->app_keypad_keys && !cfg.no_applic_k
-                    && cfg.funky_type != 2)
-       || cfg.funky_type == 3 || cfg.nethack_keypad || compose_state) {
+                    && cfg.funky_type != FUNKY_XTERM)
+       || cfg.funky_type == FUNKY_VT400 || cfg.nethack_keypad || compose_state) {
        if ((HIWORD(lParam) & KF_EXTENDED) == 0) {
            int nParam = 0;
            switch (wParam) {
@@ -3580,8 +3578,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
        if (!left_alt) {
            int xkey = 0;
 
-           if (cfg.funky_type == 3 ||
-               (cfg.funky_type <= 1 &&
+           if (cfg.funky_type == FUNKY_VT400 ||
+               (cfg.funky_type <= FUNKY_LINUX &&
                 term->app_keypad_keys && !cfg.no_applic_k)) switch (wParam) {
                  case VK_EXECUTE:
                    xkey = 'P';
@@ -3633,7 +3631,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
                    xkey = 'n';
                    break;
                  case VK_ADD:
-                   if (cfg.funky_type == 2) {
+                   if (cfg.funky_type == FUNKY_XTERM) {
                        if (shift_state)
                            xkey = 'l';
                        else
@@ -3645,15 +3643,15 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
                    break;
 
                  case VK_DIVIDE:
-                   if (cfg.funky_type == 2)
+                   if (cfg.funky_type == FUNKY_XTERM)
                        xkey = 'o';
                    break;
                  case VK_MULTIPLY:
-                   if (cfg.funky_type == 2)
+                   if (cfg.funky_type == FUNKY_XTERM)
                        xkey = 'j';
                    break;
                  case VK_SUBTRACT:
-                   if (cfg.funky_type == 2)
+                   if (cfg.funky_type == FUNKY_XTERM)
                        xkey = 'm';
                    break;
 
@@ -3825,7 +3823,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
            break;
        }
        /* Reorder edit keys to physical order */
-       if (cfg.funky_type == 3 && code <= 6)
+       if (cfg.funky_type == FUNKY_VT400 && code <= 6)
            code = "\0\2\1\4\5\3\6"[code];
 
        if (term->vt52_mode && code > 0 && code <= 6) {
@@ -3833,7 +3831,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
            return p - output;
        }
 
-       if (cfg.funky_type == 5 &&     /* SCO function keys */
+       if (cfg.funky_type == FUNKY_SCO &&     /* SCO function keys */
            code >= 11 && code <= 34) {
            char codes[] = "MNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@[\\]^_`{";
            int index = 0;
@@ -3856,7 +3854,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
            p += sprintf((char *) p, "\x1B[%c", codes[index]);
            return p - output;
        }
-       if (cfg.funky_type == 5 &&     /* SCO small keypad */
+       if (cfg.funky_type == FUNKY_SCO &&     /* SCO small keypad */
            code >= 1 && code <= 6) {
            char codes[] = "HL.FIG";
            if (code == 3) {
@@ -3866,7 +3864,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
            }
            return p - output;
        }
-       if ((term->vt52_mode || cfg.funky_type == 4) && code >= 11 && code <= 24) {
+       if ((term->vt52_mode || cfg.funky_type == FUNKY_VT100P) && code >= 11 && code <= 24) {
            int offt = 0;
            if (code > 15)
                offt++;
@@ -3879,11 +3877,11 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
                    sprintf((char *) p, "\x1BO%c", code + 'P' - 11 - offt);
            return p - output;
        }
-       if (cfg.funky_type == 1 && code >= 11 && code <= 15) {
+       if (cfg.funky_type == FUNKY_LINUX && code >= 11 && code <= 15) {
            p += sprintf((char *) p, "\x1B[[%c", code + 'A' - 11);
            return p - output;
        }
-       if (cfg.funky_type == 2 && code >= 11 && code <= 14) {
+       if (cfg.funky_type == FUNKY_XTERM && code >= 11 && code <= 14) {
            if (term->vt52_mode)
                p += sprintf((char *) p, "\x1B%c", code + 'P' - 11);
            else