summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/platform.h9
-rw-r--r--client/red_client.cpp37
-rw-r--r--client/red_client.h1
-rw-r--r--client/windows/platform.cpp13
-rw-r--r--client/x11/platform.cpp13
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;