diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/process_loop.cpp | 10 | ||||
-rw-r--r-- | client/process_loop.h | 5 | ||||
-rw-r--r-- | client/windows/platform.cpp | 52 | ||||
-rw-r--r-- | client/windows/red_window.cpp | 2 | ||||
-rw-r--r-- | client/windows/win_platform.h | 6 |
5 files changed, 75 insertions, 0 deletions
diff --git a/client/process_loop.cpp b/client/process_loop.cpp index 66f676f3..794f29d9 100644 --- a/client/process_loop.cpp +++ b/client/process_loop.cpp @@ -394,3 +394,13 @@ void ProcessLoop::deactivate_interval_timer(Timer* timer) { _timers_queue.deactivate_interval_timer(timer); } + +int ProcessLoop::get_soonest_timeout() +{ + return _timers_queue.get_soonest_timeout(); +} + +void ProcessLoop::timers_action() +{ + _timers_queue.timers_action(); +} diff --git a/client/process_loop.h b/client/process_loop.h index df8650dc..ea9eea43 100644 --- a/client/process_loop.h +++ b/client/process_loop.h @@ -205,6 +205,11 @@ public: void deactivate_interval_timer(Timer* timer); void process_events_queue(); + /* can be used for handling timers in modal loop state in Windows (mainly, + for updating the screen) */ + int get_soonest_timeout(); + void timers_action(); + void* get_owner() { return _owner;} bool is_same_thread(pthread_t thread) { return _started && pthread_equal(_thread, thread);} 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) {} |