146 |
if (result == NULL) |
if (result == NULL) |
147 |
return NULL; |
return NULL; |
148 |
|
|
149 |
inptr = (uint16*)data; |
inptr = (uint16 *) data; |
150 |
outptr = (uint16*)result; |
outptr = (uint16 *) result; |
151 |
|
|
152 |
/* Check for a reversed BOM */ |
/* Check for a reversed BOM */ |
153 |
Bool swap_endianess = (*inptr == 0xfffe); |
Bool swap_endianess = (*inptr == 0xfffe); |
154 |
|
|
155 |
while ((uint8*)inptr < data + *size) |
while ((uint8 *) inptr < data + *size) |
156 |
{ |
{ |
157 |
uint16 uvalue = *inptr; |
uint16 uvalue = *inptr; |
158 |
if (swap_endianess) |
if (swap_endianess) |
161 |
*outptr++ = swap_endianess ? 0x0d00 : 0x0d; |
*outptr++ = swap_endianess ? 0x0d00 : 0x0d; |
162 |
*outptr++ = *inptr++; |
*outptr++ = *inptr++; |
163 |
} |
} |
164 |
*outptr++ = 0; /* null termination */ |
*outptr++ = 0; /* null termination */ |
165 |
*size = (uint8*)outptr - result; |
*size = (uint8 *) outptr - result; |
166 |
|
|
167 |
return result; |
return result; |
168 |
} |
} |
260 |
to the expected RDP format as necessary. Returns true if data was sent. |
to the expected RDP format as necessary. Returns true if data was sent. |
261 |
*/ |
*/ |
262 |
static Bool |
static Bool |
263 |
xclip_send_data_with_convert(uint8* source, size_t source_size, Atom target) |
xclip_send_data_with_convert(uint8 * source, size_t source_size, Atom target) |
264 |
{ |
{ |
265 |
#ifdef USE_UNICODE_CLIPBOARD |
#ifdef USE_UNICODE_CLIPBOARD |
266 |
if (target == format_string_atom || |
if (target == format_string_atom || |
267 |
target == format_unicode_atom || |
target == format_unicode_atom || target == format_utf8_string_atom) |
|
target == format_utf8_string_atom) |
|
268 |
{ |
{ |
269 |
if (rdp_clipboard_request_format != RDP_CF_TEXT) |
if (rdp_clipboard_request_format != RDP_CF_TEXT) |
270 |
return False; |
return False; |
275 |
WinNT versions are Unicode-minded). |
WinNT versions are Unicode-minded). |
276 |
*/ |
*/ |
277 |
size_t unicode_buffer_size; |
size_t unicode_buffer_size; |
278 |
char* unicode_buffer; |
char *unicode_buffer; |
279 |
iconv_t cd; |
iconv_t cd; |
280 |
|
|
281 |
if (target == format_string_atom) |
if (target == format_string_atom) |
282 |
{ |
{ |
283 |
char* locale_charset = nl_langinfo(CODESET); |
char *locale_charset = nl_langinfo(CODESET); |
284 |
cd = iconv_open(WINDOWS_CODEPAGE, locale_charset); |
cd = iconv_open(WINDOWS_CODEPAGE, locale_charset); |
285 |
if (cd == (iconv_t)-1) |
if (cd == (iconv_t) - 1) |
286 |
{ |
{ |
287 |
DEBUG_CLIPBOARD(("Locale charset %s not found in iconv. Unable to convert clipboard text.\n", locale_charset)); |
DEBUG_CLIPBOARD(("Locale charset %s not found in iconv. Unable to convert clipboard text.\n", locale_charset)); |
288 |
return False; |
return False; |
292 |
else if (target == format_unicode_atom) |
else if (target == format_unicode_atom) |
293 |
{ |
{ |
294 |
cd = iconv_open(WINDOWS_CODEPAGE, "UCS-2"); |
cd = iconv_open(WINDOWS_CODEPAGE, "UCS-2"); |
295 |
if (cd == (iconv_t)-1) |
if (cd == (iconv_t) - 1) |
296 |
{ |
{ |
297 |
return False; |
return False; |
298 |
} |
} |
301 |
else if (target == format_utf8_string_atom) |
else if (target == format_utf8_string_atom) |
302 |
{ |
{ |
303 |
cd = iconv_open(WINDOWS_CODEPAGE, "UTF-8"); |
cd = iconv_open(WINDOWS_CODEPAGE, "UTF-8"); |
304 |
if (cd == (iconv_t)-1) |
if (cd == (iconv_t) - 1) |
305 |
{ |
{ |
306 |
return False; |
return False; |
307 |
} |
} |
317 |
|
|
318 |
unicode_buffer = xmalloc(unicode_buffer_size); |
unicode_buffer = xmalloc(unicode_buffer_size); |
319 |
size_t unicode_buffer_size_remaining = unicode_buffer_size; |
size_t unicode_buffer_size_remaining = unicode_buffer_size; |
320 |
char* unicode_buffer_remaining = unicode_buffer; |
char *unicode_buffer_remaining = unicode_buffer; |
321 |
char* data_remaining = (char*)source; |
char *data_remaining = (char *) source; |
322 |
size_t data_size_remaining = source_size; |
size_t data_size_remaining = source_size; |
323 |
iconv(cd, &data_remaining, &data_size_remaining, &unicode_buffer_remaining, &unicode_buffer_size_remaining); |
iconv(cd, &data_remaining, &data_size_remaining, &unicode_buffer_remaining, |
324 |
|
&unicode_buffer_size_remaining); |
325 |
iconv_close(cd); |
iconv_close(cd); |
326 |
|
|
327 |
/* translate linebreaks */ |
/* translate linebreaks */ |
328 |
uint32 translated_data_size = unicode_buffer_size - unicode_buffer_size_remaining; |
uint32 translated_data_size = unicode_buffer_size - unicode_buffer_size_remaining; |
329 |
uint8* translated_data = utf16_lf2crlf((uint8*)unicode_buffer, &translated_data_size); |
uint8 *translated_data = |
330 |
|
utf16_lf2crlf((uint8 *) unicode_buffer, &translated_data_size); |
331 |
if (translated_data != NULL) |
if (translated_data != NULL) |
332 |
{ |
{ |
333 |
DEBUG_CLIPBOARD(("Sending Unicode string of %d bytes\n", translated_data_size)); |
DEBUG_CLIPBOARD(("Sending Unicode string of %d bytes\n", |
334 |
|
translated_data_size)); |
335 |
cliprdr_send_data(translated_data, translated_data_size); |
cliprdr_send_data(translated_data, translated_data_size); |
336 |
xfree(translated_data); /* Not the same thing as XFree! */ |
xfree(translated_data); /* Not the same thing as XFree! */ |
337 |
} |
} |
340 |
|
|
341 |
return True; |
return True; |
342 |
} |
} |
343 |
#else |
#else |
344 |
if (target == format_string_atom) |
if (target == format_string_atom) |
345 |
{ |
{ |
346 |
uint8 *translated_data; |
uint8 *translated_data; |
359 |
|
|
360 |
return True; |
return True; |
361 |
} |
} |
362 |
#endif |
#endif |
363 |
else if (target == rdesktop_clipboard_formats_atom) |
else if (target == rdesktop_clipboard_formats_atom) |
364 |
{ |
{ |
365 |
helper_cliprdr_send_response(source, source_size + 1); |
helper_cliprdr_send_response(source, source_size + 1); |
434 |
(ignore TEXT and COMPOUND_TEXT because we don't have code to handle them) |
(ignore TEXT and COMPOUND_TEXT because we don't have code to handle them) |
435 |
*/ |
*/ |
436 |
int text_target_satisfaction = 0; |
int text_target_satisfaction = 0; |
437 |
Atom best_text_target = 0; /* measures how much we're satisfied with what we found */ |
Atom best_text_target = 0; /* measures how much we're satisfied with what we found */ |
438 |
if (type != None) |
if (type != None) |
439 |
{ |
{ |
440 |
supported_targets = (Atom *) data; |
supported_targets = (Atom *) data; |
451 |
text_target_satisfaction = 1; |
text_target_satisfaction = 1; |
452 |
} |
} |
453 |
} |
} |
454 |
#ifdef USE_UNICODE_CLIPBOARD |
#ifdef USE_UNICODE_CLIPBOARD |
455 |
else if (supported_targets[i] == format_unicode_atom) |
else if (supported_targets[i] == format_unicode_atom) |
456 |
{ |
{ |
457 |
if (text_target_satisfaction < 2) |
if (text_target_satisfaction < 2) |
470 |
text_target_satisfaction = 3; |
text_target_satisfaction = 3; |
471 |
} |
} |
472 |
} |
} |
473 |
#endif |
#endif |
474 |
} |
} |
475 |
} |
} |
476 |
|
|
479 |
*/ |
*/ |
480 |
if (best_text_target != 0) |
if (best_text_target != 0) |
481 |
{ |
{ |
482 |
XConvertSelection(g_display, clipboard_atom, best_text_target, rdesktop_clipboard_target_atom, g_wnd, event->time); |
XConvertSelection(g_display, clipboard_atom, best_text_target, |
483 |
|
rdesktop_clipboard_target_atom, g_wnd, event->time); |
484 |
return; |
return; |
485 |
} |
} |
486 |
else |
else |
553 |
Otherwise, we default to RDP_CF_TEXT. |
Otherwise, we default to RDP_CF_TEXT. |
554 |
*/ |
*/ |
555 |
res = XGetWindowProperty(g_display, event->requestor, |
res = XGetWindowProperty(g_display, event->requestor, |
556 |
rdesktop_clipboard_target_atom, 0, 1, True, XA_INTEGER, |
rdesktop_clipboard_target_atom, 0, 1, True, |
557 |
&type, &format, &nitems, &bytes_left, &prop_return); |
XA_INTEGER, &type, &format, &nitems, &bytes_left, |
558 |
|
&prop_return); |
559 |
wanted_format = (uint32 *) prop_return; |
wanted_format = (uint32 *) prop_return; |
560 |
format = (res == Success) ? *wanted_format : RDP_CF_TEXT; |
format = (res == Success) ? *wanted_format : RDP_CF_TEXT; |
561 |
XFree(prop_return); |
XFree(prop_return); |
562 |
} |
} |
563 |
else if (event->target == format_string_atom || |
else if (event->target == format_string_atom || event->target == XA_STRING) |
|
event->target == XA_STRING) |
|
564 |
{ |
{ |
565 |
/* STRING and XA_STRING are defined to be ISO8859-1 */ |
/* STRING and XA_STRING are defined to be ISO8859-1 */ |
566 |
format = CF_TEXT; |
format = CF_TEXT; |
567 |
} |
} |
568 |
else if (event->target == format_utf8_string_atom) |
else if (event->target == format_utf8_string_atom) |
569 |
{ |
{ |
570 |
#ifdef USE_UNICODE_CLIPBOARD |
#ifdef USE_UNICODE_CLIPBOARD |
571 |
format = CF_UNICODETEXT; |
format = CF_UNICODETEXT; |
572 |
#else |
#else |
573 |
DEBUG_CLIPBOARD(("Requested target unavailable due to lack of Unicode support. (It was not in TARGETS, so why did you ask for it?!)\n")); |
DEBUG_CLIPBOARD(("Requested target unavailable due to lack of Unicode support. (It was not in TARGETS, so why did you ask for it?!)\n")); |
574 |
xclip_refuse_selection(event); |
xclip_refuse_selection(event); |
575 |
return; |
return; |
576 |
#endif |
#endif |
577 |
} |
} |
578 |
else if (event->target == format_unicode_atom) |
else if (event->target == format_unicode_atom) |
579 |
{ |
{ |
590 |
cliprdr_send_data_request(format); |
cliprdr_send_data_request(format); |
591 |
selection_request = *event; |
selection_request = *event; |
592 |
has_selection_request = True; |
has_selection_request = True; |
593 |
return; /* wait for data */ |
return; /* wait for data */ |
594 |
} |
} |
595 |
} |
} |
596 |
|
|
654 |
|
|
655 |
if (g_clip_buflen > 0) |
if (g_clip_buflen > 0) |
656 |
{ |
{ |
657 |
if (!xclip_send_data_with_convert(g_clip_buffer, g_clip_buflen, g_incr_target)) |
if (!xclip_send_data_with_convert |
658 |
|
(g_clip_buffer, g_clip_buflen, g_incr_target)) |
659 |
{ |
{ |
660 |
helper_cliprdr_send_empty_response(); |
helper_cliprdr_send_empty_response(); |
661 |
} |
} |
667 |
else |
else |
668 |
{ |
{ |
669 |
/* Another chunk in the INCR transfer */ |
/* Another chunk in the INCR transfer */ |
670 |
offset += (nitems / 4); /* offset at which to begin the next slurp */ |
offset += (nitems / 4); /* offset at which to begin the next slurp */ |
671 |
g_clip_buffer = xrealloc(g_clip_buffer, g_clip_buflen + nitems); |
g_clip_buffer = xrealloc(g_clip_buffer, g_clip_buflen + nitems); |
672 |
memcpy(g_clip_buffer + g_clip_buflen, data, nitems); |
memcpy(g_clip_buffer + g_clip_buflen, data, nitems); |
673 |
g_clip_buflen += nitems; |
g_clip_buflen += nitems; |
681 |
|
|
682 |
if ((event->atom == rdesktop_clipboard_formats_atom) && |
if ((event->atom == rdesktop_clipboard_formats_atom) && |
683 |
(event->window == DefaultRootWindow(g_display)) && |
(event->window == DefaultRootWindow(g_display)) && |
684 |
!have_primary /* not interested in our own events */) |
!have_primary /* not interested in our own events */ ) |
685 |
{ |
{ |
686 |
if (event->state == PropertyNewValue) |
if (event->state == PropertyNewValue) |
687 |
{ |
{ |
689 |
|
|
690 |
res = XGetWindowProperty(g_display, DefaultRootWindow(g_display), |
res = XGetWindowProperty(g_display, DefaultRootWindow(g_display), |
691 |
rdesktop_clipboard_formats_atom, 0, |
rdesktop_clipboard_formats_atom, 0, |
692 |
XMaxRequestSize(g_display), False, XA_STRING, &type, |
XMaxRequestSize(g_display), False, XA_STRING, |
693 |
&format, &nitems, &bytes_left, &data); |
&type, &format, &nitems, &bytes_left, &data); |
694 |
|
|
695 |
if ((res == Success) && (nitems > 0)) |
if ((res == Success) && (nitems > 0)) |
696 |
{ |
{ |
739 |
{ |
{ |
740 |
BOOL free_data = False; |
BOOL free_data = False; |
741 |
|
|
742 |
if (selection_request.target == format_string_atom || |
if (selection_request.target == format_string_atom || selection_request.target == XA_STRING) |
743 |
selection_request.target == XA_STRING) |
{ |
|
{ |
|
744 |
/* We're expecting a CF_TEXT response */ |
/* We're expecting a CF_TEXT response */ |
745 |
uint8 *firstnull; |
uint8 *firstnull; |
746 |
|
|
747 |
/* translate linebreaks */ |
/* translate linebreaks */ |
748 |
crlf2lf(data, &length); |
crlf2lf(data, &length); |
749 |
|
|
750 |
/* Only send data up to null byte, if any */ |
/* Only send data up to null byte, if any */ |
751 |
firstnull = (uint8 *) strchr((char *) data, '\0'); |
firstnull = (uint8 *) strchr((char *) data, '\0'); |
752 |
if (firstnull) |
if (firstnull) |
753 |
{ |
{ |
754 |
length = firstnull - data + 1; |
length = firstnull - data + 1; |
755 |
} |
} |
756 |
} |
} |
757 |
#ifdef USE_UNICODE_CLIPBOARD |
#ifdef USE_UNICODE_CLIPBOARD |
758 |
else if (selection_request.target == format_utf8_string_atom) |
else if (selection_request.target == format_utf8_string_atom) |
759 |
{ |
{ |
760 |
/* We're expecting a CF_UNICODETEXT response */ |
/* We're expecting a CF_UNICODETEXT response */ |
761 |
iconv_t cd = iconv_open("UTF-8", WINDOWS_CODEPAGE); |
iconv_t cd = iconv_open("UTF-8", WINDOWS_CODEPAGE); |
762 |
if (cd != (iconv_t)-1) |
if (cd != (iconv_t) - 1) |
763 |
{ |
{ |
764 |
size_t utf8_length = length * 2; |
size_t utf8_length = length * 2; |
765 |
char* utf8_data = malloc(utf8_length); |
char *utf8_data = malloc(utf8_length); |
766 |
size_t utf8_length_remaining = utf8_length; |
size_t utf8_length_remaining = utf8_length; |
767 |
char* utf8_data_remaining = utf8_data; |
char *utf8_data_remaining = utf8_data; |
768 |
char* data_remaining = (char*)data; |
char *data_remaining = (char *) data; |
769 |
size_t length_remaining = (size_t)length; |
size_t length_remaining = (size_t) length; |
770 |
if (utf8_data == NULL) |
if (utf8_data == NULL) |
771 |
{ |
{ |
772 |
iconv_close(cd); |
iconv_close(cd); |
773 |
return; |
return; |
774 |
} |
} |
775 |
iconv(cd, &data_remaining, &length_remaining, &utf8_data_remaining, &utf8_length_remaining); |
iconv(cd, &data_remaining, &length_remaining, &utf8_data_remaining, |
776 |
|
&utf8_length_remaining); |
777 |
iconv_close(cd); |
iconv_close(cd); |
778 |
free_data = True; |
free_data = True; |
779 |
data = (uint8*)utf8_data; |
data = (uint8 *) utf8_data; |
780 |
length = utf8_length - utf8_length_remaining; |
length = utf8_length - utf8_length_remaining; |
781 |
} |
} |
782 |
} |
} |
872 |
targets[num_targets++] = timestamp_atom; |
targets[num_targets++] = timestamp_atom; |
873 |
targets[num_targets++] = rdesktop_clipboard_formats_atom; |
targets[num_targets++] = rdesktop_clipboard_formats_atom; |
874 |
targets[num_targets++] = format_string_atom; |
targets[num_targets++] = format_string_atom; |
875 |
#ifdef USE_UNICODE_CLIPBOARD |
#ifdef USE_UNICODE_CLIPBOARD |
876 |
targets[num_targets++] = format_utf8_string_atom; |
targets[num_targets++] = format_utf8_string_atom; |
877 |
#endif |
#endif |
878 |
targets[num_targets++] = format_unicode_atom; |
targets[num_targets++] = format_unicode_atom; |
879 |
targets[num_targets++] = XA_STRING; |
targets[num_targets++] = XA_STRING; |
880 |
|
|