From eb85aae81ffe544273b724cc1288ecd143ef07a6 Mon Sep 17 00:00:00 2001 From: Yonit Halperin Date: Mon, 9 Nov 2009 19:19:00 +0200 Subject: spice client: calling the timers during modal loop in Windows --- client/windows/platform.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++ client/windows/red_window.cpp | 2 ++ client/windows/win_platform.h | 6 +++++ 3 files changed, 60 insertions(+) (limited to 'client/windows') diff --git a/client/windows/platform.cpp b/client/windows/platform.cpp index 0fe7b244..24c9ca93 100644 --- a/client/windows/platform.cpp +++ b/client/windows/platform.cpp @@ -43,6 +43,11 @@ static Platform::EventListener* event_listener = &default_event_listener; static HWND paltform_win; static ProcessLoop* main_loop = NULL; +static const unsigned long MODAL_LOOP_TIMER_ID = 1; +static const int MODAL_LOOP_DEFAULT_TIMEOUT = 100; +static bool modal_loop_active = false; +static bool set_modal_loop_timer(); + void Platform::send_quit_request() { ASSERT(main_loop); @@ -52,6 +57,15 @@ void Platform::send_quit_request() static LRESULT CALLBACK PlatformWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { + case WM_TIMER: + if (modal_loop_active) { + main_loop->timers_action(); + if (!set_modal_loop_timer()) { + LOG_WARN("failed to set modal loop timer"); + } + } else { + LOG_WARN("received WM_TIMER not inside a modal loop"); + } case WM_ACTIVATEAPP: if (wParam) { event_listener->on_app_activated(); @@ -618,3 +632,41 @@ Icon* Platform::load_icon(int id) } return new WinIcon(icon); } + +void WinPlatform::enter_modal_loop() +{ + if (modal_loop_active) { + LOG_INFO("modal loop already active"); + return; + } + + if (set_modal_loop_timer()) { + modal_loop_active = true; + } else { + LOG_WARN("failed to create modal loop timer"); + } +} + +static bool set_modal_loop_timer() +{ + int timeout = main_loop->get_soonest_timeout(); + if (timeout == INFINITE) { + timeout = MODAL_LOOP_DEFAULT_TIMEOUT; /* for cases timeouts are added after + the enterance to the loop*/ + } + + if (!SetTimer(paltform_win, MODAL_LOOP_TIMER_ID, timeout, NULL)) { + return false; + } + return true; +} + +void WinPlatform::exit_modal_loop() +{ + if (!modal_loop_active) { + LOG_INFO("not inside the loop"); + return; + } + KillTimer(paltform_win, MODAL_LOOP_TIMER_ID); + modal_loop_active = false; +} diff --git a/client/windows/red_window.cpp b/client/windows/red_window.cpp index 0b25a798..01d82e59 100644 --- a/client/windows/red_window.cpp +++ b/client/windows/red_window.cpp @@ -191,10 +191,12 @@ LRESULT CALLBACK RedWindow_p::WindowProc(HWND hWnd, UINT message, WPARAM wParam, case WM_ENTERSIZEMOVE: case WM_ENTERMENULOOP: window->get_listener().enter_modal_loop(); + WinPlatform::enter_modal_loop(); return DefWindowProc(hWnd, message, wParam, lParam); case WM_EXITSIZEMOVE: case WM_EXITMENULOOP: window->get_listener().exit_modal_loop(); + WinPlatform::exit_modal_loop(); return DefWindowProc(hWnd, message, wParam, lParam); case WM_SETCURSOR: if (!window->_pointer_in_window) { diff --git a/client/windows/win_platform.h b/client/windows/win_platform.h index a821f63d..86bbf935 100644 --- a/client/windows/win_platform.h +++ b/client/windows/win_platform.h @@ -20,6 +20,12 @@ #include "icon.h" +class WinPlatform { +public: + static void enter_modal_loop(); + static void exit_modal_loop(); +}; + class WinIcon: public Icon { public: WinIcon(HICON icon) : _icon (icon) {} -- cgit