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; }
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); } }