mirror of https://github.com/FreeRDP/FreeRDP
xfreerdp: further cliprdr refactoring
This commit is contained in:
parent
94da63f980
commit
7a5d45ed34
|
@ -52,12 +52,12 @@
|
|||
#define DEBUG_X11_CLIPRDR(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
struct xf_format_mapping
|
||||
struct xf_cliprdr_format
|
||||
{
|
||||
Atom target_format;
|
||||
UINT32 format_id;
|
||||
UINT32 formatId;
|
||||
Atom atom;
|
||||
};
|
||||
typedef struct xf_format_mapping xfFormatMapping;
|
||||
typedef struct xf_cliprdr_format xfCliprdrFormat;
|
||||
|
||||
struct xf_clipboard
|
||||
{
|
||||
|
@ -65,30 +65,29 @@ struct xf_clipboard
|
|||
rdpChannels* channels;
|
||||
CliprdrClientContext* context;
|
||||
|
||||
UINT32 requestedFormatId;
|
||||
|
||||
Window root_window;
|
||||
Atom clipboard_atom;
|
||||
Atom property_atom;
|
||||
Atom identity_atom;
|
||||
|
||||
int num_format_mappings;
|
||||
xfFormatMapping format_mappings[20];
|
||||
int numClientFormats;
|
||||
xfCliprdrFormat clientFormats[20];
|
||||
|
||||
/* server->client data */
|
||||
UINT32* formats;
|
||||
int num_formats;
|
||||
int numServerFormats;
|
||||
CLIPRDR_FORMAT* serverFormats;
|
||||
|
||||
int numTargets;
|
||||
Atom targets[20];
|
||||
int num_targets;
|
||||
|
||||
int requestedFormatId;
|
||||
|
||||
BYTE* data;
|
||||
UINT32 data_format;
|
||||
UINT32 data_alt_format;
|
||||
int data_length;
|
||||
XEvent* respond;
|
||||
|
||||
/* client->server data */
|
||||
Window owner;
|
||||
int request_index;
|
||||
BOOL sync;
|
||||
|
||||
/* INCR mechanism */
|
||||
|
@ -210,46 +209,69 @@ static BOOL xf_cliprdr_is_self_owned(xfClipboard* clipboard)
|
|||
return (id ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
static int xf_cliprdr_select_format_by_id(xfClipboard* clipboard, UINT32 format_id)
|
||||
static xfCliprdrFormat* xf_cliprdr_get_format_by_id(xfClipboard* clipboard, UINT32 formatId)
|
||||
{
|
||||
int i;
|
||||
UINT32 index;
|
||||
xfCliprdrFormat* format;
|
||||
|
||||
for (i = 0; i < clipboard->num_format_mappings; i++)
|
||||
for (index = 0; index < clipboard->numClientFormats; index++)
|
||||
{
|
||||
if (clipboard->format_mappings[i].format_id == format_id)
|
||||
return i;
|
||||
format = &(clipboard->clientFormats[index]);
|
||||
|
||||
if (format->formatId == formatId)
|
||||
return format;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int xf_cliprdr_select_format_by_atom(xfClipboard* clipboard, Atom target)
|
||||
static xfCliprdrFormat* xf_cliprdr_get_format_by_atom(xfClipboard* clipboard, Atom atom)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int i, j;
|
||||
xfCliprdrFormat* format;
|
||||
|
||||
if (clipboard->formats == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < clipboard->num_format_mappings; i++)
|
||||
for (i = 0; i < clipboard->numClientFormats; i++)
|
||||
{
|
||||
if (clipboard->format_mappings[i].target_format != target)
|
||||
format = &(clipboard->clientFormats[i]);
|
||||
|
||||
if (format->atom != atom)
|
||||
continue;
|
||||
|
||||
if (clipboard->format_mappings[i].format_id == CB_FORMAT_RAW)
|
||||
return i;
|
||||
if (format->formatId == CLIPRDR_FORMAT_RAW)
|
||||
return format;
|
||||
|
||||
for (j = 0; j < clipboard->num_formats; j++)
|
||||
for (j = 0; j < clipboard->numServerFormats; j++)
|
||||
{
|
||||
if (clipboard->format_mappings[i].format_id == clipboard->formats[j])
|
||||
return i;
|
||||
if (clipboard->serverFormats[j].formatId == format->formatId)
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_raw_format_list(xfClipboard* clipboard)
|
||||
static void xf_cliprdr_send_supported_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
int i;
|
||||
RDP_CB_FORMAT_LIST_EVENT* event;
|
||||
|
||||
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_FormatList, NULL, NULL);
|
||||
|
||||
event->formats = (UINT32*) malloc(sizeof(UINT32) * clipboard->numClientFormats);
|
||||
event->num_formats = clipboard->numClientFormats;
|
||||
|
||||
for (i = 0; i < clipboard->numClientFormats; i++)
|
||||
event->formats[i] = clipboard->clientFormats[i].formatId;
|
||||
|
||||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if (xf_cliprdr_is_self_owned(clipboard))
|
||||
{
|
||||
Atom type;
|
||||
BYTE* format_data;
|
||||
|
@ -279,8 +301,7 @@ static void xf_cliprdr_send_raw_format_list(xfClipboard* clipboard)
|
|||
|
||||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_null_format_list(xfClipboard* clipboard)
|
||||
else if (clipboard->owner == None)
|
||||
{
|
||||
RDP_CB_FORMAT_LIST_EVENT* event;
|
||||
|
||||
|
@ -291,36 +312,6 @@ static void xf_cliprdr_send_null_format_list(xfClipboard* clipboard)
|
|||
|
||||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_supported_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
int i;
|
||||
RDP_CB_FORMAT_LIST_EVENT* event;
|
||||
|
||||
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_FormatList, NULL, NULL);
|
||||
|
||||
event->formats = (UINT32*) malloc(sizeof(UINT32) * clipboard->num_format_mappings);
|
||||
event->num_formats = clipboard->num_format_mappings;
|
||||
|
||||
for (i = 0; i < clipboard->num_format_mappings; i++)
|
||||
event->formats[i] = clipboard->format_mappings[i].format_id;
|
||||
|
||||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if (xf_cliprdr_is_self_owned(clipboard))
|
||||
{
|
||||
xf_cliprdr_send_raw_format_list(clipboard);
|
||||
}
|
||||
else if (clipboard->owner == None)
|
||||
{
|
||||
xf_cliprdr_send_null_format_list(clipboard);
|
||||
}
|
||||
else if (clipboard->owner != xfc->drawable)
|
||||
{
|
||||
/* Request the owner for TARGETS, and wait for SelectionNotify event */
|
||||
|
@ -354,11 +345,6 @@ static void xf_cliprdr_send_data_response(xfClipboard* clipboard, BYTE* data, in
|
|||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_null_data_response(xfClipboard* clipboard)
|
||||
{
|
||||
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_process_cb_monitor_ready_event(xfClipboard* clipboard)
|
||||
{
|
||||
xf_cliprdr_send_format_list(clipboard);
|
||||
|
@ -367,41 +353,37 @@ static void xf_cliprdr_process_cb_monitor_ready_event(xfClipboard* clipboard)
|
|||
|
||||
static void xf_cliprdr_process_cb_data_request_event(xfClipboard* clipboard, RDP_CB_DATA_REQUEST_EVENT* event)
|
||||
{
|
||||
int i;
|
||||
xfCliprdrFormat* format = NULL;
|
||||
UINT32 formatId = event->format;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
DEBUG_X11_CLIPRDR("format %d", event->format);
|
||||
|
||||
if (xf_cliprdr_is_self_owned(clipboard))
|
||||
{
|
||||
/* CB_FORMAT_RAW */
|
||||
i = 0;
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, CLIPRDR_FORMAT_RAW);
|
||||
|
||||
XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
||||
XA_INTEGER, 32, PropModeReplace, (BYTE*) &event->format, 1);
|
||||
XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = xf_cliprdr_select_format_by_id(clipboard, event->format);
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, formatId);
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
if (!format)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("unsupported format requested");
|
||||
xf_cliprdr_send_null_data_response(clipboard);
|
||||
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipboard->request_index = i;
|
||||
|
||||
DEBUG_X11_CLIPRDR("target=%d", (int) clipboard->format_mappings[i].target_format);
|
||||
clipboard->requestedFormatId = formatId;
|
||||
|
||||
XConvertSelection(xfc->display, clipboard->clipboard_atom,
|
||||
clipboard->format_mappings[i].target_format, clipboard->property_atom,
|
||||
xfc->drawable, CurrentTime);
|
||||
format->atom, clipboard->property_atom, xfc->drawable, CurrentTime);
|
||||
|
||||
XFlush(xfc->display);
|
||||
|
||||
/* After this point, we expect a SelectionNotify event from the clipboard owner. */
|
||||
}
|
||||
}
|
||||
|
||||
static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
{
|
||||
|
@ -417,29 +399,23 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
|||
XGetWindowProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
||||
0, 200, 0, XA_ATOM, &atom, &format, &length, &bytes_left, &data);
|
||||
|
||||
DEBUG_X11_CLIPRDR("type=%d format=%d length=%d bytes_left=%d",
|
||||
(int) atom, format, (int) length, (int) bytes_left);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_FormatList, NULL, NULL);
|
||||
|
||||
event->formats = (UINT32*) malloc(sizeof(UINT32) * clipboard->num_format_mappings);
|
||||
event->formats = (UINT32*) malloc(sizeof(UINT32) * clipboard->numClientFormats);
|
||||
num = 0;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
atom = ((Atom*) data)[i];
|
||||
DEBUG_X11("atom %d", (int) atom);
|
||||
|
||||
for (j = 0; j < clipboard->num_format_mappings; j++)
|
||||
for (j = 0; j < clipboard->numClientFormats; j++)
|
||||
{
|
||||
if (clipboard->format_mappings[j].target_format == atom)
|
||||
if (clipboard->clientFormats[j].atom == atom)
|
||||
{
|
||||
DEBUG_X11("found format %d for atom %d",
|
||||
clipboard->format_mappings[j].format_id, (int)atom);
|
||||
event->formats[num++] = clipboard->format_mappings[j].format_id;
|
||||
event->formats[num++] = clipboard->clientFormats[j].formatId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +431,12 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
|||
if (data)
|
||||
XFree(data);
|
||||
|
||||
xf_cliprdr_send_null_format_list(clipboard);
|
||||
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_FormatList, NULL, NULL);
|
||||
|
||||
event->num_formats = 0;
|
||||
|
||||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,30 +569,33 @@ static BYTE* xf_cliprdr_process_requested_html(BYTE* data, int* size)
|
|||
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL has_data, BYTE* data, int size)
|
||||
{
|
||||
BYTE* outbuf;
|
||||
xfCliprdrFormat* format;
|
||||
|
||||
if (clipboard->incr_starts && has_data)
|
||||
return;
|
||||
|
||||
if (!has_data || !data)
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (!has_data || !data || !format)
|
||||
{
|
||||
xf_cliprdr_send_null_data_response(clipboard);
|
||||
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (clipboard->format_mappings[clipboard->request_index].format_id)
|
||||
switch (format->formatId)
|
||||
{
|
||||
case CB_FORMAT_RAW:
|
||||
case CLIPRDR_FORMAT_RAW:
|
||||
case CB_FORMAT_PNG:
|
||||
case CB_FORMAT_JPEG:
|
||||
case CB_FORMAT_GIF:
|
||||
outbuf = xf_cliprdr_process_requested_raw(data, &size);
|
||||
break;
|
||||
|
||||
case CB_FORMAT_UNICODETEXT:
|
||||
case CLIPRDR_FORMAT_UNICODETEXT:
|
||||
outbuf = xf_cliprdr_process_requested_unicodetext(data, &size);
|
||||
break;
|
||||
|
||||
case CB_FORMAT_TEXT:
|
||||
case CLIPRDR_FORMAT_TEXT:
|
||||
outbuf = xf_cliprdr_process_requested_text(data, &size);
|
||||
break;
|
||||
|
||||
|
@ -631,7 +615,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL has_d
|
|||
if (outbuf)
|
||||
xf_cliprdr_send_data_response(clipboard, outbuf, size);
|
||||
else
|
||||
xf_cliprdr_send_null_data_response(clipboard);
|
||||
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
|
||||
if (!clipboard->xfixes_supported)
|
||||
{
|
||||
|
@ -643,25 +627,26 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL has_d
|
|||
static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
||||
{
|
||||
Atom type;
|
||||
int format;
|
||||
BYTE* data = NULL;
|
||||
BOOL has_data = FALSE;
|
||||
unsigned long length, bytes_left, dummy;
|
||||
int format_property;
|
||||
unsigned long dummy;
|
||||
unsigned long length;
|
||||
unsigned long bytes_left;
|
||||
xfCliprdrFormat* format;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if ((clipboard->request_index < 0) || (clipboard->format_mappings[clipboard->request_index].target_format != target))
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (!format || (format->atom != target))
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("invalid target");
|
||||
xf_cliprdr_send_null_data_response(clipboard);
|
||||
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
XGetWindowProperty(xfc->display, xfc->drawable,
|
||||
clipboard->property_atom, 0, 0, 0, target,
|
||||
&type, &format, &length, &bytes_left, &data);
|
||||
|
||||
DEBUG_X11_CLIPRDR("type=%d format=%d bytes=%d request_index=%d",
|
||||
(int) type, format, (int) bytes_left, clipboard->request_index);
|
||||
&type, &format_property, &length, &bytes_left, &data);
|
||||
|
||||
if (data)
|
||||
{
|
||||
|
@ -670,11 +655,10 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
|||
}
|
||||
if (bytes_left <= 0 && !clipboard->incr_starts)
|
||||
{
|
||||
DEBUG_X11("no data");
|
||||
|
||||
}
|
||||
else if (type == clipboard->incr_atom)
|
||||
{
|
||||
DEBUG_X11("INCR started");
|
||||
clipboard->incr_starts = TRUE;
|
||||
if (clipboard->incr_data)
|
||||
{
|
||||
|
@ -695,17 +679,15 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
|||
bytes_left = clipboard->incr_data_length;
|
||||
clipboard->incr_data_length = 0;
|
||||
clipboard->incr_starts = 0;
|
||||
DEBUG_X11("INCR finished");
|
||||
has_data = TRUE;
|
||||
}
|
||||
else if (XGetWindowProperty(xfc->display, xfc->drawable,
|
||||
clipboard->property_atom, 0, bytes_left, 0, target,
|
||||
&type, &format, &length, &dummy, &data) == Success)
|
||||
&type, &format_property, &length, &dummy, &data) == Success)
|
||||
{
|
||||
if (clipboard->incr_starts)
|
||||
{
|
||||
bytes_left = length * format / 8;
|
||||
DEBUG_X11("%d bytes", (int)bytes_left);
|
||||
bytes_left = length * format_property / 8;
|
||||
clipboard->incr_data = (BYTE*) realloc(clipboard->incr_data, clipboard->incr_data_length + bytes_left);
|
||||
CopyMemory(clipboard->incr_data + clipboard->incr_data_length, data, bytes_left);
|
||||
clipboard->incr_data_length += bytes_left;
|
||||
|
@ -716,9 +698,10 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
|||
}
|
||||
else
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("XGetWindowProperty failed");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
XDeleteProperty(xfc->display, xfc->drawable, clipboard->property_atom);
|
||||
|
||||
xf_cliprdr_process_requested_data(clipboard, has_data, data, (int) bytes_left);
|
||||
|
@ -733,16 +716,16 @@ static void xf_cliprdr_append_target(xfClipboard* clipboard, Atom target)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (clipboard->num_targets >= ARRAYSIZE(clipboard->targets))
|
||||
if (clipboard->numTargets >= ARRAYSIZE(clipboard->targets))
|
||||
return;
|
||||
|
||||
for (i = 0; i < clipboard->num_targets; i++)
|
||||
for (i = 0; i < clipboard->numTargets; i++)
|
||||
{
|
||||
if (clipboard->targets[i] == target)
|
||||
return;
|
||||
}
|
||||
|
||||
clipboard->targets[clipboard->num_targets++] = target;
|
||||
clipboard->targets[clipboard->numTargets++] = target;
|
||||
}
|
||||
|
||||
static void xf_cliprdr_provide_targets(xfClipboard* clipboard, XEvent* respond)
|
||||
|
@ -751,11 +734,9 @@ static void xf_cliprdr_provide_targets(xfClipboard* clipboard, XEvent* respond)
|
|||
|
||||
if (respond->xselection.property != None)
|
||||
{
|
||||
XChangeProperty(xfc->display,
|
||||
respond->xselection.requestor,
|
||||
respond->xselection.property,
|
||||
XA_ATOM, 32, PropModeReplace,
|
||||
(BYTE*) clipboard->targets, clipboard->num_targets);
|
||||
XChangeProperty(xfc->display, respond->xselection.requestor,
|
||||
respond->xselection.property, XA_ATOM, 32, PropModeReplace,
|
||||
(BYTE*) clipboard->targets, clipboard->numTargets);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -765,10 +746,8 @@ static void xf_cliprdr_provide_data(xfClipboard* clipboard, XEvent* respond)
|
|||
|
||||
if (respond->xselection.property != None)
|
||||
{
|
||||
XChangeProperty(xfc->display,
|
||||
respond->xselection.requestor,
|
||||
respond->xselection.property,
|
||||
respond->xselection.target, 8, PropModeReplace,
|
||||
XChangeProperty(xfc->display, respond->xselection.requestor,
|
||||
respond->xselection.property, respond->xselection.target, 8, PropModeReplace,
|
||||
(BYTE*) clipboard->data, clipboard->data_length);
|
||||
}
|
||||
}
|
||||
|
@ -784,24 +763,35 @@ static void xf_cliprdr_process_cb_format_list_event(xfClipboard* clipboard, RDP_
|
|||
clipboard->data = NULL;
|
||||
}
|
||||
|
||||
if (clipboard->formats)
|
||||
free(clipboard->formats);
|
||||
if (clipboard->serverFormats)
|
||||
{
|
||||
free(clipboard->serverFormats);
|
||||
clipboard->serverFormats = NULL;
|
||||
}
|
||||
|
||||
clipboard->numServerFormats = event->num_formats;
|
||||
clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT));
|
||||
|
||||
if (!clipboard->serverFormats)
|
||||
return;
|
||||
|
||||
for (i = 0; i < clipboard->numServerFormats; i++)
|
||||
{
|
||||
clipboard->serverFormats[i].formatId = event->formats[i];
|
||||
}
|
||||
|
||||
clipboard->formats = event->formats;
|
||||
clipboard->num_formats = event->num_formats;
|
||||
event->formats = NULL;
|
||||
event->num_formats = 0;
|
||||
|
||||
clipboard->num_targets = 2;
|
||||
clipboard->numTargets = 2;
|
||||
|
||||
for (i = 0; i < clipboard->num_formats; i++)
|
||||
for (i = 0; i < clipboard->numServerFormats; i++)
|
||||
{
|
||||
for (j = 0; j < clipboard->num_format_mappings; j++)
|
||||
for (j = 0; j < clipboard->numClientFormats; j++)
|
||||
{
|
||||
if (clipboard->formats[i] == clipboard->format_mappings[j].format_id)
|
||||
if (clipboard->serverFormats[i].formatId == clipboard->clientFormats[j].formatId)
|
||||
{
|
||||
DEBUG_X11("announce format#%d : %d", i, clipboard->formats[i]);
|
||||
xf_cliprdr_append_target(clipboard, clipboard->format_mappings[j].target_format);
|
||||
xf_cliprdr_append_target(clipboard, clipboard->clientFormats[j].atom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -811,8 +801,7 @@ static void xf_cliprdr_process_cb_format_list_event(xfClipboard* clipboard, RDP_
|
|||
if (event->raw_format_data)
|
||||
{
|
||||
XChangeProperty(xfc->display, clipboard->root_window, clipboard->property_atom,
|
||||
XA_STRING, 8, PropModeReplace,
|
||||
event->raw_format_data, event->raw_format_data_size);
|
||||
XA_STRING, 8, PropModeReplace, event->raw_format_data, event->raw_format_data_size);
|
||||
}
|
||||
|
||||
XFlush(xfc->display);
|
||||
|
@ -908,13 +897,8 @@ static void xf_cliprdr_process_cb_data_response_event(xfClipboard* clipboard, RD
|
|||
{
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
DEBUG_X11_CLIPRDR("size=%d", event->size);
|
||||
|
||||
if (!clipboard->respond)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("unexpected data");
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->size == 0)
|
||||
{
|
||||
|
@ -930,7 +914,7 @@ static void xf_cliprdr_process_cb_data_response_event(xfClipboard* clipboard, RD
|
|||
|
||||
switch (clipboard->data_format)
|
||||
{
|
||||
case CB_FORMAT_RAW:
|
||||
case CLIPRDR_FORMAT_RAW:
|
||||
case CB_FORMAT_PNG:
|
||||
case CB_FORMAT_JPEG:
|
||||
case CB_FORMAT_GIF:
|
||||
|
@ -940,15 +924,15 @@ static void xf_cliprdr_process_cb_data_response_event(xfClipboard* clipboard, RD
|
|||
event->size = 0;
|
||||
break;
|
||||
|
||||
case CB_FORMAT_TEXT:
|
||||
case CLIPRDR_FORMAT_TEXT:
|
||||
xf_cliprdr_process_text(clipboard, event->data, event->size);
|
||||
break;
|
||||
|
||||
case CB_FORMAT_UNICODETEXT:
|
||||
case CLIPRDR_FORMAT_UNICODETEXT:
|
||||
xf_cliprdr_process_unicodetext(clipboard, event->data, event->size);
|
||||
break;
|
||||
|
||||
case CB_FORMAT_DIB:
|
||||
case CLIPRDR_FORMAT_DIB:
|
||||
xf_cliprdr_process_dib(clipboard, event->data, event->size);
|
||||
break;
|
||||
|
||||
|
@ -965,6 +949,7 @@ static void xf_cliprdr_process_cb_data_response_event(xfClipboard* clipboard, RD
|
|||
|
||||
XSendEvent(xfc->display, clipboard->respond->xselection.requestor, 0, 0, clipboard->respond);
|
||||
XFlush(xfc->display);
|
||||
|
||||
free(clipboard->respond);
|
||||
clipboard->respond = NULL;
|
||||
}
|
||||
|
@ -1001,7 +986,6 @@ static BOOL xf_cliprdr_process_selection_notify(xfClipboard* clipboard, XEvent*
|
|||
{
|
||||
if (xevent->xselection.property == None)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("owner not support TARGETS. sending all format.");
|
||||
xf_cliprdr_send_supported_format_list(clipboard);
|
||||
}
|
||||
else
|
||||
|
@ -1019,24 +1003,20 @@ static BOOL xf_cliprdr_process_selection_notify(xfClipboard* clipboard, XEvent*
|
|||
|
||||
static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* xevent)
|
||||
{
|
||||
int i;
|
||||
int fmt;
|
||||
Atom type;
|
||||
UINT32 format;
|
||||
UINT32 formatId;
|
||||
XEvent* respond;
|
||||
UINT32 alt_format;
|
||||
UINT32 altFormatId;
|
||||
BYTE* data = NULL;
|
||||
BOOL delay_respond;
|
||||
unsigned long length, bytes_left;
|
||||
unsigned long length;
|
||||
unsigned long bytes_left;
|
||||
xfCliprdrFormat* format;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
DEBUG_X11_CLIPRDR("target=%d", (int) xevent->xselectionrequest.target);
|
||||
|
||||
if (xevent->xselectionrequest.owner != xfc->drawable)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("not owner");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
delay_respond = FALSE;
|
||||
|
||||
|
@ -1053,27 +1033,23 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
|||
if (xevent->xselectionrequest.target == clipboard->targets[0]) /* TIMESTAMP */
|
||||
{
|
||||
/* TODO */
|
||||
DEBUG_X11_CLIPRDR("target: TIMESTAMP (unimplemented)");
|
||||
}
|
||||
else if (xevent->xselectionrequest.target == clipboard->targets[1]) /* TARGETS */
|
||||
{
|
||||
/* Someone else requests our available formats */
|
||||
DEBUG_X11_CLIPRDR("target: TARGETS");
|
||||
respond->xselection.property = xevent->xselectionrequest.property;
|
||||
xf_cliprdr_provide_targets(clipboard, respond);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("target: other");
|
||||
format = xf_cliprdr_get_format_by_atom(clipboard, xevent->xselectionrequest.target);
|
||||
|
||||
i = xf_cliprdr_select_format_by_atom(clipboard, xevent->xselectionrequest.target);
|
||||
|
||||
if (i >= 0 && xevent->xselectionrequest.requestor != xfc->drawable)
|
||||
if (format && (xevent->xselectionrequest.requestor != xfc->drawable))
|
||||
{
|
||||
format = clipboard->format_mappings[i].format_id;
|
||||
alt_format = format;
|
||||
formatId = format->formatId;
|
||||
altFormatId = formatId;
|
||||
|
||||
if (format == CB_FORMAT_RAW)
|
||||
if (formatId == CLIPRDR_FORMAT_RAW)
|
||||
{
|
||||
if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor,
|
||||
clipboard->property_atom, 0, 4, 0, XA_INTEGER,
|
||||
|
@ -1083,14 +1059,12 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
|||
}
|
||||
if (data)
|
||||
{
|
||||
CopyMemory(&alt_format, data, 4);
|
||||
CopyMemory(&altFormatId, data, 4);
|
||||
XFree(data);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_X11_CLIPRDR("provide format 0x%04x alt_format 0x%04x", format, alt_format);
|
||||
|
||||
if ((clipboard->data != 0) && (format == clipboard->data_format) && (alt_format == clipboard->data_alt_format))
|
||||
if ((clipboard->data != 0) && (formatId == clipboard->data_format) && (altFormatId == clipboard->data_alt_format))
|
||||
{
|
||||
/* Cached clipboard data available. Send it now */
|
||||
respond->xselection.property = xevent->xselectionrequest.property;
|
||||
|
@ -1114,11 +1088,11 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
|||
|
||||
respond->xselection.property = xevent->xselectionrequest.property;
|
||||
clipboard->respond = respond;
|
||||
clipboard->data_format = format;
|
||||
clipboard->data_alt_format = alt_format;
|
||||
clipboard->data_format = formatId;
|
||||
clipboard->data_alt_format = altFormatId;
|
||||
delay_respond = TRUE;
|
||||
|
||||
xf_cliprdr_send_data_request(clipboard, alt_format);
|
||||
xf_cliprdr_send_data_request(clipboard, altFormatId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1147,6 +1121,7 @@ static BOOL xf_cliprdr_process_selection_clear(xfClipboard* clipboard, XEvent* x
|
|||
|
||||
static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* xevent)
|
||||
{
|
||||
xfCliprdrFormat* format;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if (!clipboard)
|
||||
|
@ -1157,16 +1132,15 @@ static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* x
|
|||
|
||||
if (xevent->xproperty.window == clipboard->root_window)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("root window PropertyNotify");
|
||||
xf_cliprdr_send_format_list(clipboard);
|
||||
}
|
||||
else if (xevent->xproperty.window == xfc->drawable &&
|
||||
xevent->xproperty.state == PropertyNewValue &&
|
||||
clipboard->incr_starts && clipboard->request_index >= 0)
|
||||
else if ((xevent->xproperty.window == xfc->drawable) &&
|
||||
(xevent->xproperty.state == PropertyNewValue) && clipboard->incr_starts)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("cliprdr window PropertyNotify");
|
||||
xf_cliprdr_get_requested_data(clipboard,
|
||||
clipboard->format_mappings[clipboard->request_index].target_format);
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (format)
|
||||
xf_cliprdr_get_requested_data(clipboard, format->atom);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1196,7 +1170,9 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event)
|
|||
if (!xfc || !event)
|
||||
return;
|
||||
|
||||
if (!(clipboard = (xfClipboard*) xfc->clipboard))
|
||||
clipboard = xfc->clipboard;
|
||||
|
||||
if (!clipboard)
|
||||
return;
|
||||
|
||||
#ifdef WITH_XFIXES
|
||||
|
@ -1213,7 +1189,7 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event)
|
|||
return;
|
||||
|
||||
clipboard->owner = None;
|
||||
xf_cliprdr_check_owner(xfc->clipboard);
|
||||
xf_cliprdr_check_owner(clipboard);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -1223,25 +1199,25 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event)
|
|||
switch (event->type)
|
||||
{
|
||||
case SelectionNotify:
|
||||
xf_cliprdr_process_selection_notify(xfc->clipboard, event);
|
||||
xf_cliprdr_process_selection_notify(clipboard, event);
|
||||
break;
|
||||
|
||||
case SelectionRequest:
|
||||
xf_cliprdr_process_selection_request(xfc->clipboard, event);
|
||||
xf_cliprdr_process_selection_request(clipboard, event);
|
||||
break;
|
||||
|
||||
case SelectionClear:
|
||||
xf_cliprdr_process_selection_clear(xfc->clipboard, event);
|
||||
xf_cliprdr_process_selection_clear(clipboard, event);
|
||||
break;
|
||||
|
||||
case PropertyNotify:
|
||||
xf_cliprdr_process_property_notify(xfc->clipboard, event);
|
||||
xf_cliprdr_process_property_notify(clipboard, event);
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
if (!clipboard->xfixes_supported)
|
||||
{
|
||||
xf_cliprdr_check_owner(xfc->clipboard);
|
||||
xf_cliprdr_check_owner(clipboard);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1268,7 +1244,7 @@ int xf_cliprdr_send_client_capabilities(xfClipboard* clipboard)
|
|||
|
||||
int xf_cliprdr_send_client_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
int index;
|
||||
UINT32 index;
|
||||
CLIPRDR_FORMAT* formats;
|
||||
CLIPRDR_FORMAT_LIST formatList;
|
||||
|
||||
|
@ -1378,6 +1354,7 @@ static int xf_cliprdr_monitor_ready(CliprdrClientContext* context, CLIPRDR_MONIT
|
|||
|
||||
xf_cliprdr_send_client_capabilities(clipboard);
|
||||
xf_cliprdr_send_client_format_list(clipboard);
|
||||
clipboard->sync = TRUE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1391,15 +1368,55 @@ static int xf_cliprdr_server_capabilities(CliprdrClientContext* context, CLIPRDR
|
|||
|
||||
static int xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList)
|
||||
{
|
||||
UINT32 index;
|
||||
int i, j;
|
||||
CLIPRDR_FORMAT* format;
|
||||
xfClipboard* clipboard = (xfClipboard*) context->custom;
|
||||
|
||||
if (clipboard->data)
|
||||
{
|
||||
free(clipboard->data);
|
||||
clipboard->data = NULL;
|
||||
}
|
||||
|
||||
if (clipboard->serverFormats)
|
||||
{
|
||||
free(clipboard->serverFormats);
|
||||
clipboard->serverFormats = NULL;
|
||||
}
|
||||
|
||||
clipboard->numServerFormats = formatList->cFormats;
|
||||
clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT));
|
||||
|
||||
if (!clipboard->serverFormats)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < formatList->cFormats; i++)
|
||||
{
|
||||
format = &formatList->formats[i];
|
||||
clipboard->serverFormats[i].formatId = format->formatId;
|
||||
clipboard->serverFormats[i].formatName = _strdup(format->formatName);
|
||||
}
|
||||
|
||||
clipboard->numTargets = 2;
|
||||
|
||||
for (i = 0; i < formatList->cFormats; i++)
|
||||
{
|
||||
format = &formatList->formats[i];
|
||||
|
||||
for (j = 0; j < clipboard->numClientFormats; j++)
|
||||
{
|
||||
if (format->formatId == clipboard->clientFormats[j].formatId)
|
||||
{
|
||||
xf_cliprdr_append_target(clipboard, clipboard->clientFormats[j].atom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xf_cliprdr_send_client_format_list_response(clipboard, TRUE);
|
||||
|
||||
for (index = 0; index < formatList->cFormats; index++)
|
||||
for (i = 0; i < formatList->cFormats; i++)
|
||||
{
|
||||
format = &formatList->formats[index];
|
||||
format = &formatList->formats[i];
|
||||
|
||||
if (format->formatId == CLIPRDR_FORMAT_UNICODETEXT)
|
||||
{
|
||||
|
@ -1452,7 +1469,7 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
|||
channels = ((rdpContext*) xfc)->channels;
|
||||
clipboard->channels = channels;
|
||||
|
||||
clipboard->request_index = -1;
|
||||
clipboard->requestedFormatId = -1;
|
||||
|
||||
clipboard->root_window = DefaultRootWindow(xfc->display);
|
||||
clipboard->clipboard_atom = XInternAtom(xfc->display, "CLIPBOARD", FALSE);
|
||||
|
@ -1496,41 +1513,44 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
|||
#endif
|
||||
|
||||
n = 0;
|
||||
clipboard->format_mappings[n].target_format = XInternAtom(xfc->display, "_FREERDP_RAW", FALSE);
|
||||
clipboard->format_mappings[n].format_id = CB_FORMAT_RAW;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "_FREERDP_RAW", FALSE);
|
||||
clipboard->clientFormats[n].formatId = CLIPRDR_FORMAT_RAW;
|
||||
n++;
|
||||
clipboard->format_mappings[n].target_format = XInternAtom(xfc->display, "UTF8_STRING", FALSE);
|
||||
clipboard->format_mappings[n].format_id = CB_FORMAT_UNICODETEXT;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "UTF8_STRING", FALSE);
|
||||
clipboard->clientFormats[n].formatId = CLIPRDR_FORMAT_UNICODETEXT;
|
||||
n++;
|
||||
clipboard->format_mappings[n].target_format = XA_STRING;
|
||||
clipboard->format_mappings[n].format_id = CB_FORMAT_TEXT;
|
||||
|
||||
clipboard->clientFormats[n].atom = XA_STRING;
|
||||
clipboard->clientFormats[n].formatId = CLIPRDR_FORMAT_TEXT;
|
||||
n++;
|
||||
clipboard->format_mappings[n].target_format = XInternAtom(xfc->display, "image/png", FALSE);
|
||||
clipboard->format_mappings[n].format_id = CB_FORMAT_PNG;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/png", FALSE);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_PNG;
|
||||
n++;
|
||||
clipboard->format_mappings[n].target_format = XInternAtom(xfc->display, "image/jpeg", FALSE);
|
||||
clipboard->format_mappings[n].format_id = CB_FORMAT_JPEG;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/jpeg", FALSE);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_JPEG;
|
||||
n++;
|
||||
clipboard->format_mappings[n].target_format = XInternAtom(xfc->display, "image/gif", FALSE);
|
||||
clipboard->format_mappings[n].format_id = CB_FORMAT_GIF;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/gif", FALSE);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_GIF;
|
||||
n++;
|
||||
clipboard->format_mappings[n].target_format = XInternAtom(xfc->display, "image/bmp", FALSE);
|
||||
clipboard->format_mappings[n].format_id = CB_FORMAT_DIB;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/bmp", FALSE);
|
||||
clipboard->clientFormats[n].formatId = CLIPRDR_FORMAT_DIB;
|
||||
n++;
|
||||
clipboard->format_mappings[n].target_format = XInternAtom(xfc->display, "text/html", FALSE);
|
||||
clipboard->format_mappings[n].format_id = CB_FORMAT_HTML;
|
||||
|
||||
clipboard->num_format_mappings = n + 1;
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/html", FALSE);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_HTML;
|
||||
n++;
|
||||
|
||||
clipboard->numClientFormats = n;
|
||||
|
||||
clipboard->targets[0] = XInternAtom(xfc->display, "TIMESTAMP", FALSE);
|
||||
clipboard->targets[1] = XInternAtom(xfc->display, "TARGETS", FALSE);
|
||||
clipboard->num_targets = 2;
|
||||
clipboard->numTargets = 2;
|
||||
|
||||
clipboard->incr_atom = XInternAtom(xfc->display, "INCR", FALSE);
|
||||
|
||||
|
@ -1542,7 +1562,7 @@ void xf_clipboard_free(xfClipboard* clipboard)
|
|||
if (!clipboard)
|
||||
return;
|
||||
|
||||
free(clipboard->formats);
|
||||
free(clipboard->serverFormats);
|
||||
free(clipboard->data);
|
||||
free(clipboard->respond);
|
||||
free(clipboard->incr_data);
|
||||
|
|
Loading…
Reference in New Issue