예제 #1
0
파일: load.c 프로젝트: OSLL/vboxhsm
static bool stubSystemWindowExist(WindowInfo *pWindow)
{
#ifdef WINDOWS
    if (pWindow->hWnd!=WindowFromDC(pWindow->drawable))
    {
        return false;
    }
#else
    Window root;
    int x, y;
    unsigned int border, depth, w, h;
    Display *dpy;

    dpy = stubGetWindowDisplay(pWindow);

    XLOCK(dpy);
    if (!XGetGeometry(dpy, pWindow->drawable, &root, &x, &y, &w, &h, &border, &depth))
    {
        XUNLOCK(dpy);
        return false;
    }
    XUNLOCK(dpy);
#endif

    return true;
}
void
stubGetWindowGeometry(WindowInfo *window, int *x, int *y, unsigned int *w, unsigned int *h)
{
    Window root, child;
    unsigned int border, depth;
    Display *dpy;

    dpy = stubGetWindowDisplay(window);

    //@todo: Performing those checks is expensive operation, especially for simple apps with high FPS.
    //       Disabling those triples glxgears fps, thus using xevents instead of per frame polling is much more preferred.
    //@todo: Check similar on windows guests, though doubtful as there're no XSync like calls on windows.
    if (window && dpy)
    {
        XLOCK(dpy);
    }

    if (!window
        || !dpy
        || !window->drawable
        || !XGetGeometry(dpy, window->drawable, &root, x, y, w, h, &border, &depth)
        || !XTranslateCoordinates(dpy, window->drawable, root, 0, 0, x, y, &child)) 
    {
        crWarning("Failed to get windows geometry for %p, try xwininfo", window);
        *x = *y = 0;
        *w = *h = 0;
    }

    if (window && dpy)
    {
        XUNLOCK(dpy);
    }
}
예제 #3
0
void stubCheckXExtensions(WindowInfo *pWindow)
{
    int evb, erb, vmi=0, vma=0;
    Display *dpy = stubGetWindowDisplay(pWindow);

    stub.bXExtensionsChecked = GL_TRUE;
    stub.trackWindowVisibleRgn = 0;

    XLOCK(dpy);
    if (XCompositeQueryExtension(dpy, &evb, &erb) 
        && XCompositeQueryVersion(dpy, &vma, &vmi) 
        && (vma>0 || vmi>=4))
    {
        stub.bHaveXComposite = GL_TRUE;
        crDebug("XComposite %i.%i", vma, vmi);
        vma=0;
        vmi=0;
        if (XFixesQueryExtension(dpy, &evb, &erb) 
            && XFixesQueryVersion(dpy, &vma, &vmi)
            && vma>=2)
        {
            crDebug("XFixes %i.%i", vma, vmi);
            stub.bHaveXFixes = GL_TRUE;
            stub.trackWindowVisibleRgn = 1;
            XUNLOCK(dpy);
            return;
        }
        else
        {
            crWarning("XFixes not found or old version (%i.%i), no VisibilityTracking", vma, vmi);
        }
    }
    else
    {
        crWarning("XComposite not found or old version (%i.%i), no VisibilityTracking", vma, vmi);
    }
    XUNLOCK(dpy);
    return;
}
GLboolean
stubIsWindowVisible(WindowInfo *win)
{
#if defined(WINDOWS)
# ifdef VBOX_WITH_WDDM
    if (stub.bRunningUnderWDDM)
        return win->mapped;
# endif
    return GL_TRUE;
#elif defined(Darwin)
    return GL_TRUE;
#elif defined(GLX)
    Display *dpy = stubGetWindowDisplay(win);
    if (dpy) 
    {
        XWindowAttributes attr;
        XLOCK(dpy);
        XGetWindowAttributes(dpy, win->drawable, &attr);
        XUNLOCK(dpy);

        if (attr.map_state == IsUnmapped)
        {
            return GL_FALSE;
        }
# if 1
        return GL_TRUE;
# else
        if (attr.override_redirect)
        {
            return GL_TRUE;
        }

        if (!stub.bXExtensionsChecked)
        {
            stubCheckXExtensions(win);
        }

        if (!stub.bHaveXComposite)
        {
            return GL_TRUE;
        }
        else
        {
            Pixmap p;

            crLockMutex(&stub.mutex);

            XLOCK(dpy);
            XSync(dpy, false);
            oldErrorHandler = XSetErrorHandler(errorHandler);
            /*@todo this will create new pixmap for window every call*/
            p = XCompositeNameWindowPixmap(dpy, win->drawable);
            XSync(dpy, false);
            XSetErrorHandler(oldErrorHandler);
            XUNLOCK(dpy);

            switch (lastXError)
            {
                case Success:
                    XFreePixmap(dpy, p);
                    crUnlockMutex(&stub.mutex);
                    return GL_FALSE;
                    break;
                case BadMatch:
                    /*Window isn't redirected*/
                    lastXError = Success;
                    break;
                default:
                    crWarning("Unexpected XError %i", (int)lastXError);
                    lastXError = Success;
            }

            crUnlockMutex(&stub.mutex);

            return GL_TRUE;
        }
# endif
    }
    else {
        /* probably created by crWindowCreate() */
        return win->mapped;
    }
#endif
}
예제 #5
0
/*
 *  Updates visible regions for given spu window.
 *  Returns GL_TRUE if regions changed since last call, GL_FALSE otherwise.
 */
GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow)
{
    XserverRegion xreg;
    int cRects, i;
    XRectangle *pXRects;
    GLint* pGLRects;
    Display *dpy;
    bool bNoUpdate = false;

    if (!stub.bXExtensionsChecked)
    {
        stubCheckXExtensions(pWindow);
        if (!stub.trackWindowVisibleRgn)
        {
            return GL_FALSE;
        }
    }

    dpy = stubGetWindowDisplay(pWindow);

    /*@todo see comment regarding size/position updates and XSync, same applies to those functions but
    * it seems there's no way to get even based updates for this. Or I've failed to find the appropriate extension.
    */
    XLOCK(dpy);
    xreg = XCompositeCreateRegionFromBorderClip(dpy, pWindow->drawable);
    pXRects = XFixesFetchRegion(dpy, xreg, &cRects);
    XFixesDestroyRegion(dpy, xreg);
    XUNLOCK(dpy);

    /* Check for compiz main window */
    if (!pWindow->pVisibleRegions && !cRects)
    {
#ifdef VBOX_TEST_MEGOO
        XWindowAttributes attr;
        XLOCK(dpy);
        XSync(dpy, false);
        XGetWindowAttributes(dpy, pWindow->drawable, &attr);
        XUNLOCK(dpy);

        bNoUpdate = attr.override_redirect;
#else
        bNoUpdate = true;
#endif
    }

    if (!bNoUpdate
        && (!pWindow->pVisibleRegions
            || pWindow->cVisibleRegions!=cRects 
            || (pWindow->pVisibleRegions && crMemcmp(pWindow->pVisibleRegions, pXRects, cRects * sizeof(XRectangle)))))
    {
        if (pWindow->pVisibleRegions)
        {
            XFree(pWindow->pVisibleRegions);
        }

        pWindow->pVisibleRegions = pXRects;
        pWindow->cVisibleRegions = cRects;

        pGLRects = crAlloc(4*cRects*sizeof(GLint));
        if (!pGLRects)
        {
            crWarning("stubUpdateWindowVisibileRegions: failed to allocate %lu bytes",
                    (unsigned long)(4*cRects*sizeof(GLint)));
            return GL_FALSE;
        }

        //crDebug("Got %i rects.", cRects);
        for (i=0; i<cRects; ++i)
        {
            pGLRects[4*i+0] = pXRects[i].x;
            pGLRects[4*i+1] = pXRects[i].y;
            pGLRects[4*i+2] = pXRects[i].x+pXRects[i].width;
            pGLRects[4*i+3] = pXRects[i].y+pXRects[i].height;
            //crDebug("Rect[%i]=(%i,%i,%i,%i)", i, pGLRects[4*i+0], pGLRects[4*i+1], pGLRects[4*i+2], pGLRects[4*i+3]);                   
        }

        crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, cRects);
        stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, cRects, pGLRects);
        crFree(pGLRects);
        return GL_TRUE;
    }
    else
    {
        XFree(pXRects);
    }

    return GL_FALSE;
}