diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/platform.h | 9 | ||||
-rw-r--r-- | client/red_client.cpp | 37 | ||||
-rw-r--r-- | client/red_client.h | 1 | ||||
-rw-r--r-- | client/windows/platform.cpp | 13 | ||||
-rw-r--r-- | client/x11/platform.cpp | 13 |
5 files changed, 73 insertions, 0 deletions
diff --git a/client/platform.h b/client/platform.h index ff6f38d2..af4a0f6c 100644 --- a/client/platform.h +++ b/client/platform.h @@ -125,6 +125,14 @@ public: static bool on_clipboard_notify(uint32_t type, const uint8_t* data, int32_t size); static bool on_clipboard_request(uint32_t type); static void on_clipboard_release(); + + enum { owner_none, owner_guest, owner_client }; + + static void set_clipboard_owner(int new_owner); + static int get_clipboard_owner() { return _clipboard_owner; } + +private: + static int _clipboard_owner; }; class Platform::EventListener { @@ -141,6 +149,7 @@ public: virtual void on_clipboard_grab(uint32_t *types, uint32_t type_count) = 0; virtual void on_clipboard_request(uint32_t type) = 0; virtual void on_clipboard_notify(uint32_t type, uint8_t* data, int32_t size) = 0; + virtual void on_clipboard_release() = 0; }; class Platform::RecordClient { diff --git a/client/red_client.cpp b/client/red_client.cpp index 3f01fb1c..a022499f 100644 --- a/client/red_client.cpp +++ b/client/red_client.cpp @@ -85,10 +85,17 @@ void ClipboardGrabEvent::response(AbstractProcessLoop& events_loop) { static_cast<RedClient*>(events_loop.get_owner())->send_agent_clipboard_message( VD_AGENT_CLIPBOARD_GRAB, _type_count * sizeof(uint32_t), _types); + Platform::set_clipboard_owner(Platform::owner_client); } void ClipboardRequestEvent::response(AbstractProcessLoop& events_loop) { + if (Platform::get_clipboard_owner() != Platform::owner_guest) { + LOG_WARN("received clipboard req from client while clipboard is not owned by guest"); + Platform::on_clipboard_notify(VD_AGENT_CLIPBOARD_NONE, NULL, 0); + return; + } + VDAgentClipboardRequest request = {_type}; static_cast<RedClient*>(events_loop.get_owner())->send_agent_clipboard_message( VD_AGENT_CLIPBOARD_REQUEST, sizeof(request), &request); @@ -865,6 +872,11 @@ void RedClient::on_clipboard_notify(uint32_t type, uint8_t* data, int32_t size) DBG(0, "clipboard change is already pending"); return; } + if (Platform::get_clipboard_owner() != Platform::owner_client) { + LOG_WARN("received clipboard data from client while clipboard is not owned by client"); + type = VD_AGENT_CLIPBOARD_NONE; + size = 0; + } _agent_out_msg_pos = 0; _agent_out_msg_size = sizeof(VDAgentMessage) + sizeof(VDAgentClipboard) + size; _agent_out_msg = (VDAgentMessage*)new uint8_t[_agent_out_msg_size]; @@ -880,6 +892,12 @@ void RedClient::on_clipboard_notify(uint32_t type, uint8_t* data, int32_t size) } } +void RedClient::on_clipboard_release() +{ + if (Platform::get_clipboard_owner() == Platform::owner_client) + send_agent_clipboard_message(VD_AGENT_CLIPBOARD_RELEASE, 0, NULL); +} + void RedClient::set_mouse_mode(uint32_t supported_modes, uint32_t current_mode) { if (current_mode != _mouse_mode) { @@ -1086,6 +1104,12 @@ void RedClient::dispatch_agent_message(VDAgentMessage* msg, void* data) break; } case VD_AGENT_CLIPBOARD: { + if (Platform::get_clipboard_owner() != Platform::owner_guest) { + LOG_WARN("received clipboard data from guest while clipboard is not owned by guest"); + Platform::on_clipboard_notify(VD_AGENT_CLIPBOARD_NONE, NULL, 0); + break; + } + VDAgentClipboard* clipboard = (VDAgentClipboard*)data; Platform::on_clipboard_notify(clipboard->type, clipboard->data, msg->size - sizeof(VDAgentClipboard)); @@ -1094,14 +1118,27 @@ void RedClient::dispatch_agent_message(VDAgentMessage* msg, void* data) case VD_AGENT_CLIPBOARD_GRAB: Platform::on_clipboard_grab((uint32_t *)data, msg->size / sizeof(uint32_t)); + Platform::set_clipboard_owner(Platform::owner_guest); break; case VD_AGENT_CLIPBOARD_REQUEST: + if (Platform::get_clipboard_owner() != Platform::owner_client) { + LOG_WARN("received clipboard req from guest while clipboard is not owned by client"); + on_clipboard_notify(VD_AGENT_CLIPBOARD_NONE, NULL, 0); + break; + } + if (!Platform::on_clipboard_request(((VDAgentClipboardRequest*)data)->type)) { on_clipboard_notify(VD_AGENT_CLIPBOARD_NONE, NULL, 0); } break; case VD_AGENT_CLIPBOARD_RELEASE: + if (Platform::get_clipboard_owner() != Platform::owner_guest) { + LOG_WARN("received clipboard release from guest while clipboard is not owned by guest"); + break; + } + Platform::on_clipboard_release(); + Platform::set_clipboard_owner(Platform::owner_none); break; default: DBG(0, "Unsupported message type %u size %u", msg->type, msg->size); diff --git a/client/red_client.h b/client/red_client.h index 2cfce494..15f06170 100644 --- a/client/red_client.h +++ b/client/red_client.h @@ -221,6 +221,7 @@ public: void on_clipboard_grab(uint32_t *types, uint32_t type_count); void on_clipboard_request(uint32_t type); void on_clipboard_notify(uint32_t type, uint8_t* data, int32_t size); + void on_clipboard_release(); void for_each_channel(ForEachChannelFunc& func); void on_mouse_capture_trigger(RedScreen& screen); diff --git a/client/windows/platform.cpp b/client/windows/platform.cpp index db6d18ab..db47079d 100644 --- a/client/windows/platform.cpp +++ b/client/windows/platform.cpp @@ -54,6 +54,7 @@ public: virtual void on_clipboard_grab(uint32_t *types, uint32_t type_count) {} virtual void on_clipboard_request(uint32_t type) {} virtual void on_clipboard_notify(uint32_t type, uint8_t* data, int32_t size) {} + virtual void on_clipboard_release() {} }; static DefaultClipboardListener default_clipboard_listener; @@ -856,6 +857,18 @@ void WinPlatform::exit_modal_loop() modal_loop_active = false; } +int Platform::_clipboard_owner = Platform::owner_none; + +void Platform::set_clipboard_owner(int new_owner) +{ + if (new_owner == owner_none) { + clipboard_listener->on_clipboard_release(); + + /* FIXME clear cached clipboard type info and data */ + } + _clipboard_owner = new_owner; +} + bool Platform::on_clipboard_grab(uint32_t *types, uint32_t type_count) { /* FIXME use all types rather then just the first one */ diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp index b7216ebb..832374a6 100644 --- a/client/x11/platform.cpp +++ b/client/x11/platform.cpp @@ -154,6 +154,7 @@ public: void on_clipboard_grab(uint32_t *types, uint32_t type_count) {} void on_clipboard_request(uint32_t type) {} void on_clipboard_notify(uint32_t type, uint8_t* data, int32_t size) {} + void on_clipboard_release() {} }; static DefaultClipboardListener default_clipboard_listener; @@ -3161,6 +3162,18 @@ bool Platform::on_clipboard_grab(uint32_t *types, uint32_t type_count) return true; } +int Platform::_clipboard_owner = Platform::owner_none; + +void Platform::set_clipboard_owner(int new_owner) +{ + if (new_owner == owner_none) { + clipboard_listener->on_clipboard_release(); + + /* FIXME clear cached clipboard type info and data */ + } + _clipboard_owner = new_owner; +} + void Platform::set_clipboard_listener(ClipboardListener* listener) { clipboard_listener = listener ? listener : &default_clipboard_listener; |