Exemplo n.º 1
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context,
        CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
{
	BOOL rawTransfer;
	xfCliprdrFormat* format = NULL;
	UINT32 formatId = formatDataRequest->requestedFormatId;
	xfClipboard* clipboard = (xfClipboard*) context->custom;
	xfContext* xfc = clipboard->xfc;
	rawTransfer = xf_cliprdr_is_raw_transfer_available(clipboard);

	if (rawTransfer)
	{
		format = xf_cliprdr_get_client_format_by_id(clipboard, CF_RAW);
		XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom,
		                XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1);
	}
	else
		format = xf_cliprdr_get_client_format_by_id(clipboard, formatId);

	if (!format)
		return xf_cliprdr_send_data_response(clipboard, NULL, 0);

	clipboard->requestedFormatId = rawTransfer ? CF_RAW : formatId;
	XConvertSelection(xfc->display, clipboard->clipboard_atom,
	                  format->atom, clipboard->property_atom, xfc->drawable, CurrentTime);
	XFlush(xfc->display);
	/* After this point, we expect a SelectionNotify event from the clipboard owner. */
	return CHANNEL_RC_OK;
}
Exemplo n.º 2
0
static void xf_cliprdr_process_requested_data(xfInfo* xfi, boolean has_data, uint8* data, int size)
{
	uint8* outbuf;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	if (cb->incr_starts && has_data)
		return;

	if (!has_data || data == NULL)
	{
		xf_cliprdr_send_null_data_response(xfi);
		return;
	}

	switch (cb->format_mappings[cb->request_index].format_id)
	{
		case CB_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:
			outbuf = xf_cliprdr_process_requested_unicodetext(data, &size);
			break;

		case CB_FORMAT_TEXT:
			outbuf = xf_cliprdr_process_requested_text(data, &size);
			break;

		case CB_FORMAT_DIB:
			outbuf = xf_cliprdr_process_requested_dib(data, &size);
			break;

		case CB_FORMAT_HTML:
			outbuf = xf_cliprdr_process_requested_html(data, &size);
			break;

		default:
			outbuf = NULL;
			break;
	}

	if (outbuf)
	{
		xf_cliprdr_send_data_response(xfi, outbuf, size);
	}
	else
	{
		xf_cliprdr_send_null_data_response(xfi);
	}

	/* Resend the format list, otherwise the server won't request again for the next paste */
	xf_cliprdr_send_format_list(xfi);
}
Exemplo n.º 3
0
static int xf_cliprdr_server_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
{
	xfCliprdrFormat* format = NULL;
	UINT32 formatId = formatDataRequest->requestedFormatId;
	xfClipboard* clipboard = (xfClipboard*) context->custom;
	xfContext* xfc = clipboard->xfc;

	if (xf_cliprdr_is_self_owned(clipboard))
	{
		format = xf_cliprdr_get_format_by_id(clipboard, 0);

		XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom,
			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 1;
	}

	clipboard->requestedFormatId = formatId;

	XConvertSelection(xfc->display, clipboard->clipboard_atom,
		format->atom, clipboard->property_atom, xfc->drawable, CurrentTime);

	XFlush(xfc->display);

	/* After this point, we expect a SelectionNotify event from the clipboard owner. */

	return 1;
}
Exemplo n.º 4
0
static void xf_cliprdr_send_null_data_response(xfInfo* xfi)
{
	xf_cliprdr_send_data_response(xfi, NULL, 0);
}
Exemplo n.º 5
0
static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
{
	Atom type;
	BYTE* data = NULL;
	BOOL has_data = FALSE;
	int format_property;
	unsigned long dummy;
	unsigned long length;
	unsigned long bytes_left;
	xfCliprdrFormat* format;
	xfContext* xfc = clipboard->xfc;

	format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);

	if (!format || (format->atom != target))
	{
		xf_cliprdr_send_data_response(clipboard, NULL, 0);
		return FALSE;
	}

	XGetWindowProperty(xfc->display, xfc->drawable,
		clipboard->property_atom, 0, 0, 0, target,
		&type, &format_property, &length, &bytes_left, &data);

	if (data)
	{
		XFree(data);
		data = NULL;
	}

	if (bytes_left <= 0 && !clipboard->incr_starts)
	{

	}
	else if (type == clipboard->incr_atom)
	{
		clipboard->incr_starts = TRUE;

		if (clipboard->incr_data)
		{
			free(clipboard->incr_data);
			clipboard->incr_data = NULL;
		}

		clipboard->incr_data_length = 0;
		has_data = TRUE; /* data will be followed in PropertyNotify event */
	}
	else
	{
		if (bytes_left <= 0)
		{
			/* INCR finish */
			data = clipboard->incr_data;
			clipboard->incr_data = NULL;
			bytes_left = clipboard->incr_data_length;
			clipboard->incr_data_length = 0;
			clipboard->incr_starts = 0;
			has_data = TRUE;
		}
		else if (XGetWindowProperty(xfc->display, xfc->drawable,
			clipboard->property_atom, 0, bytes_left, 0, target,
			&type, &format_property, &length, &dummy, &data) == Success)
		{
			if (clipboard->incr_starts)
			{
				BYTE *new_data;

				bytes_left = length * format_property / 8;
				new_data = (BYTE*) realloc(clipboard->incr_data, clipboard->incr_data_length + bytes_left);
				if (!new_data)
					return FALSE;
				clipboard->incr_data = new_data;
				CopyMemory(clipboard->incr_data + clipboard->incr_data_length, data, bytes_left);
				clipboard->incr_data_length += bytes_left;
				XFree(data);
				data = NULL;
			}
			has_data = TRUE;
		}
		else
		{

		}
	}

	XDeleteProperty(xfc->display, xfc->drawable, clipboard->property_atom);

	xf_cliprdr_process_requested_data(clipboard, has_data, data, (int) bytes_left);

	if (data)
		XFree(data);

	return TRUE;
}
Exemplo n.º 6
0
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasData, BYTE* data, int size)
{
	BOOL bSuccess;
	UINT32 SrcSize;
	UINT32 DstSize;
	UINT32 formatId;
	UINT32 altFormatId;
	BYTE* pSrcData = NULL;
	BYTE* pDstData = NULL;
	xfCliprdrFormat* format;

	if (clipboard->incr_starts && hasData)
		return;

	format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);

	if (!hasData || !data || !format)
	{
		xf_cliprdr_send_data_response(clipboard, NULL, 0);
		return;
	}

	formatId = 0;
	altFormatId = 0;

	switch (format->formatId)
	{
		case CF_TEXT:
		case CF_OEMTEXT:
		case CF_UNICODETEXT:
			size = strlen((char*) data) + 1;
			formatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
			break;

		case CF_DIB:
			formatId = ClipboardGetFormatId(clipboard->system, "image/bmp");
			break;

		case CB_FORMAT_HTML:
			size = strlen((char*) data) + 1;
			formatId = ClipboardGetFormatId(clipboard->system, "text/html");
			break;
	}

	SrcSize = (UINT32) size;
	pSrcData = (BYTE*) malloc(SrcSize);

	if (!pSrcData)
		return;

	CopyMemory(pSrcData, data, SrcSize);

	bSuccess = ClipboardSetData(clipboard->system, formatId, (void*) pSrcData, SrcSize);

	if (!bSuccess)
		free(pSrcData);

	altFormatId = clipboard->requestedFormatId;

	if (bSuccess && altFormatId)
	{
		DstSize = 0;
		pDstData = (BYTE*) ClipboardGetData(clipboard->system, altFormatId, &DstSize);
	}

	if (!pDstData)
	{
		xf_cliprdr_send_data_response(clipboard, NULL, 0);
		return;
	}

	xf_cliprdr_send_data_response(clipboard, pDstData, (int) DstSize);
	free(pDstData);
}
Exemplo n.º 7
0
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard,
        BOOL hasData, BYTE* data, int size)
{
	BOOL bSuccess;
	UINT32 SrcSize;
	UINT32 DstSize;
	UINT32 srcFormatId;
	UINT32 dstFormatId;
	BYTE* pDstData = NULL;
	xfCliprdrFormat* format;

	if (clipboard->incr_starts && hasData)
		return;

	format = xf_cliprdr_get_client_format_by_id(clipboard,
	         clipboard->requestedFormatId);

	if (!hasData || !data || !format)
	{
		xf_cliprdr_send_data_response(clipboard, NULL, 0);
		return;
	}

	srcFormatId = 0;

	switch (format->formatId)
	{
		case CF_RAW:
			srcFormatId = CF_RAW;
			break;

		case CF_TEXT:
		case CF_OEMTEXT:
		case CF_UNICODETEXT:
			size = strlen((char*) data) + 1;
			srcFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
			break;

		case CF_DIB:
			srcFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp");
			break;

		case CB_FORMAT_HTML:
			srcFormatId = ClipboardGetFormatId(clipboard->system, "text/html");
			break;

		case CB_FORMAT_TEXTURILIST:
			srcFormatId = ClipboardGetFormatId(clipboard->system, "text/uri-list");
			break;
	}

	SrcSize = (UINT32) size;
	bSuccess = ClipboardSetData(clipboard->system, srcFormatId, data, SrcSize);

	if (format->formatName)
		dstFormatId = ClipboardGetFormatId(clipboard->system, format->formatName);
	else
		dstFormatId = format->formatId;

	if (bSuccess)
	{
		DstSize = 0;
		pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
	}

	if (!pDstData)
	{
		xf_cliprdr_send_data_response(clipboard, NULL, 0);
		return;
	}

	/*
	 * File lists require a bit of postprocessing to convert them from WinPR's FILDESCRIPTOR
	 * format to CLIPRDR_FILELIST expected by the server.
	 *
	 * We check for "FileGroupDescriptorW" format being registered (i.e., nonzero) in order
	 * to not process CF_RAW as a file list in case WinPR does not support file transfers.
	 */
	if (dstFormatId &&
	    (dstFormatId == ClipboardGetFormatId(clipboard->system, "FileGroupDescriptorW")))
	{
		UINT error = NO_ERROR;
		FILEDESCRIPTOR* file_array = (FILEDESCRIPTOR*) pDstData;
		UINT32 file_count = DstSize / sizeof(FILEDESCRIPTOR);
		pDstData = NULL;
		DstSize = 0;
		error = cliprdr_serialize_file_list(file_array, file_count, &pDstData, &DstSize);

		if (error)
			WLog_ERR(TAG, "failed to serialize CLIPRDR_FILELIST: 0x%08X", error);

		free(file_array);
	}

	xf_cliprdr_send_data_response(clipboard, pDstData, (int) DstSize);
	free(pDstData);
}