Shrink the PuTTYgen window for 640x480 friendliness (thanks Jacob)
[sgt/putty] / window.c
index 8e576bf..006e5ff 100644 (file)
--- a/window.c
+++ b/window.c
@@ -9,6 +9,12 @@
 #include <winsock.h>
 #endif
 #endif
+
+#if (WINVER < 0x0500) && !defined(NO_MULTIMON)
+#define COMPILE_MULTIMON_STUBS
+#include <multimon.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -42,6 +48,7 @@
 #define IDM_ABOUT     0x0140
 #define IDM_SAVEDSESS 0x0150
 #define IDM_COPYALL   0x0160
+#define IDM_FULLSCREEN 0x0170
 
 #define IDM_SESSLGP   0x0250          /* log type printable */
 #define IDM_SESSLGA   0x0260          /* log type all chars */
@@ -72,11 +79,14 @@ static void deinit_fonts(void);
 
 /* Window layout information */
 static void reset_window(int);
-static int full_screen = 0, extra_width, extra_height;
+static int full_screen = 0, want_full_screen = 0;
+static int extra_width, extra_height;
 static int font_width, font_height, font_dualwidth;
 static int offset_width, offset_height;
 static int was_zoomed = 0;
+static int was_full_screen = 0;
 static int prev_rows, prev_cols;
+static int pre_fs_rows, pre_fs_cols;
   
 static LONG old_wind_style;
 static WINDOWPLACEMENT old_wind_placement;
@@ -579,6 +589,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        AppendMenu(m, MF_ENABLED, IDM_CLRSB, "C&lear Scrollback");
        AppendMenu(m, MF_ENABLED, IDM_RESET, "Rese&t Terminal");
        AppendMenu(m, MF_SEPARATOR, 0, 0);
+       AppendMenu(m, MF_ENABLED, IDM_FULLSCREEN, "&Full Screen");
+       AppendMenu(m, MF_SEPARATOR, 0, 0);
        AppendMenu(m, MF_ENABLED, IDM_ABOUT, "&About PuTTY");
     }
 
@@ -1189,7 +1201,7 @@ static void reset_window(int reinit) {
 #endif
     }
 
-    if (IsZoomed(hwnd)) {
+    if (IsZoomed(hwnd) || full_screen) {
        /* We're fullscreen, this means we must not change the size of
         * the window so it's the font size or the terminal itself.
         */
@@ -1398,6 +1410,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                last_movement = now;
            }
        }
+       net_pending_errors();
        return 0;
       case WM_CREATE:
        break;
@@ -1497,6 +1510,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                if (!do_reconfig(hwnd))
                    break;
 
+               /* If user forcibly disables full-screen, gracefully unzoom */
+               if (full_screen && !cfg.fullscreenonaltenter) {
+                   flip_full_screen();
+               }
+
                if (strcmp(prev_cfg.logfilename, cfg.logfilename) ||
                    prev_cfg.logtype != cfg.logtype) {
                    logfclose();       /* reset logging */
@@ -1597,6 +1615,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
 
                InvalidateRect(hwnd, NULL, TRUE);
                reset_window(init_lvl);
+               net_pending_errors();
            }
            break;
          case IDM_COPYALL:
@@ -1610,42 +1629,55 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            break;
          case IDM_TEL_AYT:
            back->special(TS_AYT);
+           net_pending_errors();
            break;
          case IDM_TEL_BRK:
            back->special(TS_BRK);
+           net_pending_errors();
            break;
          case IDM_TEL_SYNCH:
            back->special(TS_SYNCH);
+           net_pending_errors();
            break;
          case IDM_TEL_EC:
            back->special(TS_EC);
+           net_pending_errors();
            break;
          case IDM_TEL_EL:
            back->special(TS_EL);
+           net_pending_errors();
            break;
          case IDM_TEL_GA:
            back->special(TS_GA);
+           net_pending_errors();
            break;
          case IDM_TEL_NOP:
            back->special(TS_NOP);
+           net_pending_errors();
            break;
          case IDM_TEL_ABORT:
            back->special(TS_ABORT);
+           net_pending_errors();
            break;
          case IDM_TEL_AO:
            back->special(TS_AO);
+           net_pending_errors();
            break;
          case IDM_TEL_IP:
            back->special(TS_IP);
+           net_pending_errors();
            break;
          case IDM_TEL_SUSP:
            back->special(TS_SUSP);
+           net_pending_errors();
            break;
          case IDM_TEL_EOR:
            back->special(TS_EOR);
+           net_pending_errors();
            break;
          case IDM_TEL_EOF:
            back->special(TS_EOF);
+           net_pending_errors();
            break;
          case IDM_ABOUT:
            showabout(hwnd);
@@ -1661,6 +1693,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            if( lParam == 0 )
                PostMessage(hwnd, WM_CHAR, ' ', 0);
            break;
+         case IDM_FULLSCREEN:
+               flip_full_screen();     
+               break;
          default:
            if (wParam >= IDM_SAVED_MIN && wParam <= IDM_SAVED_MAX) {
                SendMessage(hwnd, WM_SYSCOMMAND, IDM_SAVEDSESS, wParam);
@@ -1983,7 +2018,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
 
            return rv;
        }
-       break;
        /* break;  (never reached) */
       case WM_SIZE:
 #ifdef RDB_DEBUG_PATCH
@@ -2032,6 +2066,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                    if (cfg.resize_action != RESIZE_FONT)
                        term_size(prev_rows, prev_cols, cfg.savelines);
                    reset_window(0);
+               } else if (was_full_screen) {
+                   was_full_screen = 0;
+                   if (cfg.resize_action != RESIZE_FONT)
+                       term_size(pre_fs_rows, pre_fs_cols, cfg.savelines);
+                   reset_window(0);
                }
                /* This is an unexpected resize, these will normally happen
                 * if the window is too large. Probably either the user
@@ -2164,6 +2203,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                }
            }
        }
+       net_pending_errors();
        return 0;
       case WM_INPUTLANGCHANGE:
        {
@@ -3804,23 +3844,62 @@ void beep(int mode)
 /*
  * Toggle full screen mode. Thanks to cwis@nerim.fr for the
  * implementation.
+ * Revised by <wez@thebrainroom.com>
  */
 static void flip_full_screen(void)
 {
-    if (!full_screen) {
-       int cx, cy;
+    want_full_screen = !want_full_screen;
 
+    if (full_screen == want_full_screen)
+       return;
+
+    full_screen = want_full_screen;
+
+    old_wind_placement.length = sizeof(old_wind_placement);
+
+    if (full_screen) {
+       int x, y, cx, cy;
+#if !defined(NO_MULTIMON) && defined(MONITOR_DEFAULTTONEAREST)
+       /* The multi-monitor safe way of doing things */
+       HMONITOR        mon;
+       MONITORINFO     mi;
+
+       mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+       mi.cbSize = sizeof(mi);
+       GetMonitorInfo(mon, &mi);
+       x = mi.rcMonitor.left;
+       y = mi.rcMonitor.top;
+       cx = mi.rcMonitor.right;
+       cy = mi.rcMonitor.bottom;
+#else
+       /* good old fashioned way of doing it */
+       x = 0;
+       y = 0;
        cx = GetSystemMetrics(SM_CXSCREEN);
        cy = GetSystemMetrics(SM_CYSCREEN);
+#endif
+
+       /* save rows for when we "restore" back down again */
+       pre_fs_rows = rows;
+       pre_fs_cols = cols;
+
        GetWindowPlacement(hwnd, &old_wind_placement);
-       old_wind_style = GetWindowLong(hwnd, GWL_STYLE);
        SetWindowLong(hwnd, GWL_STYLE,
-                     old_wind_style & ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME));
-       SetWindowPos(hwnd, HWND_TOP, 0, 0, cx, cy, SWP_SHOWWINDOW);
-       full_screen = 1;
+                     GetWindowLong(hwnd, GWL_STYLE)
+                     & ~((cfg.scrollbar_in_fullscreen ? 0 : WS_VSCROLL)
+                         | WS_CAPTION | WS_BORDER | WS_THICKFRAME));
+       /* become topmost */
+       SetWindowPos(hwnd, HWND_TOP, x, y, cx, cy, SWP_FRAMECHANGED);
     } else {
-       SetWindowLong(hwnd, GWL_STYLE, old_wind_style);
+       was_full_screen = 1;
+       SetWindowLong(hwnd, GWL_STYLE,
+                     GetWindowLong(hwnd, GWL_STYLE)
+                     | (cfg.scrollbar ? WS_VSCROLL : 0)
+                     | WS_CAPTION | WS_BORDER | WS_THICKFRAME);
+       SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
+                    SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);
        SetWindowPlacement(hwnd,&old_wind_placement);
-       full_screen = 0;
     }
+    CheckMenuItem(GetSystemMenu(hwnd, FALSE), IDM_FULLSCREEN,
+                 MF_BYCOMMAND| full_screen ? MF_CHECKED : MF_UNCHECKED);
 }