summaryrefslogtreecommitdiff
path: root/vdagent
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2012-05-25 20:02:54 +0200
committerMarc-André Lureau <marcandre.lureau@gmail.com>2012-05-25 20:21:54 +0200
commit0cef8ba42b88132343306d1dca097f5cb61e493b (patch)
tree69b5b889cecc1d3ed169da47f0fe609960f3d9e1 /vdagent
parent7d75ac51cc8ffa85e47fee57265b0277870712ee (diff)
vdagent: reset clipboard event
Waiting for a Windows event will not last if it is already set. For example, the client may send clipboard_release() messages while we are not waiting in on_clipboard_request(), and this will SetEvent(clipboard_event) The following clipboard request will thus not wait for the data, resulting in an empty clipboard & paste for the guest application. We could say there is fundamentally a race as there is no obvious way to know if a received message is related to the current request, but by reseting the event before waiting for new events to come, we at least clear the past events.
Diffstat (limited to 'vdagent')
-rw-r--r--vdagent/vdagent.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 9046476..eb6ffd4 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -918,13 +918,32 @@ void VDAgent::on_clipboard_request(UINT format)
VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)) {
return;
}
+
VDAgentClipboardRequest request = {type};
if (!write_message(VD_AGENT_CLIPBOARD_REQUEST, sizeof(request), &request)) {
return;
}
+
+ // next clipboard event will be considered a reply to this request
+ ResetEvent(_clipboard_event);
+
DWORD start_tick = GetTickCount();
- while (WaitForSingleObjectEx(_clipboard_event, 1000, TRUE) != WAIT_OBJECT_0 &&
- GetTickCount() < start_tick + VD_CLIPBOARD_TIMEOUT_MS);
+ do {
+ DWORD wait_result = WaitForSingleObjectEx(_clipboard_event, 1000, TRUE);
+
+ switch (wait_result) {
+ case WAIT_OBJECT_0:
+ return;
+ case WAIT_IO_COMPLETION:
+ case WAIT_TIMEOUT:
+ break;
+ default:
+ vd_printf("Wait error (%d)\n", GetLastError());
+ return;
+ }
+ } while (GetTickCount() < start_tick + VD_CLIPBOARD_TIMEOUT_MS);
+
+ vd_printf("wait timeout.. ");
}
void VDAgent::on_clipboard_release()