- Timestamp:
- Nov 25, 2019 8:45:21 AM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134966
- Location:
- trunk/src/VBox
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
r81960 r82156 33 33 #include <VBox/HostServices/VBoxClipboardSvc.h> 34 34 #include <VBox/GuestHost/SharedClipboard.h> 35 #include <VBox/GuestHost/SharedClipboard-x11.h> 35 36 36 37 #include "VBoxClient.h" … … 52 53 SHCLTRANSFERCTX TransferCtx; 53 54 #endif 54 /** Pointer to the X11 clipboard backend. */55 CLIPBACKEND *pBackend;55 /** X11 clipboard context. */ 56 SHCLX11CTX X11; 56 57 }; 57 58 … … 71 72 * returned. 72 73 */ 73 DECLCALLBACK(int) ClipRequestDataForX11Callback(SHCLCONTEXT *pCtx, SHCLFORMAT Format, void **ppv, uint32_t *pcb)74 DECLCALLBACK(int) ShClX11RequestDataForX11Callback(PSHCLCONTEXT pCtx, SHCLFORMAT Format, void **ppv, uint32_t *pcb) 74 75 { 75 76 RT_NOREF(pCtx); … … 160 161 * @param Formats The formats to report. 161 162 */ 162 DECLCALLBACK(void) ClipReportX11FormatsCallback(SHCLCONTEXT *pCtx, SHCLFORMATS Formats)163 DECLCALLBACK(void) ShClX11ReportFormatsCallback(PSHCLCONTEXT pCtx, SHCLFORMATS Formats) 163 164 { 164 165 RT_NOREF(pCtx); … … 187 188 * @param cb The size of the data in @a pv. 188 189 */ 189 DECLCALLBACK(void) ClipRequestFromX11CompleteCallback(SHCLCONTEXT *pCtx, int rc, CLIPREADCBREQ *pReq, void *pv, uint32_t cb)190 DECLCALLBACK(void) ShClRequestFromX11CompleteCallback(PSHCLCONTEXT pCtx, int rc, CLIPREADCBREQ *pReq, void *pv, uint32_t cb) 190 191 { 191 192 RT_NOREF(pCtx); … … 221 222 LogFlowFuncEnter(); 222 223 223 int rc; 224 225 g_Ctx.pBackend = ClipConstructX11(&g_Ctx, false); 226 if (g_Ctx.pBackend) 227 { 228 rc = ClipStartX11(g_Ctx.pBackend, false /* grab */); 224 int rc = ShClX11Init(&g_Ctx.X11, &g_Ctx, false /* fHeadless */); 225 if (RT_SUCCESS(rc)) 226 { 227 rc = ShClX11ThreadStart(&g_Ctx.X11, false /* grab */); 229 228 if (RT_SUCCESS(rc)) 230 229 { … … 235 234 #endif 236 235 if (RT_FAILURE(rc)) 237 ClipStopX11(g_Ctx.pBackend);236 ShClX11ThreadStop(&g_Ctx.X11); 238 237 } 239 238 } … … 246 245 247 246 VbglR3ClipboardDisconnectEx(&g_Ctx.CmdCtx); 248 ClipDestructX11(g_Ctx.pBackend);247 ShClX11Destroy(&g_Ctx.X11); 249 248 } 250 249 … … 262 261 int rc; 263 262 264 SHCLCONTEXT *pCtx = &g_Ctx;263 PSHCLCONTEXT pCtx = &g_Ctx; 265 264 266 265 bool fShutdown = false; … … 367 366 case VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS: 368 367 { 369 ClipAnnounceFormatToX11(g_Ctx.pBackend, pEvent->u.ReportedFormats.Formats);368 ShClX11ReportFormatsToX11(&g_Ctx.X11, pEvent->u.ReportedFormats.Formats); 370 369 break; 371 370 } … … 379 378 { 380 379 pReq->Format = pEvent->u.ReadData.uFmt; 381 ClipReadDataFromX11(g_Ctx.pBackend, pReq->Format, pReq);380 ShClX11ReadDataFromX11(&g_Ctx.X11, pReq->Format, pReq); 382 381 } 383 382 else -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp
r81960 r82156 63 63 64 64 #include <VBox/GuestHost/SharedClipboard.h> 65 #include <VBox/GuestHost/SharedClipboard-x11.h> 65 66 #include <VBox/GuestHost/clipboard-helper.h> 66 67 #include <VBox/HostServices/VBoxClipboardSvc.h> … … 75 76 * Structures and Typedefs * 76 77 *********************************************************************************************************************************/ 77 /** The different clipboard formats which we support. */78 enum CLIPFORMAT79 {80 INVALID = 0,81 TARGETS,82 TEXT, /* Treat this as UTF-8, but it may really be ascii */83 UTF8,84 BMP,85 HTML86 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS87 , URI_LIST88 #endif89 };90 91 typedef unsigned CLIPX11FORMAT;92 78 93 79 … … 96 82 *********************************************************************************************************************************/ 97 83 class formats; 98 static Atom clipGetAtom( CLIPBACKEND *pCtx, const char *pszName);84 static Atom clipGetAtom(PSHCLX11CTX pCtx, const char *pszName); 99 85 100 86 … … 152 138 * @param widget a valid Xt widget 153 139 */ 154 static Atom clipAtomForX11Format( CLIPBACKEND *pCtx, CLIPX11FORMAT format)140 static Atom clipAtomForX11Format(PSHCLX11CTX pCtx, CLIPX11FORMAT format) 155 141 { 156 142 LogFlowFunc(("format=%u -> pcszAtom=%s\n", format, g_aFormats[format].pcszAtom)); … … 181 167 * @param Widget a valid Xt widget. 182 168 */ 183 static CLIPX11FORMAT clipFindX11FormatByAtom( CLIPBACKEND *pCtx, Atom atomFormat)169 static CLIPX11FORMAT clipFindX11FormatByAtom(PSHCLX11CTX pCtx, Atom atomFormat) 184 170 { 185 171 for (unsigned i = 0; i < RT_ELEMENTS(g_aFormats); ++i) … … 223 209 } 224 210 225 /** Global context information used by the X11 clipboard backend */226 struct _CLIPBACKEND227 {228 /** Opaque data structure describing the front-end. */229 SHCLCONTEXT *pFrontend;230 /** Is an X server actually available? */231 bool fHaveX11;232 /** The X Toolkit application context structure */233 XtAppContext appContext;234 235 /** We have a separate thread to wait for Window and Clipboard events */236 RTTHREAD thread;237 /** The X Toolkit widget which we use as our clipboard client. It is never made visible. */238 Widget widget;239 240 /** Should we try to grab the clipboard on startup? */241 bool fGrabClipboardOnStart;242 243 /** The best text format X11 has to offer, as an index into the formats244 * table */245 CLIPX11FORMAT X11TextFormat;246 /** The best bitmap format X11 has to offer, as an index into the formats247 * table */248 CLIPX11FORMAT X11BitmapFormat;249 /** The best HTML format X11 has to offer, as an index into the formats250 * table */251 CLIPX11FORMAT X11HTMLFormat;252 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS253 /** The best HTML format X11 has to offer, as an index into the formats254 * table */255 CLIPX11FORMAT X11URIListFormat;256 #endif257 /** What kind of formats does VBox have to offer? */258 SHCLFORMATS vboxFormats;259 /** Cache of the last unicode data that we received */260 void *pvUnicodeCache;261 /** Size of the unicode data in the cache */262 uint32_t cbUnicodeCache;263 /** When we wish the clipboard to exit, we have to wake up the event264 * loop. We do this by writing into a pipe. This end of the pipe is265 * the end that another thread can write to. */266 int wakeupPipeWrite;267 /** The reader end of the pipe */268 int wakeupPipeRead;269 /** A pointer to the XFixesSelectSelectionInput function */270 void (*fixesSelectInput)(Display *, Window, Atom, unsigned long);271 /** The first XFixes event number */272 int fixesEventBase;273 };274 275 211 /** 276 212 * The number of simultaneous instances we support. For all normal purposes … … 290 226 Widget widget; 291 227 /** The context associated with the widget */ 292 CLIPBACKEND *pCtx;228 PSHCLX11CTX pCtx; 293 229 } g_contexts[CLIP_MAX_CONTEXTS]; 294 230 … … 298 234 * @param pCtx The clipboard backend context to use. 299 235 */ 300 static int clipRegisterContext( CLIPBACKEND *pCtx)236 static int clipRegisterContext(PSHCLX11CTX pCtx) 301 237 { 302 238 AssertPtrReturn(pCtx, VERR_INVALID_PARAMETER); … … 326 262 * @param pCtx The clipboard backend context to use. 327 263 */ 328 static void clipUnregisterContext( CLIPBACKEND *pCtx)264 static void clipUnregisterContext(PSHCLX11CTX pCtx) 329 265 { 330 266 AssertPtrReturnVoid(pCtx); … … 348 284 349 285 /** Finds an X11 clipboard context. */ 350 static CLIPBACKEND*clipLookupContext(Widget widget)286 static SHCLX11CTX *clipLookupContext(Widget widget) 351 287 { 352 288 AssertPtrReturn(widget, NULL); … … 367 303 * before asking the server. 368 304 */ 369 static Atom clipGetAtom( CLIPBACKEND *pCtx, const char *pszName)305 static Atom clipGetAtom(PSHCLX11CTX pCtx, const char *pszName) 370 306 { 371 307 AssertPtrReturn(pszName, None); … … 388 324 * writing to the wakeup pipe which it monitors. 389 325 */ 390 static int clipQueueToEventThread( CLIPBACKEND *pCtx,326 static int clipQueueToEventThread(PSHCLX11CTX pCtx, 391 327 void (*proc)(void *, void *), 392 328 void *client_data) … … 417 353 * @param pCtx The clipboard backend context to use. 418 354 */ 419 static void clipReportFormatsToVBox( CLIPBACKEND *pCtx)355 static void clipReportFormatsToVBox(PSHCLX11CTX pCtx) 420 356 { 421 357 uint32_t fFormats = clipVBoxFormatForX11Format(pCtx->X11TextFormat); … … 433 369 #endif 434 370 435 LogRel2(("Shared Clipboard: Reported formats =0x%x\n", fFormats));436 437 ClipReportX11FormatsCallback(pCtx->pFrontend, fFormats);371 LogRel2(("Shared Clipboard: X11 reported available formats 0x%x\n", fFormats)); 372 373 ShClX11ReportFormatsCallback(pCtx->pFrontend, fFormats); 438 374 } 439 375 … … 444 380 * @param pCtx The clipboard backend context to use. 445 381 */ 446 static void clipResetX11Formats( CLIPBACKEND *pCtx)382 static void clipResetX11Formats(PSHCLX11CTX pCtx) 447 383 { 448 384 LogFlowFuncEnter(); … … 461 397 * @param pCtx The clipboard backend context to use. 462 398 */ 463 static void clipReportEmptyX11CB( CLIPBACKEND *pCtx)399 static void clipReportEmptyX11CB(PSHCLX11CTX pCtx) 464 400 { 465 401 clipResetX11Formats(pCtx); … … 477 413 * @param cTargets The size of the list in @a pTargets. 478 414 */ 479 static CLIPX11FORMAT clipGetTextFormatFromTargets( CLIPBACKEND *pCtx,415 static CLIPX11FORMAT clipGetTextFormatFromTargets(PSHCLX11CTX pCtx, 480 416 CLIPX11FORMAT *pTargets, 481 417 size_t cTargets) … … 503 439 504 440 #ifdef TESTCASE 505 static bool tstClipTextFormatConversion( CLIPBACKEND *pCtx)441 static bool tstClipTextFormatConversion(PSHCLX11CTX pCtx) 506 442 { 507 443 bool fSuccess = true; … … 532 468 * @param cTargets The size of the list in @a pTargets. 533 469 */ 534 static CLIPX11FORMAT clipGetBitmapFormatFromTargets( CLIPBACKEND *pCtx,470 static CLIPX11FORMAT clipGetBitmapFormatFromTargets(PSHCLX11CTX pCtx, 535 471 CLIPX11FORMAT *pTargets, 536 472 size_t cTargets) … … 566 502 * @param cTargets The size of the list in @a pTargets. 567 503 */ 568 static CLIPX11FORMAT clipGetHtmlFormatFromTargets( CLIPBACKEND *pCtx,504 static CLIPX11FORMAT clipGetHtmlFormatFromTargets(PSHCLX11CTX pCtx, 569 505 CLIPX11FORMAT *pTargets, 570 506 size_t cTargets) … … 601 537 * @param cTargets The size of the list in @a pTargets. 602 538 */ 603 static CLIPX11FORMAT clipGetURIListFormatFromTargets( CLIPBACKEND *pCtx,539 static CLIPX11FORMAT clipGetURIListFormatFromTargets(PSHCLX11CTX pCtx, 604 540 CLIPX11FORMAT *pTargets, 605 541 size_t cTargets) … … 636 572 * @param cTargets The size of the list in @a pTargets. 637 573 */ 638 static void clipGetFormatsFromTargets( CLIPBACKEND *pCtx,574 static void clipGetFormatsFromTargets(PSHCLX11CTX pCtx, 639 575 CLIPX11FORMAT *pTargets, size_t cTargets) 640 576 { … … 662 598 } 663 599 664 static DECLCALLBACK(void) clipQueryX11FormatsCallback( CLIPBACKEND *pCtx);600 static DECLCALLBACK(void) clipQueryX11FormatsCallback(PSHCLX11CTX pCtx); 665 601 666 602 /** … … 672 608 * @param cTargets The size of the array @a pTargets. 673 609 */ 674 static void clipUpdateX11Targets( CLIPBACKEND *pCtx, CLIPX11FORMAT *pTargets, size_t cTargets)610 static void clipUpdateX11Targets(PSHCLX11CTX pCtx, CLIPX11FORMAT *pTargets, size_t cTargets) 675 611 { 676 612 LogFlowFuncEnter(); … … 702 638 RT_NOREF(piFormat); 703 639 704 CLIPBACKEND *pCtx = reinterpret_cast<CLIPBACKEND*>(pClient);640 PSHCLX11CTX pCtx = reinterpret_cast<SHCLX11CTX *>(pClient); 705 641 706 642 Atom *pAtoms = (Atom *)pValue; … … 762 698 763 699 #ifdef TESTCASE 764 void tstRequestTargets( CLIPBACKEND *pCtx);700 void tstRequestTargets(PSHCLX11CTX pCtx); 765 701 #endif 766 702 … … 770 706 * @param pCtx The clipboard backend context to use. 771 707 */ 772 static DECLCALLBACK(void) clipQueryX11FormatsCallback( CLIPBACKEND *pCtx)708 static DECLCALLBACK(void) clipQueryX11FormatsCallback(PSHCLX11CTX pCtx) 773 709 { 774 710 LogFlowFuncEnter(); … … 807 743 * @param pCtx The clipboard backend context to use. 808 744 */ 809 void clipPeekEventAndDoXFixesHandling( CLIPBACKEND *pCtx)745 void clipPeekEventAndDoXFixesHandling(PSHCLX11CTX pCtx) 810 746 { 811 747 union … … 840 776 LogRel(("Shared Clipboard: Starting X11 event thread\n")); 841 777 842 CLIPBACKEND *pCtx = (CLIPBACKEND*)pvUser;778 PSHCLX11CTX pCtx = (SHCLX11CTX *)pvUser; 843 779 844 780 if (pCtx->fGrabClipboardOnStart) … … 863 799 * @param pCtx The clipboard backend context to use. 864 800 */ 865 static void clipUninit( CLIPBACKEND *pCtx)801 static void clipUninit(PSHCLX11CTX pCtx) 866 802 { 867 803 AssertPtrReturnVoid(pCtx); … … 890 826 { 891 827 892 CLIPBACKEND *pCtx = (CLIPBACKEND*)pUserData;828 PSHCLX11CTX pCtx = (SHCLX11CTX *)pUserData; 893 829 894 830 /* This might mean that we are getting stopped twice. */ … … 905 841 * Sets up the XFixes library and load the XFixesSelectSelectionInput symbol. 906 842 */ 907 static int clipLoadXFixes(Display *pDisplay, CLIPBACKEND *pCtx)843 static int clipLoadXFixes(Display *pDisplay, PSHCLX11CTX pCtx) 908 844 { 909 845 int rc; … … 966 902 LogFlowFuncEnter(); 967 903 968 CLIPBACKEND *pCtx = (CLIPBACKEND*)pUserData;904 PSHCLX11CTX pCtx = (SHCLX11CTX *)pUserData; 969 905 char acBuf[WAKE_UP_STRING_LEN]; 970 906 … … 980 916 * @param pCtx The clipboard backend context to use. 981 917 */ 982 static int clipInit( CLIPBACKEND *pCtx)918 static int clipInit(PSHCLX11CTX pCtx) 983 919 { 984 920 /* Create a window and make it a clipboard viewer. */ … … 1066 1002 1067 1003 /** 1068 * Constructs the X11 backend of the shared clipboard. 1069 * 1070 * @note X11 backend code 1071 */ 1072 CLIPBACKEND *ClipConstructX11(SHCLCONTEXT *pFrontend, bool fHeadless) 1073 { 1074 CLIPBACKEND *pCtx = (CLIPBACKEND *)RTMemAllocZ(sizeof(CLIPBACKEND)); 1075 if (pCtx && fHeadless) 1004 * Initializes the X11 context of the Shared Clipboard. 1005 * 1006 * @returns VBox status code. 1007 * @param pCtx The clipboard context to initialize. 1008 * @param pParent Parent context to use. 1009 * @param fHeadless Whether the code runs in a headless environment or not. 1010 */ 1011 int ShClX11Init(PSHCLX11CTX pCtx, PSHCLCONTEXT pParent, bool fHeadless) 1012 { 1013 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1014 AssertPtrReturn(pParent, VERR_INVALID_POINTER); 1015 1016 if (fHeadless) 1076 1017 { 1077 1018 /* … … 1082 1023 */ 1083 1024 LogRel(("Shared Clipboard: X11 DISPLAY variable not set -- disabling clipboard sharing\n")); 1084 pCtx->fHaveX11 = false; 1085 return pCtx; 1086 } 1087 1088 pCtx->fHaveX11 = true; 1089 1090 LogRel(("Shared Clipboard: Initializing X11 clipboard backend\n")); 1091 1092 if (pCtx) 1093 pCtx->pFrontend = pFrontend; 1094 return pCtx; 1095 } 1096 1097 /** 1098 * Destructs the shared clipboard X11 backend. 1099 * 1100 * @note X11 backend code. 1101 * 1102 * @param pCtx The clipboard backend context to use. 1103 */ 1104 void ClipDestructX11(CLIPBACKEND *pCtx) 1025 } 1026 1027 pCtx->fHaveX11 = !fHeadless; 1028 pCtx->pFrontend = pParent; 1029 1030 LogFlowFuncLeaveRC(VINF_SUCCESS); 1031 return VINF_SUCCESS; 1032 } 1033 1034 /** 1035 * Destructs the Shared Clipboard X11 context. 1036 * 1037 * @param pCtx The clipboard backend context to destroy. 1038 */ 1039 void ShClX11Destroy(PSHCLX11CTX pCtx) 1105 1040 { 1106 1041 if (!pCtx) … … 1114 1049 Assert(pCtx->widget == NULL); 1115 1050 } 1116 1117 RTMemFree(pCtx);1118 1051 } 1119 1052 … … 1125 1058 * @param fGrab Whether we should try to grab the shared clipboard at once. 1126 1059 */ 1127 int ClipStartX11(CLIPBACKEND *pCtx, bool fGrab)1060 int ShClX11ThreadStart(PSHCLX11CTX pCtx, bool fGrab) 1128 1061 { 1129 1062 int rc = VINF_SUCCESS; … … 1168 1101 * @param pCtx The clipboard backend context to use. 1169 1102 */ 1170 int ClipStopX11(CLIPBACKEND *pCtx)1103 int ShClX11ThreadStop(PSHCLX11CTX pCtx) 1171 1104 { 1172 1105 int rc, rcThread; … … 1222 1155 * @note X11 backend code, called by the XtOwnSelection callback. 1223 1156 */ 1224 static int clipCreateX11Targets( CLIPBACKEND *pCtx, Atom *atomTypeReturn,1157 static int clipCreateX11Targets(PSHCLX11CTX pCtx, Atom *atomTypeReturn, 1225 1158 XtPointer *pValReturn, 1226 1159 unsigned long *pcLenReturn, … … 1258 1191 1259 1192 /** 1260 * This is a wrapper around ClipRequestDataForX11Callback that will cache the1193 * This is a wrapper around ShClX11RequestDataForX11Callback that will cache the 1261 1194 * data returned. 1262 1195 */ 1263 static int clipReadVBoxShCl( CLIPBACKEND *pCtx, SHCLFORMAT Format,1196 static int clipReadVBoxShCl(PSHCLX11CTX pCtx, SHCLFORMAT Format, 1264 1197 void **ppv, uint32_t *pcb) 1265 1198 { … … 1271 1204 { 1272 1205 if (pCtx->pvUnicodeCache == NULL) 1273 rc = ClipRequestDataForX11Callback(pCtx->pFrontend, Format,1206 rc = ShClX11RequestDataForX11Callback(pCtx->pFrontend, Format, 1274 1207 &pCtx->pvUnicodeCache, 1275 1208 &pCtx->cbUnicodeCache); … … 1286 1219 } 1287 1220 else 1288 rc = ClipRequestDataForX11Callback(pCtx->pFrontend, Format,1221 rc = ShClX11RequestDataForX11Callback(pCtx->pFrontend, Format, 1289 1222 ppv, pcb); 1290 1223 if (RT_SUCCESS(rc)) … … 1469 1402 * @param selType The atom in question. 1470 1403 */ 1471 static bool clipIsSupportedSelectionType( CLIPBACKEND *pCtx, Atom selType)1404 static bool clipIsSupportedSelectionType(PSHCLX11CTX pCtx, Atom selType) 1472 1405 { 1473 1406 return( (selType == clipGetAtom(pCtx, "CLIPBOARD")) … … 1494 1427 } 1495 1428 1496 static int clipConvertVBoxCBForX11( CLIPBACKEND *pCtx, Atom *atomTarget,1429 static int clipConvertVBoxCBForX11(PSHCLX11CTX pCtx, Atom *atomTarget, 1497 1430 Atom *atomTypeReturn, 1498 1431 XtPointer *pValReturn, … … 1586 1519 RT_FALL_THROUGH(); 1587 1520 case UTF8: 1588 { 1589 void *pv = NULL; 1590 uint32_t cb = 0; 1591 rc = clipReadVBoxShCl(pCtx, VBOX_SHCL_FMT_URI_LIST, &pv, &cb); 1592 1593 RTMemFree(pv); 1594 break; 1595 } 1596 1521 RT_FALL_THROUGH(); 1597 1522 case URI_LIST: 1598 1523 { … … 1638 1563 LogFlowFuncEnter(); 1639 1564 1640 CLIPBACKEND *pCtx = clipLookupContext(widget);1565 PSHCLX11CTX pCtx = clipLookupContext(widget); 1641 1566 int rc = VINF_SUCCESS; 1642 1567 … … 1664 1589 { 1665 1590 /** Context information for the X11 clipboard. */ 1666 CLIPBACKEND *pCtx;1591 PSHCLX11CTX pCtx; 1667 1592 /** Formats supported by VBox. */ 1668 1593 SHCLFORMATS Formats; … … 1670 1595 1671 1596 /** Invalidates the local cache of the data in the VBox clipboard. */ 1672 static void clipInvalidateVBoxCBCache( CLIPBACKEND *pCtx)1597 static void clipInvalidateVBoxCBCache(PSHCLX11CTX pCtx) 1673 1598 { 1674 1599 if (pCtx->pvUnicodeCache != NULL) … … 1682 1607 * Takes possession of the X11 clipboard (and middle-button selection). 1683 1608 */ 1684 static void clipGrabX11CB( CLIPBACKEND *pCtx, SHCLFORMATS Formats)1609 static void clipGrabX11CB(PSHCLX11CTX pCtx, SHCLFORMATS Formats) 1685 1610 { 1686 1611 LogFlowFuncEnter(); … … 1707 1632 1708 1633 /** 1709 * Worker function for ClipAnnounceFormatToX11 which runs on the1634 * Worker function for ShClX11ReportFormatsToX11 which runs on the 1710 1635 * event thread. 1711 1636 * … … 1714 1639 * clipboard context data. Must be freed by the worker. 1715 1640 */ 1716 static void clipAnnounceFormatToX11Worker(void *pUserData, 1717 void * /* interval */) 1641 static void ShClX11ReportFormatsToX11Worker(void *pUserData, void * /* interval */) 1718 1642 { 1719 1643 CLIPNEWVBOXFORMATS *pFormats = (CLIPNEWVBOXFORMATS *)pUserData; 1720 CLIPBACKEND *pCtx = pFormats->pCtx;1644 PSHCLX11CTX pCtx = pFormats->pCtx; 1721 1645 1722 1646 uint32_t fFormats = pFormats->Formats; … … 1739 1663 * @param Formats Clipboard formats offered. 1740 1664 */ 1741 int ClipAnnounceFormatToX11(CLIPBACKEND *pCtx, uint32_t Formats)1665 int ShClX11ReportFormatsToX11(PSHCLX11CTX pCtx, uint32_t Formats) 1742 1666 { 1743 1667 /* … … 1756 1680 pFormats->Formats = Formats; 1757 1681 1758 rc = clipQueueToEventThread(pCtx, clipAnnounceFormatToX11Worker,1682 rc = clipQueueToEventThread(pCtx, ShClX11ReportFormatsToX11Worker, 1759 1683 (XtPointer) pFormats); 1760 1684 } … … 2012 1936 CLIPX11FORMAT mX11Format; 2013 1937 /** The clipboard context this request is associated with. */ 2014 CLIPBACKEND*mpCtx;1938 SHCLX11CTX *mpCtx; 2015 1939 /** The request structure passed in from the backend. */ 2016 1940 CLIPREADCBREQ *mpReq; … … 2217 2141 rc = VERR_NOT_SUPPORTED; 2218 2142 2219 ClipRequestFromX11CompleteCallback(pReq->mpCtx->pFrontend, rc, pReq->mpReq,2143 ShClRequestFromX11CompleteCallback(pReq->mpCtx->pFrontend, rc, pReq->mpReq, 2220 2144 pvDst, cbDst); 2221 2145 RTMemFree(pvDst); … … 2252 2176 2253 2177 #ifdef TESTCASE 2254 static void tstClipRequestData( CLIPBACKEND* pCtx, CLIPX11FORMAT target,2178 static void tstClipRequestData(SHCLX11CTX* pCtx, CLIPX11FORMAT target, 2255 2179 void *closure); 2256 2180 #endif 2257 2181 2258 static int clipGetSelectionValue( CLIPBACKEND *pCtx, CLIPX11FORMAT format,2182 static int clipGetSelectionValue(PSHCLX11CTX pCtx, CLIPX11FORMAT format, 2259 2183 CLIPREADX11CBREQ *pReq) 2260 2184 { … … 2273 2197 2274 2198 /** 2275 * Worker function for ClipReadDataFromX11 which runs on the event thread.2276 */ 2277 static void clipReadDataFromX11Worker(void *pvUserData, void * /* interval */)2199 * Worker function for ShClX11ReadDataFromX11 which runs on the event thread. 2200 */ 2201 static void ShClX11ReadDataFromX11Worker(void *pvUserData, void * /* interval */) 2278 2202 { 2279 2203 AssertPtrReturnVoid(pvUserData); 2280 2204 2281 2205 CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *)pvUserData; 2282 CLIPBACKEND*pCtx = pReq->mpCtx;2206 SHCLX11CTX *pCtx = pReq->mpCtx; 2283 2207 2284 2208 LogFlowFunc(("pReq->mFormat = %02X\n", pReq->mFormat)); … … 2333 2257 /* The clipboard callback was never scheduled, so we must signal 2334 2258 * that the request processing is finished and clean up ourselves. */ 2335 ClipRequestFromX11CompleteCallback(pReq->mpCtx->pFrontend, rc, pReq->mpReq,2259 ShClRequestFromX11CompleteCallback(pReq->mpCtx->pFrontend, rc, pReq->mpReq, 2336 2260 NULL /* pv */ ,0 /* cb */); 2337 2261 RTMemFree(pReq); … … 2351 2275 * @note We allocate a request structure which must be freed by the worker. 2352 2276 */ 2353 int ClipReadDataFromX11(CLIPBACKEND *pCtx, SHCLFORMAT Format, CLIPREADCBREQ *pReq)2277 int ShClX11ReadDataFromX11(PSHCLX11CTX pCtx, SHCLFORMAT Format, CLIPREADCBREQ *pReq) 2354 2278 { 2355 2279 /* … … 2369 2293 2370 2294 /* We use this to schedule a worker function on the event thread. */ 2371 rc = clipQueueToEventThread(pCtx, clipReadDataFromX11Worker, (XtPointer)pX11Req);2295 rc = clipQueueToEventThread(pCtx, ShClX11ReadDataFromX11Worker, (XtPointer)pX11Req); 2372 2296 } 2373 2297 else … … 2410 2334 2411 2335 /* Set empty data in the simulated VBox clipboard. */ 2412 static void tstClipEmptyVBox( CLIPBACKEND *pCtx, int retval)2336 static void tstClipEmptyVBox(PSHCLX11CTX pCtx, int retval) 2413 2337 { 2414 2338 g_tstVBoxDataRC = retval; … … 2416 2340 g_tstVBoxDataPv = NULL; 2417 2341 g_tstVBoxDataCb = 0; 2418 ClipAnnounceFormatToX11(pCtx, 0);2342 ShClX11ReportFormatsToX11(pCtx, 0); 2419 2343 } 2420 2344 2421 2345 /* Set the data in the simulated VBox clipboard. */ 2422 static int tstClipSetVBoxUtf16( CLIPBACKEND *pCtx, int retval,2346 static int tstClipSetVBoxUtf16(PSHCLX11CTX pCtx, int retval, 2423 2347 const char *pcszData, size_t cb) 2424 2348 { … … 2438 2362 g_tstVBoxDataPv = pv; 2439 2363 g_tstVBoxDataCb = cb; 2440 ClipAnnounceFormatToX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT);2364 ShClX11ReportFormatsToX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT); 2441 2365 return VINF_SUCCESS; 2442 2366 } 2443 2367 2444 2368 /* Return the data in the simulated VBox clipboard. */ 2445 DECLCALLBACK(int) ClipRequestDataForX11Callback(SHCLCONTEXT *pCtx, uint32_t Format, void **ppv, uint32_t *pcb)2369 DECLCALLBACK(int) ShClX11RequestDataForX11Callback(PSHCLCONTEXT pCtx, uint32_t Format, void **ppv, uint32_t *pcb) 2446 2370 { 2447 2371 RT_NOREF(pCtx, Format); … … 2524 2448 static size_t g_cTargets = 0; 2525 2449 2526 void tstRequestTargets( CLIPBACKEND* pCtx)2450 void tstRequestTargets(SHCLX11CTX* pCtx) 2527 2451 { 2528 2452 clipUpdateX11Targets(pCtx, g_selTargets, g_cTargets); … … 2536 2460 static int g_selFormat = 0; 2537 2461 2538 void tstClipRequestData( CLIPBACKEND *pCtx, CLIPX11FORMAT target, void *closure)2462 void tstClipRequestData(PSHCLX11CTX pCtx, CLIPX11FORMAT target, void *closure) 2539 2463 { 2540 2464 RT_NOREF(pCtx); … … 2563 2487 static uint32_t g_fX11Formats = 0; 2564 2488 2565 DECLCALLBACK(void) ClipReportX11FormatsCallback(SHCLCONTEXT *pCtx, SHCLFORMATS Formats)2489 DECLCALLBACK(void) ShClX11ReportFormatsCallback(PSHCLCONTEXT pCtx, SHCLFORMATS Formats) 2566 2490 { 2567 2491 RT_NOREF(pCtx); … … 2656 2580 } 2657 2581 2658 static void tstClipSendTargetUpdate( CLIPBACKEND *pCtx)2582 static void tstClipSendTargetUpdate(PSHCLX11CTX pCtx) 2659 2583 { 2660 2584 clipQueryX11FormatsCallback(pCtx); … … 2711 2635 static char g_completedBuf[MAX_BUF_SIZE]; 2712 2636 2713 void ClipRequestFromX11CompleteCallback(SHCLCONTEXT *pCtx, int rc, CLIPREADCBREQ *pReq, void *pv, uint32_t cb)2637 void ShClRequestFromX11CompleteCallback(PSHCLCONTEXT pCtx, int rc, CLIPREADCBREQ *pReq, void *pv, uint32_t cb) 2714 2638 { 2715 2639 RT_NOREF(pCtx); … … 2752 2676 #endif 2753 2677 2754 static void tstStringFromX11(RTTEST hTest, CLIPBACKEND *pCtx,2678 static void tstStringFromX11(RTTEST hTest, PSHCLX11CTX pCtx, 2755 2679 const char *pcszExp, int rcExp) 2756 2680 { … … 2764 2688 char *pc; 2765 2689 CLIPREADCBREQ *pReq = (CLIPREADCBREQ *)&pReq, *pReqRet = NULL; 2766 ClipReadDataFromX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT, pReq);2690 ShClX11ReadDataFromX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT, pReq); 2767 2691 int rc = VINF_SUCCESS; 2768 2692 uint32_t cbActual = 0; … … 2809 2733 } 2810 2734 2811 static void tstLatin1FromX11(RTTEST hTest, CLIPBACKEND *pCtx,2735 static void tstLatin1FromX11(RTTEST hTest, PSHCLX11CTX pCtx, 2812 2736 const char *pcszExp, int rcExp) 2813 2737 { … … 2821 2745 char *pc; 2822 2746 CLIPREADCBREQ *pReq = (CLIPREADCBREQ *)&pReq, *pReqRet = NULL; 2823 ClipReadDataFromX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT, pReq);2747 ShClX11ReadDataFromX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT, pReq); 2824 2748 int rc = VINF_SUCCESS; 2825 2749 uint32_t cbActual = 0; … … 2862 2786 } 2863 2787 2864 static void tstStringFromVBox(RTTEST hTest, CLIPBACKEND *pCtx, const char *pcszTarget, Atom typeExp, const char *valueExp)2788 static void tstStringFromVBox(RTTEST hTest, PSHCLX11CTX pCtx, const char *pcszTarget, Atom typeExp, const char *valueExp) 2865 2789 { 2866 2790 RT_NOREF(pCtx); … … 2894 2818 } 2895 2819 2896 static void tstNoX11( CLIPBACKEND *pCtx, const char *pcszTestCtx)2820 static void tstNoX11(PSHCLX11CTX pCtx, const char *pcszTestCtx) 2897 2821 { 2898 2822 CLIPREADCBREQ *pReq = (CLIPREADCBREQ *)&pReq; 2899 int rc = ClipReadDataFromX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT, pReq);2823 int rc = ShClX11ReadDataFromX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT, pReq); 2900 2824 RTTESTI_CHECK_MSG(rc == VERR_NO_DATA, ("context: %s\n", pcszTestCtx)); 2901 2825 } 2902 2826 2903 static void tstStringFromVBoxFailed(RTTEST hTest, CLIPBACKEND *pCtx, const char *pcszTarget)2827 static void tstStringFromVBoxFailed(RTTEST hTest, PSHCLX11CTX pCtx, const char *pcszTarget) 2904 2828 { 2905 2829 RT_NOREF(pCtx); … … 2916 2840 } 2917 2841 2918 static void tstNoSelectionOwnership( CLIPBACKEND *pCtx, const char *pcszTestCtx)2842 static void tstNoSelectionOwnership(PSHCLX11CTX pCtx, const char *pcszTestCtx) 2919 2843 { 2920 2844 RT_NOREF(pCtx); … … 2922 2846 } 2923 2847 2924 static void tstBadFormatRequestFromHost(RTTEST hTest, CLIPBACKEND *pCtx)2848 static void tstBadFormatRequestFromHost(RTTEST hTest, PSHCLX11CTX pCtx) 2925 2849 { 2926 2850 tstClipSetSelectionValues("UTF8_STRING", XA_STRING, "hello world", … … 2934 2858 char *pc; 2935 2859 CLIPREADCBREQ *pReq = (CLIPREADCBREQ *)&pReq, *pReqRet = NULL; 2936 ClipReadDataFromX11(pCtx, 100, pReq); /* Bad format. */2860 ShClX11ReadDataFromX11(pCtx, 100, pReq); /* Bad format. */ 2937 2861 int rc = VINF_SUCCESS; 2938 2862 uint32_t cbActual = 0; … … 2962 2886 * Run the test. 2963 2887 */ 2964 CLIPBACKEND *pCtx = ClipConstructX11(NULL, false);2888 PSHCLX11CTX pCtx = ShClX11Init(NULL, false); 2965 2889 char *pc; 2966 2890 uint32_t cbActual; 2967 2891 CLIPREADCBREQ *pReq = (CLIPREADCBREQ *)&pReq, *pReqRet = NULL; 2968 rc = ClipStartX11(pCtx, false /* fGrab */);2892 rc = ShClX11ThreadStart(pCtx, false /* fGrab */); 2969 2893 AssertRCReturn(rc, 1); 2970 2894 … … 3043 2967 tstClipSetSelectionValues("UTF8_STRING", XA_STRING, NULL, 3044 2968 0, 8); 3045 ClipReadDataFromX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT, pReq);2969 ShClX11ReadDataFromX11(pCtx, VBOX_SHCL_FMT_UNICODETEXT, pReq); 3046 2970 tstClipGetCompletedRequest(&rc, &pc, &cbActual, &pReqRet); 3047 2971 RTTEST_CHECK_MSG(hTest, rc == VERR_NO_DATA, … … 3061 2985 /*** request for an invalid VBox format from X11 ***/ 3062 2986 RTTestSub(hTest, "a request for an invalid VBox format from X11"); 3063 ClipReadDataFromX11(pCtx, 0xffff, pReq);2987 ShClX11ReadDataFromX11(pCtx, 0xffff, pReq); 3064 2988 tstClipGetCompletedRequest(&rc, &pc, &cbActual, &pReqRet); 3065 2989 RTTEST_CHECK_MSG(hTest, rc == VERR_NOT_IMPLEMENTED, … … 3146 3070 tstClipSetSelectionValues("TEXT", XA_STRING, "", sizeof(""), 8); 3147 3071 tstClipSetVBoxUtf16(pCtx, VINF_SUCCESS, "", 2); 3148 ClipAnnounceFormatToX11(pCtx, 0xa0000);3072 ShClX11ReportFormatsToX11(pCtx, 0xa0000); 3149 3073 RTTEST_CHECK_MSG(hTest, g_ownsSel, 3150 3074 (hTest, "VBox grabbed the clipboard with unknown data and we ignored it\n")); … … 3155 3079 tstBadFormatRequestFromHost(hTest, pCtx); 3156 3080 3157 rc = ClipStopX11(pCtx);3081 rc = ShClX11ThreadStop(pCtx); 3158 3082 AssertRCReturn(rc, 1); 3159 ClipDestructX11(pCtx);3083 ShClX11Destroy(pCtx); 3160 3084 3161 3085 /*** Headless clipboard tests ***/ 3162 3086 3163 pCtx = ClipConstructX11(NULL, true);3164 rc = ClipStartX11(pCtx, false /* fGrab */);3087 pCtx = ShClX11Init(NULL, true); 3088 rc = ShClX11ThreadStart(pCtx, false /* fGrab */); 3165 3089 AssertRCReturn(rc, 1); 3166 3090 … … 3183 3107 tstNoSelectionOwnership(pCtx, "reading from VBox, headless clipboard"); 3184 3108 3185 rc = ClipStopX11(pCtx);3109 rc = ShClX11ThreadStop(pCtx); 3186 3110 AssertRCReturn(rc, 1); 3187 ClipDestructX11(pCtx);3111 ShClX11Destroy(pCtx); 3188 3112 3189 3113 return RTTestSummaryAndDestroy(hTest); … … 3202 3126 # include <iprt/test.h> 3203 3127 3204 DECLCALLBACK(int) ClipRequestDataForX11Callback(SHCLCONTEXT *pCtx, SHCLFORMAT Format, void **ppv, uint32_t *pcb)3128 DECLCALLBACK(int) ShClX11RequestDataForX11Callback(PSHCLCONTEXT pCtx, SHCLFORMAT Format, void **ppv, uint32_t *pcb) 3205 3129 { 3206 3130 RT_NOREF(pCtx, Format, ppv, pcb); … … 3208 3132 } 3209 3133 3210 DECLCALLBACK(void) ClipReportX11FormatsCallback(SHCLCONTEXT *pCtx, SHCLFORMATS Formats)3134 DECLCALLBACK(void) ShClX11ReportFormatsCallback(PSHCLCONTEXT pCtx, SHCLFORMATS Formats) 3211 3135 { 3212 3136 RT_NOREF(pCtx, Formats); 3213 3137 } 3214 3138 3215 DECLCALLBACK(void) ClipRequestFromX11CompleteCallback(SHCLCONTEXT *pCtx, int rc, CLIPREADCBREQ *pReq, void *pv, uint32_t cb)3139 DECLCALLBACK(void) ShClRequestFromX11CompleteCallback(PSHCLCONTEXT pCtx, int rc, CLIPREADCBREQ *pReq, void *pv, uint32_t cb) 3216 3140 { 3217 3141 RT_NOREF(pCtx, rc, pReq, pv, cb); … … 3241 3165 return RTTestSummaryAndDestroy(hTest); 3242 3166 } 3243 CLIPBACKEND *pCtx = ClipConstructX11(NULL, false);3167 PSHCLX11CTX pCtx = ShClX11Init(NULL, false); 3244 3168 AssertReturn(pCtx, 1); 3245 rc = ClipStartX11(pCtx, false /* fGrab */);3169 rc = ShClX11ThreadStart(pCtx, false /* fGrab */); 3246 3170 AssertRCReturn(rc, 1); 3247 3171 /* Give the clipboard time to synchronise. */ 3248 3172 RTThreadSleep(500); 3249 rc = ClipStopX11(pCtx);3173 rc = ShClX11ThreadStop(pCtx); 3250 3174 AssertRCReturn(rc, 1); 3251 ClipDestructX11(pCtx);3175 ShClX11Destroy(pCtx); 3252 3176 return RTTestSummaryAndDestroy(hTest); 3253 3177 } -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11.cpp
r81843 r82156 29 29 30 30 #include <VBox/GuestHost/SharedClipboard.h> 31 #include <VBox/GuestHost/SharedClipboard-x11.h> 31 32 #include <VBox/HostServices/VBoxClipboardSvc.h> 32 33 #include <iprt/errcore.h> … … 47 48 * which might clash with others. */ 48 49 RTCRITSECT CritSect; 49 /** Pointer to the opaque X11 backend structure*/50 CLIPBACKEND *pBackend;50 /** X11 context data. */ 51 SHCLX11CTX X11; 51 52 /** Pointer to the VBox host client data structure. */ 52 53 PSHCLCLIENT pClient; … … 74 75 int ShClSvcImplConnect(PSHCLCLIENT pClient, bool fHeadless) 75 76 { 76 int rc = VINF_SUCCESS;77 int rc; 77 78 78 79 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)RTMemAllocZ(sizeof(SHCLCONTEXT)); 79 80 if (pCtx) 80 81 { 81 RTCritSectInit(&pCtx->CritSect); 82 CLIPBACKEND *pBackend = ClipConstructX11(pCtx, fHeadless); 83 if (!pBackend) 82 rc = RTCritSectInit(&pCtx->CritSect); 83 if (RT_SUCCESS(rc)) 84 84 { 85 rc = VERR_NO_MEMORY; 85 rc = ShClX11Init(&pCtx->X11, pCtx, fHeadless); 86 if (RT_SUCCESS(rc)) 87 { 88 pClient->State.pCtx = pCtx; 89 pCtx->pClient = pClient; 90 91 rc = ShClX11ThreadStart(&pCtx->X11, true /* grab shared clipboard */); 92 if (RT_FAILURE(rc)) 93 ShClX11Destroy(&pCtx->X11); 94 } 95 96 if (RT_FAILURE(rc)) 97 RTCritSectDelete(&pCtx->CritSect); 86 98 } 87 99 else 88 {89 pCtx->pBackend = pBackend;90 pClient->State.pCtx = pCtx;91 pCtx->pClient = pClient;92 93 rc = ClipStartX11(pBackend, true /* grab shared clipboard */);94 if (RT_FAILURE(rc))95 ClipDestructX11(pBackend);96 }97 98 if (RT_FAILURE(rc))99 {100 RTCritSectDelete(&pCtx->CritSect);101 100 RTMemFree(pCtx); 102 }103 101 } 104 102 else … … 140 138 pCtx->fShuttingDown = true; 141 139 142 int rc = ClipStopX11(pCtx->pBackend);140 int rc = ShClX11ThreadStop(&pCtx->X11); 143 141 /** @todo handle this slightly more reasonably, or be really sure 144 142 * it won't go wrong. */ 145 143 AssertRC(rc); 146 144 147 if (RT_SUCCESS(rc)) /* And if not? */ 148 { 149 ClipDestructX11(pCtx->pBackend); 150 RTCritSectDelete(&pCtx->CritSect); 151 RTMemFree(pCtx); 152 } 145 ShClX11Destroy(&pCtx->X11); 146 RTCritSectDelete(&pCtx->CritSect); 147 148 RTMemFree(pCtx); 153 149 154 150 LogFlowFuncLeaveRC(rc); … … 161 157 RT_NOREF(pCmdCtx); 162 158 163 int rc = ClipAnnounceFormatToX11(pClient->State.pCtx->pBackend, pFormats->Formats);159 int rc = ShClX11ReportFormatsToX11(&pClient->State.pCtx->X11, pFormats->Formats); 164 160 165 161 LogFlowFuncLeaveRC(rc); … … 209 205 if (RT_SUCCESS(rc)) 210 206 { 211 rc = ClipReadDataFromX11(pClient->State.pCtx->pBackend, pData->uFormat, pReq);207 rc = ShClX11ReadDataFromX11(&pClient->State.pCtx->X11, pData->uFormat, pReq); 212 208 if (RT_SUCCESS(rc)) 213 209 { … … 257 253 * @param Formats The formats available. 258 254 */ 259 DECLCALLBACK(void) ClipReportX11FormatsCallback(PSHCLCONTEXT pCtx, uint32_t Formats)255 DECLCALLBACK(void) ShClX11ReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t Formats) 260 256 { 261 257 LogFlowFunc(("pCtx=%p, Formats=%02X\n", pCtx, Formats)); … … 289 285 * @todo Change this to deal with the buffer issues rather than offloading them onto the caller. 290 286 */ 291 DECLCALLBACK(void) ClipRequestFromX11CompleteCallback(PSHCLCONTEXT pCtx, int rcCompletion,287 DECLCALLBACK(void) ShClRequestFromX11CompleteCallback(PSHCLCONTEXT pCtx, int rcCompletion, 292 288 CLIPREADCBREQ *pReq, void *pv, uint32_t cb) 293 289 { … … 328 324 * returned. 329 325 */ 330 DECLCALLBACK(int) ClipRequestDataForX11Callback(PSHCLCONTEXT pCtx, SHCLFORMAT Format, void **ppv, uint32_t *pcb)326 DECLCALLBACK(int) ShClX11RequestDataForX11Callback(PSHCLCONTEXT pCtx, SHCLFORMAT Format, void **ppv, uint32_t *pcb) 331 327 { 332 328 LogFlowFunc(("pCtx=%p, Format=0x%x\n", pCtx, Format)); … … 414 410 pReq->uEvent = uEvent; 415 411 416 rc = ClipReadDataFromX11(pClient->State.pCtx->pBackend, VBOX_SHCL_FMT_URI_LIST, pReq);412 rc = ShClX11ReadDataFromX11(&pClient->State.pCtx->X11, VBOX_SHCL_FMT_URI_LIST, pReq); 417 413 if (RT_SUCCESS(rc)) 418 414 {
Note:
See TracChangeset
for help on using the changeset viewer.