⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xclip.c

📁 LInux 下的远程桌面工具 Rdesktop
💻 C
📖 第 1 页 / 共 3 页
字号:
			res = XGetWindowProperty(g_display, event->requestor,						 event->property, 0, 1, True,						 XA_INTEGER, &type, &format, &nitems, &bytes_left,						 &prop_return);			if (res != Success || (!prop_return))			{				DEBUG_CLIPBOARD(("Requested native format but didn't specifiy which.\n"));				xclip_refuse_selection(event);				return;			}			format = *(uint32 *) prop_return;			XFree(prop_return);		}		else if (event->target == format_string_atom || event->target == XA_STRING)		{			/* STRING and XA_STRING are defined to be ISO8859-1 */			format = CF_TEXT;		}		else if (event->target == format_utf8_string_atom)		{#ifdef USE_UNICODE_CLIPBOARD			format = CF_UNICODETEXT;#else			DEBUG_CLIPBOARD(("Requested target unavailable due to lack of Unicode support. (It was not in TARGETS, so why did you ask for it?!)\n"));			xclip_refuse_selection(event);			return;#endif		}		else if (event->target == format_unicode_atom)		{			/* Assuming text/unicode to be UTF-16 */			format = CF_UNICODETEXT;		}		else		{			DEBUG_CLIPBOARD(("Requested target unavailable. (It was not in TARGETS, so why did you ask for it?!)\n"));			xclip_refuse_selection(event);			return;		}		cliprdr_send_data_request(format);		selection_request = *event;		has_selection_request = True;		return;		/* wait for data */	}}/* While this rdesktop holds ownership over the clipboard, it means the clipboard data   is offered by the RDP server (and when it is pasted inside RDP, there's no network   roundtrip).   This event (SelectionClear) symbolizes this rdesktop lost onwership of the clipboard   to some other X client. We should find out what clipboard formats this other   client offers and announce that to RDP. */voidxclip_handle_SelectionClear(void){	DEBUG_CLIPBOARD(("xclip_handle_SelectionClear\n"));	xclip_notify_change();	xclip_probe_selections();}/* Called when any property changes in our window or the root window. */voidxclip_handle_PropertyNotify(XPropertyEvent * event){	unsigned long nitems;	unsigned long offset = 0;	unsigned long bytes_left = 1;	int format;	XWindowAttributes wa;	uint8 *data;	Atom type;	if (event->state == PropertyNewValue && g_waiting_for_INCR)	{		DEBUG_CLIPBOARD(("x_clip_handle_PropertyNotify: g_waiting_for_INCR != 0\n"));		while (bytes_left > 0)		{			/* Unlike the specification, we don't set the 'delete' arugment to True			   since we slurp the INCR's chunks in even-smaller chunks of 4096 bytes. */			if ((XGetWindowProperty			     (g_display, g_wnd, rdesktop_clipboard_target_atom, offset, 4096L,			      False, AnyPropertyType, &type, &format, &nitems, &bytes_left,			      &data) != Success))			{				XFree(data);				return;			}			if (nitems == 0)			{				/* INCR transfer finished */				XGetWindowAttributes(g_display, g_wnd, &wa);				XSelectInput(g_display, g_wnd,					     (wa.your_event_mask ^ PropertyChangeMask));				XFree(data);				g_waiting_for_INCR = 0;				if (g_clip_buflen > 0)				{					if (!xclip_send_data_with_convert					    (g_clip_buffer, g_clip_buflen, g_incr_target))					{						helper_cliprdr_send_empty_response();					}					xfree(g_clip_buffer);					g_clip_buffer = NULL;					g_clip_buflen = 0;				}			}			else			{				/* Another chunk in the INCR transfer */				offset += (nitems / 4);	/* offset at which to begin the next slurp */				g_clip_buffer = xrealloc(g_clip_buffer, g_clip_buflen + nitems);				memcpy(g_clip_buffer + g_clip_buflen, data, nitems);				g_clip_buflen += nitems;				XFree(data);			}		}		XDeleteProperty(g_display, g_wnd, rdesktop_clipboard_target_atom);		return;	}	if ((event->atom == rdesktop_selection_notify_atom) &&	    (event->window == DefaultRootWindow(g_display)))		xclip_probe_selections();}#endif/* Called when the RDP server announces new clipboard data formats.   In response, we:   - take ownership over the clipboard   - declare those formats in their Windows native form     to other rdesktop instances on this X server */voidui_clip_format_announce(uint8 * data, uint32 length){	acquire_time = g_last_gesturetime;	XSetSelectionOwner(g_display, primary_atom, g_wnd, acquire_time);	if (XGetSelectionOwner(g_display, primary_atom) != g_wnd)		warning("Failed to aquire ownership of PRIMARY clipboard\n");	XSetSelectionOwner(g_display, clipboard_atom, g_wnd, acquire_time);	if (XGetSelectionOwner(g_display, clipboard_atom) != g_wnd)		warning("Failed to aquire ownership of CLIPBOARD clipboard\n");	if (formats_data)		xfree(formats_data);	formats_data = xmalloc(length);	memcpy(formats_data, data, length);	formats_data_length = length;	xclip_notify_change();}/* Called when the RDP server responds with clipboard data (after we've requested it). */voidui_clip_handle_data(uint8 * data, uint32 length){	RD_BOOL free_data = False;	if (length == 0)	{		xclip_refuse_selection(&selection_request);		has_selection_request = False;		return;	}	if (selection_request.target == format_string_atom || selection_request.target == XA_STRING)	{		/* We're expecting a CF_TEXT response */		uint8 *firstnull;		/* translate linebreaks */		crlf2lf(data, &length);		/* Only send data up to null byte, if any */		firstnull = (uint8 *) strchr((char *) data, '\0');		if (firstnull)		{			length = firstnull - data + 1;		}	}#ifdef USE_UNICODE_CLIPBOARD	else if (selection_request.target == format_utf8_string_atom)	{		/* We're expecting a CF_UNICODETEXT response */		iconv_t cd = iconv_open("UTF-8", WINDOWS_CODEPAGE);		if (cd != (iconv_t) - 1)		{			size_t utf8_length = length * 2;			char *utf8_data = malloc(utf8_length);			size_t utf8_length_remaining = utf8_length;			char *utf8_data_remaining = utf8_data;			char *data_remaining = (char *) data;			size_t length_remaining = (size_t) length;			if (utf8_data == NULL)			{				iconv_close(cd);				return;			}			iconv(cd, (ICONV_CONST char **) &data_remaining, &length_remaining,			      &utf8_data_remaining, &utf8_length_remaining);			iconv_close(cd);			free_data = True;			data = (uint8 *) utf8_data;			length = utf8_length - utf8_length_remaining;			/* translate linebreaks (works just as well on UTF-8) */			crlf2lf(data, &length);		}	}	else if (selection_request.target == format_unicode_atom)	{		/* We're expecting a CF_UNICODETEXT response, so what we're		   receiving matches our requirements and there's no need		   for further conversions. */	}#endif	else if (selection_request.target == rdesktop_native_atom)	{		/* Pass as-is */	}	else	{		DEBUG_CLIPBOARD(("ui_clip_handle_data: BUG! I don't know how to convert selection target %s!\n", XGetAtomName(g_display, selection_request.target)));		xclip_refuse_selection(&selection_request);		has_selection_request = False;		return;	}	xclip_provide_selection(&selection_request, selection_request.target, 8, data, length - 1);	has_selection_request = False;	if (free_data)		free(data);}voidui_clip_request_failed(){	xclip_refuse_selection(&selection_request);	has_selection_request = False;}voidui_clip_request_data(uint32 format){	Window primary_owner, clipboard_owner;	DEBUG_CLIPBOARD(("Request from server for format %d\n", format));	rdp_clipboard_request_format = format;	if (probing_selections)	{		DEBUG_CLIPBOARD(("ui_clip_request_data: Selection probe in progress. Cannot handle request.\n"));		helper_cliprdr_send_empty_response();		return;	}	xclip_clear_target_props();	if (rdesktop_is_selection_owner)	{		XChangeProperty(g_display, g_wnd, rdesktop_clipboard_target_atom,				XA_INTEGER, 32, PropModeReplace, (unsigned char *) &format, 1);		XConvertSelection(g_display, primary_atom, rdesktop_native_atom,				  rdesktop_clipboard_target_atom, g_wnd, CurrentTime);		return;	}	if (auto_mode)		primary_owner = XGetSelectionOwner(g_display, primary_atom);	else		primary_owner = None;	clipboard_owner = XGetSelectionOwner(g_display, clipboard_atom);	/* Both available */	if ((primary_owner != None) && (clipboard_owner != None))	{		primary_timestamp = 0;		clipboard_timestamp = 0;		XConvertSelection(g_display, primary_atom, timestamp_atom,				  rdesktop_primary_timestamp_target_atom, g_wnd, CurrentTime);		XConvertSelection(g_display, clipboard_atom, timestamp_atom,				  rdesktop_clipboard_timestamp_target_atom, g_wnd, CurrentTime);		return;	}	/* Just PRIMARY */	if (primary_owner != None)	{		XConvertSelection(g_display, primary_atom, targets_atom,				  rdesktop_clipboard_target_atom, g_wnd, CurrentTime);		return;	}	/* Just CLIPBOARD */	if (clipboard_owner != None)	{		XConvertSelection(g_display, clipboard_atom, targets_atom,				  rdesktop_clipboard_target_atom, g_wnd, CurrentTime);		return;	}	/* No data available */	helper_cliprdr_send_empty_response();}voidui_clip_sync(void){	xclip_probe_selections();}voidui_clip_set_mode(const char *optarg){	g_rdpclip = True;	if (str_startswith(optarg, "PRIMARYCLIPBOARD"))		auto_mode = True;	else if (str_startswith(optarg, "CLIPBOARD"))		auto_mode = False;	else	{		warning("Invalid clipboard mode '%s'.\n", optarg);		g_rdpclip = False;	}}voidxclip_init(void){	if (!g_rdpclip)		return;	if (!cliprdr_init())		return;	primary_atom = XInternAtom(g_display, "PRIMARY", False);	clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False);	targets_atom = XInternAtom(g_display, "TARGETS", False);	timestamp_atom = XInternAtom(g_display, "TIMESTAMP", False);	rdesktop_clipboard_target_atom =		XInternAtom(g_display, "_RDESKTOP_CLIPBOARD_TARGET", False);	rdesktop_primary_timestamp_target_atom =		XInternAtom(g_display, "_RDESKTOP_PRIMARY_TIMESTAMP_TARGET", False);	rdesktop_clipboard_timestamp_target_atom =		XInternAtom(g_display, "_RDESKTOP_CLIPBOARD_TIMESTAMP_TARGET", False);	incr_atom = XInternAtom(g_display, "INCR", False);	format_string_atom = XInternAtom(g_display, "STRING", False);	format_utf8_string_atom = XInternAtom(g_display, "UTF8_STRING", False);	format_unicode_atom = XInternAtom(g_display, "text/unicode", False);	/* rdesktop sets _RDESKTOP_SELECTION_NOTIFY on the root window when acquiring the clipboard.	   Other interested rdesktops can use this to notify their server of the available formats. */	rdesktop_selection_notify_atom =		XInternAtom(g_display, "_RDESKTOP_SELECTION_NOTIFY", False);	XSelectInput(g_display, DefaultRootWindow(g_display), PropertyChangeMask);	probing_selections = False;	rdesktop_native_atom = XInternAtom(g_display, "_RDESKTOP_NATIVE", False);	rdesktop_clipboard_formats_atom =		XInternAtom(g_display, "_RDESKTOP_CLIPBOARD_FORMATS", False);	rdesktop_primary_owner_atom = XInternAtom(g_display, "_RDESKTOP_PRIMARY_OWNER", False);	rdesktop_clipboard_owner_atom = XInternAtom(g_display, "_RDESKTOP_CLIPBOARD_OWNER", False);	num_targets = 0;	targets[num_targets++] = targets_atom;	targets[num_targets++] = timestamp_atom;	targets[num_targets++] = rdesktop_native_atom;	targets[num_targets++] = rdesktop_clipboard_formats_atom;#ifdef USE_UNICODE_CLIPBOARD	targets[num_targets++] = format_utf8_string_atom;#endif	targets[num_targets++] = format_unicode_atom;	targets[num_targets++] = format_string_atom;	targets[num_targets++] = XA_STRING;}voidxclip_deinit(void){	if (XGetSelectionOwner(g_display, primary_atom) == g_wnd)		XSetSelectionOwner(g_display, primary_atom, None, acquire_time);	if (XGetSelectionOwner(g_display, clipboard_atom) == g_wnd)		XSetSelectionOwner(g_display, clipboard_atom, None, acquire_time);	xclip_notify_change();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -