예제 #1
0
BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
{
	int i;
	int fmt;
	Atom type;
	UINT32 format;
	XEvent* respond;
	UINT32 alt_format;
	BYTE* data = NULL;
	BOOL delay_respond;
	unsigned long length, bytes_left;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	DEBUG_X11_CLIPRDR("target=%d", (int) xevent->xselectionrequest.target);

	if (xevent->xselectionrequest.owner != xfi->drawable)
	{
		DEBUG_X11_CLIPRDR("not owner");
		return FALSE;
	}

	delay_respond = FALSE;

	respond = (XEvent*) malloc(sizeof(XEvent));
	ZeroMemory(respond, sizeof(XEvent));

	respond->xselection.property = None;
	respond->xselection.type = SelectionNotify;
	respond->xselection.display = xevent->xselectionrequest.display;
	respond->xselection.requestor = xevent->xselectionrequest.requestor;
	respond->xselection.selection = xevent->xselectionrequest.selection;
	respond->xselection.target = xevent->xselectionrequest.target;
	respond->xselection.time = xevent->xselectionrequest.time;

	if (xevent->xselectionrequest.target == cb->targets[0]) /* TIMESTAMP */
	{
		/* TODO */
		DEBUG_X11_CLIPRDR("target: TIMESTAMP (unimplemented)");
	}
	else if (xevent->xselectionrequest.target == cb->targets[1]) /* TARGETS */
	{
		/* Someone else requests our available formats */
		DEBUG_X11_CLIPRDR("target: TARGETS");
		respond->xselection.property = xevent->xselectionrequest.property;
		xf_cliprdr_provide_targets(xfi, respond);
	}
	else
	{
		DEBUG_X11_CLIPRDR("target: other");

		i = xf_cliprdr_select_format_by_atom(cb, xevent->xselectionrequest.target);

		if (i >= 0 && xevent->xselectionrequest.requestor != xfi->drawable)
		{
			format = cb->format_mappings[i].format_id;
			alt_format = format;

			if (format == CB_FORMAT_RAW)
			{
				if (XGetWindowProperty(xfi->display, xevent->xselectionrequest.requestor,
					cb->property_atom, 0, 4, 0, XA_INTEGER,
					&type, &fmt, &length, &bytes_left, &data) != Success)
				{
					DEBUG_X11_CLIPRDR("XGetWindowProperty failed");
				}
				if (data)
				{
					CopyMemory(&alt_format, data, 4);
					XFree(data);
				}
			}

			DEBUG_X11_CLIPRDR("provide format 0x%04x alt_format 0x%04x", format, alt_format);

			if ((cb->data != 0) && (format == cb->data_format) && (alt_format == cb->data_alt_format))
			{
				/* Cached clipboard data available. Send it now */
				respond->xselection.property = xevent->xselectionrequest.property;
				xf_cliprdr_provide_data(xfi, respond);
			}
			else if (cb->respond)
			{
				DEBUG_X11_CLIPRDR("duplicated request");
			}
			else
			{
				/**
				 * Send clipboard data request to the server.
				 * Response will be postponed after receiving the data
				 */
				if (cb->data)
				{
					free(cb->data);
					cb->data = NULL;
				}

				respond->xselection.property = xevent->xselectionrequest.property;
				cb->respond = respond;
				cb->data_format = format;
				cb->data_alt_format = alt_format;
				delay_respond = TRUE;

				xf_cliprdr_send_data_request(xfi, alt_format);
			}
		}
	}

	if (delay_respond == FALSE)
	{
		XSendEvent(xfi->display, xevent->xselectionrequest.requestor, 0, 0, respond);
		XFlush(xfi->display);
		free(respond);
	}

	return TRUE;
}
예제 #2
0
static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* xevent)
{
	int fmt;
	Atom type;
	UINT32 formatId;
	XEvent* respond;
	UINT32 altFormatId;
	BYTE* data = NULL;
	BOOL delayRespond;
	unsigned long length;
	unsigned long bytes_left;
	xfCliprdrFormat* format;
	xfContext* xfc = clipboard->xfc;

	if (xevent->xselectionrequest.owner != xfc->drawable)
		return FALSE;

	delayRespond = FALSE;

	respond = (XEvent*) calloc(1, sizeof(XEvent));

	respond->xselection.property = None;
	respond->xselection.type = SelectionNotify;
	respond->xselection.display = xevent->xselectionrequest.display;
	respond->xselection.requestor = xevent->xselectionrequest.requestor;
	respond->xselection.selection = xevent->xselectionrequest.selection;
	respond->xselection.target = xevent->xselectionrequest.target;
	respond->xselection.time = xevent->xselectionrequest.time;

	if (xevent->xselectionrequest.target == clipboard->targets[0]) /* TIMESTAMP */
	{
		/* TODO */
	}
	else if (xevent->xselectionrequest.target == clipboard->targets[1]) /* TARGETS */
	{
		/* Someone else requests our available formats */
		respond->xselection.property = xevent->xselectionrequest.property;
		xf_cliprdr_provide_targets(clipboard, respond);
	}
	else
	{
		format = xf_cliprdr_get_format_by_atom(clipboard, xevent->xselectionrequest.target);

		if (format && (xevent->xselectionrequest.requestor != xfc->drawable))
		{
			formatId = format->formatId;
			altFormatId = formatId;

			if (formatId == 0)
			{
				if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor,
					clipboard->property_atom, 0, 4, 0, XA_INTEGER,
					&type, &fmt, &length, &bytes_left, &data) != Success)
				{

				}

				if (data)
				{
					CopyMemory(&altFormatId, data, 4);
					XFree(data);
				}
			}

			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;
				xf_cliprdr_provide_data(clipboard, respond, clipboard->data, clipboard->data_length);
			}
			else if (clipboard->respond)
			{
				/* duplicate request */
			}
			else
			{
				/**
				 * Send clipboard data request to the server.
				 * Response will be postponed after receiving the data
				 */
				if (clipboard->data)
				{
					free(clipboard->data);
					clipboard->data = NULL;
				}

				respond->xselection.property = xevent->xselectionrequest.property;
				clipboard->respond = respond;
				clipboard->data_format = formatId;
				clipboard->data_alt_format = altFormatId;
				delayRespond = TRUE;

				xf_cliprdr_send_data_request(clipboard, altFormatId);
			}
		}
	}

	if (!delayRespond)
	{
		XSendEvent(xfc->display, xevent->xselectionrequest.requestor, 0, 0, respond);
		XFlush(xfc->display);
		free(respond);
	}

	return TRUE;
}
예제 #3
0
boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
{
	int i;
	int fmt;
	Atom type;
	uint32 format;
	XEvent* respond;
	uint32 alt_format;
	uint8* data = NULL;
	boolean delay_respond;
	unsigned long len, bytes_left;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	DEBUG_X11("target=%d", (int)xevent->xselectionrequest.target);

	if (xevent->xselectionrequest.owner != xfi->window->handle)
	{
		DEBUG_X11("not owner");
		return False;
	}

	delay_respond = False;
	respond = xnew(XEvent);
	respond->xselection.property = None;
	respond->xselection.type = SelectionNotify;
	respond->xselection.display = xevent->xselectionrequest.display;
	respond->xselection.requestor = xevent->xselectionrequest.requestor;
	respond->xselection.selection = xevent->xselectionrequest.selection;
	respond->xselection.target = xevent->xselectionrequest.target;
	respond->xselection.time = xevent->xselectionrequest.time;
	if (xevent->xselectionrequest.target == cb->targets[0]) /* TIMESTAMP */
	{
		/* TODO */
	}
	else if (xevent->xselectionrequest.target == cb->targets[1]) /* TARGETS */
	{
		/* Someone else requests our available formats */
		respond->xselection.property = xevent->xselectionrequest.property;
		xf_cliprdr_provide_targets(xfi, respond);
	}
	else
	{
		i = xf_cliprdr_select_format_by_atom(cb, xevent->xselectionrequest.target);
		if (i >= 0 && xevent->xselectionrequest.requestor != xfi->window->handle)
		{
			format = cb->format_mappings[i].format_id;
			alt_format = format;
			if (format == CB_FORMAT_RAW)
			{
				if (XGetWindowProperty(xfi->display, xevent->xselectionrequest.requestor,
					cb->property_atom, 0, 4, 0, XA_INTEGER,
					&type, &fmt, &len, &bytes_left, &data) != Success)
				{
					DEBUG_X11("XGetWindowProperty failed");
				}
				if (data)
				{
					memcpy(&alt_format, data, 4);
					XFree(data);
				}
			}
			DEBUG_X11("provide format 0x%04x alt_format 0x%04x", format, alt_format);
			if (cb->data != 0 &&
				format == cb->data_format &&
				alt_format == cb->data_alt_format)
			{
				/* Cached clipboard data available. Send it now */
				respond->xselection.property = xevent->xselectionrequest.property;
				xf_cliprdr_provide_data(xfi, respond);
			}
			else if (cb->respond)
			{
				DEBUG_X11("duplicated request");
			}
			else
			{
				/**
				 * Send clipboard data request to the server.
				 * Response will be postponed after receiving the data
				 */
				if (cb->data)
				{
					xfree(cb->data);
					cb->data = NULL;
				}
				respond->xselection.property = xevent->xselectionrequest.property;
				cb->respond = respond;
				cb->data_format = format;
				cb->data_alt_format = alt_format;
				delay_respond = True;

				xf_cliprdr_send_data_request(xfi, alt_format);
			}
		}
	}

	if (!delay_respond)
	{
		XSendEvent(xfi->display, xevent->xselectionrequest.requestor, 0, 0, respond);
		XFlush(xfi->display);
		xfree(respond);
	}

	return True;
}
예제 #4
0
static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard,
        XEvent* xevent)
{
	int fmt;
	Atom type;
	UINT32 formatId;
	const char* formatName;
	XEvent* respond;
	BYTE* data = NULL;
	BOOL delayRespond;
	BOOL rawTransfer;
	BOOL matchingFormat;
	unsigned long length;
	unsigned long bytes_left;
	CLIPRDR_FORMAT* format;
	xfContext* xfc = clipboard->xfc;

	if (xevent->xselectionrequest.owner != xfc->drawable)
		return FALSE;

	delayRespond = FALSE;

	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;
	respond->xselection.display = xevent->xselectionrequest.display;
	respond->xselection.requestor = xevent->xselectionrequest.requestor;
	respond->xselection.selection = xevent->xselectionrequest.selection;
	respond->xselection.target = xevent->xselectionrequest.target;
	respond->xselection.time = xevent->xselectionrequest.time;

	if (xevent->xselectionrequest.target == clipboard->targets[0]) /* TIMESTAMP */
	{
		/* TODO */
	}
	else if (xevent->xselectionrequest.target ==
	         clipboard->targets[1]) /* TARGETS */
	{
		/* Someone else requests our available formats */
		respond->xselection.property = xevent->xselectionrequest.property;
		xf_cliprdr_provide_targets(clipboard, respond);
	}
	else
	{
		format = xf_cliprdr_get_server_format_by_atom(clipboard,
		         xevent->xselectionrequest.target);

		if (format && (xevent->xselectionrequest.requestor != xfc->drawable))
		{
			formatId = format->formatId;
			formatName = format->formatName;
			rawTransfer = FALSE;

			if (formatId == CF_RAW)
			{
				if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor,
				                       clipboard->property_atom, 0, 4, 0, XA_INTEGER,
				                       &type, &fmt, &length, &bytes_left, &data) != Success)
				{
				}

				if (data)
				{
					rawTransfer = TRUE;
					CopyMemory(&formatId, data, 4);
					XFree(data);
				}
			}

			/* We can compare format names by pointer value here as they are both
			 * taken from the same clipboard->serverFormats array */
			matchingFormat = (formatId == clipboard->data_format_id)
			                 && (formatName == clipboard->data_format_name);

			if (matchingFormat && (clipboard->data != 0) && !rawTransfer)
			{
				/* Cached converted clipboard data available. Send it now */
				respond->xselection.property = xevent->xselectionrequest.property;
				xf_cliprdr_provide_data(clipboard, respond, clipboard->data,
				                        clipboard->data_length);
			}
			else if (matchingFormat && (clipboard->data_raw != 0) && rawTransfer)
			{
				/* Cached raw clipboard data available. Send it now */
				respond->xselection.property = xevent->xselectionrequest.property;
				xf_cliprdr_provide_data(clipboard, respond, clipboard->data_raw, clipboard->data_raw_length);
			}
			else if (clipboard->respond)
			{
				/* duplicate request */
			}
			else
			{
				/**
				 * Send clipboard data request to the server.
				 * Response will be postponed after receiving the data
				 */
				xf_cliprdr_clear_cached_data(clipboard);
				respond->xselection.property = xevent->xselectionrequest.property;
				clipboard->respond = respond;
				clipboard->data_format_id = formatId;
				clipboard->data_format_name = formatName;
				clipboard->data_raw_format = rawTransfer;
				delayRespond = TRUE;
				xf_cliprdr_send_data_request(clipboard, formatId);
			}
		}
	}

	if (!delayRespond)
	{
		XSendEvent(xfc->display, xevent->xselectionrequest.requestor, 0, 0, respond);
		XFlush(xfc->display);
		free(respond);
	}

	return TRUE;
}