Beispiel #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;
}
Beispiel #2
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;
}