summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2009-11-09 19:19:00 +0200
committerYaniv Kamay <ykamay@redhat.com>2010-01-03 17:21:06 +0200
commiteb85aae81ffe544273b724cc1288ecd143ef07a6 (patch)
treedf730fd92c1e257cb6129b327adf43c5e24b57b8 /client
parent74db5629bde5cf33f613a17cc3cdb3e2ba49233d (diff)
downloadspice-eb85aae81ffe544273b724cc1288ecd143ef07a6.tar.gz
spice-eb85aae81ffe544273b724cc1288ecd143ef07a6.tar.xz
spice-eb85aae81ffe544273b724cc1288ecd143ef07a6.zip
spice client: calling the timers during modal loop in Windows
Diffstat (limited to 'client')
-rw-r--r--client/process_loop.cpp10
-rw-r--r--client/process_loop.h5
-rw-r--r--client/windows/platform.cpp52
-rw-r--r--client/windows/red_window.cpp2
-rw-r--r--client/windows/win_platform.h6
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) {}