Changeset 99600 in vbox
- Timestamp:
- May 4, 2023 10:29:18 AM (19 months ago)
- Location:
- trunk/src/VBox/Additions/x11/VBoxClient
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
r98535 r99600 36 36 #include <VBox/log.h> 37 37 38 #include "seamless.h" 38 39 #include "seamless-x11.h" 39 40 #include "VBoxClient.h" … … 90 91 * @returns true if it can handle seamless, false otherwise 91 92 */ 92 int SeamlessX11::init(PFNSENDREGIONUPDATE pHostCallback)93 int VBClX11SeamlessMonitor::init(PFNSENDREGIONUPDATE pHostCallback) 93 94 { 94 95 int rc = VINF_SUCCESS; … … 115 116 * Shutdown seamless event monitoring. 116 117 */ 117 void SeamlessX11::uninit(void)118 void VBClX11SeamlessMonitor::uninit(void) 118 119 { 119 120 if (mHostCallback) … … 150 151 * @todo This function should switch the guest to fullscreen mode. 151 152 */ 152 int SeamlessX11::start(void)153 int VBClX11SeamlessMonitor::start(void) 153 154 { 154 155 int rc = VINF_SUCCESS; … … 169 170 /** Stop reporting seamless events to the host. Free information about guest windows 170 171 and stop requesting updates. */ 171 void SeamlessX11::stop(void)172 void VBClX11SeamlessMonitor::stop(void) 172 173 { 173 174 LogRelFlowFuncEnter(); … … 180 181 } 181 182 182 void SeamlessX11::monitorClientList(void)183 void VBClX11SeamlessMonitor::monitorClientList(void) 183 184 { 184 185 LogRelFlowFuncEnter(); … … 186 187 } 187 188 188 void SeamlessX11::unmonitorClientList(void)189 void VBClX11SeamlessMonitor::unmonitorClientList(void) 189 190 { 190 191 LogRelFlowFuncEnter(); … … 196 197 * X server. 197 198 */ 198 void SeamlessX11::rebuildWindowTree(void)199 void VBClX11SeamlessMonitor::rebuildWindowTree(void) 199 200 { 200 201 LogRelFlowFuncEnter(); … … 211 212 * @param hRoot the virtual root window to be examined 212 213 */ 213 void SeamlessX11::addClients(const Window hRoot)214 void VBClX11SeamlessMonitor::addClients(const Window hRoot) 214 215 { 215 216 /** Unused out parameters of XQueryTree */ … … 233 234 234 235 235 void SeamlessX11::addClientWindow(const Window hWin)236 void VBClX11SeamlessMonitor::addClientWindow(const Window hWin) 236 237 { 237 238 LogRelFlowFuncEnter(); … … 297 298 * @param hWin the window to be examined 298 299 */ 299 bool SeamlessX11::isVirtualRoot(Window hWin)300 bool VBClX11SeamlessMonitor::isVirtualRoot(Window hWin) 300 301 { 301 302 unsigned char *windowTypeRaw = NULL; … … 331 332 * Free all information in the tree of visible windows 332 333 */ 333 void SeamlessX11::freeWindowTree(void)334 void VBClX11SeamlessMonitor::freeWindowTree(void) 334 335 { 335 336 /* We use post-increment in the operation to prevent the iterator from being invalidated. */ … … 345 346 * @note Called from the guest event thread. 346 347 */ 347 void SeamlessX11::nextConfigurationEvent(void)348 void VBClX11SeamlessMonitor::nextConfigurationEvent(void) 348 349 { 349 350 XEvent event; … … 423 424 * @param hWin the window to be examined 424 425 */ 425 void SeamlessX11::doConfigureEvent(Window hWin)426 void VBClX11SeamlessMonitor::doConfigureEvent(Window hWin) 426 427 { 427 428 VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin); … … 445 446 * @param hWin the window to be examined 446 447 */ 447 void SeamlessX11::doShapeEvent(Window hWin)448 void VBClX11SeamlessMonitor::doShapeEvent(Window hWin) 448 449 { 449 450 LogRelFlowFuncEnter(); … … 471 472 * Gets the list of visible rectangles 472 473 */ 473 RTRECT * SeamlessX11::getRects(void)474 RTRECT *VBClX11SeamlessMonitor::getRects(void) 474 475 { 475 476 return mpRects; … … 479 480 * Gets the number of rectangles in the visible rectangle list 480 481 */ 481 size_t SeamlessX11::getRectCount(void)482 size_t VBClX11SeamlessMonitor::getRectCount(void) 482 483 { 483 484 return mcRects; … … 529 530 * Updates the list of seamless rectangles 530 531 */ 531 int SeamlessX11::updateRects(void)532 int VBClX11SeamlessMonitor::updateRects(void) 532 533 { 533 534 LogRelFlowFuncEnter(); … … 554 555 * @note This function should only be called from the host event thread. 555 556 */ 556 bool SeamlessX11::interruptEventWait(void)557 bool VBClX11SeamlessMonitor::interruptEventWait(void) 557 558 { 558 559 LogRelFlowFuncEnter(); … … 587 588 return rc; 588 589 } 590 591 592 /********************************************************************************************************************************* 593 * VBClX11SeamlessSvc implementation * 594 ********************************************************************************************************************************/ 595 596 VBClX11SeamlessSvc::VBClX11SeamlessSvc(void) 597 { 598 mX11MonitorThread = NIL_RTTHREAD; 599 mX11MonitorThreadStopping = false; 600 601 mMode = VMMDev_Seamless_Disabled; 602 mfPaused = true; 603 } 604 605 VBClX11SeamlessSvc::~VBClX11SeamlessSvc() 606 { 607 /* Stopping will be done via main.cpp. */ 608 } 609 610 /** @copydoc VBCLSERVICE::pfnInit */ 611 int VBClX11SeamlessSvc::init(void) 612 { 613 int rc; 614 const char *pcszStage; 615 616 do 617 { 618 pcszStage = "Connecting to the X server"; 619 rc = mX11Monitor.init(VBClSeamnlessSendRegionUpdate); 620 if (RT_FAILURE(rc)) 621 break; 622 pcszStage = "Setting guest IRQ filter mask"; 623 rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0); 624 if (RT_FAILURE(rc)) 625 break; 626 pcszStage = "Reporting support for seamless capability"; 627 rc = VbglR3SeamlessSetCap(true); 628 if (RT_FAILURE(rc)) 629 break; 630 rc = startX11MonitorThread(); 631 if (RT_FAILURE(rc)) 632 break; 633 634 } while(0); 635 636 if (RT_FAILURE(rc)) 637 VBClLogError("Failed to start in stage '%s' -- error %Rrc\n", pcszStage, rc); 638 639 return rc; 640 } 641 642 /** @copydoc VBCLSERVICE::pfnWorker */ 643 int VBClX11SeamlessSvc::worker(bool volatile *pfShutdown) 644 { 645 int rc = VINF_SUCCESS; 646 647 /* Let the main thread know that it can continue spawning services. */ 648 RTThreadUserSignal(RTThreadSelf()); 649 650 /* This will only exit if something goes wrong. */ 651 for (;;) 652 { 653 if (ASMAtomicReadBool(pfShutdown)) 654 break; 655 656 rc = nextStateChangeEvent(); 657 658 if (rc == VERR_TRY_AGAIN) 659 rc = VINF_SUCCESS; 660 661 if (RT_FAILURE(rc)) 662 break; 663 664 if (ASMAtomicReadBool(pfShutdown)) 665 break; 666 667 /* If we are not stopping, sleep for a bit to avoid using up too 668 much CPU while retrying. */ 669 RTThreadYield(); 670 } 671 672 return rc; 673 } 674 675 /** @copydoc VBCLSERVICE::pfnStop */ 676 void VBClX11SeamlessSvc::stop(void) 677 { 678 VbglR3SeamlessSetCap(false); 679 VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST); 680 stopX11MonitorThread(); 681 } 682 683 /** @copydoc VBCLSERVICE::pfnTerm */ 684 int VBClX11SeamlessSvc::term(void) 685 { 686 mX11Monitor.uninit(); 687 return VINF_SUCCESS; 688 } 689 690 /** 691 * Waits for a seamless state change events from the host and dispatch it. 692 * 693 * @returns VBox return code, or 694 * VERR_TRY_AGAIN if no new status is available and we have to try it again 695 * at some later point in time. 696 */ 697 int VBClX11SeamlessSvc::nextStateChangeEvent(void) 698 { 699 VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled; 700 701 int rc = VbglR3SeamlessWaitEvent(&newMode); 702 if (RT_SUCCESS(rc)) 703 { 704 mMode = newMode; 705 switch (newMode) 706 { 707 case VMMDev_Seamless_Visible_Region: 708 /* A simplified seamless mode, obtained by making the host VM window 709 * borderless and making the guest desktop transparent. */ 710 VBClLogVerbose(2, "\"Visible region\" mode requested\n"); 711 break; 712 case VMMDev_Seamless_Disabled: 713 VBClLogVerbose(2, "\"Disabled\" mode requested\n"); 714 break; 715 case VMMDev_Seamless_Host_Window: 716 /* One host window represents one guest window. Not yet implemented. */ 717 VBClLogVerbose(2, "Unsupported \"host window\" mode requested\n"); 718 return VERR_NOT_SUPPORTED; 719 default: 720 VBClLogError("Unsupported mode %d requested\n", newMode); 721 return VERR_NOT_SUPPORTED; 722 } 723 } 724 if ( RT_SUCCESS(rc) 725 || rc == VERR_TRY_AGAIN) 726 { 727 if (mMode == VMMDev_Seamless_Visible_Region) 728 mfPaused = false; 729 else 730 mfPaused = true; 731 mX11Monitor.interruptEventWait(); 732 } 733 else 734 VBClLogError("VbglR3SeamlessWaitEvent returned %Rrc\n", rc); 735 736 return rc; 737 } 738 739 /** 740 * The actual X11 window configuration change monitor thread function. 741 */ 742 int VBClX11SeamlessSvc::x11MonitorThread(RTTHREAD hThreadSelf, void *pvUser) 743 { 744 RT_NOREF(hThreadSelf); 745 746 VBClX11SeamlessSvc *pThis = (VBClX11SeamlessSvc *)pvUser; 747 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 748 749 int rc = VINF_SUCCESS; 750 751 RTThreadUserSignal(hThreadSelf); 752 753 VBClLogVerbose(2, "X11 monitor thread started\n"); 754 755 while (!pThis->mX11MonitorThreadStopping) 756 { 757 if (!pThis->mfPaused) 758 { 759 rc = pThis->mX11Monitor.start(); 760 if (RT_FAILURE(rc)) 761 VBClLogFatalError("Failed to change the X11 seamless service state, mfPaused=%RTbool, rc=%Rrc\n", 762 pThis->mfPaused, rc); 763 } 764 765 pThis->mX11Monitor.nextConfigurationEvent(); 766 767 if ( pThis->mfPaused 768 || pThis->mX11MonitorThreadStopping) 769 { 770 pThis->mX11Monitor.stop(); 771 } 772 } 773 774 VBClLogVerbose(2, "X11 monitor thread ended\n"); 775 776 return rc; 777 } 778 779 /** 780 * Start the X11 window configuration change monitor thread. 781 */ 782 int VBClX11SeamlessSvc::startX11MonitorThread(void) 783 { 784 mX11MonitorThreadStopping = false; 785 786 if (isX11MonitorThreadRunning()) 787 return VINF_SUCCESS; 788 789 int rc = RTThreadCreate(&mX11MonitorThread, x11MonitorThread, this, 0, 790 RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, 791 "seamless x11"); 792 if (RT_SUCCESS(rc)) 793 rc = RTThreadUserWait(mX11MonitorThread, RT_MS_30SEC); 794 795 if (RT_FAILURE(rc)) 796 VBClLogError("Failed to start X11 monitor thread, rc=%Rrc\n", rc); 797 798 return rc; 799 } 800 801 /** 802 * Stops the monitor thread. 803 */ 804 int VBClX11SeamlessSvc::stopX11MonitorThread(void) 805 { 806 if (!isX11MonitorThreadRunning()) 807 return VINF_SUCCESS; 808 809 mX11MonitorThreadStopping = true; 810 if (!mX11Monitor.interruptEventWait()) 811 { 812 VBClLogError("Unable to notify X11 monitor thread\n"); 813 return VERR_INVALID_STATE; 814 } 815 816 int rcThread; 817 int rc = RTThreadWait(mX11MonitorThread, RT_MS_30SEC, &rcThread); 818 if (RT_SUCCESS(rc)) 819 rc = rcThread; 820 821 if (RT_SUCCESS(rc)) 822 { 823 mX11MonitorThread = NIL_RTTHREAD; 824 } 825 else 826 VBClLogError("Waiting for X11 monitor thread to stop failed, rc=%Rrc\n", rc); 827 828 return rc; 829 } 830 -
trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
r98103 r99600 175 175 }; 176 176 177 class SeamlessX11177 class VBClX11SeamlessMonitor 178 178 { 179 179 private: 180 180 // We don't want a copy constructor or assignment operator 181 SeamlessX11(const SeamlessX11&);182 SeamlessX11& operator=(const SeamlessX11&);181 VBClX11SeamlessMonitor(const VBClX11SeamlessMonitor&); 182 VBClX11SeamlessMonitor& operator=(const VBClX11SeamlessMonitor&); 183 183 184 184 // Private member variables … … 259 259 void doShapeEvent(Window hWin); 260 260 261 SeamlessX11(void)261 VBClX11SeamlessMonitor(void) 262 262 : mHostCallback(NULL), mDisplay(NULL), mpRects(NULL), mcRects(0), 263 263 mSupportsShape(false), mEnabled(false), mChanged(false) {} 264 264 265 ~ SeamlessX11()265 ~VBClX11SeamlessMonitor() 266 266 { 267 267 uninit(); -
trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp
r98474 r99600 1 1 /* $Id$ */ 2 2 /** @file 3 * X11 Guest client - seamless mode: main logic, communication with the host and 4 * wrapper interface for the main code of the VBoxClient deamon. The 5 * X11-specific parts are split out into their own file for ease of testing. 3 * Guest Additions - Common seamless mode wrapper service. 6 4 */ 7 5 … … 51 49 *********************************************************************************************************************************/ 52 50 53 /** 54 * Struct for keeping a service instance. 55 */ 56 struct SEAMLESSSERVICE 57 { 58 /** Seamless service object. */ 59 SeamlessMain mSeamless; 60 }; 61 62 /** Service instance data. */ 63 static SEAMLESSSERVICE g_Svc; 51 /** Pointer to the DnD interface class. */ 52 static VBClSeamlessSvc *g_pSvc = NULL; 64 53 65 54 66 SeamlessMain::SeamlessMain(void) 67 { 68 mX11MonitorThread = NIL_RTTHREAD; 69 mX11MonitorThreadStopping = false; 70 71 mMode = VMMDev_Seamless_Disabled; 72 mfPaused = true; 73 } 74 75 SeamlessMain::~SeamlessMain() 76 { 77 /* Stopping will be done via main.cpp. */ 78 } 55 /********************************************************************************************************************************* 56 * Common functions * 57 *********************************************************************************************************************************/ 79 58 80 59 /** 81 * Update the set of visible rectangles in the host. 60 * Reports region updates to the host. 61 * 62 * @param pRects Pointer to array of regions to report. 63 * @param cRects Number of regions in \a pRect. 82 64 */ 83 static void sendRegionUpdate(RTRECT *pRects, size_t cRects)65 void VBClSeamnlessSendRegionUpdate(RTRECT *pRects, size_t cRects) 84 66 { 85 67 if ( cRects … … 92 74 } 93 75 94 /** @copydoc VBCLSERVICE::pfnInit */95 int SeamlessMain::init(void)96 {97 int rc;98 const char *pcszStage;99 76 100 do 101 { 102 pcszStage = "Connecting to the X server"; 103 rc = mX11Monitor.init(sendRegionUpdate); 104 if (RT_FAILURE(rc)) 105 break; 106 pcszStage = "Setting guest IRQ filter mask"; 107 rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0); 108 if (RT_FAILURE(rc)) 109 break; 110 pcszStage = "Reporting support for seamless capability"; 111 rc = VbglR3SeamlessSetCap(true); 112 if (RT_FAILURE(rc)) 113 break; 114 rc = startX11MonitorThread(); 115 if (RT_FAILURE(rc)) 116 break; 117 118 } while(0); 119 120 if (RT_FAILURE(rc)) 121 VBClLogError("Failed to start in stage '%s' -- error %Rrc\n", pcszStage, rc); 122 123 return rc; 124 } 125 126 /** @copydoc VBCLSERVICE::pfnWorker */ 127 int SeamlessMain::worker(bool volatile *pfShutdown) 128 { 129 int rc = VINF_SUCCESS; 130 131 /* Let the main thread know that it can continue spawning services. */ 132 RTThreadUserSignal(RTThreadSelf()); 133 134 /* This will only exit if something goes wrong. */ 135 for (;;) 136 { 137 if (ASMAtomicReadBool(pfShutdown)) 138 break; 139 140 rc = nextStateChangeEvent(); 141 142 if (rc == VERR_TRY_AGAIN) 143 rc = VINF_SUCCESS; 144 145 if (RT_FAILURE(rc)) 146 break; 147 148 if (ASMAtomicReadBool(pfShutdown)) 149 break; 150 151 /* If we are not stopping, sleep for a bit to avoid using up too 152 much CPU while retrying. */ 153 RTThreadYield(); 154 } 155 156 return rc; 157 } 158 159 /** @copydoc VBCLSERVICE::pfnStop */ 160 void SeamlessMain::stop(void) 161 { 162 VbglR3SeamlessSetCap(false); 163 VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST); 164 stopX11MonitorThread(); 165 } 166 167 /** @copydoc VBCLSERVICE::pfnTerm */ 168 int SeamlessMain::term(void) 169 { 170 mX11Monitor.uninit(); 171 return VINF_SUCCESS; 172 } 173 174 /** 175 * Waits for a seamless state change events from the host and dispatch it. 176 * 177 * @returns VBox return code, or 178 * VERR_TRY_AGAIN if no new status is available and we have to try it again 179 * at some later point in time. 180 */ 181 int SeamlessMain::nextStateChangeEvent(void) 182 { 183 VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled; 184 185 int rc = VbglR3SeamlessWaitEvent(&newMode); 186 if (RT_SUCCESS(rc)) 187 { 188 mMode = newMode; 189 switch (newMode) 190 { 191 case VMMDev_Seamless_Visible_Region: 192 /* A simplified seamless mode, obtained by making the host VM window 193 * borderless and making the guest desktop transparent. */ 194 VBClLogVerbose(2, "\"Visible region\" mode requested\n"); 195 break; 196 case VMMDev_Seamless_Disabled: 197 VBClLogVerbose(2, "\"Disabled\" mode requested\n"); 198 break; 199 case VMMDev_Seamless_Host_Window: 200 /* One host window represents one guest window. Not yet implemented. */ 201 VBClLogVerbose(2, "Unsupported \"host window\" mode requested\n"); 202 return VERR_NOT_SUPPORTED; 203 default: 204 VBClLogError("Unsupported mode %d requested\n", newMode); 205 return VERR_NOT_SUPPORTED; 206 } 207 } 208 if ( RT_SUCCESS(rc) 209 || rc == VERR_TRY_AGAIN) 210 { 211 if (mMode == VMMDev_Seamless_Visible_Region) 212 mfPaused = false; 213 else 214 mfPaused = true; 215 mX11Monitor.interruptEventWait(); 216 } 217 else 218 VBClLogError("VbglR3SeamlessWaitEvent returned %Rrc\n", rc); 219 220 return rc; 221 } 222 223 /** 224 * The actual X11 window configuration change monitor thread function. 225 */ 226 int SeamlessMain::x11MonitorThread(RTTHREAD hThreadSelf, void *pvUser) 227 { 228 RT_NOREF(hThreadSelf); 229 230 SeamlessMain *pThis = (SeamlessMain *)pvUser; 231 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 232 233 int rc = VINF_SUCCESS; 234 235 RTThreadUserSignal(hThreadSelf); 236 237 VBClLogVerbose(2, "X11 monitor thread started\n"); 238 239 while (!pThis->mX11MonitorThreadStopping) 240 { 241 if (!pThis->mfPaused) 242 { 243 rc = pThis->mX11Monitor.start(); 244 if (RT_FAILURE(rc)) 245 VBClLogFatalError("Failed to change the X11 seamless service state, mfPaused=%RTbool, rc=%Rrc\n", 246 pThis->mfPaused, rc); 247 } 248 249 pThis->mX11Monitor.nextConfigurationEvent(); 250 251 if ( pThis->mfPaused 252 || pThis->mX11MonitorThreadStopping) 253 { 254 pThis->mX11Monitor.stop(); 255 } 256 } 257 258 VBClLogVerbose(2, "X11 monitor thread ended\n"); 259 260 return rc; 261 } 262 263 /** 264 * Start the X11 window configuration change monitor thread. 265 */ 266 int SeamlessMain::startX11MonitorThread(void) 267 { 268 mX11MonitorThreadStopping = false; 269 270 if (isX11MonitorThreadRunning()) 271 return VINF_SUCCESS; 272 273 int rc = RTThreadCreate(&mX11MonitorThread, x11MonitorThread, this, 0, 274 RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, 275 "seamless x11"); 276 if (RT_SUCCESS(rc)) 277 rc = RTThreadUserWait(mX11MonitorThread, RT_MS_30SEC); 278 279 if (RT_FAILURE(rc)) 280 VBClLogError("Failed to start X11 monitor thread, rc=%Rrc\n", rc); 281 282 return rc; 283 } 284 285 /** 286 * Stops the monitor thread. 287 */ 288 int SeamlessMain::stopX11MonitorThread(void) 289 { 290 if (!isX11MonitorThreadRunning()) 291 return VINF_SUCCESS; 292 293 mX11MonitorThreadStopping = true; 294 if (!mX11Monitor.interruptEventWait()) 295 { 296 VBClLogError("Unable to notify X11 monitor thread\n"); 297 return VERR_INVALID_STATE; 298 } 299 300 int rcThread; 301 int rc = RTThreadWait(mX11MonitorThread, RT_MS_30SEC, &rcThread); 302 if (RT_SUCCESS(rc)) 303 rc = rcThread; 304 305 if (RT_SUCCESS(rc)) 306 { 307 mX11MonitorThread = NIL_RTTHREAD; 308 } 309 else 310 VBClLogError("Waiting for X11 monitor thread to stop failed, rc=%Rrc\n", rc); 311 312 return rc; 313 } 77 /********************************************************************************************************************************* 78 * Service wrapper * 79 *********************************************************************************************************************************/ 314 80 315 81 /** … … 318 84 static DECLCALLBACK(int) vbclSeamlessInit(void) 319 85 { 320 return g_Svc.mSeamless.init(); 86 switch (VBClGetSessionType()) 87 { 88 case VBGHSESSIONTYPE_X11: 89 g_pSvc = new VBClX11SeamlessSvc(); 90 break; 91 92 case VBGHSESSIONTYPE_WAYLAND: 93 RT_FALL_THROUGH(); 94 default: 95 return VERR_NOT_SUPPORTED; 96 } 97 98 if (!g_pSvc) 99 return VERR_NO_MEMORY; 100 101 return g_pSvc->init(); 321 102 } 322 103 … … 326 107 static DECLCALLBACK(int) vbclSeamlessWorker(bool volatile *pfShutdown) 327 108 { 328 return g_ Svc.mSeamless.worker(pfShutdown);109 return g_pSvc->worker(pfShutdown); 329 110 } 330 111 … … 334 115 static DECLCALLBACK(void) vbclSeamlessStop(void) 335 116 { 336 return g_ Svc.mSeamless.stop();117 return g_pSvc->stop(); 337 118 } 338 119 … … 342 123 static DECLCALLBACK(int) vbclSeamlessTerm(void) 343 124 { 344 return g_Svc.mSeamless.term(); 125 int rc = VINF_SUCCESS; 126 127 if (g_pSvc) 128 { 129 rc = g_pSvc->term(); 130 131 delete g_pSvc; 132 g_pSvc = NULL; 133 } 134 135 return rc; 345 136 } 346 137 -
trunk/src/VBox/Additions/x11/VBoxClient/seamless.h
r98103 r99600 33 33 #endif 34 34 35 #include <iprt/asm.h> 35 36 #include <iprt/thread.h> 36 37 … … 40 41 #include "seamless-x11.h" 41 42 43 /** @name Generic seamless functions 44 * @{ */ 45 void VBClSeamnlessSendRegionUpdate(RTRECT *pRects, size_t cRects); 46 /** @} */ 47 42 48 /** 43 * Interface to the host49 * Interface class for seamless mode service implementation. 44 50 */ 45 class SeamlessMain51 class VBClSeamlessSvc 46 52 { 53 protected: 54 55 /* Note: Constructor must not throw, as we don't have exception handling on the guest side. */ 56 VBClSeamlessSvc(void) { } 57 58 public: 59 60 virtual ~VBClSeamlessSvc(void) { } 61 62 public: 63 64 virtual int init(void) { return VINF_SUCCESS; } 65 virtual int worker(bool volatile *pfShutdown) { RT_NOREF(pfShutdown); return VINF_SUCCESS; } 66 virtual void reset(void) { } 67 virtual void stop(void) { } 68 virtual int term(void) { return VINF_SUCCESS; } 69 70 #ifdef IN_GUEST 71 RTMEM_IMPLEMENT_NEW_AND_DELETE(); 72 #endif 73 }; 74 75 /** 76 * Service class which implements seamless mode for X11. 77 */ 78 class VBClX11SeamlessSvc : public VBClSeamlessSvc 79 { 80 public: 81 VBClX11SeamlessSvc(void); 82 83 virtual ~VBClX11SeamlessSvc(); 84 85 public: 86 87 /** @copydoc VBCLSERVICE::pfnInit */ 88 virtual int init(void); 89 90 /** @copydoc VBCLSERVICE::pfnWorker */ 91 virtual int worker(bool volatile *pfShutdown); 92 93 /** @copydoc VBCLSERVICE::pfnStop */ 94 virtual void stop(void); 95 96 /** @copydoc VBCLSERVICE::pfnTerm */ 97 virtual int term(void); 98 47 99 private: 48 / / We don't want a copy constructor or assignment operator49 SeamlessMain(const SeamlessMain&);50 SeamlessMain& operator=(const SeamlessMain&);100 /** Note: We don't want a copy constructor or assignment operator. */ 101 VBClX11SeamlessSvc(const VBClX11SeamlessSvc&); 102 VBClX11SeamlessSvc& operator=(const VBClX11SeamlessSvc&); 51 103 52 /** X11 event monitor object */53 SeamlessX11mX11Monitor;104 /** X11 event monitor object. */ 105 VBClX11SeamlessMonitor mX11Monitor; 54 106 55 107 /** Thread to start and stop when we enter and leave seamless mode which … … 86 138 return mX11MonitorThread != NIL_RTTHREAD; 87 139 } 88 89 public:90 SeamlessMain(void);91 virtual ~SeamlessMain();92 #ifdef RT_NEED_NEW_AND_DELETE93 RTMEM_IMPLEMENT_NEW_AND_DELETE();94 #endif95 96 /** @copydoc VBCLSERVICE::pfnInit */97 int init(void);98 99 /** @copydoc VBCLSERVICE::pfnWorker */100 int worker(bool volatile *pfShutdown);101 102 /** @copydoc VBCLSERVICE::pfnStop */103 void stop(void);104 105 /** @copydoc VBCLSERVICE::pfnTerm */106 int term(void);107 140 }; 108 141 -
trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
r98103 r99600 676 676 static unsigned smlsDoFixture(SMLSFIXTURE *pFixture, const char *pszDesc) 677 677 { 678 SeamlessX11subject;678 VBClX11SeamlessMonitor subject; 679 679 unsigned cErrs = 0; 680 680 -
trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
r98103 r99600 33 33 #include <iprt/string.h> 34 34 #include <iprt/stream.h> 35 35 36 #include <VBox/VBoxGuestLib.h> 37 #include <VBox/GuestHost/SessionType.h> 36 38 37 39 #include "../seamless.h" 38 40 39 41 static RTSEMEVENT eventSem; 42 43 VBGHSESSIONTYPE VBClGetSessionType(void) 44 { 45 return VBGHSESSIONTYPE_X11; 46 } 40 47 41 48 void VBClLogError(const char *pszFormat, ...) … … 169 176 RTSemEventCreate(&eventSem); 170 177 /** Our instance of the seamless class. */ 171 SeamlessMainseamless;178 VBClX11SeamlessSvc seamless; 172 179 LogRel(("Starting seamless Guest Additions...\n")); 173 180 rc = seamless.init();
Note:
See TracChangeset
for help on using the changeset viewer.