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)
|
#define DEBUG_X11_CLIPRDR(fmt, ...) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct xf_format_mapping
|
struct xf_cliprdr_format
|
||||||
{
|
{
|
||||||
Atom target_format;
|
UINT32 formatId;
|
||||||
UINT32 format_id;
|
Atom atom;
|
||||||
};
|
};
|
||||||
typedef struct xf_format_mapping xfFormatMapping;
|
typedef struct xf_cliprdr_format xfCliprdrFormat;
|
||||||
|
|
||||||
struct xf_clipboard
|
struct xf_clipboard
|
||||||
{
|
{
|
||||||
|
@ -65,30 +65,29 @@ struct xf_clipboard
|
||||||
rdpChannels* channels;
|
rdpChannels* channels;
|
||||||
CliprdrClientContext* context;
|
CliprdrClientContext* context;
|
||||||
|
|
||||||
UINT32 requestedFormatId;
|
|
||||||
|
|
||||||
Window root_window;
|
Window root_window;
|
||||||
Atom clipboard_atom;
|
Atom clipboard_atom;
|
||||||
Atom property_atom;
|
Atom property_atom;
|
||||||
Atom identity_atom;
|
Atom identity_atom;
|
||||||
|
|
||||||
int num_format_mappings;
|
int numClientFormats;
|
||||||
xfFormatMapping format_mappings[20];
|
xfCliprdrFormat clientFormats[20];
|
||||||
|
|
||||||
/* server->client data */
|
int numServerFormats;
|
||||||
UINT32* formats;
|
CLIPRDR_FORMAT* serverFormats;
|
||||||
int num_formats;
|
|
||||||
|
int numTargets;
|
||||||
Atom targets[20];
|
Atom targets[20];
|
||||||
int num_targets;
|
|
||||||
|
int requestedFormatId;
|
||||||
|
|
||||||
BYTE* data;
|
BYTE* data;
|
||||||
UINT32 data_format;
|
UINT32 data_format;
|
||||||
UINT32 data_alt_format;
|
UINT32 data_alt_format;
|
||||||
int data_length;
|
int data_length;
|
||||||
XEvent* respond;
|
XEvent* respond;
|
||||||
|
|
||||||
/* client->server data */
|
|
||||||
Window owner;
|
Window owner;
|
||||||
int request_index;
|
|
||||||
BOOL sync;
|
BOOL sync;
|
||||||
|
|
||||||
/* INCR mechanism */
|
/* INCR mechanism */
|
||||||
|
@ -210,86 +209,45 @@ static BOOL xf_cliprdr_is_self_owned(xfClipboard* clipboard)
|
||||||
return (id ? TRUE : FALSE);
|
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)
|
format = &(clipboard->clientFormats[index]);
|
||||||
return i;
|
|
||||||
|
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 i, j;
|
||||||
int j;
|
xfCliprdrFormat* format;
|
||||||
|
|
||||||
if (clipboard->formats == NULL)
|
for (i = 0; i < clipboard->numClientFormats; i++)
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (i = 0; i < clipboard->num_format_mappings; i++)
|
|
||||||
{
|
{
|
||||||
if (clipboard->format_mappings[i].target_format != target)
|
format = &(clipboard->clientFormats[i]);
|
||||||
|
|
||||||
|
if (format->atom != atom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (clipboard->format_mappings[i].format_id == CB_FORMAT_RAW)
|
if (format->formatId == CLIPRDR_FORMAT_RAW)
|
||||||
return i;
|
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])
|
if (clipboard->serverFormats[j].formatId == format->formatId)
|
||||||
return i;
|
return format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
static void xf_cliprdr_send_raw_format_list(xfClipboard* clipboard)
|
|
||||||
{
|
|
||||||
Atom type;
|
|
||||||
BYTE* format_data;
|
|
||||||
int format, result;
|
|
||||||
unsigned long length, bytes_left;
|
|
||||||
RDP_CB_FORMAT_LIST_EVENT* event;
|
|
||||||
xfContext* xfc = clipboard->xfc;
|
|
||||||
|
|
||||||
result = XGetWindowProperty(xfc->display, clipboard->root_window,
|
|
||||||
clipboard->property_atom, 0, 3600, 0, XA_STRING,
|
|
||||||
&type, &format, &length, &bytes_left, (BYTE**) &format_data);
|
|
||||||
|
|
||||||
if (result != Success)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "XGetWindowProperty failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DEBUG_X11_CLIPRDR("format=%d len=%d bytes_left=%d", format, (int) length, (int) bytes_left);
|
|
||||||
|
|
||||||
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
|
||||||
CliprdrChannel_FormatList, NULL, NULL);
|
|
||||||
|
|
||||||
event->raw_format_data = (BYTE*) malloc(length);
|
|
||||||
CopyMemory(event->raw_format_data, format_data, length);
|
|
||||||
event->raw_format_data_size = length;
|
|
||||||
XFree(format_data);
|
|
||||||
|
|
||||||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xf_cliprdr_send_null_format_list(xfClipboard* clipboard)
|
|
||||||
{
|
|
||||||
RDP_CB_FORMAT_LIST_EVENT* event;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xf_cliprdr_send_supported_format_list(xfClipboard* clipboard)
|
static void xf_cliprdr_send_supported_format_list(xfClipboard* clipboard)
|
||||||
|
@ -300,11 +258,11 @@ static void xf_cliprdr_send_supported_format_list(xfClipboard* clipboard)
|
||||||
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||||
CliprdrChannel_FormatList, NULL, NULL);
|
CliprdrChannel_FormatList, NULL, NULL);
|
||||||
|
|
||||||
event->formats = (UINT32*) malloc(sizeof(UINT32) * clipboard->num_format_mappings);
|
event->formats = (UINT32*) malloc(sizeof(UINT32) * clipboard->numClientFormats);
|
||||||
event->num_formats = clipboard->num_format_mappings;
|
event->num_formats = clipboard->numClientFormats;
|
||||||
|
|
||||||
for (i = 0; i < clipboard->num_format_mappings; i++)
|
for (i = 0; i < clipboard->numClientFormats; i++)
|
||||||
event->formats[i] = clipboard->format_mappings[i].format_id;
|
event->formats[i] = clipboard->clientFormats[i].formatId;
|
||||||
|
|
||||||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
||||||
}
|
}
|
||||||
|
@ -315,11 +273,44 @@ static void xf_cliprdr_send_format_list(xfClipboard* clipboard)
|
||||||
|
|
||||||
if (xf_cliprdr_is_self_owned(clipboard))
|
if (xf_cliprdr_is_self_owned(clipboard))
|
||||||
{
|
{
|
||||||
xf_cliprdr_send_raw_format_list(clipboard);
|
Atom type;
|
||||||
|
BYTE* format_data;
|
||||||
|
int format, result;
|
||||||
|
unsigned long length, bytes_left;
|
||||||
|
RDP_CB_FORMAT_LIST_EVENT* event;
|
||||||
|
xfContext* xfc = clipboard->xfc;
|
||||||
|
|
||||||
|
result = XGetWindowProperty(xfc->display, clipboard->root_window,
|
||||||
|
clipboard->property_atom, 0, 3600, 0, XA_STRING,
|
||||||
|
&type, &format, &length, &bytes_left, (BYTE**) &format_data);
|
||||||
|
|
||||||
|
if (result != Success)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "XGetWindowProperty failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DEBUG_X11_CLIPRDR("format=%d len=%d bytes_left=%d", format, (int) length, (int) bytes_left);
|
||||||
|
|
||||||
|
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||||
|
CliprdrChannel_FormatList, NULL, NULL);
|
||||||
|
|
||||||
|
event->raw_format_data = (BYTE*) malloc(length);
|
||||||
|
CopyMemory(event->raw_format_data, format_data, length);
|
||||||
|
event->raw_format_data_size = length;
|
||||||
|
XFree(format_data);
|
||||||
|
|
||||||
|
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
||||||
}
|
}
|
||||||
else if (clipboard->owner == None)
|
else if (clipboard->owner == None)
|
||||||
{
|
{
|
||||||
xf_cliprdr_send_null_format_list(clipboard);
|
RDP_CB_FORMAT_LIST_EVENT* event;
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
else if (clipboard->owner != xfc->drawable)
|
else if (clipboard->owner != xfc->drawable)
|
||||||
{
|
{
|
||||||
|
@ -354,11 +345,6 @@ static void xf_cliprdr_send_data_response(xfClipboard* clipboard, BYTE* data, in
|
||||||
freerdp_channels_send_event(clipboard->channels, (wMessage*) event);
|
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)
|
static void xf_cliprdr_process_cb_monitor_ready_event(xfClipboard* clipboard)
|
||||||
{
|
{
|
||||||
xf_cliprdr_send_format_list(clipboard);
|
xf_cliprdr_send_format_list(clipboard);
|
||||||
|
@ -367,40 +353,36 @@ 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)
|
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;
|
xfContext* xfc = clipboard->xfc;
|
||||||
|
|
||||||
DEBUG_X11_CLIPRDR("format %d", event->format);
|
|
||||||
|
|
||||||
if (xf_cliprdr_is_self_owned(clipboard))
|
if (xf_cliprdr_is_self_owned(clipboard))
|
||||||
{
|
{
|
||||||
/* CB_FORMAT_RAW */
|
format = xf_cliprdr_get_format_by_id(clipboard, CLIPRDR_FORMAT_RAW);
|
||||||
i = 0;
|
|
||||||
XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
||||||
XA_INTEGER, 32, PropModeReplace, (BYTE*) &event->format, 1);
|
XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1);
|
||||||
}
|
}
|
||||||
else
|
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_data_response(clipboard, NULL, 0);
|
||||||
xf_cliprdr_send_null_data_response(clipboard);
|
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,
|
XConvertSelection(xfc->display, clipboard->clipboard_atom,
|
||||||
clipboard->format_mappings[i].target_format, clipboard->property_atom,
|
format->atom, clipboard->property_atom, xfc->drawable, CurrentTime);
|
||||||
xfc->drawable, CurrentTime);
|
|
||||||
XFlush(xfc->display);
|
XFlush(xfc->display);
|
||||||
/* After this point, we expect a SelectionNotify event from the clipboard owner. */
|
|
||||||
}
|
/* After this point, we expect a SelectionNotify event from the clipboard owner. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
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,
|
XGetWindowProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
||||||
0, 200, 0, XA_ATOM, &atom, &format, &length, &bytes_left, &data);
|
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)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||||
CliprdrChannel_FormatList, NULL, NULL);
|
CliprdrChannel_FormatList, NULL, NULL);
|
||||||
|
|
||||||
event->formats = (UINT32*) malloc(sizeof(UINT32) * clipboard->num_format_mappings);
|
event->formats = (UINT32*) malloc(sizeof(UINT32) * clipboard->numClientFormats);
|
||||||
num = 0;
|
num = 0;
|
||||||
|
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
atom = ((Atom*) data)[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",
|
event->formats[num++] = clipboard->clientFormats[j].formatId;
|
||||||
clipboard->format_mappings[j].format_id, (int)atom);
|
|
||||||
event->formats[num++] = clipboard->format_mappings[j].format_id;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,7 +431,12 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||||
if (data)
|
if (data)
|
||||||
XFree(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)
|
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL has_data, BYTE* data, int size)
|
||||||
{
|
{
|
||||||
BYTE* outbuf;
|
BYTE* outbuf;
|
||||||
|
xfCliprdrFormat* format;
|
||||||
|
|
||||||
if (clipboard->incr_starts && has_data)
|
if (clipboard->incr_starts && has_data)
|
||||||
return;
|
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;
|
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_PNG:
|
||||||
case CB_FORMAT_JPEG:
|
case CB_FORMAT_JPEG:
|
||||||
case CB_FORMAT_GIF:
|
case CB_FORMAT_GIF:
|
||||||
outbuf = xf_cliprdr_process_requested_raw(data, &size);
|
outbuf = xf_cliprdr_process_requested_raw(data, &size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CB_FORMAT_UNICODETEXT:
|
case CLIPRDR_FORMAT_UNICODETEXT:
|
||||||
outbuf = xf_cliprdr_process_requested_unicodetext(data, &size);
|
outbuf = xf_cliprdr_process_requested_unicodetext(data, &size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CB_FORMAT_TEXT:
|
case CLIPRDR_FORMAT_TEXT:
|
||||||
outbuf = xf_cliprdr_process_requested_text(data, &size);
|
outbuf = xf_cliprdr_process_requested_text(data, &size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -631,7 +615,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL has_d
|
||||||
if (outbuf)
|
if (outbuf)
|
||||||
xf_cliprdr_send_data_response(clipboard, outbuf, size);
|
xf_cliprdr_send_data_response(clipboard, outbuf, size);
|
||||||
else
|
else
|
||||||
xf_cliprdr_send_null_data_response(clipboard);
|
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||||
|
|
||||||
if (!clipboard->xfixes_supported)
|
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)
|
static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
||||||
{
|
{
|
||||||
Atom type;
|
Atom type;
|
||||||
int format;
|
|
||||||
BYTE* data = NULL;
|
BYTE* data = NULL;
|
||||||
BOOL has_data = FALSE;
|
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;
|
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_data_response(clipboard, NULL, 0);
|
||||||
xf_cliprdr_send_null_data_response(clipboard);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
XGetWindowProperty(xfc->display, xfc->drawable,
|
XGetWindowProperty(xfc->display, xfc->drawable,
|
||||||
clipboard->property_atom, 0, 0, 0, target,
|
clipboard->property_atom, 0, 0, 0, target,
|
||||||
&type, &format, &length, &bytes_left, &data);
|
&type, &format_property, &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);
|
|
||||||
|
|
||||||
if (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)
|
if (bytes_left <= 0 && !clipboard->incr_starts)
|
||||||
{
|
{
|
||||||
DEBUG_X11("no data");
|
|
||||||
}
|
}
|
||||||
else if (type == clipboard->incr_atom)
|
else if (type == clipboard->incr_atom)
|
||||||
{
|
{
|
||||||
DEBUG_X11("INCR started");
|
|
||||||
clipboard->incr_starts = TRUE;
|
clipboard->incr_starts = TRUE;
|
||||||
if (clipboard->incr_data)
|
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;
|
bytes_left = clipboard->incr_data_length;
|
||||||
clipboard->incr_data_length = 0;
|
clipboard->incr_data_length = 0;
|
||||||
clipboard->incr_starts = 0;
|
clipboard->incr_starts = 0;
|
||||||
DEBUG_X11("INCR finished");
|
|
||||||
has_data = TRUE;
|
has_data = TRUE;
|
||||||
}
|
}
|
||||||
else if (XGetWindowProperty(xfc->display, xfc->drawable,
|
else if (XGetWindowProperty(xfc->display, xfc->drawable,
|
||||||
clipboard->property_atom, 0, bytes_left, 0, target,
|
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)
|
if (clipboard->incr_starts)
|
||||||
{
|
{
|
||||||
bytes_left = length * format / 8;
|
bytes_left = length * format_property / 8;
|
||||||
DEBUG_X11("%d bytes", (int)bytes_left);
|
|
||||||
clipboard->incr_data = (BYTE*) realloc(clipboard->incr_data, clipboard->incr_data_length + bytes_left);
|
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);
|
CopyMemory(clipboard->incr_data + clipboard->incr_data_length, data, bytes_left);
|
||||||
clipboard->incr_data_length += bytes_left;
|
clipboard->incr_data_length += bytes_left;
|
||||||
|
@ -716,9 +698,10 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_X11_CLIPRDR("XGetWindowProperty failed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XDeleteProperty(xfc->display, xfc->drawable, clipboard->property_atom);
|
XDeleteProperty(xfc->display, xfc->drawable, clipboard->property_atom);
|
||||||
|
|
||||||
xf_cliprdr_process_requested_data(clipboard, has_data, data, (int) bytes_left);
|
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;
|
int i;
|
||||||
|
|
||||||
if (clipboard->num_targets >= ARRAYSIZE(clipboard->targets))
|
if (clipboard->numTargets >= ARRAYSIZE(clipboard->targets))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < clipboard->num_targets; i++)
|
for (i = 0; i < clipboard->numTargets; i++)
|
||||||
{
|
{
|
||||||
if (clipboard->targets[i] == target)
|
if (clipboard->targets[i] == target)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboard->targets[clipboard->num_targets++] = target;
|
clipboard->targets[clipboard->numTargets++] = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xf_cliprdr_provide_targets(xfClipboard* clipboard, XEvent* respond)
|
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)
|
if (respond->xselection.property != None)
|
||||||
{
|
{
|
||||||
XChangeProperty(xfc->display,
|
XChangeProperty(xfc->display, respond->xselection.requestor,
|
||||||
respond->xselection.requestor,
|
respond->xselection.property, XA_ATOM, 32, PropModeReplace,
|
||||||
respond->xselection.property,
|
(BYTE*) clipboard->targets, clipboard->numTargets);
|
||||||
XA_ATOM, 32, PropModeReplace,
|
|
||||||
(BYTE*) clipboard->targets, clipboard->num_targets);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,10 +746,8 @@ static void xf_cliprdr_provide_data(xfClipboard* clipboard, XEvent* respond)
|
||||||
|
|
||||||
if (respond->xselection.property != None)
|
if (respond->xselection.property != None)
|
||||||
{
|
{
|
||||||
XChangeProperty(xfc->display,
|
XChangeProperty(xfc->display, respond->xselection.requestor,
|
||||||
respond->xselection.requestor,
|
respond->xselection.property, respond->xselection.target, 8, PropModeReplace,
|
||||||
respond->xselection.property,
|
|
||||||
respond->xselection.target, 8, PropModeReplace,
|
|
||||||
(BYTE*) clipboard->data, clipboard->data_length);
|
(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;
|
clipboard->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clipboard->formats)
|
if (clipboard->serverFormats)
|
||||||
free(clipboard->formats);
|
{
|
||||||
|
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->formats = NULL;
|
||||||
event->num_formats = 0;
|
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->clientFormats[j].atom);
|
||||||
xf_cliprdr_append_target(clipboard, clipboard->format_mappings[j].target_format);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -811,8 +801,7 @@ static void xf_cliprdr_process_cb_format_list_event(xfClipboard* clipboard, RDP_
|
||||||
if (event->raw_format_data)
|
if (event->raw_format_data)
|
||||||
{
|
{
|
||||||
XChangeProperty(xfc->display, clipboard->root_window, clipboard->property_atom,
|
XChangeProperty(xfc->display, clipboard->root_window, clipboard->property_atom,
|
||||||
XA_STRING, 8, PropModeReplace,
|
XA_STRING, 8, PropModeReplace, event->raw_format_data, event->raw_format_data_size);
|
||||||
event->raw_format_data, event->raw_format_data_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XFlush(xfc->display);
|
XFlush(xfc->display);
|
||||||
|
@ -908,13 +897,8 @@ static void xf_cliprdr_process_cb_data_response_event(xfClipboard* clipboard, RD
|
||||||
{
|
{
|
||||||
xfContext* xfc = clipboard->xfc;
|
xfContext* xfc = clipboard->xfc;
|
||||||
|
|
||||||
DEBUG_X11_CLIPRDR("size=%d", event->size);
|
|
||||||
|
|
||||||
if (!clipboard->respond)
|
if (!clipboard->respond)
|
||||||
{
|
|
||||||
DEBUG_X11_CLIPRDR("unexpected data");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (event->size == 0)
|
if (event->size == 0)
|
||||||
{
|
{
|
||||||
|
@ -930,7 +914,7 @@ static void xf_cliprdr_process_cb_data_response_event(xfClipboard* clipboard, RD
|
||||||
|
|
||||||
switch (clipboard->data_format)
|
switch (clipboard->data_format)
|
||||||
{
|
{
|
||||||
case CB_FORMAT_RAW:
|
case CLIPRDR_FORMAT_RAW:
|
||||||
case CB_FORMAT_PNG:
|
case CB_FORMAT_PNG:
|
||||||
case CB_FORMAT_JPEG:
|
case CB_FORMAT_JPEG:
|
||||||
case CB_FORMAT_GIF:
|
case CB_FORMAT_GIF:
|
||||||
|
@ -940,15 +924,15 @@ static void xf_cliprdr_process_cb_data_response_event(xfClipboard* clipboard, RD
|
||||||
event->size = 0;
|
event->size = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CB_FORMAT_TEXT:
|
case CLIPRDR_FORMAT_TEXT:
|
||||||
xf_cliprdr_process_text(clipboard, event->data, event->size);
|
xf_cliprdr_process_text(clipboard, event->data, event->size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CB_FORMAT_UNICODETEXT:
|
case CLIPRDR_FORMAT_UNICODETEXT:
|
||||||
xf_cliprdr_process_unicodetext(clipboard, event->data, event->size);
|
xf_cliprdr_process_unicodetext(clipboard, event->data, event->size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CB_FORMAT_DIB:
|
case CLIPRDR_FORMAT_DIB:
|
||||||
xf_cliprdr_process_dib(clipboard, event->data, event->size);
|
xf_cliprdr_process_dib(clipboard, event->data, event->size);
|
||||||
break;
|
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);
|
XSendEvent(xfc->display, clipboard->respond->xselection.requestor, 0, 0, clipboard->respond);
|
||||||
XFlush(xfc->display);
|
XFlush(xfc->display);
|
||||||
|
|
||||||
free(clipboard->respond);
|
free(clipboard->respond);
|
||||||
clipboard->respond = NULL;
|
clipboard->respond = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1001,7 +986,6 @@ static BOOL xf_cliprdr_process_selection_notify(xfClipboard* clipboard, XEvent*
|
||||||
{
|
{
|
||||||
if (xevent->xselection.property == None)
|
if (xevent->xselection.property == None)
|
||||||
{
|
{
|
||||||
DEBUG_X11_CLIPRDR("owner not support TARGETS. sending all format.");
|
|
||||||
xf_cliprdr_send_supported_format_list(clipboard);
|
xf_cliprdr_send_supported_format_list(clipboard);
|
||||||
}
|
}
|
||||||
else
|
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)
|
static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* xevent)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int fmt;
|
int fmt;
|
||||||
Atom type;
|
Atom type;
|
||||||
UINT32 format;
|
UINT32 formatId;
|
||||||
XEvent* respond;
|
XEvent* respond;
|
||||||
UINT32 alt_format;
|
UINT32 altFormatId;
|
||||||
BYTE* data = NULL;
|
BYTE* data = NULL;
|
||||||
BOOL delay_respond;
|
BOOL delay_respond;
|
||||||
unsigned long length, bytes_left;
|
unsigned long length;
|
||||||
|
unsigned long bytes_left;
|
||||||
|
xfCliprdrFormat* format;
|
||||||
xfContext* xfc = clipboard->xfc;
|
xfContext* xfc = clipboard->xfc;
|
||||||
|
|
||||||
DEBUG_X11_CLIPRDR("target=%d", (int) xevent->xselectionrequest.target);
|
|
||||||
|
|
||||||
if (xevent->xselectionrequest.owner != xfc->drawable)
|
if (xevent->xselectionrequest.owner != xfc->drawable)
|
||||||
{
|
|
||||||
DEBUG_X11_CLIPRDR("not owner");
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
delay_respond = 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 */
|
if (xevent->xselectionrequest.target == clipboard->targets[0]) /* TIMESTAMP */
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
DEBUG_X11_CLIPRDR("target: TIMESTAMP (unimplemented)");
|
|
||||||
}
|
}
|
||||||
else if (xevent->xselectionrequest.target == clipboard->targets[1]) /* TARGETS */
|
else if (xevent->xselectionrequest.target == clipboard->targets[1]) /* TARGETS */
|
||||||
{
|
{
|
||||||
/* Someone else requests our available formats */
|
/* Someone else requests our available formats */
|
||||||
DEBUG_X11_CLIPRDR("target: TARGETS");
|
|
||||||
respond->xselection.property = xevent->xselectionrequest.property;
|
respond->xselection.property = xevent->xselectionrequest.property;
|
||||||
xf_cliprdr_provide_targets(clipboard, respond);
|
xf_cliprdr_provide_targets(clipboard, respond);
|
||||||
}
|
}
|
||||||
else
|
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 (format && (xevent->xselectionrequest.requestor != xfc->drawable))
|
||||||
|
|
||||||
if (i >= 0 && xevent->xselectionrequest.requestor != xfc->drawable)
|
|
||||||
{
|
{
|
||||||
format = clipboard->format_mappings[i].format_id;
|
formatId = format->formatId;
|
||||||
alt_format = format;
|
altFormatId = formatId;
|
||||||
|
|
||||||
if (format == CB_FORMAT_RAW)
|
if (formatId == CLIPRDR_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor,
|
if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor,
|
||||||
clipboard->property_atom, 0, 4, 0, XA_INTEGER,
|
clipboard->property_atom, 0, 4, 0, XA_INTEGER,
|
||||||
|
@ -1083,14 +1059,12 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||||
}
|
}
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
CopyMemory(&alt_format, data, 4);
|
CopyMemory(&altFormatId, data, 4);
|
||||||
XFree(data);
|
XFree(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_X11_CLIPRDR("provide format 0x%04x alt_format 0x%04x", format, alt_format);
|
if ((clipboard->data != 0) && (formatId == clipboard->data_format) && (altFormatId == clipboard->data_alt_format))
|
||||||
|
|
||||||
if ((clipboard->data != 0) && (format == clipboard->data_format) && (alt_format == clipboard->data_alt_format))
|
|
||||||
{
|
{
|
||||||
/* Cached clipboard data available. Send it now */
|
/* Cached clipboard data available. Send it now */
|
||||||
respond->xselection.property = xevent->xselectionrequest.property;
|
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;
|
respond->xselection.property = xevent->xselectionrequest.property;
|
||||||
clipboard->respond = respond;
|
clipboard->respond = respond;
|
||||||
clipboard->data_format = format;
|
clipboard->data_format = formatId;
|
||||||
clipboard->data_alt_format = alt_format;
|
clipboard->data_alt_format = altFormatId;
|
||||||
delay_respond = TRUE;
|
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)
|
static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* xevent)
|
||||||
{
|
{
|
||||||
|
xfCliprdrFormat* format;
|
||||||
xfContext* xfc = clipboard->xfc;
|
xfContext* xfc = clipboard->xfc;
|
||||||
|
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
|
@ -1157,16 +1132,15 @@ static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* x
|
||||||
|
|
||||||
if (xevent->xproperty.window == clipboard->root_window)
|
if (xevent->xproperty.window == clipboard->root_window)
|
||||||
{
|
{
|
||||||
DEBUG_X11_CLIPRDR("root window PropertyNotify");
|
|
||||||
xf_cliprdr_send_format_list(clipboard);
|
xf_cliprdr_send_format_list(clipboard);
|
||||||
}
|
}
|
||||||
else if (xevent->xproperty.window == xfc->drawable &&
|
else if ((xevent->xproperty.window == xfc->drawable) &&
|
||||||
xevent->xproperty.state == PropertyNewValue &&
|
(xevent->xproperty.state == PropertyNewValue) && clipboard->incr_starts)
|
||||||
clipboard->incr_starts && clipboard->request_index >= 0)
|
|
||||||
{
|
{
|
||||||
DEBUG_X11_CLIPRDR("cliprdr window PropertyNotify");
|
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||||
xf_cliprdr_get_requested_data(clipboard,
|
|
||||||
clipboard->format_mappings[clipboard->request_index].target_format);
|
if (format)
|
||||||
|
xf_cliprdr_get_requested_data(clipboard, format->atom);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1196,7 +1170,9 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event)
|
||||||
if (!xfc || !event)
|
if (!xfc || !event)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(clipboard = (xfClipboard*) xfc->clipboard))
|
clipboard = xfc->clipboard;
|
||||||
|
|
||||||
|
if (!clipboard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef WITH_XFIXES
|
#ifdef WITH_XFIXES
|
||||||
|
@ -1213,7 +1189,7 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clipboard->owner = None;
|
clipboard->owner = None;
|
||||||
xf_cliprdr_check_owner(xfc->clipboard);
|
xf_cliprdr_check_owner(clipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1223,25 +1199,25 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event)
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case SelectionNotify:
|
case SelectionNotify:
|
||||||
xf_cliprdr_process_selection_notify(xfc->clipboard, event);
|
xf_cliprdr_process_selection_notify(clipboard, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionRequest:
|
case SelectionRequest:
|
||||||
xf_cliprdr_process_selection_request(xfc->clipboard, event);
|
xf_cliprdr_process_selection_request(clipboard, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionClear:
|
case SelectionClear:
|
||||||
xf_cliprdr_process_selection_clear(xfc->clipboard, event);
|
xf_cliprdr_process_selection_clear(clipboard, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
xf_cliprdr_process_property_notify(xfc->clipboard, event);
|
xf_cliprdr_process_property_notify(clipboard, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
if (!clipboard->xfixes_supported)
|
if (!clipboard->xfixes_supported)
|
||||||
{
|
{
|
||||||
xf_cliprdr_check_owner(xfc->clipboard);
|
xf_cliprdr_check_owner(clipboard);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1268,7 +1244,7 @@ int xf_cliprdr_send_client_capabilities(xfClipboard* clipboard)
|
||||||
|
|
||||||
int xf_cliprdr_send_client_format_list(xfClipboard* clipboard)
|
int xf_cliprdr_send_client_format_list(xfClipboard* clipboard)
|
||||||
{
|
{
|
||||||
int index;
|
UINT32 index;
|
||||||
CLIPRDR_FORMAT* formats;
|
CLIPRDR_FORMAT* formats;
|
||||||
CLIPRDR_FORMAT_LIST formatList;
|
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_capabilities(clipboard);
|
||||||
xf_cliprdr_send_client_format_list(clipboard);
|
xf_cliprdr_send_client_format_list(clipboard);
|
||||||
|
clipboard->sync = TRUE;
|
||||||
|
|
||||||
return 1;
|
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)
|
static int xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList)
|
||||||
{
|
{
|
||||||
UINT32 index;
|
int i, j;
|
||||||
CLIPRDR_FORMAT* format;
|
CLIPRDR_FORMAT* format;
|
||||||
xfClipboard* clipboard = (xfClipboard*) context->custom;
|
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);
|
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)
|
if (format->formatId == CLIPRDR_FORMAT_UNICODETEXT)
|
||||||
{
|
{
|
||||||
|
@ -1452,7 +1469,7 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||||
channels = ((rdpContext*) xfc)->channels;
|
channels = ((rdpContext*) xfc)->channels;
|
||||||
clipboard->channels = channels;
|
clipboard->channels = channels;
|
||||||
|
|
||||||
clipboard->request_index = -1;
|
clipboard->requestedFormatId = -1;
|
||||||
|
|
||||||
clipboard->root_window = DefaultRootWindow(xfc->display);
|
clipboard->root_window = DefaultRootWindow(xfc->display);
|
||||||
clipboard->clipboard_atom = XInternAtom(xfc->display, "CLIPBOARD", FALSE);
|
clipboard->clipboard_atom = XInternAtom(xfc->display, "CLIPBOARD", FALSE);
|
||||||
|
@ -1496,41 +1513,44 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
n = 0;
|
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++;
|
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++;
|
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++;
|
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++;
|
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++;
|
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++;
|
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++;
|
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[0] = XInternAtom(xfc->display, "TIMESTAMP", FALSE);
|
||||||
clipboard->targets[1] = XInternAtom(xfc->display, "TARGETS", FALSE);
|
clipboard->targets[1] = XInternAtom(xfc->display, "TARGETS", FALSE);
|
||||||
clipboard->num_targets = 2;
|
clipboard->numTargets = 2;
|
||||||
|
|
||||||
clipboard->incr_atom = XInternAtom(xfc->display, "INCR", FALSE);
|
clipboard->incr_atom = XInternAtom(xfc->display, "INCR", FALSE);
|
||||||
|
|
||||||
|
@ -1542,7 +1562,7 @@ void xf_clipboard_free(xfClipboard* clipboard)
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free(clipboard->formats);
|
free(clipboard->serverFormats);
|
||||||
free(clipboard->data);
|
free(clipboard->data);
|
||||||
free(clipboard->respond);
|
free(clipboard->respond);
|
||||||
free(clipboard->incr_data);
|
free(clipboard->incr_data);
|
||||||
|
|
Loading…
Reference in New Issue