Further fix for lcc-win32. The PuTTY suite now compiles fine for me
[u/mdw/putty] / windows / window.c
index 066c4a4..d4d8a71 100644 (file)
@@ -108,6 +108,7 @@ static void *backhandle;
 
 static struct unicode_data ucsdata;
 static int session_closed;
+static int reconfiguring = FALSE;
 
 static const struct telnet_special *specials;
 static int n_specials;
@@ -478,6 +479,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
                    sfree(s1);
                    sfree(s2);
                    exit(0);
+               } else if (!strcmp(p, "-pgpfp")) {
+                   pgp_fingerprints();
+                   exit(1);
                } else if (*p != '-') {
                    char *q = p;
                    if (got_host) {
@@ -1210,8 +1214,17 @@ static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc,
                          unsigned short *lpString, UINT cbCount,
                          CONST INT *lpDx, int opaque)
 {
-
+#ifdef __LCC__
+    /*
+     * The LCC include files apparently don't supply the
+     * GCP_RESULTSW type, but we can make do with GCP_RESULTS
+     * proper: the differences aren't important to us (the only
+     * variable-width string parameter is one we don't use anyway).
+     */
+    GCP_RESULTS gcpr;
+#else
     GCP_RESULTSW gcpr;
+#endif
     char *buffer = snewn(cbCount*2+2, char);
     char *classbuffer = snewn(cbCount, char);
     memset(&gcpr, 0, sizeof(gcpr));
@@ -1292,24 +1305,11 @@ static void init_fonts(int pick_width, int pick_height)
 
     f(FONT_NORMAL, cfg.font.charset, fw_dontcare, FALSE);
 
-    lfont.lfHeight = font_height;
-    lfont.lfWidth = font_width;
-    lfont.lfEscapement = 0;
-    lfont.lfOrientation  = 0;
-    lfont.lfWeight  = fw_dontcare;
-    lfont.lfItalic = FALSE;
-    lfont.lfUnderline = FALSE;
-    lfont.lfStrikeOut = FALSE;
-    lfont.lfCharSet = cfg.font.charset;
-    lfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
-    lfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-    lfont.lfQuality = DEFAULT_QUALITY;
-    lfont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
-    strncpy(lfont.lfFaceName, cfg.font.name, LF_FACESIZE);
-
     SelectObject(hdc, fonts[FONT_NORMAL]);
     GetTextMetrics(hdc, &tm);
 
+    GetObject(fonts[FONT_NORMAL], sizeof(LOGFONT), &lfont);
+
     if (pick_width == 0 || pick_height == 0) {
        font_height = tm.tmHeight;
        font_width = tm.tmAveCharWidth;
@@ -1977,11 +1977,20 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            {
                Config prev_cfg;
                int init_lvl = 1;
+               int reconfig_result;
+
+               if (reconfiguring)
+                   break;
+               else
+                   reconfiguring = TRUE;
 
                GetWindowText(hwnd, cfg.wintitle, sizeof(cfg.wintitle));
                prev_cfg = cfg;
 
-               if (!do_reconfig(hwnd, back ? back->cfg_info(backhandle) : 0))
+               reconfig_result =
+                   do_reconfig(hwnd, back ? back->cfg_info(backhandle) : 0);
+               reconfiguring = FALSE;
+               if (!reconfig_result)
                    break;
 
                {
@@ -2360,12 +2369,44 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                RealizePalette(hdc);
            }
 
+           /*
+            * We have to be careful about term_paint(). It will
+            * set a bunch of character cells to INVALID and then
+            * call do_paint(), which will redraw those cells and
+            * _then mark them as done_. This may not be accurate:
+            * when painting in WM_PAINT context we are restricted
+            * to the rectangle which has just been exposed - so if
+            * that only covers _part_ of a character cell and the
+            * rest of it was already visible, that remainder will
+            * not be redrawn at all. Accordingly, we must not
+            * paint any character cell in a WM_PAINT context which
+            * already has a pending update due to terminal output.
+            * The simplest solution to this - and many, many
+            * thanks to Hung-Te Lin for working all this out - is
+            * not to do any actual painting at _all_ if there's a
+            * pending terminal update: just mark the relevant
+            * character cells as INVALID and wait for the
+            * scheduled full update to sort it out.
+            * 
+            * I have a suspicion this isn't the _right_ solution.
+            * An alternative approach would be to have terminal.c
+            * separately track what _should_ be on the terminal
+            * screen and what _is_ on the terminal screen, and
+            * have two completely different types of redraw (one
+            * for full updates, which syncs the former with the
+            * terminal itself, and one for WM_PAINT which syncs
+            * the latter with the former); yet another possibility
+            * would be to have the Windows front end do what the
+            * GTK one already does, and maintain a bitmap of the
+            * current terminal appearance so that WM_PAINT becomes
+            * completely trivial. However, this should do for now.
+            */
            term_paint(term, hdc, 
                       (p.rcPaint.left-offset_width)/font_width,
                       (p.rcPaint.top-offset_height)/font_height,
                       (p.rcPaint.right-offset_width-1)/font_width,
                       (p.rcPaint.bottom-offset_height-1)/font_height,
-                      TRUE);
+                      !term->window_update_pending);
 
            if (p.fErase ||
                p.rcPaint.left  < offset_width  ||
@@ -2702,13 +2743,15 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            unsigned char buf[20];
            int len;
 
-           if (wParam == VK_PROCESSKEY) {
-               MSG m;
-               m.hwnd = hwnd;
-               m.message = WM_KEYDOWN;
-               m.wParam = wParam;
-               m.lParam = lParam & 0xdfff;
-               TranslateMessage(&m);
+           if (wParam == VK_PROCESSKEY) { /* IME PROCESS key */
+               if (message == WM_KEYDOWN) {
+                   MSG m;
+                   m.hwnd = hwnd;
+                   m.message = WM_KEYDOWN;
+                   m.wParam = wParam;
+                   m.lParam = lParam & 0xdfff;
+                   TranslateMessage(&m);
+               } else break; /* pass to Windows for default processing */
            } else {
                len = TranslateKey(message, wParam, lParam, buf);
                if (len == -1)
@@ -2746,12 +2789,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
        set_input_locale((HKL)lParam);
        sys_cursor_update();
        break;
-      case WM_IME_NOTIFY:
-       if(wParam == IMN_SETOPENSTATUS) {
+      case WM_IME_STARTCOMPOSITION:
+       {
            HIMC hImc = ImmGetContext(hwnd);
            ImmSetCompositionFont(hImc, &lfont);
            ImmReleaseContext(hwnd, hImc);
-           return 0;
        }
        break;
       case WM_IME_COMPOSITION:
@@ -2892,6 +2934,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
        }
     }
 
+    /*
+     * Any messages we don't process completely above are passed through to
+     * DefWindowProc() for default processing.
+     */
     return DefWindowProc(hwnd, message, wParam, lParam);
 }