]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - windows/window.c
Giant const-correctness patch of doom!
[PuTTY.git] / windows / window.c
index bc89195579f94da84cf248a3b1500e50cfffbba8..b021b05f0e28d207c02236abfba92b6fdda9d4d4 100644 (file)
@@ -88,7 +88,7 @@ static void another_font(int);
 static void deinit_fonts(void);
 static void set_input_locale(HKL);
 static void update_savedsess_menu(void);
-static void init_flashwindow(void);
+static void init_winfuncs(void);
 
 static int is_full_screen(void);
 static void make_full_screen(void);
@@ -215,8 +215,11 @@ static UINT wm_mousewheel = WM_MOUSEWHEEL;
     (((wch) >= 0x180B && (wch) <= 0x180D) || /* MONGOLIAN FREE VARIATION SELECTOR */ \
      ((wch) >= 0xFE00 && (wch) <= 0xFE0F)) /* VARIATION SELECTOR 1-16 */
 
+const int share_can_be_downstream = TRUE;
+const int share_can_be_upstream = TRUE;
+
 /* Dummy routine, only required in plink. */
-void ldisc_update(void *frontend, int echo, int edit)
+void frontend_echoedit_update(void *frontend, int echo, int edit)
 {
 }
 
@@ -367,7 +370,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 
     init_help();
 
-    init_flashwindow();
+    init_winfuncs();
 
     conf = conf_new();
 
@@ -545,8 +548,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
                            q += 2;
                        conf_set_int(conf, CONF_protocol, PROT_TELNET);
                        p = q;
-                       while (*p && *p != ':' && *p != '/')
-                           p++;
+                        p += host_strcspn(p, ":/");
                        c = *p;
                        if (*p)
                            *p++ = '\0';
@@ -611,15 +613,15 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 
             /*
              * Trim a colon suffix off the hostname if it's there. In
-             * order to protect IPv6 address literals against this
-             * treatment, we do not do this if there's _more_ than one
-             * colon.
+             * order to protect unbracketed IPv6 address literals
+             * against this treatment, we do not do this if there's
+             * _more_ than one colon.
              */
             {
-                char *c = strchr(host, ':');
+                char *c = host_strchr(host, ':');
  
                 if (c) {
-                    char *d = strchr(c+1, ':');
+                    char *d = host_strchr(c+1, ':');
                     if (!d)
                         *c = '\0';
                 }
@@ -847,11 +849,38 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     while (1) {
        HANDLE *handles;
        int nhandles, n;
+        DWORD timeout;
+
+        if (toplevel_callback_pending() ||
+            PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
+            /*
+             * If we have anything we'd like to do immediately, set
+             * the timeout for MsgWaitForMultipleObjects to zero so
+             * that we'll only do a quick check of our handles and
+             * then get on with whatever that was.
+             *
+             * One such option is a pending toplevel callback. The
+             * other is a non-empty Windows message queue, which you'd
+             * think we could leave to MsgWaitForMultipleObjects to
+             * check for us along with all the handles, but in fact we
+             * can't because once PeekMessage in one iteration of this
+             * loop has removed a message from the queue, the whole
+             * queue is considered uninteresting by the next
+             * invocation of MWFMO. So we check ourselves whether the
+             * message queue is non-empty, and if so, set this timeout
+             * to zero to ensure MWFMO doesn't block.
+             */
+            timeout = 0;
+        } else {
+            timeout = INFINITE;
+            /* The messages seem unreliable; especially if we're being tricky */
+            term_set_focus(term, GetForegroundWindow() == hwnd);
+        }
 
        handles = handle_get_events(&nhandles);
 
-       n = MsgWaitForMultipleObjects(nhandles, handles, FALSE, INFINITE,
-                                     QS_ALLINPUT);
+       n = MsgWaitForMultipleObjects(nhandles, handles, FALSE,
+                                      timeout, QS_ALLINPUT);
 
        if ((unsigned)(n - WAIT_OBJECT_0) < (unsigned)nhandles) {
            handle_got_event(handles[n - WAIT_OBJECT_0]);
@@ -859,8 +888,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        } else
            sfree(handles);
 
-        run_toplevel_callbacks();
-
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_QUIT)
                goto finished;         /* two-level break */
@@ -868,11 +895,30 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
            if (!(IsWindow(logbox) && IsDialogMessage(logbox, &msg)))
                DispatchMessage(&msg);
 
-            run_toplevel_callbacks();
+            /*
+             * WM_NETEVENT messages seem to jump ahead of others in
+             * the message queue. I'm not sure why; the docs for
+             * PeekMessage mention that messages are prioritised in
+             * some way, but I'm unclear on which priorities go where.
+             *
+             * Anyway, in practice I observe that WM_NETEVENT seems to
+             * jump to the head of the queue, which means that if we
+             * were to only process one message every time round this
+             * loop, we'd get nothing but NETEVENTs if the server
+             * flooded us with data, and stop responding to any other
+             * kind of window message. So instead, we keep on round
+             * this loop until we've consumed at least one message
+             * that _isn't_ a NETEVENT, or run out of messages
+             * completely (whichever comes first). And we don't go to
+             * run_toplevel_callbacks (which is where the netevents
+             * are actually processed, causing fresh NETEVENT messages
+             * to appear) until we've done this.
+             */
+            if (msg.message != WM_NETEVENT)
+                break;
        }
 
-       /* The messages seem unreliable; especially if we're being tricky */
-       term_set_focus(term, GetForegroundWindow() == hwnd);
+        run_toplevel_callbacks();
     }
 
     finished:
@@ -1080,7 +1126,7 @@ void set_raw_mouse_mode(void *frontend, int activate)
 /*
  * Print a message box and close the connection.
  */
-void connection_fatal(void *frontend, char *fmt, ...)
+void connection_fatal(void *frontend, const char *fmt, ...)
 {
     va_list ap;
     char *stuff, morestuff[100];
@@ -1102,7 +1148,7 @@ void connection_fatal(void *frontend, char *fmt, ...)
 /*
  * Report an error at the command-line parsing stage.
  */
-void cmdline_error(char *fmt, ...)
+void cmdline_error(const char *fmt, ...)
 {
     va_list ap;
     char *stuff, morestuff[100];
@@ -2119,7 +2165,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                    unsigned int sessno = ((lParam - IDM_SAVED_MIN)
                                           / MENU_SAVED_STEP) + 1;
                    if (sessno < (unsigned)sesslist.nsessions) {
-                       char *session = sesslist.sessions[sessno];
+                       const char *session = sesslist.sessions[sessno];
                        cl = dupprintf("putty @%s", session);
                        inherit_handles = FALSE;
                        freecl = TRUE;
@@ -2210,9 +2256,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                 * Flush the line discipline's edit buffer in the
                 * case where local editing has just been disabled.
                 */
-               ldisc_configure(ldisc, conf);
-               if (ldisc)
-                   ldisc_send(ldisc, NULL, 0, 0);
+               if (ldisc) {
+                    ldisc_configure(ldisc, conf);
+                   ldisc_echoedit_update(ldisc);
+                }
                if (pal)
                    DeleteObject(pal);
                logpal = NULL;
@@ -2354,7 +2401,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
          case IDM_RESET:
            term_pwron(term, TRUE);
            if (ldisc)
-               ldisc_send(ldisc, NULL, 0, 0);
+               ldisc_echoedit_update(ldisc);
            break;
          case IDM_ABOUT:
            showabout(hwnd);
@@ -3224,10 +3271,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                                   TO_CHR_X(p.x),
                                   TO_CHR_Y(p.y), shift_pressed,
                                   control_pressed, is_alt_pressed());
-                       term_mouse(term, b, translate_button(b),
-                                  MA_RELEASE, TO_CHR_X(p.x),
-                                  TO_CHR_Y(p.y), shift_pressed,
-                                  control_pressed, is_alt_pressed());
                    } /* else: not sure when this can fail */
                } else {
                    /* trigger a scroll */
@@ -3859,6 +3902,17 @@ int char_width(Context ctx, int uc) {
     return ibuf;
 }
 
+DECL_WINDOWS_FUNCTION(static, BOOL, FlashWindowEx, (PFLASHWINFO));
+DECL_WINDOWS_FUNCTION(static, BOOL, ToUnicodeEx,
+                      (UINT, UINT, const BYTE *, LPWSTR, int, UINT, HKL));
+
+static void init_winfuncs(void)
+{
+    HMODULE user32_module = load_system32_dll("user32.dll");
+    GET_WINDOWS_FUNCTION(user32_module, FlashWindowEx);
+    GET_WINDOWS_FUNCTION(user32_module, ToUnicodeEx);
+}
+
 /*
  * Translate a WM_(SYS)?KEY(UP|DOWN) message into a string of ASCII
  * codes. Returns number of bytes used, zero to drop the message,
@@ -4552,9 +4606,9 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
        /* 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) {
-           r = ToUnicodeEx(wParam, scan, keystate, keys_unicode,
-                            lenof(keys_unicode), 0, kbd_layout);
+       if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT && p_ToUnicodeEx) {
+           r = p_ToUnicodeEx(wParam, scan, keystate, keys_unicode,
+                              lenof(keys_unicode), 0, kbd_layout);
        } else {
            /* XXX 'keys' parameter is declared in MSDN documentation as
             * 'LPWORD lpChar'.
@@ -5291,7 +5345,7 @@ void optimised_move(void *frontend, int to, int from, int lines)
 /*
  * Print a message box and perform a fatal exit.
  */
-void fatalbox(char *fmt, ...)
+void fatalbox(const char *fmt, ...)
 {
     va_list ap;
     char *stuff, morestuff[100];
@@ -5308,7 +5362,7 @@ void fatalbox(char *fmt, ...)
 /*
  * Print a modal (Really Bad) message box and perform a fatal exit.
  */
-void modalfatalbox(char *fmt, ...)
+void modalfatalbox(const char *fmt, ...)
 {
     va_list ap;
     char *stuff, morestuff[100];
@@ -5326,7 +5380,7 @@ void modalfatalbox(char *fmt, ...)
 /*
  * Print a message box and don't close the connection.
  */
-void nonfatal(char *fmt, ...)
+void nonfatal(const char *fmt, ...)
 {
     va_list ap;
     char *stuff, morestuff[100];
@@ -5339,14 +5393,6 @@ void nonfatal(char *fmt, ...)
     sfree(stuff);
 }
 
-DECL_WINDOWS_FUNCTION(static, BOOL, FlashWindowEx, (PFLASHWINFO));
-
-static void init_flashwindow(void)
-{
-    HMODULE user32_module = load_system32_dll("user32.dll");
-    GET_WINDOWS_FUNCTION(user32_module, FlashWindowEx);
-}
-
 static BOOL flash_window_ex(DWORD dwFlags, UINT uCount, DWORD dwTimeout)
 {
     if (p_FlashWindowEx) {
@@ -5741,7 +5787,7 @@ int from_backend_eof(void *frontend)
     return TRUE;   /* do respond to incoming EOF with outgoing */
 }
 
-int get_userpass_input(prompts_t *p, unsigned char *in, int inlen)
+int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen)
 {
     int ret;
     ret = cmdline_get_passwd_input(p, in, inlen);