#endif
#endif
+#if WINVER < 0x0500
+#define COMPILE_MULTIMON_STUBS
+#include <multimon.h>
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define IDM_TEL_SUSP 0x0110
#define IDM_TEL_EOR 0x0120
#define IDM_TEL_EOF 0x0130
-#define IDM_ABOUT 0x0140
-#define IDM_SAVEDSESS 0x0150
-#define IDM_COPYALL 0x0160
-#define IDM_FULLSCREEN 0x0170
+#define IDM_HELP 0x0140
+#define IDM_ABOUT 0x0150
+#define IDM_SAVEDSESS 0x0160
+#define IDM_COPYALL 0x0170
+#define IDM_FULLSCREEN 0x0180
#define IDM_SESSLGP 0x0250 /* log type printable */
#define IDM_SESSLGA 0x0260 /* log type all chars */
#define IDM_SAVED_MAX 0x2000
#define WM_IGNORE_CLIP (WM_XUSER + 2)
+#define WM_FULLSCR_ON_MAX (WM_XUSER + 3)
/* Needed for Chinese support and apparently not always defined. */
#ifndef VK_PROCESSKEY
static void deinit_fonts(void);
static void set_input_locale(HKL);
+static int is_full_screen(void);
+static void make_full_screen(void);
+static void clear_full_screen(void);
+static void flip_full_screen(void);
+
/* Window layout information */
static void reset_window(int);
-static int full_screen = 0;
static int extra_width, extra_height;
static int font_width, font_height, font_dualwidth;
static int offset_width, offset_height;
static LPARAM pend_netevent_lParam = 0;
static void enact_pending_netevent(void);
static void flash_window(int mode);
-static void flip_full_screen(void);
static time_t last_movement = 0;
}
}
+ /*
+ * See if we can find our Help file.
+ */
+ {
+ char b[2048], *p, *q, *r;
+ FILE *fp;
+ GetModuleFileName(NULL, b, sizeof(b) - 1);
+ r = b;
+ p = strrchr(b, '\\');
+ if (p && p >= r) r = p+1;
+ q = strrchr(b, ':');
+ if (q && q >= r) r = q+1;
+ strcpy(r, "putty.hlp");
+ if ( (fp = fopen(b, "r")) != NULL) {
+ help_path = dupstr(b);
+ fclose(fp);
+ } else
+ help_path = NULL;
+ strcpy(r, "putty.cnt");
+ if ( (fp = fopen(b, "r")) != NULL) {
+ help_has_contents = TRUE;
+ fclose(fp);
+ } else
+ help_has_contents = FALSE;
+ }
+
/*
* Process the command line.
*/
char msg[1024], *title;
char *realhost;
- error = back->init(cfg.host, cfg.port, &realhost);
+ error = back->init(cfg.host, cfg.port, &realhost, cfg.tcp_nodelay);
if (error) {
sprintf(msg, "Unable to open connection to\n"
"%.800s\n" "%s", cfg.host, error);
AppendMenu(m, (cfg.resize_action == RESIZE_DISABLED) ?
MF_GRAYED : MF_ENABLED, IDM_FULLSCREEN, "&Full Screen");
AppendMenu(m, MF_SEPARATOR, 0, 0);
+ if (help_path)
+ AppendMenu(m, MF_ENABLED, IDM_HELP, "&Help");
AppendMenu(m, MF_ENABLED, IDM_ABOUT, "&About PuTTY");
}
HDC hdc;
static int ignore_clip = FALSE;
static int need_backend_resize = FALSE;
+ static int fullscr_on_max = FALSE;
switch (message) {
case WM_TIMER:
sprintf(c, "putty &%p", filemap);
cl = c;
} else if (wParam == IDM_SAVEDSESS) {
- char *session =
- sessions[(lParam - IDM_SAVED_MIN) / 16];
- cl = smalloc(16 + strlen(session)); /* 8, but play safe */
- if (!cl)
- cl = NULL; /* not a very important failure mode */
- else {
- sprintf(cl, "putty @%s", session);
- freecl = TRUE;
- }
+ if ((lParam - IDM_SAVED_MIN) / 16 < nsessions) {
+ char *session =
+ sessions[(lParam - IDM_SAVED_MIN) / 16];
+ cl = smalloc(16 + strlen(session));
+ /* 8, but play safe */
+ if (!cl)
+ cl = NULL;
+ /* not a very important failure mode */
+ else {
+ sprintf(cl, "putty @%s", session);
+ freecl = TRUE;
+ }
+ } else
+ break;
} else
cl = NULL;
(cfg.resize_action == RESIZE_DISABLED)
? MF_GRAYED : MF_ENABLED);
/* Gracefully unzoom if necessary */
- if (full_screen &&
+ if (IsZoomed(hwnd) &&
(cfg.resize_action == RESIZE_DISABLED)) {
- flip_full_screen();
+ ShowWindow(hwnd, SW_RESTORE);
}
}
cfg.width != prev_cfg.width ||
cfg.savelines != prev_cfg.savelines ||
cfg.resize_action == RESIZE_FONT ||
+ (cfg.resize_action == RESIZE_EITHER && IsZoomed(hwnd)) ||
cfg.resize_action == RESIZE_DISABLED)
term_size(cfg.height, cfg.width, cfg.savelines);
nexflag &= ~(WS_EX_CLIENTEDGE);
nflg = flag;
- if (full_screen ?
+ if (is_full_screen() ?
cfg.scrollbar_in_fullscreen : cfg.scrollbar)
nflg |= WS_VSCROLL;
else
nflg &= ~WS_VSCROLL;
+
+ if (cfg.resize_action == RESIZE_DISABLED ||
+ is_full_screen())
+ nflg &= ~WS_THICKFRAME;
+ else
+ nflg |= WS_THICKFRAME;
+
if (cfg.resize_action == RESIZE_DISABLED)
- nflg &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);
+ nflg &= ~WS_MAXIMIZEBOX;
else
- nflg |= (WS_THICKFRAME | WS_MAXIMIZEBOX);
+ nflg |= WS_MAXIMIZEBOX;
if (nflg != flag || nexflag != exflag) {
if (nflg != flag)
case IDM_ABOUT:
showabout(hwnd);
break;
+ case IDM_HELP:
+ WinHelp(hwnd, help_path,
+ help_has_contents ? HELP_FINDER : HELP_CONTENTS, 0);
+ break;
case SC_MOUSEMENU:
/*
* We get this if the System menu has been activated
PostMessage(hwnd, WM_CHAR, ' ', 0);
break;
case IDM_FULLSCREEN:
- flip_full_screen();
- break;
+ flip_full_screen();
+ break;
default:
if (wParam >= IDM_SAVED_MIN && wParam <= IDM_SAVED_MAX) {
SendMessage(hwnd, WM_SYSCOMMAND, IDM_SAVEDSESS, wParam);
* window, we put up the System menu instead of doing
* selection.
*/
- if (full_screen && press && button == MBT_LEFT &&
+ if (is_full_screen() && press && button == MBT_LEFT &&
X_POS(lParam) == 0 && Y_POS(lParam) == 0) {
SendMessage(hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, 0);
return 0;
term_update();
break;
case WM_KILLFOCUS:
- if (full_screen) flip_full_screen();
show_mouseptr(1);
has_focus = FALSE;
DestroyCaret();
return rv;
}
/* break; (never reached) */
+ case WM_FULLSCR_ON_MAX:
+ fullscr_on_max = TRUE;
+ break;
case WM_SIZE:
#ifdef RDB_DEBUG_PATCH
debug((27, "WM_SIZE %s (%d,%d)",
cfg.win_name_always ? window_name : icon_name);
if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)
SetWindowText(hwnd, window_name);
+ if (wParam == SIZE_RESTORED)
+ clear_full_screen();
+ if (wParam == SIZE_MAXIMIZED && fullscr_on_max) {
+ make_full_screen();
+ fullscr_on_max = FALSE;
+ }
if (cfg.resize_action == RESIZE_DISABLED) {
/* A resize, well it better be a minimize. */
{
SCROLLINFO si;
- if ((full_screen && !cfg.scrollbar_in_fullscreen) ||
- (!full_screen && !cfg.scrollbar))
+ if (is_full_screen() ? !cfg.scrollbar_in_fullscreen : !cfg.scrollbar)
return;
si.cbSize = sizeof(si);
len * sizeof(wchar_t));
clipdata2 = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, len2);
- if (!clipdata || !clipdata2 || !clipdata3) {
+ if (!clipdata || !clipdata2) {
if (clipdata)
GlobalFree(clipdata);
if (clipdata2)
GlobalFree(clipdata2);
- if (clipdata3)
- GlobalFree(clipdata3);
return;
}
if (!(lock = GlobalLock(clipdata)))
}
}
-/*
- * Toggle full screen mode. Thanks to cwis@nerim.fr for the
- * implementation.
- * Revised by <wez@thebrainroom.com>
- */
-static void flip_full_screen(void)
-{
- WINDOWPLACEMENT wp;
- LONG style;
-
- wp.length = sizeof(wp);
- GetWindowPlacement(hwnd, &wp);
-
- full_screen = !full_screen;
-
- if (full_screen) {
- if (wp.showCmd == SW_SHOWMAXIMIZED) {
- /* Ooops it was already 'zoomed' we have to unzoom it before
- * everything will work right.
- */
- wp.showCmd = SW_SHOWNORMAL;
- SetWindowPlacement(hwnd, &wp);
- }
-
- style = GetWindowLong(hwnd, GWL_STYLE) & ~(WS_CAPTION|WS_THICKFRAME);
- style &= ~WS_VSCROLL;
- if (cfg.scrollbar_in_fullscreen)
- style |= WS_VSCROLL;
- SetWindowLong(hwnd, GWL_STYLE, style);
-
- /* Some versions of explorer get confused and don't take
- * notice of us going fullscreen, so go topmost too.
- */
- SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOCOPYBITS |
- SWP_NOMOVE | SWP_NOSIZE |
- SWP_FRAMECHANGED);
-
- wp.showCmd = SW_SHOWMAXIMIZED;
- SetWindowPlacement(hwnd, &wp);
- } else {
- style = GetWindowLong(hwnd, GWL_STYLE) | WS_CAPTION;
- if (cfg.resize_action != RESIZE_DISABLED)
- style |= WS_THICKFRAME;
- style &= ~WS_VSCROLL;
- if (cfg.scrollbar)
- style |= WS_VSCROLL;
- SetWindowLong(hwnd, GWL_STYLE, style);
-
- SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOCOPYBITS |
- SWP_NOMOVE | SWP_NOSIZE |
- SWP_FRAMECHANGED);
-
- wp.showCmd = SW_SHOWNORMAL;
- SetWindowPlacement(hwnd, &wp);
- }
-
- CheckMenuItem(GetSystemMenu(hwnd, FALSE), IDM_FULLSCREEN,
- MF_BYCOMMAND| full_screen ? MF_CHECKED : MF_UNCHECKED);
-}
-
/*
* Minimise or restore the window in response to a server-side
* request.
*/
void set_zorder(int top)
{
- if (cfg.alwaysontop || full_screen)
+ if (cfg.alwaysontop)
return; /* ignore */
SetWindowPos(hwnd, top ? HWND_TOP : HWND_BOTTOM, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE);
*/
void set_zoomed(int zoomed)
{
- if (IsZoomed(hwnd) || full_screen) {
- if (!zoomed) {
- if (full_screen)
- flip_full_screen();
- else
- ShowWindow(hwnd, SW_RESTORE);
- }
+ if (IsZoomed(hwnd)) {
+ if (!zoomed)
+ ShowWindow(hwnd, SW_RESTORE);
} else {
if (zoomed)
ShowWindow(hwnd, SW_MAXIMIZE);
{
return icon ? icon_name : window_name;
}
+
+/*
+ * See if we're in full-screen mode.
+ */
+int is_full_screen()
+{
+ if (!IsZoomed(hwnd))
+ return FALSE;
+ if (GetWindowLong(hwnd, GWL_STYLE) & WS_CAPTION)
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Go full-screen. This should only be called when we are already
+ * maximised.
+ */
+void make_full_screen()
+{
+ DWORD style;
+ int x, y, w, h;
+
+ assert(IsZoomed(hwnd));
+
+ /* Remove the window furniture. */
+ style = GetWindowLong(hwnd, GWL_STYLE);
+ style &= ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME);
+ if (cfg.scrollbar_in_fullscreen)
+ style |= WS_VSCROLL;
+ else
+ style &= ~WS_VSCROLL;
+ 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);
+
+ /* Tick the menu item in the System menu. */
+ CheckMenuItem(GetSystemMenu(hwnd, FALSE), IDM_FULLSCREEN,
+ MF_CHECKED);
+}
+
+/*
+ * Clear the full-screen attributes.
+ */
+void clear_full_screen()
+{
+ DWORD oldstyle, style;
+
+ /* Reinstate the window furniture. */
+ style = oldstyle = GetWindowLong(hwnd, GWL_STYLE);
+ style |= WS_CAPTION | WS_BORDER;
+ if (cfg.resize_action == RESIZE_DISABLED)
+ style &= ~WS_THICKFRAME;
+ else
+ style |= WS_THICKFRAME;
+ if (cfg.scrollbar)
+ style |= WS_VSCROLL;
+ else
+ style &= ~WS_VSCROLL;
+ if (style != oldstyle) {
+ SetWindowLong(hwnd, GWL_STYLE, style);
+ SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+ SWP_FRAMECHANGED);
+ }
+
+ /* Untick the menu item in the System menu. */
+ CheckMenuItem(GetSystemMenu(hwnd, FALSE), IDM_FULLSCREEN,
+ MF_UNCHECKED);
+}
+
+/*
+ * Toggle full-screen mode.
+ */
+void flip_full_screen()
+{
+ if (is_full_screen()) {
+ ShowWindow(hwnd, SW_RESTORE);
+ } else if (IsZoomed(hwnd)) {
+ make_full_screen();
+ } else {
+ SendMessage(hwnd, WM_FULLSCR_ON_MAX, 0, 0);
+ ShowWindow(hwnd, SW_MAXIMIZE);
+ }
+}