X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/62ddb51e0424dd4bd1098b024f2427959aefc729..9e164d82c8990d3c8cff58d866fb9938907d4d7b:/windows/window.c diff --git a/windows/window.c b/windows/window.c index a2ef1bf0..1d4b7152 100644 --- a/windows/window.c +++ b/windows/window.c @@ -10,6 +10,10 @@ #include #include +#ifndef NO_MULTIMON +#define COMPILE_MULTIMON_STUBS +#endif + #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" #include "terminal.h" @@ -17,11 +21,8 @@ #include "win_res.h" #ifndef NO_MULTIMON -#if WINVER < 0x0500 -#define COMPILE_MULTIMON_STUBS #include #endif -#endif #include #include @@ -86,6 +87,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 int is_full_screen(void); static void make_full_screen(void); @@ -217,12 +219,7 @@ static void start_backend(void) * Select protocol. This is farmed out into a table in a * separate file to enable an ssh-free variant. */ - back = NULL; - for (i = 0; backends[i].backend != NULL; i++) - if (backends[i].protocol == cfg.protocol) { - back = backends[i].backend; - break; - } + back = backend_from_proto(cfg.protocol); if (back == NULL) { char *str = dupprintf("%s Internal Error", appname); MessageBox(NULL, "Unsupported protocol number found", @@ -297,6 +294,7 @@ static void close_session(void) back->free(backhandle); backhandle = NULL; back = NULL; + term_provide_resize_fn(term, NULL, NULL); update_specials_menu(NULL); } @@ -350,23 +348,26 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) init_help(); + init_flashwindow(); + /* * Process the command line. */ { char *p; int got_host = 0; + /* By default, we bring up the config dialog, rather than launching + * a session. This gets set to TRUE if something happens to change + * that (e.g., a hostname is specified on the command-line). */ + int allow_launch = FALSE; default_protocol = be_default_protocol; /* Find the appropriate default port. */ { - int i; + Backend *b = backend_from_proto(default_protocol); default_port = 0; /* illegal */ - for (i = 0; backends[i].backend != NULL; i++) - if (backends[i].protocol == default_protocol) { - default_port = backends[i].backend->default_port; - break; - } + if (b) + default_port = b->default_port; } cfg.logtype = LGTYP_NONE; @@ -392,6 +393,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) if (!cfg_launchable(&cfg) && !do_config()) { cleanup_exit(0); } + allow_launch = TRUE; /* allow it to be launched directly */ } else if (*p == '&') { /* * An initial & means we've been given a command line @@ -410,6 +412,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } else if (!do_config()) { cleanup_exit(0); } + allow_launch = TRUE; } else { /* * Otherwise, break up the command line and deal with @@ -534,7 +537,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) cmdline_run_saved(&cfg); - if (!cfg_launchable(&cfg) && !do_config()) { + if (loaded_session || got_host) + allow_launch = TRUE; + + if ((!allow_launch || !cfg_launchable(&cfg)) && !do_config()) { cleanup_exit(0); } @@ -811,9 +817,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) sfree(handles); if (must_close_session) close_session(); - } - - sfree(handles); + } else + sfree(handles); while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) @@ -1233,7 +1238,7 @@ static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc, gcpr.lStructSize = sizeof(gcpr); gcpr.lpGlyphs = (void *)buffer; - gcpr.lpClass = classbuffer; + gcpr.lpClass = (void *)classbuffer; gcpr.nGlyphs = cbCount; GetCharacterPlacementW(hdc, lpString, cbCount, 0, &gcpr, @@ -3559,8 +3564,9 @@ int char_width(Context ctx, int uc) { /* * Translate a WM_(SYS)?KEY(UP|DOWN) message into a string of ASCII - * codes. Returns number of bytes used or zero to drop the message - * or -1 to forward the message to windows. + * codes. Returns number of bytes used, zero to drop the message, + * -1 to forward the message to Windows, or another negative number + * to indicate a NUL-terminated "special" string. */ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned char *output) @@ -3980,9 +3986,9 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, return p - output; } if (wParam == VK_CANCEL && shift_state == 2) { /* Ctrl-Break */ - *p++ = 3; - *p++ = 0; - return -2; + if (back) + back->special(backhandle, TS_BRK); + return 0; } if (wParam == VK_PAUSE) { /* Break/Pause */ *p++ = 26; @@ -4997,10 +5003,41 @@ void modalfatalbox(char *fmt, ...) cleanup_exit(1); } +typedef BOOL (WINAPI *p_FlashWindowEx_t)(PFLASHWINFO); +static p_FlashWindowEx_t p_FlashWindowEx = NULL; + +static void init_flashwindow(void) +{ + HMODULE user32_module = LoadLibrary("USER32.DLL"); + if (user32_module) { + p_FlashWindowEx = (p_FlashWindowEx_t) + GetProcAddress(user32_module, "FlashWindowEx"); + } +} + +static BOOL flash_window_ex(DWORD dwFlags, UINT uCount, DWORD dwTimeout) +{ + if (p_FlashWindowEx) { + FLASHWINFO fi; + fi.cbSize = sizeof(fi); + fi.hwnd = hwnd; + fi.dwFlags = dwFlags; + fi.uCount = uCount; + fi.dwTimeout = dwTimeout; + return (*p_FlashWindowEx)(&fi); + } + else + return FALSE; /* shrug */ +} + static void flash_window(int mode); static long next_flash; static int flashing = 0; +/* + * Timer for platforms where we must maintain window flashing manually + * (e.g., Win95). + */ static void flash_window_timer(void *ctx, long now) { if (flashing && now - next_flash >= 0) { @@ -5017,21 +5054,37 @@ static void flash_window(int mode) if ((mode == 0) || (cfg.beep_ind == B_IND_DISABLED)) { /* stop */ if (flashing) { - FlashWindow(hwnd, FALSE); flashing = 0; + if (p_FlashWindowEx) + flash_window_ex(FLASHW_STOP, 0, 0); + else + FlashWindow(hwnd, FALSE); } } else if (mode == 2) { /* start */ if (!flashing) { flashing = 1; - FlashWindow(hwnd, TRUE); - next_flash = schedule_timer(450, flash_window_timer, hwnd); + if (p_FlashWindowEx) { + /* For so-called "steady" mode, we use uCount=2, which + * seems to be the traditional number of flashes used + * by user notifications (e.g., by Explorer). + * uCount=0 appears to enable continuous flashing, per + * "flashing" mode, although I haven't seen this + * documented. */ + flash_window_ex(FLASHW_ALL | FLASHW_TIMER, + (cfg.beep_ind == B_IND_FLASH ? 0 : 2), + 0 /* system cursor blink rate */); + /* No need to schedule timer */ + } else { + FlashWindow(hwnd, TRUE); + next_flash = schedule_timer(450, flash_window_timer, hwnd); + } } } else if ((mode == 1) && (cfg.beep_ind == B_IND_FLASH)) { /* maintain */ - if (flashing) { + if (flashing && !p_FlashWindowEx) { FlashWindow(hwnd, TRUE); /* toggle */ next_flash = schedule_timer(450, flash_window_timer, hwnd); }