Example #1
0
int cliprdr_process_data_request_response(struct stream* s, int msg_flags, int size)
{
	int clipboard_size = 0;
	unsigned char* clipboard_data = NULL;

	if (msg_flags == CB_RESPONSE_FAIL)
	{
		log_message(l_config, LOG_LEVEL_WARNING, "vchannel_cliprdr[cliprdr_process_data_request_response]: "
				"Unable to get clipboard data");
		return 1;
	}
	log_hexdump(l_config, LOG_LEVEL_DEBUG_PLUS, (unsigned char*)s->p, size);
	if (XGetSelectionOwner(display, clipboard_atom) != wclip)
	{
		log_message(l_config, LOG_LEVEL_WARNING, "vchannel_cliprdr[cliprdr_process_data_request_response]: "
				"Xrpd is not the owner of the selection");
		return 1;
	}
	if (clipboard_data != 0)
	{
		g_free(clipboard_data);
	}

	/* An UTF-16 String form RDP is always on 16bits. An UTF-8 string can be coded either
	 * on 8, 16, 24 or 32 bits. So it can be AT MOST input size*2
	 */

	clipboard_data = g_malloc(size*2, 1);
	clipboard_size = uni_rdp_in_str(s, (char*)clipboard_data, size*2, size);

	// Remove NULL characters from clipboard data end, it is not a null terminated string
	if (clipboard_data)
	{
		while (clipboard_size > 0 && clipboard_data[clipboard_size-1] == '\0')
		{
			clipboard_size--;
		}
	}

	clipboard_add_current_clipboard_data(&clipboard, clipboard_data, clipboard_size, format_utf8_string_atom);

	return 0;
}
Example #2
0
static void
cliprdr_get_clipboard(XEvent* e)
{
	Atom type;
	unsigned long len, bytes_left, dummy;
	int format, result;
	unsigned char *data;


	log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: "
			"New owner %i", e->xselection.requestor);

	XGetWindowProperty (e->xselection.display,
											e->xselection.requestor,
											e->xselection.property,
											0, 0,
											False,
											AnyPropertyType,
											&type,
											&format,
											&len, &bytes_left,
											&data);
	// Check Format list
	if (type == XA_ATOM || format == 32)
	{
		result = XGetWindowProperty (e->xselection.display, e->xselection.requestor, e->xselection.property, 0, bytes_left, 0, XA_ATOM, &type, &format, &len, &dummy, &data);
		if (result == Success)
		{
			int i = 0;
			Atom atom;
			for (i = 0; i < len ; i++)
			{
				atom = ((Atom*)data)[i];
				log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: "
						"format : %s", XGetAtomName(display, atom));
				if (clipboard_format_supported(&clipboard, atom))
				{
					clipboard_add_current_clipboard_format(&clipboard, atom);
				}
			}
			if (clipboard_current_clipboard_size(&clipboard) > 0)
			{
				atom = clipboard_get_current_clipboard_format(&clipboard, 0);
				log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: "
						"Request for format %s", XGetAtomName(display, atom));

				XConvertSelection(display, clipboard_atom, atom, xrdp_clipboard, wclip, CurrentTime);
				XSync (e->xselectionclear.display, False);
			}
			return;
		}

		log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: "
				"Failed to parse atom list");
		return;
	}

	// DATA is There
	log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: "
			"Data type : %s\n", XGetAtomName(e->xselection.display, e->xselection.property));

	if (bytes_left > 0 && clipboard_format_supported(&clipboard, e->xselection.target))
	{
		unsigned char* clipboard_data = NULL;
		int clipboard_size = 0;

		result = XGetWindowProperty(e->xselection.display, e->xselection.requestor, e->xselection.property, 0, bytes_left, 0, e->xselection.target, &type, &format, &len, &dummy, &data);
		if (result == Success)
		{
			log_message(l_config, LOG_LEVEL_DEBUG_PLUS, "vchannel_cliprdr[cliprdr_get_clipboard]: "
					"New data in clipboard: %s", data);
			int index = -1;
			index = clipboard_get_current_clipboard_format_index(&clipboard, e->xselection.target);

			// Don't forget the null terminated character
			clipboard_data = g_malloc(bytes_left + 1, 1);
			clipboard_size = bytes_left;
			g_memcpy(clipboard_data, data, bytes_left);
			log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: "
					"clipboard %s[%i] updated with '%s'", XGetAtomName(display, e->xselection.target), index, data);

			clipboard_add_current_clipboard_data(&clipboard, clipboard_data, clipboard_size, e->xselection.target);

			if (index < (clipboard_current_clipboard_size(&clipboard) - 1))
			{
				Atom format = clipboard_get_current_clipboard_format(&clipboard, index + 1);
				log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: "
						"Request for format %s", XGetAtomName(display, format));

				XConvertSelection(display, clipboard_atom, format, xrdp_clipboard, wclip, CurrentTime);
				XSync (e->xselectionclear.display, False);
			}
			else
			{
				XSetSelectionOwner(display, clipboard_atom, wclip, CurrentTime);
				XSync(display, False);
				// File content is not supported for now
				if ((! clipboard_current_clipboard_format_exist(&clipboard, format_file_gnome_atom)) && (! clipboard_current_clipboard_format_exist(&clipboard, format_file_text_uri_list_atom)))
					cliprdr_send_format_list();
			}
		}
		else
		{
			log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: "
					"Failed to get clipboard content");
		}
		XFree (data);
	}
}