Changeset 92160 in vbox
- Timestamp:
- Oct 30, 2021 1:40:42 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 147983
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/clipboard/ClipUtil.cpp
r92159 r92160 138 138 typedef CLIPUTILTARGET const *PCCLIPUTILTARGET; 139 139 #endif /* MULTI_TARGET_CLIPBOARD */ 140 141 142 #ifdef RT_OS_OS2 143 /** Header for Odin32 specific clipboard entries. 144 * (Used to get the correct size of the data.) 145 */ 146 typedef struct _Odin32ClipboardHeader 147 { 148 /** Magic (CLIPHEADER_MAGIC) */ 149 char achMagic[8]; 150 /** Size of the following data. 151 * (The interpretation depends on the type.) */ 152 unsigned cbData; 153 /** Odin32 format number. */ 154 unsigned uFormat; 155 } CLIPHEADER, *PCLIPHEADER; 156 157 #define CLIPHEADER_MAGIC "Odin\1\0\1" 158 #endif 140 159 141 160 … … 211 230 /** The message queue handle. */ 212 231 static HMQ g_hOs2MsgQueue = NULLHANDLE; 232 /** Windows that becomes clipboard owner when setting data. */ 233 static HWND g_hOs2Wnd = NULLHANDLE; 213 234 /** Set if we've opened the clipboard. */ 214 235 static bool g_fOs2OpenedClipboard = false; 236 /** Set if we're the clipboard owner. */ 237 static bool g_fOs2ClipboardOwner = false; 215 238 216 239 #elif defined(RT_OS_WINDOWS) … … 252 275 g_aFormats[i].fFormat = WinAddAtom(WinQuerySystemAtomTable(), g_aFormats[i].pszFormat); 253 276 if (g_aFormats[i].fFormat == 0) 254 RTMsgError("WinAddAtom(,%s) failed: % u (%#x)", g_aFormats[i].pszFormat, WinGetLastError(), WinGetLastError());277 RTMsgError("WinAddAtom(,%s) failed: %#x", g_aFormats[i].pszFormat, WinGetLastError(g_hOs2Hab)); 255 278 } 256 279 … … 281 304 282 305 #elif defined(RT_OS_OS2) 283 AdHoc.pszFormat = psz Desc;284 AdHoc.fFormat = WinAddAtom(WinQuerySystemAtomTable(), p wszDesc);306 AdHoc.pszFormat = pszFormat; 307 AdHoc.fFormat = WinAddAtom(WinQuerySystemAtomTable(), pszFormat); 285 308 if (AdHoc.fFormat == 0) 286 309 { 287 RTMsgError("Invalid format '%s' (% u (%#x))", pszFormat, WinGetLastError(), WinGetLastError());310 RTMsgError("Invalid format '%s' (%#x)", pszFormat, WinGetLastError(g_hOs2Hab)); 288 311 return NULL; 289 312 } … … 320 343 321 344 /** 345 * The window procedure for the object window. 346 * 347 * @returns Message result. 348 * 349 * @param hwnd The window handle. 350 * @param msg The message. 351 * @param mp1 Message parameter 1. 352 * @param mp2 Message parameter 2. 353 */ 354 static MRESULT EXPENTRY CuOs2WinProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 355 { 356 if (g_uVerbosity > 2) 357 RTMsgInfo("CuOs2WinProc: hwnd=%#lx msg=%#lx mp1=%#lx mp2=%#lx\n", hwnd, msg, mp1, mp2); 358 359 switch (msg) 360 { 361 case WM_CREATE: 362 return NULL; /* FALSE(/NULL) == Continue*/ 363 case WM_DESTROY: 364 break; 365 366 /* 367 * Clipboard viewer message - the content has been changed. 368 * This is sent *after* releasing the clipboard sem 369 * and during the WinSetClipbrdViewer call. 370 */ 371 case WM_DRAWCLIPBOARD: 372 break; 373 374 /* 375 * Clipboard owner message - the content was replaced. 376 * This is sent by someone with an open clipboard, so don't try open it now. 377 */ 378 case WM_DESTROYCLIPBOARD: 379 break; 380 381 /* 382 * Clipboard owner message - somebody is requesting us to render a format. 383 * This is called by someone which owns the clipboard, but that's fine. 384 */ 385 case WM_RENDERFMT: 386 break; 387 388 /* 389 * Clipboard owner message - we're about to quit and should render all formats. 390 */ 391 case WM_RENDERALLFMTS: 392 break; 393 394 /* 395 * Clipboard owner messages dealing with owner drawn content. 396 * We shouldn't be seeing any of these. 397 */ 398 case WM_PAINTCLIPBOARD: 399 case WM_SIZECLIPBOARD: 400 case WM_HSCROLLCLIPBOARD: 401 case WM_VSCROLLCLIPBOARD: 402 AssertMsgFailed(("msg=%lx (%ld)\n", msg, msg)); 403 break; 404 405 /* 406 * We shouldn't be seeing any other messages according to the docs. 407 * But for whatever reason, PM sends us a WM_ADJUSTWINDOWPOS message 408 * during WinCreateWindow. So, ignore that and assert on anything else. 409 */ 410 default: 411 AssertMsgFailed(("msg=%lx (%ld)\n", msg, msg)); 412 case WM_ADJUSTWINDOWPOS: 413 break; 414 } 415 return NULL; 416 } 417 418 /** 322 419 * Initialize the OS/2 bits. 323 420 */ … … 326 423 g_hOs2Hab = WinInitialize(0); 327 424 if (g_hOs2Hab == NULLHANDLE) 328 return RTMsgErrorExitFailure("WinInitialize failed : %u", WinGetLastError());425 return RTMsgErrorExitFailure("WinInitialize failed!"); 329 426 330 427 g_hOs2MsgQueue = WinCreateMsgQueue(g_hOs2Hab, 10); 331 428 if (g_hOs2MsgQueue == NULLHANDLE) 332 return RTMsgErrorExitFailure("WinCreateMsgQueue failed: %u", WinGetLastError()); 429 return RTMsgErrorExitFailure("WinCreateMsgQueue failed: %#x", WinGetLastError(g_hOs2Hab)); 430 431 static char s_szClass[] = "VBox-ClipUtilClipboardClass"; 432 if (!WinRegisterClass(g_hOs2Wnd, (PCSZ)s_szClass, CuOs2WinProc, 0, 0)) 433 return RTMsgErrorExitFailure("WinRegisterClass failed: %#x", WinGetLastError(g_hOs2Hab)); 434 435 g_hOs2Wnd = WinCreateWindow(HWND_OBJECT, /* hwndParent */ 436 (PCSZ)s_szClass, /* pszClass */ 437 (PCSZ)"VirtualBox Clipboard Utility", /* pszName */ 438 0, /* flStyle */ 439 0, 0, 0, 0, /* x, y, cx, cy */ 440 NULLHANDLE, /* hwndOwner */ 441 HWND_BOTTOM, /* hwndInsertBehind */ 442 42, /* id */ 443 NULL, /* pCtlData */ 444 NULL); /* pPresParams */ 445 if (g_hOs2Wnd == NULLHANDLE) 446 return RTMsgErrorExitFailure("WinCreateWindow failed: %#x", WinGetLastError(g_hOs2Hab)); 447 333 448 return RTEXITCODE_SUCCESS; 334 449 } … … 343 458 { 344 459 if (!WinCloseClipbrd(g_hOs2Hab)) 345 return RTMsgErrorExitFailure("WinCloseClipbrd failed: % u", WinGetLastError());460 return RTMsgErrorExitFailure("WinCloseClipbrd failed: %#x", WinGetLastError(g_hOs2Hab)); 346 461 g_fOs2OpenedClipboard = false; 347 462 } 348 463 349 WinDestroyMsgQueue(g_hOs2Hab, g_hOs2MsgQueue); 464 WinDestroyWindow(g_hOs2Wnd); 465 g_hOs2Wnd = NULLHANDLE; 466 467 WinDestroyMsgQueue(g_hOs2MsgQueue); 350 468 g_hOs2MsgQueue = NULLHANDLE; 351 469 … … 354 472 355 473 return RTEXITCODE_SUCCESS; 474 } 475 476 477 /** 478 * Opens the OS/2 clipboard. 479 */ 480 static RTEXITCODE CuOs2OpenClipboardIfNecessary(void) 481 { 482 if (g_fOs2OpenedClipboard) 483 return RTEXITCODE_SUCCESS; 484 if (WinOpenClipbrd(g_hOs2Hab)) 485 { 486 g_fOs2OpenedClipboard = true; 487 return RTEXITCODE_SUCCESS; 488 } 489 return RTMsgErrorExitFailure("WinOpenClipbrd failed: %#x", WinGetLastError(g_hOs2Hab)); 356 490 } 357 491 … … 456 590 static RTEXITCODE ListClipboardContent(void) 457 591 { 458 #ifdef RT_OS_WINDOWS 592 #if defined(RT_OS_OS2) 593 RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary(); 594 if (rcExit == RTEXITCODE_SUCCESS) 595 { 596 HATOMTBL const hAtomTbl = WinQuerySystemAtomTable(); 597 uint32_t idx = 0; 598 ULONG fFormat = 0; 599 while ((fFormat = WinEnumClipbrdFmts(g_hOs2Hab)) != 0) 600 { 601 char szName[256] = {0}; 602 ULONG cchRet = WinQueryAtomName(hAtomTbl, fFormat, szName, sizeof(szName)); 603 if (cchRet != 0) 604 RTPrintf("#%u: %#06x - %s\n", idx, fFormat, szName); 605 else 606 { 607 const char *pszName = NULL; 608 switch (fFormat) 609 { 610 case CF_TEXT: pszName = "CF_TEXT"; break; 611 case CF_BITMAP: pszName = "CF_BITMAP"; break; 612 case CF_DSPTEXT: pszName = "CF_DSPTEXT"; break; 613 case CF_DSPBITMAP: pszName = "CF_DSPBITMAP"; break; 614 case CF_METAFILE: pszName = "CF_METAFILE"; break; 615 case CF_DSPMETAFILE: pszName = "CF_DSPMETAFILE"; break; 616 case CF_PALETTE: pszName = "CF_PALETTE"; break; 617 default: 618 break; 619 } 620 if (pszName) 621 RTPrintf("#%02u: %#06x - %s\n", idx, fFormat, pszName); 622 else 623 RTPrintf("#%02u: %#06x\n", idx, fFormat); 624 } 625 626 idx++; 627 } 628 } 629 630 return rcExit; 631 632 #elif defined(RT_OS_WINDOWS) 459 633 RTEXITCODE rcExit = WinOpenClipboardIfNecessary(); 460 634 if (rcExit == RTEXITCODE_SUCCESS) … … 508 682 509 683 #elif defined(CU_X11) 510 684 /* Request the TARGETS property: */ 511 685 Atom uAtomDst = g_uX11AtomTargets; 512 686 int rc = XConvertSelection(g_pX11Display, g_pTarget->uAtom, g_uX11AtomTargets, uAtomDst, g_hX11Window, CurrentTime); … … 514 688 RTPrintf("XConvertSelection -> %d\n", rc); 515 689 690 /* Wait for the reply: */ 516 691 for (;;) 517 692 { … … 527 702 return RTMsgErrorExitFailure("XConvertSelection(,%s,TARGETS,) failed", g_pTarget->pszName); 528 703 704 /* Get the TARGETS property data: */ 529 705 Atom uAtomRetType = 0; 530 706 int iActualFmt = 0; … … 540 716 if (pbData && cItems > 0) 541 717 { 718 /* Display the TARGETS: */ 542 719 Atom const *paTargets = (Atom const *)pbData; 543 720 for (unsigned long i = 0; i < cItems; i++) … … 581 758 *pcbData = 0; 582 759 583 #ifdef RT_OS_WINDOWS 760 #if defined(RT_OS_OS2) 761 RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary(); 762 if (rcExit == RTEXITCODE_SUCCESS) 763 { 764 ULONG fFmtInfo = 0; 765 if (WinQueryClipbrdFmtInfo(g_hOs2Hab, pFmtDesc->fFormat, &fFmtInfo)) 766 { 767 ULONG uData = WinQueryClipbrdData(g_hOs2Hab, pFmtDesc->fFormat); 768 if (fFmtInfo & CFI_POINTER) 769 { 770 PCLIPHEADER pOdinHdr = (PCLIPHEADER)uData; 771 if (pFmtDesc->fFormat == CF_TEXT) 772 { 773 if (pFmtDesc->fFlags & CLIPUTILFORMAT_F_CONVERT_UTF8) 774 { 775 char *pszUtf8 = NULL; 776 int rc = RTStrCurrentCPToUtf8(&pszUtf8, (const char *)uData); 777 if (RT_SUCCESS(rc)) 778 { 779 *pcbData = strlen(pszUtf8) + 1; 780 *ppvData = RTMemDup(pszUtf8, *pcbData); 781 RTStrFree(pszUtf8); 782 } 783 else 784 return RTMsgErrorExitFailure("RTStrCurrentCPToUtf8 failed: %Rrc", rc); 785 } 786 else 787 { 788 *pcbData = strlen((const char *)uData) + 1; 789 *ppvData = RTMemDup((const char *)uData, *pcbData); 790 } 791 } 792 else if ( strcmp(pFmtDesc->pszFormat, "Odin32 UnicodeText") == 0 793 && memcmp(pOdinHdr->achMagic, CLIPHEADER_MAGIC, sizeof(pOdinHdr->achMagic)) == 0) 794 { 795 *pcbData = pOdinHdr->cbData; 796 *ppvData = RTMemDup(pOdinHdr + 1, pOdinHdr->cbData); 797 } 798 else 799 { 800 /* We could use DosQueryMem here to figure out the size of the allocation... */ 801 *pcbData = PAGE_SIZE - (uData & PAGE_OFFSET_MASK); 802 *ppvData = RTMemDup((void const *)uData, *pcbData); 803 } 804 } 805 else 806 { 807 *pcbData = sizeof(uData); 808 *ppvData = RTMemDup(&uData, sizeof(uData)); 809 } 810 if (!*ppvData) 811 rcExit = RTMsgErrorExitFailure("Out of memory allocating %#zx bytes.", *pcbData); 812 } 813 else 814 rcExit = RTMsgErrorExitFailure("WinQueryClipbrdFmtInfo(,%s,) failed: %#x\n", 815 pFmtDesc->pszName, WinGetLastError(g_hOs2Hab)); 816 } 817 return rcExit; 818 819 #elif defined(RT_OS_WINDOWS) 584 820 RTEXITCODE rcExit = WinOpenClipboardIfNecessary(); 585 821 if (rcExit == RTEXITCODE_SUCCESS) … … 701 937 static RTEXITCODE WriteClipboardData(PCCLIPUTILFORMAT pFmtDesc, void const *pvData, size_t cbData) 702 938 { 703 #ifdef RT_OS_WINDOWS 939 #if defined(RT_OS_OS2) 940 RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary(); 941 if (rcExit == RTEXITCODE_SUCCESS) 942 { 943 /** @todo do we need to become owner? */ 944 945 /* Convert to local code page if needed: */ 946 char *pszLocale = NULL; 947 if (pFmtDesc->fFlags & CLIPUTILFORMAT_F_CONVERT_UTF8) 948 { 949 int rc = RTStrUtf8ToCurrentCPEx(&pszLocale, (char *)pvData, cbData); 950 if (RT_SUCCESS(rc)) 951 { 952 pvData = pszLocale; 953 cbData = strlen(pszLocale) + 1; 954 } 955 else 956 return RTMsgErrorExitFailure("RTStrUtf8ToCurrentCPEx failed: %Rrc\n", rc); 957 } 958 959 /* Allocate a bunch of shared memory for the object. */ 960 PVOID pvShared = NULL; 961 APIRET orc = DosAllocSharedMem(&pvShared, NULL, cbData, 962 OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE | PAG_READ | PAG_WRITE | PAG_COMMIT); 963 if (orc == NO_ERROR) 964 { 965 memcpy(pvShared, pvData, cbData); 966 967 if (WinSetClipbrdData(g_hOs2Hab, (uintptr_t)pvShared, pFmtDesc->fFormat, CFI_POINTER)) 968 rcExit = RTEXITCODE_SUCCESS; 969 else 970 { 971 rcExit = RTMsgErrorExitFailure("WinSetClipbrdData(,%p LB %#x,%s,) failed: %#x\n", 972 pvShared, cbData, pFmtDesc->pszName, WinGetLastError(g_hOs2Hab)); 973 DosFreeMem(pvShared); 974 } 975 } 976 else 977 rcExit = RTMsgErrorExitFailure("DosAllocSharedMem(,, %#x,) -> %u", cbData, orc); 978 RTStrFree(pszLocale); 979 } 980 return rcExit; 981 982 983 #elif defined(RT_OS_WINDOWS) 704 984 RTEXITCODE rcExit = WinOpenClipboardIfNecessary(); 705 985 if (rcExit == RTEXITCODE_SUCCESS) … … 941 1221 static RTEXITCODE CheckFormatNotOnClipboard(PCCLIPUTILFORMAT pFmtDesc) 942 1222 { 943 #ifdef RT_OS_WINDOWS 1223 #if defined(RT_OS_OS2) 1224 RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary(); 1225 if (rcExit == RTEXITCODE_SUCCESS) 1226 { 1227 ULONG fFmtInfo = 0; 1228 if (WinQueryClipbrdFmtInfo(g_hOs2Hab, pFmtDesc->fFormat, &fFmtInfo)) 1229 rcExit = RTMsgErrorExitFailure("Format '%s' is present"); 1230 } 1231 return rcExit; 1232 1233 #elif defined(RT_OS_WINDOWS) 944 1234 RTEXITCODE rcExit = WinOpenClipboardIfNecessary(); 945 1235 if (rcExit == RTEXITCODE_SUCCESS) … … 964 1254 static RTEXITCODE ZapAllClipboardData(void) 965 1255 { 966 #ifdef RT_OS_WINDOWS 1256 #if defined(RT_OS_OS2) 1257 RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary(); 1258 if (rcExit == RTEXITCODE_SUCCESS) 1259 { 1260 ULONG fFmtInfo = 0; 1261 if (WinEmptyClipbrd(g_hOs2Hab)) 1262 { 1263 WinSetClipbrdOwner(g_hOs2Hab, g_hOs2Wnd); /* Probably unnecessary? */ 1264 WinSetClipbrdOwner(g_hOs2Hab, NULLHANDLE); 1265 g_fOs2ClipboardOwner = false; 1266 } 1267 else 1268 rcExit = RTMsgErrorExitFailure("WinEmptyClipbrd() failed: %#x\n", WinGetLastError(g_hOs2Hab)); 1269 } 1270 return rcExit; 1271 1272 #elif defined(RT_OS_WINDOWS) 967 1273 RTEXITCODE rcExit = WinOpenClipboardIfNecessary(); 968 1274 if (rcExit == RTEXITCODE_SUCCESS)
Note:
See TracChangeset
for help on using the changeset viewer.