diff --git a/client/main.c b/client/main.c index 08708643..f300b173 100644 --- a/client/main.c +++ b/client/main.c @@ -487,10 +487,11 @@ static inline const uint32_t mapScancode(SDL_Scancode scancode) } -bool spiceClipboardNotice(const SpiceDataType type) +void spiceClipboardNotice(const SpiceDataType type) { // we only support text data for now - return (type == SPICE_DATA_TEXT); + if (type == SPICE_DATA_TEXT) + spice_clipboard_request(type); } void spiceClipboardData(const SpiceDataType type, uint8_t * buffer, uint32_t size) diff --git a/client/spice/spice.c b/client/spice/spice.c index a6adbd38..55ebdf32 100644 --- a/client/spice/spice.c +++ b/client/spice/spice.c @@ -116,6 +116,7 @@ struct Spice bool cbSupported; bool cbSelection; + bool cbGrabbed; SpiceDataType cbType; uint8_t * cbBuffer; uint32_t cbRemain; @@ -1007,6 +1008,7 @@ bool spice_agent_process(uint32_t dataSize) if (msg.type == VD_AGENT_CLIPBOARD_RELEASE) { DEBUG_PROTO("VD_AGENT_CLIPBOARD_RELEASE"); + spice.cbGrabbed = false; return true; } @@ -1093,28 +1095,17 @@ bool spice_agent_process(uint32_t dataSize) return true; } - if (spice.cbNoticeFn && spice.cbNoticeFn(spice.cbType)) + spice.cbGrabbed = true; + if (spice.cbSelection) { - if (spice.cbSelection) - { - // Windows doesnt support this, so until it's needed no point messing with it - DEBUG_ERROR("Fixme!"); - return false; - } - - VDAgentClipboardRequest req; - req.type = types[0]; - - if (!spice_agent_write_msg(VD_AGENT_CLIPBOARD_REQUEST, &req, sizeof(req))) - { - DEBUG_ERROR("failed to request clipboard data"); - free(types); - return false; - } - - return true; + // Windows doesnt support this, so until it's needed there is no point messing with it + DEBUG_ERROR("Fixme!"); + return false; } + if (spice.cbNoticeFn) + spice.cbNoticeFn(spice.cbType); + free(types); return true; } @@ -1470,6 +1461,45 @@ bool spice_mouse_release(uint32_t button) // ============================================================================ +bool spice_clipboard_request(SpiceDataType type) +{ + VDAgentClipboardRequest req; + + if (!spice.cbGrabbed) + { + DEBUG_ERROR("the agent has not grabbed any data yet"); + return false; + } + + if (type != spice.cbType) + { + DEBUG_ERROR("data type requested doesn't match reported data type"); + return false; + } + + switch(type) + { + case SPICE_DATA_TEXT: req.type = VD_AGENT_CLIPBOARD_UTF8_TEXT ; break; + case SPICE_DATA_PNG : req.type = VD_AGENT_CLIPBOARD_IMAGE_PNG ; break; + case SPICE_DATA_BMP : req.type = VD_AGENT_CLIPBOARD_IMAGE_BMP ; break; + case SPICE_DATA_TIFF: req.type = VD_AGENT_CLIPBOARD_IMAGE_TIFF; break; + case SPICE_DATA_JPG : req.type = VD_AGENT_CLIPBOARD_IMAGE_JPG ; break; + default: + DEBUG_ERROR("invalid clipboard data type requested"); + return false; + } + + if (!spice_agent_write_msg(VD_AGENT_CLIPBOARD_REQUEST, &req, sizeof(req))) + { + DEBUG_ERROR("failed to request clipboard data"); + return false; + } + + return true; +} + +// ============================================================================ + bool spice_set_on_clipboard_cb(SpiceClipboardNotice cbNoticeFn, SpiceClipboardData cbDataFn) { if ((cbNoticeFn && !cbDataFn) || (cbDataFn && !cbNoticeFn)) diff --git a/client/spice/spice.h b/client/spice/spice.h index e8df09be..3444026a 100644 --- a/client/spice/spice.h +++ b/client/spice/spice.h @@ -31,7 +31,7 @@ typedef enum SpiceDataType } SpiceDataType; -typedef bool (*SpiceClipboardNotice)(const SpiceDataType type); +typedef void (*SpiceClipboardNotice)(const SpiceDataType type); typedef void (*SpiceClipboardData )(const SpiceDataType type, uint8_t * buffer, uint32_t size); bool spice_connect(const char * host, const unsigned short port, const char * password); @@ -47,5 +47,7 @@ bool spice_mouse_motion ( int32_t x, int32_t y); bool spice_mouse_press (uint32_t button); bool spice_mouse_release (uint32_t button); +bool spice_clipboard_request(SpiceDataType type); + /* events */ bool spice_set_on_clipboard_cb(SpiceClipboardNotice cbNoticeFn, SpiceClipboardData cbDataFn); \ No newline at end of file