Add a configuration option for TCP keepalives (SO_KEEPALIVE), default off.
[u/mdw/putty] / window.c
index f13f0d4..e720ed3 100644 (file)
--- a/window.c
+++ b/window.c
@@ -611,7 +611,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        char *realhost;
 
        error = back->init(NULL, &backhandle, &cfg,
-                          cfg.host, cfg.port, &realhost, cfg.tcp_nodelay);
+                          cfg.host, cfg.port, &realhost, cfg.tcp_nodelay,
+                          cfg.tcp_keepalives);
        back->provide_logctx(backhandle, logctx);
        if (error) {
            char *str = dupprintf("%s Error", appname);
@@ -1081,6 +1082,36 @@ static void init_palette(void)
 }
 
 /*
+ * 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
  * if/when they are needed.
@@ -2989,9 +3020,13 @@ 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));
 
-       ExtTextOutW(hdc, x,
+       /* 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,
                    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)) {
@@ -3170,6 +3205,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
     HKL kbd_layout = GetKeyboardLayout(0);
 
+    /* keys is for ToAsciiEx. There's some ick here, see below. */
     static WORD keys[3];
     static int compose_char = 0;
     static WPARAM compose_key = 0;
@@ -3861,7 +3897,27 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
            keystate[VK_CAPITAL] = 0;
        }
 
-       r = ToAsciiEx(wParam, scan, keystate, keys, 0, kbd_layout);
+       /* XXX how do we know what the max size of the keys array should
+        * be is? There's indication on MS' website of an Inquire/InquireEx
+        * functioning returning a KBINFO structure which tells us. */
+       if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+           /* XXX 'keys' parameter is declared in MSDN documentation as
+            * 'LPWORD lpChar'.
+            * The experience of a French user indicates that on
+            * Win98, WORD[] should be passed in, but on Win2K, it should
+            * be BYTE[]. German WinXP and my Win2K with "US International"
+            * driver corroborate this.
+            * Experimentally I've conditionalised the behaviour on the
+            * Win9x/NT split, but I suspect it's worse than that.
+            * See wishlist item `win-dead-keys' for more horrible detail
+            * and speculations. */
+           BYTE keybs[3];
+           int i;
+           r = ToAsciiEx(wParam, scan, keystate, (LPWORD)keybs, 0, kbd_layout);
+           for (i=0; i<3; i++) keys[i] = keybs[i];
+       } else {
+           r = ToAsciiEx(wParam, scan, keystate, keys, 0, kbd_layout);
+       }
 #ifdef SHOW_TOASCII_RESULT
        if (r == 1 && !key_down) {
            if (alt_sum) {