diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2012-05-25 20:02:54 +0200 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@gmail.com> | 2012-05-25 20:21:54 +0200 |
commit | 0cef8ba42b88132343306d1dca097f5cb61e493b (patch) | |
tree | 69b5b889cecc1d3ed169da47f0fe609960f3d9e1 /vdagent | |
parent | 7d75ac51cc8ffa85e47fee57265b0277870712ee (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.cpp | 23 |
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() |