Changeset 92158 in vbox for trunk/src/VBox/ValidationKit
- Timestamp:
- Oct 30, 2021 12:06:36 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 147981
- Location:
- trunk/src/VBox/ValidationKit/utils/clipboard
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/clipboard/ClipUtil.cpp
r92026 r92158 50 50 #include <iprt/zero.h> 51 51 52 #ifdef RT_OS_WINDOWS 52 #ifdef RT_OS_DARWIN 53 /** @todo */ 54 #elif defined(RT_OS_WINDOWS) 53 55 # include <iprt/nt/nt-and-windows.h> 56 #elif !defined(RT_OS_OS2) 57 # include <X11/Xlib.h> 58 # include <X11/Xatom.h> 54 59 #endif 55 60 … … 60 65 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) || defined(RT_OS_DARWIN) 61 66 # undef MULTI_TARGET_CLIPBOARD 67 # undef CU_X11 62 68 #else 63 69 # define MULTI_TARGET_CLIPBOARD 70 # define CU_X11 64 71 #endif 65 72 … … 92 99 CFStringRef *hStrFormat; 93 100 #else 101 /** The X11 atom for the format. */ 102 Atom uAtom; 103 /** The X11 atom name if uAtom must be termined dynamically. */ 104 const char *pszAtomName; 94 105 /** @todo X11 */ 95 106 #endif … … 105 116 /** Convert to/from UTF-8. */ 106 117 #define CLIPUTILFORMAT_F_CONVERT_UTF8 RT_BIT_32(0) 107 108 118 /** Ad hoc entry. */ 119 #define CLIPUTILFORMAT_F_AD_HOC RT_BIT_32(1) 120 121 122 #ifdef MULTI_TARGET_CLIPBOARD 109 123 /** 110 124 * Clipboard target descriptor. … … 114 128 /** Target name. */ 115 129 const char *pszName; 130 /** The X11 atom for the target. */ 131 Atom uAtom; 132 /** The X11 atom name if uAtom must be termined dynamically. */ 133 const char *pszAtomName; 116 134 /** Description. */ 117 135 const char *pszDesc; … … 119 137 /** Pointer to clipboard target descriptor. */ 120 138 typedef CLIPUTILTARGET const *PCCLIPUTILTARGET; 139 #endif /* MULTI_TARGET_CLIPBOARD */ 121 140 122 141 … … 146 165 147 166 /** Format descriptors. */ 148 static constCLIPUTILFORMAT g_aFormats[] =167 static CLIPUTILFORMAT g_aFormats[] = 149 168 { 150 169 #if defined(RT_OS_WINDOWS) … … 165 184 #else 166 185 /** @todo X11 */ 167 { "text/utf-8", "UTF-8 text", 0 },186 { "text/utf-8", None, "UTF8_STRING", "UTF-8 text", 0 }, 168 187 #endif 169 188 }; 170 189 190 #ifdef MULTI_TARGET_CLIPBOARD 171 191 /** Target descriptors. */ 172 static const CLIPUTILTARGET g_aTargets[] = 173 { 174 #ifndef MULTI_TARGET_CLIPBOARD 175 { "default", "placeholder" } 176 #else 177 { "default", "default" }, /** @todo X11 */ 178 #endif 192 static CLIPUTILTARGET g_aTargets[] = 193 { 194 { "clipboard", 0, "CLIPBOARD", "XA_CLIPBOARD: The clipboard (default)" }, 195 { "primary", XA_PRIMARY, NULL, "XA_PRIMARY: Primary selected text (middle mouse button)" }, 196 { "secondary", XA_SECONDARY, NULL, "XA_SECONDARY: Secondary selected text (with ctrl)" }, 179 197 }; 198 199 /** The current clipboard target. */ 200 static CLIPUTILTARGET *g_pTarget = &g_aTargets[0]; 201 #endif /* MULTI_TARGET_CLIPBOARD */ 180 202 181 203 /** The -v/-q state. */ 182 204 static unsigned g_uVerbosity = 1; 183 205 184 #ifdef RT_OS_WINDOWS 206 #ifdef RT_OS_DARWIN 207 208 #elif defined(RT_OS_OS2) 209 /** Anchorblock handle. */ 210 static HAB g_hOs2Hab = NULLHANDLE; 211 /** The message queue handle. */ 212 static HMQ g_hOs2MsgQueue = NULLHANDLE; 213 /** Set if we've opened the clipboard. */ 214 static bool g_fOs2OpenedClipboard = false; 215 216 #elif defined(RT_OS_WINDOWS) 217 /** Set if we've opened the clipboard. */ 185 218 static bool g_fOpenedClipboard = false; 186 #endif 187 188 189 /** 190 * Gets a format descriptor, complaining if unknown format. 219 220 #else 221 /** Number of errors (incremented by error handle callback). */ 222 static uint32_t volatile g_cX11Errors; 223 /** The X11 display. */ 224 static Display *g_pX11Display = NULL; 225 /** The X11 dummy window. */ 226 static Window g_hX11Window = 0; 227 /** TARGETS */ 228 static Atom g_uX11AtomTargets; 229 /** MULTIPLE */ 230 static Atom g_uX11AtomMultiple; 231 232 #endif 233 234 235 /** 236 * Gets a format descriptor, complaining if invalid format. 191 237 * 192 238 * @returns Pointer to the descriptor if found, NULL + msg if not. … … 196 242 { 197 243 for (size_t i = 0; i < RT_ELEMENTS(g_aFormats); i++) 198 if (strcmp(pszFormat, g_aFormats[i].pszName)) 244 if (strcmp(pszFormat, g_aFormats[i].pszName) == 0) 245 { 246 #if defined(RT_OS_DARWIN) 247 /** @todo */ 248 249 #elif defined(RT_OS_OS2) 250 if (g_aFormats[i].pszFormat && g_aFormats[i].fFormat == 0) 251 { 252 g_aFormats[i].fFormat = WinAddAtom(WinQuerySystemAtomTable(), g_aFormats[i].pszFormat); 253 if (g_aFormats[i].fFormat == 0) 254 RTMsgError("WinAddAtom(,%s) failed: %u (%#x)", g_aFormats[i].pszFormat, WinGetLastError(), WinGetLastError()); 255 } 256 257 #elif defined(RT_OS_WINDOWS) 258 if (g_aFormats[i].pwszFormat && g_aFormats[i].fFormat == 0) 259 { 260 g_aFormats[i].fFormat = RegisterClipboardFormatW(pFmtDesc->pwszFormat); 261 if (g_aFormats[i].fFormat == 0) 262 RTMsgError("RegisterClipboardFormatW(%ls) failed: %u (%#x)", 263 g_aFormats[i].pwszFormat, GetLastError(), GetLastError()); 264 } 265 #elif defined(CU_X11) 266 if (g_aFormats[i].pszAtomName && g_aFormats[i].uAtom == 0) 267 g_aFormats[i].uAtom = XInternAtom(g_pX11Display, g_aFormats[i].pszAtomName, False); 268 #endif 199 269 return &g_aFormats[i]; 200 RTMsgError("Unknown format '%s'", pszFormat); 201 return NULL; 202 } 203 204 #ifdef RT_OS_WINDOWS 270 } 271 272 /* 273 * Try register the format. 274 */ 275 static CLIPUTILFORMAT AdHoc; 276 AdHoc.pszName = pszFormat; 277 AdHoc.pszDesc = pszFormat; 278 AdHoc.fFlags = CLIPUTILFORMAT_F_AD_HOC; 279 #ifdef RT_OS_DARWIN 280 /** @todo */ 281 282 #elif defined(RT_OS_OS2) 283 AdHoc.pszFormat = pszDesc; 284 AdHoc.fFormat = WinAddAtom(WinQuerySystemAtomTable(), pwszDesc); 285 if (AdHoc.fFormat == 0) 286 { 287 RTMsgError("Invalid format '%s' (%u (%#x))", pszFormat, WinGetLastError(), WinGetLastError()); 288 return NULL; 289 } 290 291 #elif defined(RT_OS_WINDOWS) 292 AdHoc.pwszFormat = NULL; 293 AdHoc.fFormat = RegisterClipboardFormatA(pszFormat); 294 if (AdHoc.fFormat == 0) 295 { 296 RTMsgError("RegisterClipboardFormatA(%s) failed: %u (%#x)", pszFormat, GetLastError(), GetLastError()); 297 return NULL; 298 } 299 300 #else 301 AdHoc.pszAtomName = pszFormat; 302 AdHoc.uAtom = XInternAtom(g_pX11Display, pszFormat, False); 303 if (AdHoc.uAtom == None) 304 { 305 RTMsgError("Invalid format '%s' or out of memory for X11 atoms", pszFormat); 306 return NULL; 307 } 308 309 #endif 310 return &AdHoc; 311 } 312 313 314 #ifdef RT_OS_DARWIN 315 316 /** @todo */ 317 318 319 #elif defined(RT_OS_OS2) 320 321 /** 322 * Initialize the OS/2 bits. 323 */ 324 static RTEXITCODE CuOs2Init(void) 325 { 326 g_hOs2Hab = WinInitialize(0); 327 if (g_hOs2Hab == NULLHANDLE) 328 return RTMsgErrorExitFailure("WinInitialize failed: %u", WinGetLastError()); 329 330 g_hOs2MsgQueue = WinCreateMsgQueue(g_hOs2Hab, 10); 331 if (g_hOs2MsgQueue == NULLHANDLE) 332 return RTMsgErrorExitFailure("WinCreateMsgQueue failed: %u", WinGetLastError()); 333 return RTEXITCODE_SUCCESS; 334 } 335 336 337 /** 338 * Terminates the OS/2 bits. 339 */ 340 static RTEXITCODE CuOs2Term(void) 341 { 342 if (g_fOs2OpenedClipboard) 343 { 344 if (!WinCloseClipbrd(g_hOs2Hab)) 345 return RTMsgErrorExitFailure("WinCloseClipbrd failed: %u", WinGetLastError()); 346 g_fOs2OpenedClipboard = false; 347 } 348 349 WinDestroyMsgQueue(g_hOs2Hab, g_hOs2MsgQueue); 350 g_hOs2MsgQueue = NULLHANDLE; 351 352 WinTerminate(g_hOs2Hab); 353 g_hOs2Hab = NULLHANDLE; 354 355 return RTEXITCODE_SUCCESS; 356 } 357 358 359 #elif defined(RT_OS_WINDOWS) 360 361 /** 362 * Terminates the Windows bits. 363 */ 364 static RTEXITCODE CuWinTerm(void) 365 { 366 if (g_fOpenedClipboard) 367 { 368 if (!CloseClipboard()) 369 return RTMsgErrorExitFailure("CloseClipboard failed: %u (%#x)", GetLastError(), GetLastError()); 370 g_fOpenedClipboard = false; 371 } 372 return RTEXITCODE_SUCCESS; 373 } 374 205 375 206 376 /** … … 220 390 221 391 222 /** 223 * Wrapper that automatically registers non-standard formats. 224 */ 225 static UINT FormatDescToWindows(PCCLIPUTILFORMAT pFmtDesc) 226 { 227 if (pFmtDesc->fFormat) 228 return pFmtDesc->fFormat; 229 Assert(pFmtDesc->pwszFormat); 230 UINT fFormat = RegisterClipboardFormatW(pFmtDesc->pwszFormat); 231 if (fFormat == 0) 232 RTMsgError("RegisterClipboardFormatW(%ls) failed: %u (%#x)", pFmtDesc->pwszFormat, GetLastError(), GetLastError()); 233 return fFormat; 234 } 235 236 #endif /* RT_OS_WINDOWS */ 237 392 #else /* X11: */ 393 394 /** 395 * Error handler callback. 396 */ 397 static int CuX11ErrorCallback(Display *pX11Display, XErrorEvent *pErrEvt) 398 { 399 g_cX11Errors++; 400 char szErr[2048]; 401 XGetErrorText(pX11Display, pErrEvt->error_code, szErr, sizeof(szErr)); 402 RTMsgError("An X Window protocol error occurred: %s\n" 403 " Request code: %u\n" 404 " Minor code: %u\n" 405 " Serial number of the failed request: %u\n", 406 szErr, pErrEvt->request_code, pErrEvt->minor_code, pErrEvt->serial); 407 return 0; 408 } 409 410 411 /** 412 * Initialize the X11 bits. 413 */ 414 static RTEXITCODE CuX11Init(void) 415 { 416 /* 417 * Open the X11 display and create a little dummy window. 418 */ 419 XSetErrorHandler(CuX11ErrorCallback); 420 g_pX11Display = XOpenDisplay(NULL); 421 if (!g_pX11Display) 422 return RTMsgErrorExitFailure("XOpenDisplay failed"); 423 424 int const iDefaultScreen = DefaultScreen(g_pX11Display); 425 g_hX11Window = XCreateSimpleWindow(g_pX11Display, 426 RootWindow(g_pX11Display, iDefaultScreen), 427 0 /*x*/, 0 /*y*/, 428 1 /*cx*/, 1 /*cy*/, 429 0 /*cPxlBorder*/, 430 BlackPixel(g_pX11Display, iDefaultScreen) /*Border*/, 431 WhitePixel(g_pX11Display, iDefaultScreen) /*Background*/); 432 433 /* 434 * Resolve any unknown atom values we might need later. 435 */ 436 for (size_t i = 0; i < RT_ELEMENTS(g_aTargets); i++) 437 if (g_aTargets[i].pszAtomName) 438 { 439 g_aTargets[i].uAtom = XInternAtom(g_pX11Display, g_aTargets[i].pszAtomName, False); 440 if (g_uVerbosity > 2) 441 RTPrintf("target %s atom=%#x\n", g_aTargets[i].pszName, g_aTargets[i].uAtom); 442 } 443 444 g_uX11AtomTargets = XInternAtom(g_pX11Display, "TARGETS", False); 445 g_uX11AtomMultiple = XInternAtom(g_pX11Display, "MULTIPLE", False); 446 447 return RTEXITCODE_SUCCESS; 448 } 449 450 #endif /* X11 */ 238 451 239 452 … … 282 495 } 283 496 if (pszName) 284 RTPrintf("#% u: %#06x - %s\n", idx, fFormat, pszName);497 RTPrintf("#%02u: %#06x - %s\n", idx, fFormat, pszName); 285 498 else 286 RTPrintf("#% u: %#06x\n", idx, fFormat);499 RTPrintf("#%02u: %#06x\n", idx, fFormat); 287 500 } 288 501 … … 293 506 } 294 507 return rcExit; 508 509 #elif defined(CU_X11) 510 511 Atom uAtomDst = g_uX11AtomTargets; 512 int rc = XConvertSelection(g_pX11Display, g_pTarget->uAtom, g_uX11AtomTargets, uAtomDst, g_hX11Window, CurrentTime); 513 if (g_uVerbosity > 1) 514 RTPrintf("XConvertSelection -> %d\n", rc); 515 516 for (;;) 517 { 518 XEvent Evt = {0}; 519 rc = XNextEvent(g_pX11Display, &Evt); 520 if (Evt.type == SelectionNotify) 521 { 522 if (g_uVerbosity > 1) 523 RTPrintf("XNextEvent -> %d; type=SelectionNotify\n", rc); 524 if (Evt.xselection.selection == g_pTarget->uAtom) 525 { 526 if (Evt.xselection.property == None) 527 return RTMsgErrorExitFailure("XConvertSelection(,%s,TARGETS,) failed", g_pTarget->pszName); 528 529 Atom uAtomRetType = 0; 530 int iActualFmt = 0; 531 unsigned long cbLeftToRead = 0; 532 unsigned long cItems = 0; 533 unsigned char *pbData = NULL; 534 rc = XGetWindowProperty(g_pX11Display, g_hX11Window, uAtomDst, 535 0 /*offset*/, sizeof(Atom) * 4096 /* should be enough */, True /*fDelete*/, XA_ATOM, 536 &uAtomRetType, &iActualFmt, &cItems, &cbLeftToRead, &pbData); 537 if (g_uVerbosity > 1) 538 RTPrintf("XConvertSelection -> %d; uAtomRetType=%u iActualFmt=%d cItems=%lu cbLeftToRead=%lu pbData=%p\n", 539 rc, uAtomRetType, iActualFmt, cItems, cbLeftToRead, pbData); 540 if (pbData && cItems > 0) 541 { 542 Atom const *paTargets = (Atom const *)pbData; 543 for (unsigned long i = 0; i < cItems; i++) 544 { 545 const char *pszName = XGetAtomName(g_pX11Display, paTargets[i]); 546 if (pszName) 547 RTPrintf("#%02u: %#06x - %s\n", i, paTargets[i], pszName); 548 else 549 RTPrintf("#%02u: %#06x\n", i, paTargets[i]); 550 } 551 } 552 else 553 RTMsgInfo("Empty"); 554 if (pbData) 555 XFree(pbData); 556 return RTEXITCODE_SUCCESS; 557 } 558 } 559 else if (g_uVerbosity > 1) 560 RTPrintf("XNextEvent -> %d; type=%d\n", rc, Evt.type); 561 } 295 562 296 563 #else … … 313 580 *ppvData = NULL; 314 581 *pcbData = 0; 582 315 583 #ifdef RT_OS_WINDOWS 316 584 RTEXITCODE rcExit = WinOpenClipboardIfNecessary(); 317 585 if (rcExit == RTEXITCODE_SUCCESS) 318 586 { 319 HANDLE hData = GetClipboardData( FormatDescToWindows(pFmtDesc));587 HANDLE hData = GetClipboardData(pFmtDesc->fFormat); 320 588 if (hData != NULL) 321 589 { … … 362 630 return rcExit; 363 631 632 #elif defined(CU_X11) 633 634 /* Request the data: */ 635 Atom const uAtomDst = pFmtDesc->uAtom; 636 int rc = XConvertSelection(g_pX11Display, g_pTarget->uAtom, pFmtDesc->uAtom, uAtomDst, g_hX11Window, CurrentTime); 637 if (g_uVerbosity > 1) 638 RTPrintf("XConvertSelection -> %d\n", rc); 639 640 /* Wait for the reply: */ 641 for (;;) 642 { 643 XEvent Evt = {0}; 644 rc = XNextEvent(g_pX11Display, &Evt); 645 if (Evt.type == SelectionNotify) 646 { 647 if (g_uVerbosity > 1) 648 RTPrintf("XNextEvent -> %d; type=SelectionNotify\n", rc); 649 if (Evt.xselection.selection == g_pTarget->uAtom) 650 { 651 if (Evt.xselection.property == None) 652 return RTMsgErrorExitFailure("XConvertSelection(,%s,%s,) failed", g_pTarget->pszName, pFmtDesc->pszName); 653 654 /* 655 * Retrieve the data. 656 */ 657 Atom uAtomRetType = 0; 658 int cBitsActualFmt = 0; 659 unsigned long cbLeftToRead = 0; 660 unsigned long cItems = 0; 661 unsigned char *pbData = NULL; 662 rc = XGetWindowProperty(g_pX11Display, g_hX11Window, uAtomDst, 663 0 /*offset*/, _64M, False/*fDelete*/, AnyPropertyType, 664 &uAtomRetType, &cBitsActualFmt, &cItems, &cbLeftToRead, &pbData); 665 if (g_uVerbosity > 1) 666 RTPrintf("XConvertSelection -> %d; uAtomRetType=%u cBitsActualFmt=%d cItems=%lu cbLeftToRead=%lu pbData=%p\n", 667 rc, uAtomRetType, cBitsActualFmt, cItems, cbLeftToRead, pbData); 668 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 669 if (pbData && cItems > 0) 670 { 671 *pcbData = cItems * (cBitsActualFmt / 8); 672 *ppvData = RTMemDup(pbData, *pcbData); 673 if (!*ppvData) 674 rcExit = RTMsgErrorExitFailure("Out of memory allocating %#zx bytes.", *pcbData); 675 } 676 if (pbData) 677 XFree(pbData); 678 XDeleteProperty(g_pX11Display, g_hX11Window, uAtomDst); 679 return rcExit; 680 } 681 } 682 else if (g_uVerbosity > 1) 683 RTPrintf("XNextEvent -> %d; type=%d\n", rc, Evt.type); 684 } 685 364 686 #else 365 687 RT_NOREF(pFmtDesc); … … 422 744 if (rcExit == RTEXITCODE_SUCCESS) 423 745 { 424 if (!SetClipboardData( FormatDescToWindows(pFmtDesc), hDstData))746 if (!SetClipboardData(pFmtDesc->fFormat, hDstData)) 425 747 { 426 748 rcExit = RTMsgErrorExitFailure("SetClipboardData(%s) failed: %u (%#x)\n", … … 623 945 if (rcExit == RTEXITCODE_SUCCESS) 624 946 { 625 if (IsClipboardFormatAvailable( FormatDescToWindows(pFmtDesc)))947 if (IsClipboardFormatAvailable(pFmtDesc->fFormat)) 626 948 rcExit = RTMsgErrorExitFailure("Format '%s' is present"); 627 949 } … … 686 1008 case 'z': pszHelp = "Zaps the clipboard content."; break; 687 1009 #ifdef MULTI_TARGET_CLIPBOARD 688 case 't': pszHelp = "Selects the target clipboard." break;1010 case 't': pszHelp = "Selects the target clipboard."; break; 689 1011 #endif 690 1012 case 'v': pszHelp = "More verbose execution."; break; … … 730 1052 731 1053 /* 1054 * Host specific init. 1055 */ 1056 #ifdef RT_OS_DARWIN 1057 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 1058 #elif defined(RT_OS_OS2) 1059 RTEXITCODE rcExit = CuOs2Init(); 1060 #elif defined(RT_OS_WINDOWS) 1061 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 1062 #else 1063 RTEXITCODE rcExit = CuX11Init(); 1064 #endif 1065 if (rcExit != RTEXITCODE_SUCCESS) 1066 return rcExit; 1067 1068 /* 732 1069 * Process options (in order). 733 1070 */ 734 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;735 1071 RTGETOPTUNION ValueUnion; 736 1072 RTGETOPTSTATE GetState; … … 764 1100 rcExit2 = ClipboardContentToFile(pFmtDesc, ValueUnion.psz); 765 1101 else 766 return RTMsgError ("No filename given with --get-file");1102 return RTMsgErrorExitFailure("No filename given with --get-file"); 767 1103 } 768 1104 else … … 780 1116 rcExit2 = PutStringOnClipboard(pFmtDesc, ValueUnion.psz); 781 1117 else 782 return RTMsgError ("No data string given with --put");1118 return RTMsgErrorExitFailure("No data string given with --put"); 783 1119 } 784 1120 else … … 796 1132 rcExit2 = PutFileOnClipboard(pFmtDesc, ValueUnion.psz); 797 1133 else 798 return RTMsgError ("No filename given with --put-file");1134 return RTMsgErrorExitFailure("No filename given with --put-file"); 799 1135 } 800 1136 else … … 812 1148 rcExit2 = CheckStringAgainstClipboard(pFmtDesc, ValueUnion.psz); 813 1149 else 814 return RTMsgError ("No data string given with --check");1150 return RTMsgErrorExitFailure("No data string given with --check"); 815 1151 } 816 1152 else … … 828 1164 rcExit2 = CheckFileAgainstClipboard(pFmtDesc, ValueUnion.psz); 829 1165 else 830 return RTMsgError ("No filename given with --check-file");1166 return RTMsgErrorExitFailure("No filename given with --check-file"); 831 1167 } 832 1168 else … … 850 1186 break; 851 1187 1188 #ifdef MULTI_TARGET_CLIPBOARD 1189 case 't': 1190 { 1191 CLIPUTILTARGET *pNewTarget = NULL; 1192 for (size_t i = 0; i < RT_ELEMENTS(g_aTargets); i++) 1193 if (strcmp(ValueUnion.psz, g_aTargets[i].pszName) == 0) 1194 { 1195 pNewTarget = &g_aTargets[i]; 1196 break; 1197 } 1198 if (!pNewTarget) 1199 return RTMsgErrorExitFailure("Unknown target '%s'", ValueUnion.psz); 1200 if (pNewTarget != g_pTarget && g_uVerbosity > 0) 1201 RTMsgInfo("Switching from '%s' to '%s'\n", g_pTarget->pszName, pNewTarget->pszName); 1202 g_pTarget = pNewTarget; 1203 break; 1204 } 1205 #endif 1206 852 1207 case 'q': 853 1208 g_uVerbosity = 0; … … 881 1236 * Host specific cleanup. 882 1237 */ 883 #ifdef RT_OS_WINDOWS 884 if (g_fOpenedClipboard) 885 { 886 if (!CloseClipboard()) 887 rcExit = RTMsgErrorExitFailure("CloseClipboard failed: %u (%#x)", GetLastError(), GetLastError()); 888 } 889 #endif 1238 #if defined(RT_OS_OS2) 1239 RTEXITCODE rcExit2 = CuOs2Term(); 1240 #elif defined(RT_OS_WINDOWS) 1241 RTEXITCODE rcExit2 = CuWinTerm(); 1242 #else 1243 RTEXITCODE rcExit2 = RTEXITCODE_SUCCESS; 1244 #endif 1245 if (rcExit2 != RTEXITCODE_SUCCESS && rcExit != RTEXITCODE_SUCCESS) 1246 rcExit = rcExit2; 890 1247 891 1248 return rcExit; -
trunk/src/VBox/ValidationKit/utils/clipboard/Makefile.kmk
r92025 r92158 34 34 ClipUtil_TEMPLATE = VBoxValidationKitR3 35 35 ClipUtil_SOURCES = ClipUtil.cpp 36 ifn1of ($(KBUILD_TARGET), darwin os2 windows) 37 ClipUtil_LIBPATH = $(VBOX_LIBPATH_X11) 38 ClipUtil_LIBS = X11 Xmu 39 endif 36 40 37 41 $(evalcall def_vbox_validationkit_process_python_sources)
Note:
See TracChangeset
for help on using the changeset viewer.