VirtualBox

Ignore:
Timestamp:
Feb 12, 2014 4:33:32 PM (11 years ago)
Author:
vboxsync
Message:

Additions/x11/VBoxClient: display/resizing: clean-up and handle VT switches.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/display.cpp

    r49877 r50432  
    3838#include "VBoxClient.h"
    3939
    40 static int initDisplay(Display *pDisplay)
    41 {
    42     int rc = VINF_SUCCESS;
    43     uint32_t fMouseFeatures = 0;
    44 
    45     LogRelFlowFunc(("testing dynamic resizing\n"));
    46     int iDummy;
    47     if (!XRRQueryExtension(pDisplay, &iDummy, &iDummy))
    48         rc = VERR_NOT_SUPPORTED;
     40/** Tell the VBoxGuest driver we no longer want any events and tell the host
     41 * we no longer support any capabilities. */
     42static int disableEventsAndCaps()
     43{
     44    int rc, rc2;
     45    rc = VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS);
     46    rc2 = VbglR3SetMouseStatus(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
     47    rc = RT_FAILURE(rc) ? rc : rc2;
     48    rc2 = VbglR3CtlFilterMask(0, VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST);
     49    rc = RT_FAILURE(rc) ? rc : rc2;
     50    return rc;
     51}
     52
     53/** Tell the VBoxGuest driver which events we want and tell the host which
     54 * capabilities we support. */
     55static int enableEventsAndCaps(Display *pDisplay, bool fFirstTime)
     56{
     57    int iDummy, rc;
     58    uint32_t fFilterMask = VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED;
     59    uint32_t fCapabilities = 0;
     60    if (XRRQueryExtension(pDisplay, &iDummy, &iDummy))
     61    {
     62        fFilterMask |= VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
     63        fCapabilities |= VMMDEV_GUEST_SUPPORTS_GRAPHICS;
     64    }
     65    else if (fFirstTime)
     66        LogRel(("VBoxClient: guest does not support dynamic resizing.\n"));
     67    rc = VbglR3CtlFilterMask(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0);
    4968    if (RT_SUCCESS(rc))
    50     {
    51         rc = VbglR3CtlFilterMask(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0);
    52 #ifdef VBOX_WITH_GUEST_KMS_DRIVER
    53         if (RT_SUCCESS(rc))
    54             VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0);
    55 #endif
    56     }
    57     else
    58         VbglR3CtlFilterMask(0, VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST);
    59     /* Log and ignore the return value, as there is not much we can do with
    60      * it. */
    61     LogRelFlowFunc(("dynamic resizing: result %Rrc\n", rc));
    62     /* Enable support for switching between hardware and software cursors */
    63     LogRelFlowFunc(("enabling relative mouse re-capturing support\n"));
    64     rc = VbglR3GetMouseStatus(&fMouseFeatures, NULL, NULL);
     69        rc = VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0);
     70    /** @todo Make sure that VBoxGuest understands
     71     * VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR as a "negative" capability: if we
     72     * don't advertise it it means we *can* switch to a software cursor and
     73     * back. */
    6574    if (RT_SUCCESS(rc))
    66     {
    67         rc = VbglR3CtlFilterMask(VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED,
    68                                  0);
    69         if (RT_SUCCESS(rc))
    70             rc = VbglR3SetMouseStatus
    71                                (  fMouseFeatures
    72                                 & ~VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
    73     }
     75        rc = VbglR3SetMouseStatus(0);
    7476    if (RT_FAILURE(rc))
    75     {
    76         VbglR3CtlFilterMask(0,   VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED
    77                                | VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST);
    78 #ifdef VBOX_WITH_GUEST_KMS_DRIVER
    79         VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS);
    80 #endif
    81         VbglR3SetMouseStatus(  fMouseFeatures
    82                              | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
    83     }
    84     LogRelFlowFunc(("mouse re-capturing support: result %Rrc\n", rc));
    85     return VINF_SUCCESS;
    86 }
    87 
    88 void cleanupDisplay(void)
    89 {
    90     uint32_t fMouseFeatures = 0;
    91     LogRelFlowFunc(("\n"));
    92     VbglR3CtlFilterMask(0,   VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST
    93                            | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED);
    94 #ifdef VBOX_WITH_GUEST_KMS_DRIVER
    95     VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS);
    96 #endif
    97     int rc = VbglR3GetMouseStatus(&fMouseFeatures, NULL, NULL);
    98     if (RT_SUCCESS(rc))
    99         VbglR3SetMouseStatus(  fMouseFeatures
    100                              | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
    101     LogRelFlowFunc(("returning\n"));
    102 }
    103 
    104 /** This thread just runs a dummy X11 event loop to be sure that we get
    105  * terminated should the X server exit. */
    106 static int x11ConnectionMonitor(RTTHREAD, void *)
    107 {
    108     XEvent ev;
    109     Display *pDisplay = XOpenDisplay(NULL);
    110     while (true)
    111         XNextEvent(pDisplay, &ev);
    112     return 0;
     77        disableEventsAndCaps();
     78    return rc;
    11379}
    11480
     
    165131 * stale.
    166132 */
    167 static int runDisplay(Display *pDisplay)
     133static void runDisplay(Display *pDisplay)
    168134{
    169135    LogRelFlowFunc(("\n"));
     
    177143    if (RTFileExists("/usr/X11/bin/xrandr"))
    178144        pcszXrandr = "/usr/X11/bin/xrandr";
    179     int rc = RTThreadCreate(NULL, x11ConnectionMonitor, NULL, 0,
    180                    RTTHREADTYPE_INFREQUENT_POLLER, 0, "X11 monitor");
    181     if (RT_FAILURE(rc))
    182         return rc;
    183145    while (true)
    184146    {
    185147        uint32_t fEvents = 0, cx = 0, cy = 0, cBits = 0, iDisplay = 0, cxOrg = 0, cyOrg = 0;
    186148        bool fEnabled = false;
    187         rc = VbglR3WaitEvent(  VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST
    188                              | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED,
    189                              RT_INDEFINITE_WAIT, &fEvents);
     149        int rc = VbglR3WaitEvent(  VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST
     150                                 | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED,
     151                                 RT_INDEFINITE_WAIT, &fEvents);
    190152        if (RT_FAILURE(rc) && rc != VERR_INTERRUPTED)  /* VERR_NO_MEMORY? */
    191             return rc;
     153        {
     154            LogRelFunc(("VBoxClient: VbglR3WaitEvent failed, rc=%Rrc\n", rc));
     155            VBoxClient::CleanUp();
     156        }
    192157        /* Jiggle the mouse pointer to wake up the driver. */
    193158        XGrabPointer(pDisplay,
     
    281246        }
    282247    }
    283     return VINF_SUCCESS;
    284248}
    285249
    286250class DisplayService : public VBoxClient::Service
    287251{
     252    Display *mDisplay;
     253    bool mfInit;
    288254public:
    289255    virtual const char *getPidFilePath()
     
    291257        return ".vboxclient-display.pid";
    292258    }
     259    virtual int init()
     260    {
     261        int rc;
     262       
     263        if (mfInit)
     264            return VERR_WRONG_ORDER;
     265        mDisplay = XOpenDisplay(NULL);
     266        if (!mDisplay)
     267            return VERR_NOT_FOUND;
     268        rc = enableEventsAndCaps(mDisplay, true);
     269        if (RT_SUCCESS(rc))
     270            mfInit = true;
     271        return rc;
     272    }
    293273    virtual int run(bool fDaemonised /* = false */)
    294274    {
    295         Display *pDisplay = XOpenDisplay(NULL);
    296         if (!pDisplay)
    297             return VERR_NOT_FOUND;
    298         int rc = initDisplay(pDisplay);
    299         if (RT_SUCCESS(rc))
    300             rc = runDisplay(pDisplay);
    301         XCloseDisplay(pDisplay);
    302         return rc;
     275        if (!mfInit)
     276            return VERR_WRONG_ORDER;
     277        runDisplay(mDisplay);
     278        return VERR_INTERNAL_ERROR;  /* "Should never reach here." */
     279    }
     280    virtual int pause()
     281    {
     282        if (!mfInit)
     283            return VERR_WRONG_ORDER;
     284        return disableEventsAndCaps();
     285    }
     286    virtual int resume()
     287    {
     288        if (!mfInit)
     289            return VERR_WRONG_ORDER;
     290        return enableEventsAndCaps(mDisplay, false);
    303291    }
    304292    virtual void cleanup()
    305293    {
    306         cleanupDisplay();
    307     }
     294        disableEventsAndCaps();
     295    }
     296    DisplayService() { mfInit = false; }
    308297};
    309298
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette