diff --git a/channels/cliprdr/cliprdr_format.c b/channels/cliprdr/cliprdr_format.c index ad86a56cd..f8781e8f3 100644 --- a/channels/cliprdr/cliprdr_format.c +++ b/channels/cliprdr/cliprdr_format.c @@ -43,6 +43,8 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS int i; STREAM* s; + DEBUG_CLIPRDR("Sending Clipboard Format List"); + if (cb_event->raw_format_data) { s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size); @@ -80,33 +82,39 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS static void cliprdr_send_format_list_response(cliprdrPlugin* cliprdr) { STREAM* s; + DEBUG_CLIPRDR("Sending Clipboard Format List Response"); s = cliprdr_packet_new(CB_FORMAT_LIST_RESPONSE, CB_RESPONSE_OK, 0); cliprdr_packet_send(cliprdr, s); } void cliprdr_process_short_format_names(cliprdrPlugin* cliprdr, STREAM* s, uint32 length, uint16 flags) { + int i; boolean ascii; int num_formats; - uint8* end_mark; CLIPRDR_FORMAT_NAME* format_name; num_formats = length / 36; + if (num_formats <= 0) + { + cliprdr->format_names = NULL; + cliprdr->num_format_names = 0; + return; + } + if (num_formats * 36 != length) DEBUG_WARN("dataLen %d not divided by 36!", length); ascii = (flags & CB_ASCII_NAMES) ? True : False; - stream_get_mark(s, end_mark); - end_mark += length; - cliprdr->format_names = (CLIPRDR_FORMAT_NAME*) xmalloc(sizeof(CLIPRDR_FORMAT_NAME) * num_formats); cliprdr->num_format_names = num_formats; - format_name = cliprdr->format_names; - while (s->p < end_mark) + for (i = 0; i < num_formats; i++) { + format_name = &cliprdr->format_names[i]; + stream_read_uint32(s, format_name->id); if (ascii) @@ -121,8 +129,6 @@ void cliprdr_process_short_format_names(cliprdrPlugin* cliprdr, STREAM* s, uint3 } stream_seek(s, 32); - - format_name++; } } @@ -149,17 +155,16 @@ void cliprdr_process_long_format_names(cliprdrPlugin* cliprdr, STREAM* s, uint32 cliprdr->format_names = (CLIPRDR_FORMAT_NAME*) xmalloc(sizeof(CLIPRDR_FORMAT_NAME) * num_formats); cliprdr->num_format_names = num_formats; - format_name = cliprdr->format_names; + num_formats = 0; while (s->p < end_mark) { + format_name = &cliprdr->format_names[num_formats++]; stream_read_uint32(s, format_name->id); format_name->name = freerdp_uniconv_in(cliprdr->uniconv, s->p, 32); format_name->length = strlen(format_name->name); stream_seek(s, 32); - - format_name++; } } @@ -186,13 +191,15 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataL else cliprdr_process_short_format_names(cliprdr, s, dataLen, msgFlags); - format_name = cliprdr->format_names; - cb_event->formats = (uint32*) xmalloc(sizeof(uint32) * cliprdr->num_format_names); + if (cliprdr->num_format_names > 0) + cb_event->formats = (uint32*) xmalloc(sizeof(uint32) * cliprdr->num_format_names); + cb_event->num_formats = 0; for (i = 0; i < cliprdr->num_format_names; i++) { supported = True; + format_name = &cliprdr->format_names[i]; format = format_name->id; switch (format) @@ -206,6 +213,8 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataL if (format_name->length > 0) { + DEBUG_CLIPRDR("format: %s", format_name->name); + if (strcmp(format_name->name, "HTML Format") == 0) { format = CB_FORMAT_HTML; @@ -234,14 +243,15 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataL if (supported) cb_event->formats[cb_event->num_formats++] = format; - - if (format_name->name != NULL) - xfree(format_name->name); - - format_name++; } - xfree(cliprdr->format_names); + if (cliprdr->format_names != NULL) + { + xfree(cliprdr->format_names); + cliprdr->format_names = NULL; + } + + cliprdr->num_format_names = 0; svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (RDP_EVENT*) cb_event); cliprdr_send_format_list_response(cliprdr); @@ -249,6 +259,8 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataL void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, uint16 msgFlags) { + /* where is this documented? */ +#if 0 RDP_EVENT* event; if ((msgFlags & CB_RESPONSE_FAIL) != 0) @@ -256,6 +268,7 @@ void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, uint16 msgFlag event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_MONITOR_READY, NULL, NULL); svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event); } +#endif } void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, STREAM* s) @@ -273,6 +286,8 @@ void cliprdr_process_format_data_response_event(cliprdrPlugin* cliprdr, RDP_CB_D { STREAM* s; + DEBUG_CLIPRDR("Sending Format Data Response"); + if (cb_event->size > 0) { s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE, CB_RESPONSE_OK, cb_event->size); @@ -289,6 +304,9 @@ void cliprdr_process_format_data_response_event(cliprdrPlugin* cliprdr, RDP_CB_D void cliprdr_process_format_data_request_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_REQUEST_EVENT* cb_event) { STREAM* s; + + DEBUG_CLIPRDR("Sending Format Data Request"); + s = cliprdr_packet_new(CB_FORMAT_DATA_REQUEST, 0, 4); stream_write_uint32(s, cb_event->format); cliprdr_packet_send(cliprdr, s); diff --git a/channels/cliprdr/cliprdr_main.c b/channels/cliprdr/cliprdr_main.c index a9425d7d9..12cf24491 100644 --- a/channels/cliprdr/cliprdr_main.c +++ b/channels/cliprdr/cliprdr_main.c @@ -123,6 +123,8 @@ static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, STREAM* s if (generalFlags & CB_CAN_LOCK_CLIPDATA) cliprdr->can_lock_clipdata = True; + + cliprdr->received_caps = True; } static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, STREAM* s) @@ -158,15 +160,20 @@ static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, STREAM* s) static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr) { STREAM* s; + uint32 flags; s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN); + DEBUG_CLIPRDR("Sending Capabilities"); + + flags = CB_USE_LONG_FORMAT_NAMES; + stream_write_uint16(s, 1); /* cCapabilitiesSets */ stream_write_uint16(s, 0); /* pad1 */ stream_write_uint16(s, CB_CAPSTYPE_GENERAL); /* capabilitySetType */ stream_write_uint16(s, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability */ stream_write_uint32(s, CB_CAPS_VERSION_2); /* version */ - stream_write_uint32(s, 0); /* generalFlags */ + stream_write_uint32(s, flags); /* generalFlags */ cliprdr_packet_send(cliprdr, s); } @@ -175,7 +182,8 @@ static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr) { RDP_EVENT* event; - cliprdr_send_clip_caps(cliprdr); + if (cliprdr->received_caps) + cliprdr_send_clip_caps(cliprdr); event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_MONITOR_READY, NULL, NULL); svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event); @@ -193,7 +201,7 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, STREAM* s) stream_read_uint32(s, dataLen); DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d", - CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); + CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); switch (msgType) { @@ -234,21 +242,22 @@ static void cliprdr_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) switch (event->event_type) { case RDP_EVENT_TYPE_CB_FORMAT_LIST: - cliprdr_process_format_list_event((cliprdrPlugin*)plugin, (RDP_CB_FORMAT_LIST_EVENT*)event); + cliprdr_process_format_list_event((cliprdrPlugin*) plugin, (RDP_CB_FORMAT_LIST_EVENT*) event); break; case RDP_EVENT_TYPE_CB_DATA_REQUEST: - cliprdr_process_format_data_request_event((cliprdrPlugin*)plugin, (RDP_CB_DATA_REQUEST_EVENT*)event); + cliprdr_process_format_data_request_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_REQUEST_EVENT*) event); break; case RDP_EVENT_TYPE_CB_DATA_RESPONSE: - cliprdr_process_format_data_response_event((cliprdrPlugin*)plugin, (RDP_CB_DATA_RESPONSE_EVENT*)event); + cliprdr_process_format_data_response_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_RESPONSE_EVENT*) event); break; default: DEBUG_WARN("unknown event type %d", event->event_type); break; } + freerdp_event_free(event); } diff --git a/channels/cliprdr/cliprdr_main.h b/channels/cliprdr/cliprdr_main.h index 043981498..e3059a272 100644 --- a/channels/cliprdr/cliprdr_main.h +++ b/channels/cliprdr/cliprdr_main.h @@ -36,6 +36,7 @@ struct cliprdr_plugin { rdpSvcPlugin plugin; UNICONV* uniconv; + boolean received_caps; boolean use_long_format_names; boolean stream_fileclip_enabled; boolean fileclip_no_file_paths; diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 5a546f388..f74d08a0a 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -231,7 +231,7 @@ static boolean xf_cliprdr_is_self_owned(xfInfo* xfi) uint32 id = 0; uint32* pid = NULL; int format, result = 0; - unsigned long len, bytes_left; + unsigned long length, bytes_left; clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; cb->owner = XGetSelectionOwner(xfi->display, cb->clipboard_atom); @@ -240,7 +240,7 @@ static boolean xf_cliprdr_is_self_owned(xfInfo* xfi) { result = XGetWindowProperty(xfi->display, cb->owner, cb->identity_atom, 0, 4, 0, XA_INTEGER, - &type, &format, &len, &bytes_left, (uint8**) &pid); + &type, &format, &length, &bytes_left, (uint8**) &pid); } if (pid) @@ -249,7 +249,7 @@ static boolean xf_cliprdr_is_self_owned(xfInfo* xfi) XFree(pid); } - if (cb->owner == None || cb->owner == xfi->drawable) + if ((cb->owner == None) || (cb->owner == xfi->drawable)) return False; if (result != Success) @@ -302,27 +302,27 @@ static void xf_cliprdr_send_raw_format_list(xfInfo* xfi) Atom type; uint8* format_data; int format, result; - unsigned long len, bytes_left; + unsigned long length, bytes_left; RDP_CB_FORMAT_LIST_EVENT* event; clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; result = XGetWindowProperty(xfi->display, cb->root_window, cb->property_atom, 0, 3600, 0, XA_STRING, - &type, &format, &len, &bytes_left, (uint8**) &format_data); + &type, &format, &length, &bytes_left, (uint8**) &format_data); if (result != Success) { DEBUG_WARN("XGetWindowProperty failed"); return; } - DEBUG_X11("format=%d len=%d bytes_left=%d", format, (int)len, (int)bytes_left); + DEBUG_X11("format=%d len=%d bytes_left=%d", format, (int) length, (int) bytes_left); event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); - event->raw_format_data = (uint8*) xmalloc(len); - memcpy(event->raw_format_data, format_data, len); - event->raw_format_data_size = len; + event->raw_format_data = (uint8*) xmalloc(length); + memcpy(event->raw_format_data, format_data, length); + event->raw_format_data_size = length; XFree(format_data); freerdp_channels_send_event(cb->channels, (RDP_EVENT*) event); @@ -386,6 +386,7 @@ static void xf_cliprdr_send_data_request(xfInfo* xfi, uint32 format) event = (RDP_CB_DATA_REQUEST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_DATA_REQUEST, NULL, NULL); + event->format = format; freerdp_channels_send_event(cb->channels, (RDP_EVENT*) event); @@ -429,13 +430,14 @@ static void xf_cliprdr_process_cb_data_request_event(xfInfo* xfi, RDP_CB_DATA_RE { /* CB_FORMAT_RAW */ i = 0; - XChangeProperty(xfi->display, xfi->drawing, cb->property_atom, + XChangeProperty(xfi->display, xfi->drawable, cb->property_atom, XA_INTEGER, 32, PropModeReplace, (uint8*) &event->format, 1); } else { i = xf_cliprdr_select_format_by_id(cb, event->format); } + if (i < 0) { DEBUG_X11("unsupported format requested"); @@ -445,7 +447,7 @@ static void xf_cliprdr_process_cb_data_request_event(xfInfo* xfi, RDP_CB_DATA_RE { cb->request_index = i; - DEBUG_X11("target=%d", (int)cb->format_mappings[i].target_format); + DEBUG_X11("target=%d", (int) cb->format_mappings[i].target_format); XConvertSelection(xfi->display, cb->clipboard_atom, cb->format_mappings[i].target_format, cb->property_atom, @@ -462,28 +464,28 @@ static void xf_cliprdr_get_requested_targets(xfInfo* xfi) Atom atom; int format; uint8* data = NULL; - unsigned long len, bytes_left; + unsigned long length, bytes_left; RDP_CB_FORMAT_LIST_EVENT* event; clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; XGetWindowProperty(xfi->display, xfi->drawable, cb->property_atom, 0, 200, 0, XA_ATOM, - &atom, &format, &len, &bytes_left, &data); + &atom, &format, &length, &bytes_left, &data); - DEBUG_X11("type=%d format=%d len=%d bytes_left=%d", - (int) atom, format, (int) len, (int) bytes_left); + DEBUG_X11("type=%d format=%d length=%d bytes_left=%d", + (int) atom, format, (int) length, (int) bytes_left); - if (len > 0) + if (length > 0) { event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); event->formats = (uint32*) xmalloc(sizeof(uint32) * cb->num_format_mappings); num = 0; - for (i = 0; i < len; i++) + for (i = 0; i < length; i++) { - atom = ((Atom*)data)[i]; - DEBUG_X11("atom %d", (int)atom); + atom = ((Atom*) data)[i]; + DEBUG_X11("atom %d", (int) atom); for (j = 0; j < cb->num_format_mappings; j++) { if (cb->format_mappings[j].target_format == atom) @@ -687,7 +689,7 @@ static void xf_cliprdr_process_requested_data(xfInfo* xfi, boolean has_data, uin xf_cliprdr_send_null_data_response(xfi); /* Resend the format list, otherwise the server won't request again for the next paste */ - xf_cliprdr_send_format_list(xfi); + //xf_cliprdr_send_format_list(xfi); } static boolean xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target) @@ -696,11 +698,11 @@ static boolean xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target) int format; uint8* data = NULL; boolean has_data = False; - unsigned long len, bytes_left, dummy; + unsigned long length, bytes_left, dummy; clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; - if (cb->request_index < 0 || - cb->format_mappings[cb->request_index].target_format != target) + if ((cb->request_index < 0) || + (cb->format_mappings[cb->request_index].target_format != target)) { DEBUG_X11("invalid target"); xf_cliprdr_send_null_data_response(xfi); @@ -709,7 +711,7 @@ static boolean xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target) XGetWindowProperty(xfi->display, xfi->drawable, cb->property_atom, 0, 0, 0, target, - &type, &format, &len, &bytes_left, &data); + &type, &format, &length, &bytes_left, &data); DEBUG_X11("type=%d format=%d bytes=%d request_index=%d", (int) type, format, (int) bytes_left, cb->request_index); @@ -751,11 +753,11 @@ static boolean xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target) } else if (XGetWindowProperty(xfi->display, xfi->drawable, cb->property_atom, 0, bytes_left, 0, target, - &type, &format, &len, &dummy, &data) == Success) + &type, &format, &length, &dummy, &data) == Success) { if (cb->incr_starts) { - bytes_left = len * format / 8; + bytes_left = length * format / 8; DEBUG_X11("%d bytes", (int)bytes_left); cb->incr_data = (uint8*) xrealloc(cb->incr_data, cb->incr_data_length + bytes_left); memcpy(cb->incr_data + cb->incr_data_length, data, bytes_left); @@ -1078,10 +1080,10 @@ boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent) uint32 alt_format; uint8* data = NULL; boolean delay_respond; - unsigned long len, bytes_left; + unsigned long length, bytes_left; clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; - DEBUG_X11("target=%d", (int)xevent->xselectionrequest.target); + DEBUG_X11("target=%d", (int) xevent->xselectionrequest.target); if (xevent->xselectionrequest.owner != xfi->drawable) { @@ -1120,7 +1122,7 @@ boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent) { if (XGetWindowProperty(xfi->display, xevent->xselectionrequest.requestor, cb->property_atom, 0, 4, 0, XA_INTEGER, - &type, &fmt, &len, &bytes_left, &data) != Success) + &type, &fmt, &length, &bytes_left, &data) != Success) { DEBUG_X11("XGetWindowProperty failed"); } @@ -1131,7 +1133,7 @@ boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent) } } 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) + 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; @@ -1164,7 +1166,7 @@ boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent) } } - if (!delay_respond) + if (delay_respond != False) { XSendEvent(xfi->display, xevent->xselectionrequest.requestor, 0, 0, respond); XFlush(xfi->display);