mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-04-26 16:46:28 +00:00
[client] spice: added clipboard callbacks to decouple spice from SDL
This commit is contained in:
parent
0dfa7425c1
commit
689a1de69b
@ -486,6 +486,27 @@ static inline const uint32_t mapScancode(SDL_Scancode scancode)
|
|||||||
return ps2;
|
return ps2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool spiceClipboardNotice(const SpiceDataType type)
|
||||||
|
{
|
||||||
|
// we only support text data for now
|
||||||
|
return (type == SPICE_DATA_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spiceClipboardData(const SpiceDataType type, uint8_t * buffer, uint32_t size)
|
||||||
|
{
|
||||||
|
// dos2unix
|
||||||
|
uint8_t * p = buffer;
|
||||||
|
for(uint32_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
uint8_t c = buffer[i];
|
||||||
|
if (c != '\r')
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
SDL_SetClipboardText((char *)buffer);
|
||||||
|
}
|
||||||
|
|
||||||
int eventFilter(void * userdata, SDL_Event * event)
|
int eventFilter(void * userdata, SDL_Event * event)
|
||||||
{
|
{
|
||||||
static bool serverMode = false;
|
static bool serverMode = false;
|
||||||
@ -951,6 +972,7 @@ int run()
|
|||||||
|
|
||||||
if (params.useSpice)
|
if (params.useSpice)
|
||||||
{
|
{
|
||||||
|
spice_set_on_clipboard_cb(spiceClipboardNotice, spiceClipboardData);
|
||||||
if (!spice_connect(params.spiceHost, params.spicePort, ""))
|
if (!spice_connect(params.spiceHost, params.spicePort, ""))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to connect to spice server");
|
DEBUG_ERROR("Failed to connect to spice server");
|
||||||
|
@ -39,8 +39,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <spice/protocol.h>
|
#include <spice/protocol.h>
|
||||||
#include <spice/vd_agent.h>
|
#include <spice/vd_agent.h>
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
|
|
||||||
@ -118,9 +116,12 @@ struct Spice
|
|||||||
bool cbSupported;
|
bool cbSupported;
|
||||||
bool cbSelection;
|
bool cbSelection;
|
||||||
|
|
||||||
char *cbBuffer;
|
SpiceDataType cbType;
|
||||||
uint32_t cbRemain;
|
uint8_t * cbBuffer;
|
||||||
uint32_t cbSize;
|
uint32_t cbRemain;
|
||||||
|
uint32_t cbSize;
|
||||||
|
SpiceClipboardNotice cbNoticeFn;
|
||||||
|
SpiceClipboardData cbDataFn;
|
||||||
};
|
};
|
||||||
|
|
||||||
// globals
|
// globals
|
||||||
@ -146,7 +147,7 @@ bool spice_on_inputs_channel_read();
|
|||||||
bool spice_agent_process (uint32_t dataSize);
|
bool spice_agent_process (uint32_t dataSize);
|
||||||
bool spice_agent_connect ();
|
bool spice_agent_connect ();
|
||||||
bool spice_agent_send_caps(bool request);
|
bool spice_agent_send_caps(bool request);
|
||||||
bool spice_agent_on_clipboard();
|
void spice_agent_on_clipboard();
|
||||||
|
|
||||||
// thread safe read/write methods
|
// thread safe read/write methods
|
||||||
bool spice_write_msg (struct SpiceChannel * channel, uint32_t type, const void * buffer, const ssize_t size);
|
bool spice_write_msg (struct SpiceChannel * channel, uint32_t type, const void * buffer, const ssize_t size);
|
||||||
@ -199,6 +200,12 @@ void spice_disconnect()
|
|||||||
spice_disconnect_channel(&spice.scInputs);
|
spice_disconnect_channel(&spice.scInputs);
|
||||||
|
|
||||||
spice.sessionID = 0;
|
spice.sessionID = 0;
|
||||||
|
|
||||||
|
if (spice.cbBuffer)
|
||||||
|
free(spice.cbBuffer);
|
||||||
|
spice.cbBuffer = NULL;
|
||||||
|
spice.cbRemain = 0;
|
||||||
|
spice.cbSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -919,7 +926,7 @@ bool spice_agent_process(uint32_t dataSize)
|
|||||||
spice.cbSize += r;
|
spice.cbSize += r;
|
||||||
|
|
||||||
if (spice.cbRemain == 0)
|
if (spice.cbRemain == 0)
|
||||||
return spice_agent_on_clipboard();
|
spice_agent_on_clipboard();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1031,7 +1038,7 @@ bool spice_agent_process(uint32_t dataSize)
|
|||||||
|
|
||||||
spice.cbSize = 0;
|
spice.cbSize = 0;
|
||||||
spice.cbRemain = remaining;
|
spice.cbRemain = remaining;
|
||||||
spice.cbBuffer = (char *)malloc(remaining);
|
spice.cbBuffer = (uint8_t *)malloc(remaining);
|
||||||
const uint32_t r = remaining > dataSize ? dataSize : remaining;
|
const uint32_t r = remaining > dataSize ? dataSize : remaining;
|
||||||
|
|
||||||
if (!spice_read_nl(&spice.scMain, spice.cbBuffer, r))
|
if (!spice_read_nl(&spice.scMain, spice.cbBuffer, r))
|
||||||
@ -1048,7 +1055,7 @@ bool spice_agent_process(uint32_t dataSize)
|
|||||||
spice.cbSize += r;
|
spice.cbSize += r;
|
||||||
|
|
||||||
if (spice.cbRemain == 0)
|
if (spice.cbRemain == 0)
|
||||||
return spice_agent_on_clipboard();
|
spice_agent_on_clipboard();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1074,8 +1081,19 @@ bool spice_agent_process(uint32_t dataSize)
|
|||||||
// there is zero documentation on the types field, it might be a bitfield
|
// there is zero documentation on the types field, it might be a bitfield
|
||||||
// but for now we are going to assume it's not.
|
// but for now we are going to assume it's not.
|
||||||
|
|
||||||
// for now we only support text
|
switch(types[0])
|
||||||
if (types[0] == VD_AGENT_CLIPBOARD_UTF8_TEXT)
|
{
|
||||||
|
case VD_AGENT_CLIPBOARD_UTF8_TEXT : spice.cbType = SPICE_DATA_TEXT; break;
|
||||||
|
case VD_AGENT_CLIPBOARD_IMAGE_PNG : spice.cbType = SPICE_DATA_PNG ; break;
|
||||||
|
case VD_AGENT_CLIPBOARD_IMAGE_BMP : spice.cbType = SPICE_DATA_BMP ; break;
|
||||||
|
case VD_AGENT_CLIPBOARD_IMAGE_TIFF: spice.cbType = SPICE_DATA_TIFF; break;
|
||||||
|
case VD_AGENT_CLIPBOARD_IMAGE_JPG : spice.cbType = SPICE_DATA_JPG ; break;
|
||||||
|
default:
|
||||||
|
DEBUG_WARN("Unknown clipboard data type: %u", types[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spice.cbNoticeFn && spice.cbNoticeFn(spice.cbType))
|
||||||
{
|
{
|
||||||
if (spice.cbSelection)
|
if (spice.cbSelection)
|
||||||
{
|
{
|
||||||
@ -1085,7 +1103,7 @@ bool spice_agent_process(uint32_t dataSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VDAgentClipboardRequest req;
|
VDAgentClipboardRequest req;
|
||||||
req.type = VD_AGENT_CLIPBOARD_UTF8_TEXT;
|
req.type = types[0];
|
||||||
|
|
||||||
if (!spice_agent_write_msg(VD_AGENT_CLIPBOARD_REQUEST, &req, sizeof(req)))
|
if (!spice_agent_write_msg(VD_AGENT_CLIPBOARD_REQUEST, &req, sizeof(req)))
|
||||||
{
|
{
|
||||||
@ -1111,25 +1129,15 @@ bool spice_agent_process(uint32_t dataSize)
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
bool spice_agent_on_clipboard()
|
void spice_agent_on_clipboard()
|
||||||
{
|
{
|
||||||
// dos2unix
|
if (spice.cbDataFn)
|
||||||
char * p = spice.cbBuffer;
|
spice.cbDataFn(spice.cbType, spice.cbBuffer, spice.cbSize);
|
||||||
for(uint32_t i = 0; i < spice.cbSize; ++i)
|
|
||||||
{
|
|
||||||
char c = spice.cbBuffer[i];
|
|
||||||
if (c != '\r')
|
|
||||||
*p++ = c;
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
SDL_SetClipboardText(spice.cbBuffer);
|
|
||||||
|
|
||||||
free(spice.cbBuffer);
|
free(spice.cbBuffer);
|
||||||
spice.cbBuffer = NULL;
|
spice.cbBuffer = NULL;
|
||||||
spice.cbSize = 0;
|
spice.cbSize = 0;
|
||||||
spice.cbRemain = 0;
|
spice.cbRemain = 0;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -1459,3 +1467,21 @@ bool spice_mouse_release(uint32_t button)
|
|||||||
|
|
||||||
return spice_write_msg(&spice.scInputs, SPICE_MSGC_INPUTS_MOUSE_RELEASE, &msg, sizeof(msg));
|
return spice_write_msg(&spice.scInputs, SPICE_MSGC_INPUTS_MOUSE_RELEASE, &msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
bool spice_set_on_clipboard_cb(SpiceClipboardNotice cbNoticeFn, SpiceClipboardData cbDataFn)
|
||||||
|
{
|
||||||
|
if ((cbNoticeFn && !cbDataFn) || (cbDataFn && !cbNoticeFn))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Clipboard callback notice and data callbacks must be specified");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
spice.cbNoticeFn = cbNoticeFn;
|
||||||
|
spice.cbDataFn = cbDataFn;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
@ -21,10 +21,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef enum SpiceDataType
|
||||||
|
{
|
||||||
|
SPICE_DATA_TEXT,
|
||||||
|
SPICE_DATA_PNG,
|
||||||
|
SPICE_DATA_BMP,
|
||||||
|
SPICE_DATA_TIFF,
|
||||||
|
SPICE_DATA_JPG
|
||||||
|
}
|
||||||
|
SpiceDataType;
|
||||||
|
|
||||||
|
typedef bool (*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);
|
bool spice_connect(const char * host, const unsigned short port, const char * password);
|
||||||
void spice_disconnect();
|
void spice_disconnect();
|
||||||
bool spice_process();
|
bool spice_process();
|
||||||
bool spice_agent_process();
|
|
||||||
bool spice_ready();
|
bool spice_ready();
|
||||||
|
|
||||||
bool spice_key_down (uint32_t code);
|
bool spice_key_down (uint32_t code);
|
||||||
@ -34,3 +46,6 @@ bool spice_mouse_position(uint32_t x, uint32_t y);
|
|||||||
bool spice_mouse_motion ( int32_t x, int32_t y);
|
bool spice_mouse_motion ( int32_t x, int32_t y);
|
||||||
bool spice_mouse_press (uint32_t button);
|
bool spice_mouse_press (uint32_t button);
|
||||||
bool spice_mouse_release (uint32_t button);
|
bool spice_mouse_release (uint32_t button);
|
||||||
|
|
||||||
|
/* events */
|
||||||
|
bool spice_set_on_clipboard_cb(SpiceClipboardNotice cbNoticeFn, SpiceClipboardData cbDataFn);
|
Loading…
x
Reference in New Issue
Block a user