Changeset 3321 in vbox for trunk/src/VBox/Additions/linux/xclient
- Timestamp:
- Jun 27, 2007 5:36:14 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 22446
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/xclient/clipboard.cpp
r3287 r3321 25 25 #define USE_UTF16 26 26 #define USE_UTF8 27 #define USE_CTEXT 27 28 #define USE_LATIN1 28 29 … … 81 82 TARGETS, 82 83 LATIN1, 84 CTEXT, 83 85 UTF8, 84 86 UTF16 … … 359 361 360 362 /** 361 * Convert a Utf16 text with Linux EOLs to Utf16-LE with Windows EOLs, allocating memory362 * for the converted text. Does no checking for validity.363 * Convert a Utf16 text with Linux EOLs to zero-terminated Utf16-LE with Windows EOLs, allocating 364 * memory for the converted text. Does no checking for validity. 363 365 * 364 366 * @returns VBox status code … … 385 387 return VINF_SUCCESS; 386 388 } 387 AssertReturn( pu16Src != 0, VERR_INVALID_PARAMETER);389 AssertReturn(VALID_PTR(pu16Src), VERR_INVALID_PARAMETER); 388 390 cwDest = 0; 389 391 for (i = 0; i < cwSrc; ++i, ++cwDest) … … 393 395 ++cwDest; 394 396 } 395 } 396 /* Leave space for a trailing null in any case */ 397 if (pu16Src[i] == 0) 398 { 399 break; 400 } 401 } 402 /* Leave space for a trailing null */ 397 403 ++cwDest; 398 404 pu16Dest = reinterpret_cast<PRTUTF16>(RTMemAlloc(cwDest * 2)); … … 408 414 pu16Dest[j] = CARRIAGERETURN; 409 415 ++j; 416 } 417 if (pu16Src[i] == 0) 418 { 419 break; 410 420 } 411 421 pu16Dest[j] = pu16Src[i]; … … 496 506 497 507 /** 508 * Convert the compound text returned from the guest X11 clipboard to UTF-16LE with Windows EOLs 509 * and send it to the host. 510 * 511 * @param pValue Source compound text 512 * @param cbSourceLen Length in 8-bit bytes of the source text 513 */ 514 static void vboxClipboardGetCText(XtPointer pValue, size_t cbSourceLen) 515 { 516 size_t cwSourceLen, cwDestLen; 517 char **ppu8SourceText = 0; 518 PRTUTF16 pu16SourceText = 0, pu16DestText; 519 XTextProperty property; 520 int rc, cProps; 521 522 LogFlowFunc(("\n")); 523 Log2 (("vboxClipboardGetCText: converting compound text to Utf-16LE. Original is %.*s\n", 524 cbSourceLen, pValue)); 525 /* First convert the compound text to Utf8 */ 526 property.value = reinterpret_cast<unsigned char *>(pValue); 527 property.encoding = g_ctx.atomCText; 528 property.format = 8; 529 property.nitems = cbSourceLen; 530 rc = Xutf8TextPropertyToTextList(XtDisplay(g_ctx.widget), &property, &ppu8SourceText, &cProps); 531 XtFree(reinterpret_cast<char *>(pValue)); 532 if (rc < 0) 533 { 534 char *pcReason; 535 switch(rc) 536 { 537 case XNoMemory: 538 pcReason = "out of memory"; 539 break; 540 case XLocaleNotSupported: 541 pcReason = "locale (Utf8) not supported"; 542 break; 543 case XConverterNotFound: 544 pcReason = "converter not found"; 545 break; 546 default: 547 pcReason = "unknown error"; 548 } 549 XFreeStringList(ppu8SourceText); 550 LogRel(("vboxClipboardGetCText: Xutf8TextPropertyToTextList failed. Reason: %s\n", 551 pcReason)); 552 vboxClipboardSendData (0, 0, 0); 553 LogFlowFunc(("sending empty data and returning\n")); 554 return; 555 } 556 /* Next convert the UTF8 to UTF16 */ 557 rc = RTStrToUtf16Ex(*ppu8SourceText, cbSourceLen, &pu16SourceText, 0, &cwSourceLen); 558 XFreeStringList(ppu8SourceText); 559 if (rc != VINF_SUCCESS) 560 { 561 vboxClipboardSendData (0, 0, 0); 562 LogFlowFunc(("sending empty data and returning\n")); 563 return; 564 } 565 rc = vboxClipboardUtf16LinToWin(pu16SourceText, cwSourceLen, &pu16DestText, &cwDestLen); 566 RTMemFree(reinterpret_cast<void *>(pu16SourceText)); 567 if (rc != VINF_SUCCESS) 568 { 569 vboxClipboardSendData (0, 0, 0); 570 LogFlowFunc(("sending empty data and returning\n")); 571 return; 572 } 573 Log2 (("vboxClipboardGetCText: converted string is %.*ls\n", cwDestLen, pu16DestText)); 574 vboxClipboardSendData (VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 575 reinterpret_cast<void *>(pu16DestText), cwDestLen * 2); 576 RTMemFree(reinterpret_cast<void *>(pu16DestText)); 577 LogFlowFunc(("returning\n")); 578 } 579 580 /** 498 581 * Convert the Latin1 text returned from the guest X11 clipboard to UTF-16LE with Windows EOLs 499 582 * and send it to the host. … … 572 655 case UTF16: 573 656 vboxClipboardGetUtf16(pValue, cTextLen / 2); 657 break; 658 case CTEXT: 659 vboxClipboardGetCText(pValue, cTextLen); 574 660 break; 575 661 case UTF8: … … 788 874 789 875 /** 790 * Get the size of the buffer needed to hold a Utf16 string with Linux EOLs converted from791 * a Utf16 string with Windows EOLs.876 * Get the size of the buffer needed to hold a zero-terminated Utf16 string with Linux EOLs 877 * converted from a Utf16 string with Windows EOLs. 792 878 * 793 879 * @returns The size of the buffer needed in bytes … … 801 887 size_t cwDest; 802 888 803 LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u ", cwSrc, pu16Src, cwSrc));889 LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u\n", cwSrc, pu16Src, cwSrc)); 804 890 AssertReturn(pu16Src != 0, VERR_INVALID_PARAMETER); 805 891 /* We only take little endian Utf16 */ … … 824 910 if (pu16Src[i] == 0) 825 911 { 826 /* The terminating zero is included in the size */827 ++cwDest;828 912 break; 829 913 } 830 914 } 915 /* The terminating null */ 916 ++cwDest; 831 917 LogFlowFunc(("returning %d\n", cwDest * 2)); 832 918 return cwDest * 2; … … 851 937 852 938 LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u, pu16Dest=%p, cwDest=%u\n", 853 cwSrc, pu16Src, cwSrc, pu16Dest, cwDest));939 cwSrc, pu16Src, cwSrc, pu16Dest, cwDest)); 854 940 /* A buffer of size 0 may not be an error, but it is not a good idea either. */ 855 941 Assert(cwDest > 0); 856 AssertReturn( pu16Src != 0, VERR_INVALID_PARAMETER);942 AssertReturn(VALID_PTR(pu16Src), VERR_INVALID_PARAMETER); 857 943 /* We only take little endian Utf16 */ 858 944 AssertReturn(pu16Src[0] != 0xfffe, VERR_INVALID_PARAMETER); … … 898 984 } 899 985 } 900 LogFlowFunc(("set string %.*ls. Returning\n", cwDestPos, pu16Dest)); 986 if (cwDestPos == cwDest) 987 { 988 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n")); 989 return VERR_BUFFER_OVERFLOW; 990 } 991 pu16Dest[cwDestPos] = 0; 992 LogFlowFunc(("set string %ls. Returning\n", pu16Dest + 1)); 901 993 return VINF_SUCCESS; 902 994 } … … 992 1084 } 993 1085 cwHostText = cbHostText / 2; 1086 Log2 (("vboxClipboardConvertUtf8: original text is %.*ls\n", cwHostText, pu16HostText)); 994 1087 cwGuestText = vboxClipboardUtf16GetLinSize(pu16HostText, cwHostText); 995 1088 pu16GuestText = reinterpret_cast<PRTUTF16>(RTMemAlloc(cwGuestText * 2)); … … 1001 1094 } 1002 1095 rc = vboxClipboardUtf16WinToLin(pu16HostText, cwHostText, pu16GuestText, cwGuestText); 1096 RTMemFree(reinterpret_cast<char *>(pu16HostText)); 1003 1097 if (rc != VINF_SUCCESS) 1004 1098 { 1005 1099 Log2(("vboxClipboardConvertUtf16: vboxClipboardUtf16WinToLin returned %Vrc\n", rc)); 1006 RTMemFree(reinterpret_cast<char *>(pu16HostText));1007 1100 RTMemFree(reinterpret_cast<char *>(pu16GuestText)); 1008 1101 LogFlowFunc(("rc = false\n")); … … 1011 1104 /* Now convert the Utf16 Linux text to Utf8 */ 1012 1105 cbGuestText = cwGuestText * 3; /* Should always be enough. */ 1013 if (rc != VINF_SUCCESS)1014 {1015 RTMemFree(reinterpret_cast<char *>(pu16HostText));1106 pcGuestText = XtMalloc(cbGuestText); 1107 if (pcGuestText == 0) 1108 { 1016 1109 RTMemFree(reinterpret_cast<char *>(pu16GuestText)); 1017 1110 LogFlowFunc(("rc = false\n")); 1018 1111 return false; 1019 1112 } 1020 pcGuestText = XtMalloc(cbGuestText);1021 1113 /* Our runtime can't cope with endian markers. */ 1022 1114 rc = RTUtf16ToUtf8Ex(pu16GuestText + 1, cwGuestText - 1, &pcGuestText, cbGuestText, 0); 1115 RTMemFree(reinterpret_cast<char *>(pu16GuestText)); 1023 1116 if (rc != VINF_SUCCESS) 1024 1117 { 1025 RTMemFree(reinterpret_cast<char *>(pu16HostText));1026 RTMemFree(reinterpret_cast<char *>(pu16GuestText));1027 1118 XtFree(pcGuestText); 1028 1119 LogFlowFunc(("rc = false\n")); 1029 1120 return false; 1030 1121 } 1031 Log2 (("vboxClipboardConvertUtf8: returning Utf-8, original text is %.*ls\n", cwHostText,1032 pu16HostText));1033 1122 Log2 (("vboxClipboardConvertUtf8: converted text is %.*s\n", cbGuestText, pcGuestText)); 1034 RTMemFree(reinterpret_cast<char *>(pu16HostText));1035 RTMemFree(reinterpret_cast<char *>(pu16GuestText));1036 1123 *atomTypeReturn = g_ctx.atomUtf8; 1037 1124 *pValReturn = reinterpret_cast<XtPointer>(pcGuestText); 1038 1125 *pcLenReturn = cbGuestText; 1039 1126 *piFormatReturn = 8; 1127 LogFlowFunc(("rc = true\n")); 1128 return true; 1129 } 1130 1131 /** 1132 * Satisfy a request from the guest to convert the clipboard text to compound text. 1133 * 1134 * @returns true if we successfully convert the data to the format requested, false otherwise. 1135 * 1136 * @param atomTypeReturn The type of the data we are returning 1137 * @param pValReturn A pointer to the data we are returning. This should be to memory 1138 * allocated by XtMalloc, which will be freed by the toolkit later 1139 * @param pcLenReturn The length of the data we are returning 1140 * @param piFormatReturn The format (8bit, 16bit, 32bit) of the data we are returning 1141 */ 1142 static Boolean vboxClipboardConvertCText(Atom *atomTypeReturn, XtPointer *pValReturn, 1143 unsigned long *pcLenReturn, int *piFormatReturn) 1144 { 1145 PRTUTF16 pu16GuestText, pu16HostText; 1146 char *pcUtf8Text; 1147 unsigned cbHostText, cwHostText, cwGuestText, cbUtf8Text; 1148 XTextProperty property; 1149 int rc; 1150 1151 LogFlowFunc(("\n")); 1152 /* Get the host Utf16 data and convert it to Linux Utf16. */ 1153 rc = vboxClipboardReadHostData(VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 1154 reinterpret_cast<void **>(&pu16HostText), &cbHostText); 1155 if ((rc != VINF_SUCCESS) || cbHostText == 0) 1156 { 1157 Log (("vboxClipboardConvertCText: vboxClipboardReadHostData returned %Vrc, %d bytes of data\n", rc, cbHostText)); 1158 g_ctx.hostFormats = 0; 1159 LogFlowFunc(("rc = false\n")); 1160 return false; 1161 } 1162 Log2 (("vboxClipboardConvertCText: original text is %.*ls\n", cwHostText, pu16HostText)); 1163 cwHostText = cbHostText / 2; 1164 cwGuestText = vboxClipboardUtf16GetLinSize(pu16HostText, cwHostText); 1165 pu16GuestText = reinterpret_cast<PRTUTF16>(RTMemAlloc(cwGuestText * 2)); 1166 if (pu16GuestText == 0) 1167 { 1168 Log(("vboxClipboardConvertCText: out of memory\n")); 1169 RTMemFree(reinterpret_cast<char *>(pu16HostText)); 1170 LogFlowFunc(("rc = false\n")); 1171 return false; 1172 } 1173 rc = vboxClipboardUtf16WinToLin(pu16HostText, cwHostText, pu16GuestText, cwGuestText); 1174 RTMemFree(reinterpret_cast<char *>(pu16HostText)); 1175 if (rc != VINF_SUCCESS) 1176 { 1177 Log2(("vboxClipboardConvertUtf16: vboxClipboardUtf16WinToLin returned %Vrc\n", rc)); 1178 RTMemFree(reinterpret_cast<char *>(pu16GuestText)); 1179 LogFlowFunc(("rc = false\n")); 1180 return false; 1181 } 1182 /* Now convert the Utf16 Linux text to Utf8 */ 1183 cbUtf8Text = cwGuestText * 3; /* Should always be enough. */ 1184 pcUtf8Text = reinterpret_cast<char *>(RTMemAlloc(cbUtf8Text)); 1185 if (pcUtf8Text == 0) 1186 { 1187 Log(("vboxClipboardConvertCText: out of memory\n")); 1188 RTMemFree(reinterpret_cast<char *>(pu16GuestText)); 1189 LogFlowFunc(("rc = false\n")); 1190 return false; 1191 } 1192 /* Our runtime can't cope with endian markers. */ 1193 rc = RTUtf16ToUtf8Ex(pu16GuestText + 1, cwGuestText - 1, &pcUtf8Text, cbUtf8Text, 0); 1194 RTMemFree(reinterpret_cast<char *>(pu16GuestText)); 1195 if (rc != VINF_SUCCESS) 1196 { 1197 Log(("vboxClipboardConvertCText: RTUtf16ToUtf8Ex failed: rc=%Vrc\n", rc)); 1198 XtFree(pcUtf8Text); 1199 LogFlowFunc(("rc = false\n")); 1200 return false; 1201 } 1202 /* And finally (!) convert the Utf8 text to compound text. */ 1203 rc = Xutf8TextListToTextProperty(XtDisplay(g_ctx.widget), &pcUtf8Text, 1, 1204 XCompoundTextStyle, &property); 1205 RTMemFree(pcUtf8Text); 1206 if (rc < 0) 1207 { 1208 char *pcReason; 1209 switch(rc) 1210 { 1211 case XNoMemory: 1212 pcReason = "out of memory"; 1213 break; 1214 case XLocaleNotSupported: 1215 pcReason = "locale (Utf8) not supported"; 1216 break; 1217 case XConverterNotFound: 1218 pcReason = "converter not found"; 1219 break; 1220 default: 1221 pcReason = "unknown error"; 1222 } 1223 LogRel(("vboxClipboardConvertCText: Xutf8TextListToTextProperty failed. Reason: %s\n", 1224 pcReason)); 1225 XFree(property.value); 1226 LogFlowFunc(("rc = false\n")); 1227 return false; 1228 } 1229 Log2 (("vboxClipboardConvertCText: converted text is %s\n", property.value)); 1230 *atomTypeReturn = property.encoding; 1231 *pValReturn = reinterpret_cast<XtPointer>(property.value); 1232 *pcLenReturn = property.nitems; 1233 *piFormatReturn = property.format; 1040 1234 LogFlowFunc(("rc = true\n")); 1041 1235 return true; … … 1160 1354 } 1161 1355 } 1162 if (*atomTarget == g_ctx.atomCText)1163 {1164 /* We do not support compound text conversion. However, as we are required to do so by1165 the X11 standards, we return Latin-1 if we are asked to do so anyway. */1166 LogRel(("An application on your guest system has asked for clipboard data in COMPOUND_TEXT format. Since VirtualBox does not support this format, international characters will get lost. Please set up your guest applications to use Unicode!\n"));1167 eFormat = LATIN1;1168 }1169 1356 switch (eFormat) 1170 1357 { … … 1179 1366 case UTF8: 1180 1367 rc = vboxClipboardConvertUtf8(atomTypeReturn, pValReturn, pcLenReturn, piFormatReturn); 1368 LogFlowFunc(("rc=%d\n", rc)); 1369 return rc; 1370 case CTEXT: 1371 rc = vboxClipboardConvertCText(atomTypeReturn, pValReturn, pcLenReturn, piFormatReturn); 1181 1372 LogFlowFunc(("rc=%d\n", rc)); 1182 1373 return rc; … … 1520 1711 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT); 1521 1712 #endif 1713 #ifdef USE_CTEXT 1714 vboxClipboardAddFormat("COMPOUND_TEXT", CTEXT, 1715 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT); 1716 #endif 1522 1717 #ifdef USE_LATIN1 1523 1718 vboxClipboardAddFormat("STRING", LATIN1,
Note:
See TracChangeset
for help on using the changeset viewer.