diff options
author | Yaniv Kamay <ykamay@redhat.com> | 2009-11-16 21:15:19 +0200 |
---|---|---|
committer | Yaniv Kamay <ykamay@redhat.com> | 2009-11-30 18:08:16 +0200 |
commit | 6f4736e08be2dfa7fec33d5bca56e33ae2f7af6f (patch) | |
tree | 6e033524cd399dbf8383f2c350ddbb6b016b4d96 | |
parent | 3b51087b3656b111886c7397d0ddd499a96f9e2d (diff) | |
download | spice-6f4736e08be2dfa7fec33d5bca56e33ae2f7af6f.tar.gz spice-6f4736e08be2dfa7fec33d5bca56e33ae2f7af6f.tar.xz spice-6f4736e08be2dfa7fec33d5bca56e33ae2f7af6f.zip |
client: split inputs handler
-rw-r--r-- | client/application.cpp | 90 | ||||
-rw-r--r-- | client/application.h | 14 | ||||
-rw-r--r-- | client/inputs_channel.cpp | 6 | ||||
-rw-r--r-- | client/inputs_channel.h | 2 | ||||
-rw-r--r-- | client/inputs_handler.h | 17 |
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 |