Fix bug in the alternative code for -DNO_MULTIMON (was breaking
[u/mdw/putty] / window.c
index 5ea24dc..10b456a 100644 (file)
--- a/window.c
+++ b/window.c
 #endif
 #endif
 
+#ifndef NO_MULTIMON
 #if WINVER < 0x0500
 #define COMPILE_MULTIMON_STUBS
 #include <multimon.h>
 #endif
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -105,6 +107,7 @@ static LPARAM pend_netevent_lParam = 0;
 static void enact_pending_netevent(void);
 static void flash_window(int mode);
 static void sys_cursor_update(void);
+static int get_fullscreen_rect(RECT * ss);
 
 static time_t last_movement = 0;
 
@@ -157,6 +160,8 @@ static char *window_name, *icon_name;
 
 static int compose_state = 0;
 
+static int wsa_started = 0;
+
 static OSVERSIONINFO osVersion;
 
 static UINT wm_mousewheel = WM_MOUSEWHEEL;
@@ -190,6 +195,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        WSACleanup();
        return 1;
     }
+    wsa_started = 1;
     /* WISHLIST: maybe allow config tweaking even if winsock not present? */
     sk_init();
 
@@ -475,8 +481,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     guess_height = extra_height + font_height * rows;
     {
        RECT r;
-       HWND w = GetDesktopWindow();
-       GetWindowRect(w, &r);
+               get_fullscreen_rect(&r);
        if (guess_width > r.right - r.left)
            guess_width = r.right - r.left;
        if (guess_height > r.bottom - r.top)
@@ -723,7 +728,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
                timer_id = 0;
            }
            HideCaret(hwnd);
-           term_out();
+           if (GetCapture() != hwnd || 
+               (send_raw_mouse && !(cfg.mouse_override && is_shift_pressed())))
+               term_out();
            term_update();
            ShowCaret(hwnd);
 
@@ -750,6 +757,15 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        }
     }
 
+    cleanup_exit(msg.wParam);         /* this doesn't return... */
+    return msg.wParam;                /* ... but optimiser doesn't know */
+}
+
+/*
+ * Clean up and exit.
+ */
+void cleanup_exit(int code)
+{
     /*
      * Clean up.
      */
@@ -757,7 +773,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     sfree(logpal);
     if (pal)
        DeleteObject(pal);
-    WSACleanup();
+    sk_cleanup();
+    if (wsa_started)
+       WSACleanup();
 
     if (cfg.protocol == PROT_SSH) {
        random_save_seed();
@@ -766,7 +784,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 #endif
     }
 
-    return msg.wParam;
+    exit(code);
 }
 
 /*
@@ -800,6 +818,7 @@ char *do_select(SOCKET skt, int startup)
  */
 void set_raw_mouse_mode(int activate)
 {
+    activate = activate && !cfg.no_mouse_rep;
     send_raw_mouse = activate;
     SetCursor(LoadCursor(NULL, activate ? IDC_ARROW : IDC_IBEAM));
 }
@@ -1194,7 +1213,7 @@ void request_resize(int w, int h)
        switch (first_time) {
          case 1:
            /* Get the size of the screen */
-           if (GetClientRect(GetDesktopWindow(), &ss))
+           if (get_fullscreen_rect(&ss))
                /* first_time = 0 */ ;
            else {
                first_time = 2;
@@ -1363,8 +1382,9 @@ static void reset_window(int reinit) {
 
            static RECT ss;
            int width, height;
+               
+               get_fullscreen_rect(&ss);
 
-           GetClientRect(GetDesktopWindow(), &ss);
            width = (ss.right - ss.left - extra_width) / font_width;
            height = (ss.bottom - ss.top - extra_height) / font_height;
 
@@ -1503,6 +1523,17 @@ static int is_alt_pressed(void)
     return FALSE;
 }
 
+static int is_shift_pressed(void)
+{
+    BYTE keystate[256];
+    int r = GetKeyboardState(keystate);
+    if (!r)
+       return FALSE;
+    if (keystate[VK_SHIFT] & 0x80)
+       return TRUE;
+    return FALSE;
+}
+
 static int resizing;
 
 static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
@@ -1517,7 +1548,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
       case WM_TIMER:
        if (pending_netevent)
            enact_pending_netevent();
-       term_out();
+       if (GetCapture() != hwnd || 
+           (send_raw_mouse && !(cfg.mouse_override && is_shift_pressed())))
+           term_out();
        noise_regular();
        HideCaret(hwnd);
        term_update();
@@ -1667,6 +1700,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                cfgtopalette();
                init_palette();
 
+               /* Give terminal a heads-up on miscellaneous stuff */
+               term_reconfig();
+
                /* Screen size changed ? */
                if (cfg.height != prev_cfg.height ||
                    cfg.width != prev_cfg.width ||
@@ -1937,7 +1973,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
         */
        noise_ultralight(lParam);
 
-       if (wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
+       if (wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON) &&
+           GetCapture() == hwnd) {
            Mouse_Button b;
            if (wParam & MK_LBUTTON)
                b = MBT_LEFT;
@@ -2180,8 +2217,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
         if (wParam == SIZE_RESTORED)
             clear_full_screen();
         if (wParam == SIZE_MAXIMIZED && fullscr_on_max) {
-            make_full_screen();
             fullscr_on_max = FALSE;
+            make_full_screen();
         }
 
        if (cfg.resize_action == RESIZE_DISABLED) {
@@ -2429,7 +2466,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            return TRUE;
        }
       default:
-       if (message == wm_mousewheel) {
+       if (message == wm_mousewheel || message == WM_MOUSEWHEEL) {
            int shift_pressed=0, control_pressed=0, alt_pressed=0;
 
            if (message == WM_MOUSEWHEEL) {
@@ -4118,7 +4155,7 @@ void fatalbox(char *fmt, ...)
     vsprintf(stuff, fmt, ap);
     va_end(ap);
     MessageBox(hwnd, stuff, "PuTTY Fatal Error", MB_ICONERROR | MB_OK);
-    exit(1);
+    cleanup_exit(1);
 }
 
 /*
@@ -4217,6 +4254,11 @@ void set_iconic(int iconic)
  */
 void move_window(int x, int y)
 {
+    if (cfg.resize_action == RESIZE_DISABLED || 
+        cfg.resize_action == RESIZE_FONT ||
+       IsZoomed(hwnd))
+       return;
+
     SetWindowPos(hwnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
 }
 
@@ -4305,6 +4347,32 @@ int is_full_screen()
     return TRUE;
 }
 
+/* Get the rect/size of a full screen window using the nearest available
+ * monitor in multimon systems; default to something sensible if only
+ * one monitor is present. */
+static int get_fullscreen_rect(RECT * ss)
+{
+#ifdef MONITOR_DEFAULTTONEAREST
+       HMONITOR mon;
+       MONITORINFO mi;
+       mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+       mi.cbSize = sizeof(mi);
+       GetMonitorInfo(mon, &mi);
+
+       /* structure copy */
+       *ss = mi.rcMonitor;
+       return TRUE;
+#else
+/* could also use code like this:
+       ss->left = ss->top = 0;
+       ss->right = GetSystemMetrics(SM_CXSCREEN);
+       ss->bottom = GetSystemMetrics(SM_CYSCREEN);
+*/ 
+       return GetClientRect(GetDesktopWindow(), ss);
+#endif
+}
+
+
 /*
  * Go full-screen. This should only be called when we are already
  * maximised.
@@ -4312,10 +4380,13 @@ int is_full_screen()
 void make_full_screen()
 {
     DWORD style;
-    int x, y, w, h;
+       RECT ss;
 
     assert(IsZoomed(hwnd));
 
+       if (is_full_screen())
+               return;
+       
     /* Remove the window furniture. */
     style = GetWindowLong(hwnd, GWL_STYLE);
     style &= ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME);
@@ -4326,24 +4397,11 @@ void make_full_screen()
     SetWindowLong(hwnd, GWL_STYLE, style);
 
     /* Resize ourselves to exactly cover the nearest monitor. */
-#ifdef MONITOR_DEFAULTTONEAREST
-    {
-       HMONITOR mon;
-       MONITORINFO mi;
-       mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
-       mi.cbSize = sizeof(mi);
-       GetMonitorInfo(mon, &mi);
-       x = mi.rcMonitor.left;
-       y = mi.rcMonitor.top;
-       w = mi.rcMonitor.right;
-       h = mi.rcMonitor.bottom;
-    }
-#else
-    x = y = 0;
-    w = GetSystemMetrics(SM_CXSCREEN);
-    h = GetSystemMetrics(SM_CYSCREEN);
-#endif
-    SetWindowPos(hwnd, HWND_TOP, x, y, w, h, SWP_FRAMECHANGED);
+       get_fullscreen_rect(&ss);
+    SetWindowPos(hwnd, HWND_TOP, ss.left, ss.top,
+                       ss.right - ss.left,
+                       ss.bottom - ss.top,
+                       SWP_FRAMECHANGED);
 
     /* Tick the menu item in the System menu. */
     CheckMenuItem(GetSystemMenu(hwnd, FALSE), IDM_FULLSCREEN,