summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaniv Kamay <ykamay@redhat.com>2009-11-16 21:15:19 +0200
committerYaniv Kamay <ykamay@redhat.com>2009-11-30 18:08:16 +0200
commit6f4736e08be2dfa7fec33d5bca56e33ae2f7af6f (patch)
tree6e033524cd399dbf8383f2c350ddbb6b016b4d96
parent3b51087b3656b111886c7397d0ddd499a96f9e2d (diff)
downloadspice-6f4736e08be2dfa7fec33d5bca56e33ae2f7af6f.tar.gz
spice-6f4736e08be2dfa7fec33d5bca56e33ae2f7af6f.tar.xz
spice-6f4736e08be2dfa7fec33d5bca56e33ae2f7af6f.zip
client: split inputs handler
-rw-r--r--client/application.cpp90
-rw-r--r--client/application.h14
-rw-r--r--client/inputs_channel.cpp6
-rw-r--r--client/inputs_channel.h2
-rw-r--r--client/inputs_handler.h17
5 files changed, 96 insertions, 33 deletions
diff --git a/client/application.cpp b/client/application.cpp
index a49576e2..d5ff48f0 100644
--- a/client/application.cpp
+++ b/client/application.cpp
@@ -243,7 +243,8 @@ void StickyKeyTimer::response(AbstractProcessLoop& events_loop)
app->deactivate_interval_timer(this);
}
-static InputsHandler default_inputs_handler;
+static MouseHandler default_mouse_handler;
+static KeyHandler default_key_handler;
enum AppCommands {
APP_CMD_INVALID,
@@ -270,7 +271,8 @@ Application::Application()
, _exit_code (0)
, _active_screen (NULL)
, _gui_layer (new GUILayer())
- , _inputs_handler (&default_inputs_handler)
+ , _key_handler (&default_key_handler)
+ , _mouse_handler (&default_mouse_handler)
, _monitors (NULL)
, _title (L"SPICEc:%d")
, _splash_mode (true)
@@ -278,7 +280,6 @@ Application::Application()
{
DBG(0, "");
Platform::set_process_loop(*this);
-
init_monitors();
init_key_table();
init_menu();
@@ -341,21 +342,68 @@ void Application::init_menu()
_app_menu.reset(root_menu.release());
}
-void Application::set_inputs_handler(InputsHandler& handler)
+void Application::__remove_key_handler(KeyHandler& handler)
+{
+ KeyHandlersStack::iterator iter = _key_handlers.begin();
+
+ for (; iter != _key_handlers.end(); iter++) {
+ if (*iter == &handler) {
+ _key_handlers.erase(iter);
+ return;
+ }
+ }
+}
+
+void Application::set_key_handler(KeyHandler& handler)
{
+ if (&handler == _key_handler) {
+ return;
+ }
+
+ __remove_key_handler(handler);
+ if (!_key_handler->permit_focus_loss()) {
+ _key_handlers.push_front(&handler);
+ return;
+ }
+
unpress_all();
- _inputs_handler = &handler;
if (_active) {
- handler.on_focus_in();
+ _key_handler->on_focus_out();
}
+
+ _key_handlers.push_front(_key_handler);
+ _key_handler = &handler;
+ if (_active) {
+ _key_handler->on_focus_in();
+ }
+}
+
+void Application::remove_key_handler(KeyHandler& handler)
+{
+ bool is_current = (&handler == _key_handler);
+
+ if (!is_current) {
+ __remove_key_handler(handler);
+ return;
+ }
+
+ KeyHandler damy_handler;
+ _key_handler = &damy_handler;
+ set_key_handler(**_key_handlers.begin());
+ __remove_key_handler(damy_handler);
+}
+
+void Application::set_mouse_handler(MouseHandler& handler)
+{
+ _mouse_handler = &handler;
}
-void Application::remove_inputs_handler(InputsHandler& handler)
+void Application::remove_mouse_handler(MouseHandler& handler)
{
- if (_inputs_handler != &handler) {
+ if (_mouse_handler != &handler) {
return;
}
- _inputs_handler = &default_inputs_handler;
+ _mouse_handler = &default_mouse_handler;
}
void Application::capture_mouse()
@@ -512,17 +560,17 @@ void Application::on_screen_destroyed(int id, bool was_captured)
void Application::on_mouse_motion(int dx, int dy, int buttons_state)
{
- _inputs_handler->on_mouse_motion(dx, dy, buttons_state);
+ _mouse_handler->on_mouse_motion(dx, dy, buttons_state);
}
void Application::on_mouse_down(int button, int buttons_state)
{
- _inputs_handler->on_mouse_down(button, buttons_state);
+ _mouse_handler->on_mouse_down(button, buttons_state);
}
void Application::on_mouse_up(int button, int buttons_state)
{
- _inputs_handler->on_mouse_up(button, buttons_state);
+ _mouse_handler->on_mouse_up(button, buttons_state);
}
void Application::init_scan_code(int index)
@@ -695,7 +743,7 @@ void Application::unpress_all()
if (_key_table[i].press) {
uint32_t scan_code = get_break_scan_code((RedKey)i);
ASSERT(scan_code);
- _inputs_handler->on_key_up(scan_code);
+ _key_handler->on_key_up(scan_code);
unpress_key((RedKey)i);
}
}
@@ -980,8 +1028,8 @@ void Application::on_key_down(RedKey key)
(_key_table[REDKEY_L_ALT].press || _key_table[REDKEY_R_ALT].press))) {
if (key == REDKEY_END || key == REDKEY_PAD_1) {
unpress_key(key);
- _inputs_handler->on_key_down(get_make_scan_code(REDKEY_DELETE));
- _inputs_handler->on_key_up(get_break_scan_code(REDKEY_DELETE));
+ _key_handler->on_key_down(get_make_scan_code(REDKEY_DELETE));
+ _key_handler->on_key_up(get_break_scan_code(REDKEY_DELETE));
} else if (key == REDKEY_DELETE || key == REDKEY_PAD_POINT) {
unpress_key(key);
return;
@@ -989,7 +1037,7 @@ void Application::on_key_down(RedKey key)
}
#endif
- _inputs_handler->on_key_down(scan_code);
+ _key_handler->on_key_down(scan_code);
}
void Application::do_on_key_up(RedKey key)
@@ -1000,7 +1048,7 @@ void Application::do_on_key_up(RedKey key)
LOG_WARN("no break code for %d", key);
return;
}
- _inputs_handler->on_key_up(scan_code);
+ _key_handler->on_key_up(scan_code);
}
void Application::on_key_up(RedKey key)
@@ -1070,13 +1118,13 @@ void Application::on_stop_screen_key_interception(RedScreen* screen)
void Application::on_app_activated()
{
_active = true;
- _inputs_handler->on_focus_in();
+ _key_handler->on_focus_in();
}
void Application::on_app_deactivated()
{
_active = false;
- _inputs_handler->on_focus_out();
+ _key_handler->on_focus_out();
#ifdef WIN32
if (!_changing_screens) {
exit_full_screen();
@@ -1379,12 +1427,12 @@ bool Application::is_cad_pressed()
void Application::send_key_down(RedKey key)
{
- _inputs_handler->on_key_down(get_make_scan_code(key));
+ _key_handler->on_key_down(get_make_scan_code(key));
}
void Application::send_key_up(RedKey key)
{
- _inputs_handler->on_key_up(get_break_scan_code(key));
+ _key_handler->on_key_up(get_break_scan_code(key));
}
void Application::send_alt_ctl_del()
diff --git a/client/application.h b/client/application.h
index 90d2fa33..5d5c1e87 100644
--- a/client/application.h
+++ b/client/application.h
@@ -109,6 +109,9 @@ typedef struct StickyInfo {
AutoRef<StickyKeyTimer> timer;
} StickyInfo;
+
+typedef std::list<KeyHandler*> KeyHandlersStack;
+
class Application : public ProcessLoop,
public Platform::EventListener,
public Platform::DisplayModeListner,
@@ -119,8 +122,10 @@ public:
int run();
- void set_inputs_handler(InputsHandler& handler);
- void remove_inputs_handler(InputsHandler& handler);
+ void set_key_handler(KeyHandler& handler);
+ void remove_key_handler(KeyHandler& handler);
+ void set_mouse_handler(MouseHandler& handler);
+ void remove_mouse_handler(MouseHandler& handler);
void capture_mouse();
void release_mouse_capture();
RedScreen* find_screen(int id);
@@ -203,6 +208,7 @@ private:
bool is_key_set_pressed(const HotkeySet& key_set);
bool is_cad_pressed();
void do_on_key_up(RedKey key);
+ void __remove_key_handler(KeyHandler& handler);
// returns the press value before operation (i.e., if it was already pressed)
bool press_key(RedKey key);
@@ -235,7 +241,9 @@ private:
HotKeys _hot_keys;
CommandsMap _commands_map;
std::auto_ptr<GUILayer> _gui_layer;
- InputsHandler* _inputs_handler;
+ KeyHandler* _key_handler;
+ KeyHandlersStack _key_handlers;
+ MouseHandler* _mouse_handler;
const MonitorsList* _monitors;
std::wstring _title;
bool _splash_mode;
diff --git a/client/inputs_channel.cpp b/client/inputs_channel.cpp
index e1b63964..13f6554a 100644
--- a/client/inputs_channel.cpp
+++ b/client/inputs_channel.cpp
@@ -50,7 +50,8 @@ public:
virtual void response(AbstractProcessLoop& events_loop)
{
- static_cast<Application*>(events_loop.get_owner())->set_inputs_handler(_channel);
+ static_cast<Application*>(events_loop.get_owner())->set_key_handler(_channel);
+ static_cast<Application*>(events_loop.get_owner())->set_mouse_handler(_channel);
AttachFunc func(_channel);
_channel.get_client().for_each_channel(func);
}
@@ -91,7 +92,8 @@ public:
virtual void do_response(AbstractProcessLoop& events_loop)
{
- static_cast<Application*>(events_loop.get_owner())->remove_inputs_handler(_channel);
+ static_cast<Application*>(events_loop.get_owner())->remove_key_handler(_channel);
+ static_cast<Application*>(events_loop.get_owner())->remove_mouse_handler(_channel);
DetachFunc detach_func;
_channel.get_client().for_each_channel(detach_func);
}
diff --git a/client/inputs_channel.h b/client/inputs_channel.h
index 530cd8ba..443b96ff 100644
--- a/client/inputs_channel.h
+++ b/client/inputs_channel.h
@@ -23,7 +23,7 @@
class ChannelFactory;
-class InputsChannel: public RedChannel, public InputsHandler {
+class InputsChannel: public RedChannel, public KeyHandler, public MouseHandler {
public:
InputsChannel(RedClient& client, uint32_t id);
virtual ~InputsChannel();
diff --git a/client/inputs_handler.h b/client/inputs_handler.h
index bfde48dc..8c868db7 100644
--- a/client/inputs_handler.h
+++ b/client/inputs_handler.h
@@ -18,17 +18,22 @@
#ifndef _H_INPUTS_HANDLER
#define _H_INPUTS_HANDLER
-
-class InputsHandler {
+class KeyHandler {
public:
- virtual ~InputsHandler() {}
- virtual void on_mouse_motion(int dx, int dy, int buttons_state) {}
- virtual void on_mouse_down(int button, int buttons_state) {}
- virtual void on_mouse_up(int button, int buttons_state) {}
+ virtual ~KeyHandler() {}
virtual void on_key_down(uint32_t scan_code) {}
virtual void on_key_up(uint32_t scan_code) {}
virtual void on_focus_in() {}
virtual void on_focus_out() {}
+ virtual bool permit_focus_loss() { return true;}
+};
+
+class MouseHandler {
+public:
+ virtual ~MouseHandler() {}
+ virtual void on_mouse_motion(int dx, int dy, int buttons_state) {}
+ virtual void on_mouse_down(int button, int buttons_state) {}
+ virtual void on_mouse_up(int button, int buttons_state) {}
};
#endif