Window root_window;
Atom clipboard_atom;
Atom property_atom;
- Atom identity_atom;
int numClientFormats;
xfCliprdrFormat clientFormats[20];
BOOL xfixes_supported;
};
-int xf_cliprdr_send_client_format_list(xfClipboard* clipboard);
+UINT xf_cliprdr_send_client_format_list(xfClipboard* clipboard);
static void xf_cliprdr_check_owner(xfClipboard* clipboard)
{
static BOOL xf_cliprdr_is_self_owned(xfClipboard* clipboard)
{
- Atom type;
- UINT32 id = 0;
- UINT32* pid = NULL;
- int format, result = 0;
- unsigned long length;
- unsigned long bytes_left;
xfContext* xfc = clipboard->xfc;
- clipboard->owner = XGetSelectionOwner(xfc->display, clipboard->clipboard_atom);
-
- if (clipboard->owner != None)
- {
- result = XGetWindowProperty(xfc->display, clipboard->owner,
- clipboard->identity_atom, 0, 4, 0, XA_INTEGER,
- &type, &format, &length, &bytes_left, (BYTE**) &pid);
- }
-
- if (pid)
- {
- id = *pid;
- XFree(pid);
- }
-
- if ((clipboard->owner == None) || (clipboard->owner == xfc->drawable))
- return FALSE;
-
- if (result != Success)
- return FALSE;
-
- return (id ? TRUE : FALSE);
+ return XGetSelectionOwner(xfc->display, clipboard->clipboard_atom) == xfc->drawable;
}
static xfCliprdrFormat* xf_cliprdr_get_format_by_id(xfClipboard* clipboard, UINT32 formatId)
return NULL;
}
-static void xf_cliprdr_send_data_request(xfClipboard* clipboard, UINT32 formatId)
+/**
+ * Function description
+ *
+ * @return 0 on success, otherwise a Win32 error code
+ */
+static UINT xf_cliprdr_send_data_request(xfClipboard* clipboard, UINT32 formatId)
{
CLIPRDR_FORMAT_DATA_REQUEST request;
request.requestedFormatId = formatId;
- clipboard->context->ClientFormatDataRequest(clipboard->context, &request);
+ return clipboard->context->ClientFormatDataRequest(clipboard->context, &request);
}
-static void xf_cliprdr_send_data_response(xfClipboard* clipboard, BYTE* data, int size)
+/**
+ * Function description
+ *
+ * @return 0 on success, otherwise a Win32 error code
+ */
+static UINT xf_cliprdr_send_data_response(xfClipboard* clipboard, BYTE* data, int size)
{
CLIPRDR_FORMAT_DATA_RESPONSE response;
response.dataLen = size;
response.requestedFormatData = data;
- clipboard->context->ClientFormatDataResponse(clipboard->context, &response);
+ return clipboard->context->ClientFormatDataResponse(clipboard->context, &response);
}
static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
0, 200, 0, XA_ATOM, &atom, &format_property, &length, &bytes_left, &data);
if (length > 0)
- formats = (CLIPRDR_FORMAT*) calloc(length, sizeof(CLIPRDR_FORMAT));
+ {
+ if (!data)
+ {
+ WLog_ERR(TAG, "XGetWindowProperty set length = %d but data is NULL", length);
+ goto out;
+ }
+ if (!(formats = (CLIPRDR_FORMAT*) calloc(length, sizeof(CLIPRDR_FORMAT))))
+ {
+ WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", length);
+ goto out;
+ }
+ }
for (i = 0; i < length; i++)
{
}
}
- XFree(data);
-
ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
formatList.msgFlags = CB_RESPONSE_OK;
clipboard->context->ClientFormatList(clipboard->context, &formatList);
+out:
+ if (data)
+ XFree(data);
free(formats);
}
delayRespond = FALSE;
- respond = (XEvent*) calloc(1, sizeof(XEvent));
+ if (!(respond = (XEvent*) calloc(1, sizeof(XEvent))))
+ {
+ WLog_ERR(TAG, "failed to allocate XEvent data");
+ return FALSE;
+ }
respond->xselection.property = None;
respond->xselection.type = SelectionNotify;
}
}
-int xf_cliprdr_send_client_capabilities(xfClipboard* clipboard)
+/**
+ * Function description
+ *
+ * @return 0 on success, otherwise a Win32 error code
+ */
+UINT xf_cliprdr_send_client_capabilities(xfClipboard* clipboard)
{
CLIPRDR_CAPABILITIES capabilities;
CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet;
generalCapabilitySet.version = CB_CAPS_VERSION_2;
generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES;
- clipboard->context->ClientCapabilities(clipboard->context, &capabilities);
-
- return 1;
+ return clipboard->context->ClientCapabilities(clipboard->context, &capabilities);
}
-int xf_cliprdr_send_client_format_list(xfClipboard* clipboard)
+/**
+ * Function description
+ *
+ * @return 0 on success, otherwise a Win32 error code
+ */
+UINT xf_cliprdr_send_client_format_list(xfClipboard* clipboard)
{
UINT32 i, numFormats;
- CLIPRDR_FORMAT* formats;
+ CLIPRDR_FORMAT* formats = NULL;
CLIPRDR_FORMAT_LIST formatList;
xfContext* xfc = clipboard->xfc;
+ UINT ret;
ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
numFormats = clipboard->numClientFormats;
- formats = (CLIPRDR_FORMAT*) calloc(numFormats, sizeof(CLIPRDR_FORMAT));
+ if (numFormats)
+ {
+ if (!(formats = (CLIPRDR_FORMAT*) calloc(numFormats, sizeof(CLIPRDR_FORMAT))))
+ {
+ WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", numFormats);
+ return CHANNEL_RC_NO_MEMORY;
+ }
+ }
for (i = 0; i < numFormats; i++)
{
formatList.numFormats = numFormats;
formatList.formats = formats;
- clipboard->context->ClientFormatList(clipboard->context, &formatList);
+ ret = clipboard->context->ClientFormatList(clipboard->context, &formatList);
free(formats);
clipboard->targets[1], clipboard->property_atom, xfc->drawable, CurrentTime);
}
- return 1;
+ return ret;
}
-int xf_cliprdr_send_client_format_list_response(xfClipboard* clipboard, BOOL status)
+/**
+ * Function description
+ *
+ * @return 0 on success, otherwise a Win32 error code
+ */
+UINT xf_cliprdr_send_client_format_list_response(xfClipboard* clipboard, BOOL status)
{
CLIPRDR_FORMAT_LIST_RESPONSE formatListResponse;
formatListResponse.msgFlags = status ? CB_RESPONSE_OK : CB_RESPONSE_FAIL;
formatListResponse.dataLen = 0;
- clipboard->context->ClientFormatListResponse(clipboard->context, &formatListResponse);
-
- return 1;
+ return clipboard->context->ClientFormatListResponse(clipboard->context, &formatListResponse);
}
+/**
+ * Function description
+ *
+ * @return 0 on success, otherwise a Win32 error code
+ */
int xf_cliprdr_send_client_format_data_request(xfClipboard* clipboard, UINT32 formatId)
{
CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
formatDataRequest.requestedFormatId = formatId;
clipboard->requestedFormatId = formatId;
- clipboard->context->ClientFormatDataRequest(clipboard->context, &formatDataRequest);
-
- return 1;
+ return clipboard->context->ClientFormatDataRequest(clipboard->context, &formatDataRequest);
}
/**
static UINT xf_cliprdr_monitor_ready(CliprdrClientContext* context, CLIPRDR_MONITOR_READY* monitorReady)
{
xfClipboard* clipboard = (xfClipboard*) context->custom;
+ UINT ret;
+
+ if ((ret = xf_cliprdr_send_client_capabilities(clipboard)) != CHANNEL_RC_OK)
+ return ret;
+ if ((ret = xf_cliprdr_send_client_format_list(clipboard)) != CHANNEL_RC_OK)
+ return ret;
- xf_cliprdr_send_client_capabilities(clipboard);
- xf_cliprdr_send_client_format_list(clipboard);
clipboard->sync = TRUE;
return CHANNEL_RC_OK;
CLIPRDR_FORMAT* format;
xfClipboard* clipboard = (xfClipboard*) context->custom;
xfContext* xfc = clipboard->xfc;
+ UINT ret;
if (clipboard->data)
{
}
clipboard->numServerFormats = formatList->numFormats;
- clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT));
- if (!clipboard->serverFormats)
- return CHANNEL_RC_NO_MEMORY;
+ if (clipboard->numServerFormats)
+ {
+ if (!(clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT)))) {
+ WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", clipboard->numServerFormats);
+ return CHANNEL_RC_NO_MEMORY;
+ }
+ }
for (i = 0; i < formatList->numFormats; i++)
{
clipboard->numServerFormats = 0;
free(clipboard->serverFormats);
clipboard->serverFormats = NULL;
- return -1;
+ return CHANNEL_RC_NO_MEMORY;
}
}
}
}
}
- xf_cliprdr_send_client_format_list_response(clipboard, TRUE);
+ ret = xf_cliprdr_send_client_format_list_response(clipboard, TRUE);
XSetSelectionOwner(xfc->display, clipboard->clipboard_atom, xfc->drawable, CurrentTime);
XFlush(xfc->display);
- return CHANNEL_RC_OK;
+ return ret;
}
/**
XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1);
}
else
- {
format = xf_cliprdr_get_format_by_id(clipboard, formatId);
- }
if (!format)
- {
- xf_cliprdr_send_data_response(clipboard, NULL, 0);
- return CHANNEL_RC_OK;
- }
+ return xf_cliprdr_send_data_response(clipboard, NULL, 0);
clipboard->requestedFormatId = formatId;
xfClipboard* xf_clipboard_new(xfContext* xfc)
{
int n;
- UINT32 id;
rdpChannels* channels;
xfClipboard* clipboard;
- clipboard = (xfClipboard*) calloc(1, sizeof(xfClipboard));
+ if (!(clipboard = (xfClipboard*) calloc(1, sizeof(xfClipboard))))
+ {
+ WLog_ERR(TAG, "failed to allocate xfClipboard data");
+ return NULL;
+ }
xfc->clipboard = clipboard;
return NULL;
}
- id = 1;
clipboard->property_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR", FALSE);
- clipboard->identity_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_ID", FALSE);
-
- XChangeProperty(xfc->display, xfc->drawable, clipboard->identity_atom,
- XA_INTEGER, 32, PropModeReplace, (BYTE*) &id, 1);
XSelectInput(xfc->display, clipboard->root_window, PropertyChangeMask);