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
}
Exemplo n.º 2
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;
}