From c674b2da4f21aa767d3154ed7a3a77192ce99845 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 12 Sep 2022 11:57:15 +0100 Subject: [PATCH] Windows: move GUI timer handling into a utils module. Previously, the timing.c subsystem worked in Windows PuTTY by means of scheduling WM_TIMER messages to be sent to the terminal window. Now it uses a separate hidden window instead, and all the machinery for handling that window lives on its own in windows/utils/gui-timing.c. Most immediately, this removes a use of wgs.term_hwnd that will become awkward when I move that structure in a following commit. But also, it will make it easier to add the same timing subsystem to unrelated GUI programs, such as Windows Pageant: if we ever decide to implement automatic deletion or re-encryption of unused keys after a timeout, this will help make that easier. --- windows/CMakeLists.txt | 1 + windows/platform.h | 2 ++ windows/utils/gui-timing.c | 56 ++++++++++++++++++++++++++++++++++++++ windows/window.c | 29 ++------------------ 4 files changed, 61 insertions(+), 27 deletions(-) create mode 100644 windows/utils/gui-timing.c diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index d34b4106..1d50a91c 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -16,6 +16,7 @@ add_sources_from_current_dir(utils utils/getdlgitemtext_alloc.c utils/get_system_dir.c utils/get_username.c + utils/gui-timing.c utils/interprocess_mutex.c utils/is_console_handle.c utils/load_system32_dll.c diff --git a/windows/platform.h b/windows/platform.h index 92dba117..c083f640 100644 --- a/windows/platform.h +++ b/windows/platform.h @@ -793,4 +793,6 @@ bool aux_match_done(AuxMatchOpt *amo); char *save_screenshot(HWND hwnd, const char *outfile); void gui_terminal_ready(HWND hwnd, Seat *seat, Backend *backend); +void setup_gui_timing(void); + #endif /* PUTTY_WINDOWS_PLATFORM_H */ diff --git a/windows/utils/gui-timing.c b/windows/utils/gui-timing.c new file mode 100644 index 00000000..b0beec9c --- /dev/null +++ b/windows/utils/gui-timing.c @@ -0,0 +1,56 @@ +#include "putty.h" + +#define TIMING_CLASS_NAME "PuTTYTimerWindow" +#define TIMING_TIMER_ID 1234 +static long timing_next_time; +static HWND timing_hwnd; + +static LRESULT CALLBACK TimingWndProc(HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_TIMER: + if ((UINT_PTR)wParam == TIMING_TIMER_ID) { + unsigned long next; + + KillTimer(hwnd, TIMING_TIMER_ID); + if (run_timers(timing_next_time, &next)) { + timer_change_notify(next); + } else { + } + } + return 0; + } + return DefWindowProc(hwnd, message, wParam, lParam); +} + +void setup_gui_timing(void) +{ + WNDCLASS wndclass; + + memset(&wndclass, 0, sizeof(wndclass)); + wndclass.lpfnWndProc = TimingWndProc; + wndclass.hInstance = hinst; + wndclass.lpszClassName = TIMING_CLASS_NAME; + + RegisterClass(&wndclass); + + timing_hwnd = CreateWindow( + TIMING_CLASS_NAME, "PuTTY: hidden timing window", + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, + 100, 100, NULL, NULL, hinst, NULL); + ShowWindow(timing_hwnd, SW_HIDE); +} + +void timer_change_notify(unsigned long next) +{ + unsigned long now = GETTICKCOUNT(); + long ticks; + if (now - next < INT_MAX) + ticks = 0; + else + ticks = next - now; + KillTimer(timing_hwnd, TIMING_TIMER_ID); + SetTimer(timing_hwnd, TIMING_TIMER_ID, ticks, NULL); + timing_next_time = next; +} diff --git a/windows/window.c b/windows/window.c index fb27f596..bd26e733 100644 --- a/windows/window.c +++ b/windows/window.c @@ -142,9 +142,6 @@ static const SessionSpecial *specials = NULL; static HMENU specials_menu = NULL; static int n_specials = 0; -#define TIMING_TIMER_ID 1234 -static long timing_next_time; - static struct { HMENU menu; } popup_menus[2]; @@ -564,6 +561,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) init_winfuncs(); + setup_gui_timing(); + conf = conf_new(); /* @@ -2106,19 +2105,6 @@ static void win_seat_notify_remote_exit(Seat *seat) queue_toplevel_callback(exit_callback, NULL); } -void timer_change_notify(unsigned long next) -{ - unsigned long now = GETTICKCOUNT(); - long ticks; - if (now - next < INT_MAX) - ticks = 0; - else - ticks = next - now; - KillTimer(wgs.term_hwnd, TIMING_TIMER_ID); - SetTimer(wgs.term_hwnd, TIMING_TIMER_ID, ticks, NULL); - timing_next_time = next; -} - static void conf_cache_data(void) { /* Cache some items from conf to speed lookups in very hot code */ @@ -2195,17 +2181,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, int resize_action; switch (message) { - case WM_TIMER: - if ((UINT_PTR)wParam == TIMING_TIMER_ID) { - unsigned long next; - - KillTimer(hwnd, TIMING_TIMER_ID); - if (run_timers(timing_next_time, &next)) { - timer_change_notify(next); - } else { - } - } - return 0; case WM_CREATE: break; case WM_CLOSE: {