Example #1
0
static Bool
RootlessAllocatePrivates(ScreenPtr pScreen)
{
    RootlessScreenRec *s;
    static unsigned long rootlessGeneration = 0;

    if (rootlessGeneration != serverGeneration) {
        rootlessScreenPrivateIndex = AllocateScreenPrivateIndex();
        if (rootlessScreenPrivateIndex == -1) return FALSE;
        rootlessGCPrivateIndex = AllocateGCPrivateIndex();
        if (rootlessGCPrivateIndex == -1) return FALSE;
        rootlessWindowPrivateIndex = AllocateWindowPrivateIndex();
        if (rootlessWindowPrivateIndex == -1) return FALSE;
        rootlessGeneration = serverGeneration;
    }

    // no allocation needed for screen privates
    if (!AllocateGCPrivate(pScreen, rootlessGCPrivateIndex,
                           sizeof(RootlessGCRec)))
        return FALSE;
    if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0))
        return FALSE;

    s = xalloc(sizeof(RootlessScreenRec));
    if (! s) return FALSE;
    SCREENREC(pScreen) = s;

    return TRUE;
}
Example #2
0
ColormapPtr
RootlessGetColormap (ScreenPtr pScreen)
{
  RootlessScreenRec *s = SCREENREC (pScreen);

  return s->colormap;
}
Example #3
0
/*
 * RootlessUpdateScreenPixmap
 *  miCreateScreenResources does not like a null framebuffer pointer,
 *  it leaves the screen pixmap with an uninitialized data pointer.
 *  Thus, rootless implementations typically set the framebuffer width
 *  to zero so that miCreateScreenResources does not allocate a screen
 *  pixmap for us. We allocate our own screen pixmap here since we need
 *  the screen pixmap to be valid (e.g. CopyArea from the root window).
 */
void
RootlessUpdateScreenPixmap(ScreenPtr pScreen)
{
    RootlessScreenRec *s = SCREENREC(pScreen);
    PixmapPtr pPix;
    unsigned int rowbytes;

    pPix = (*pScreen->GetScreenPixmap)(pScreen);
    if (pPix == NULL) {
        pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
        (*pScreen->SetScreenPixmap)(pPix);
    }

    rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);

    if (s->pixmap_data_size < rowbytes) {
        free(s->pixmap_data);

        s->pixmap_data_size = rowbytes;
        s->pixmap_data = malloc(s->pixmap_data_size);
        if (s->pixmap_data == NULL)
            return;

        memset(s->pixmap_data, 0xFF, s->pixmap_data_size);

        pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
                                    pScreen->rootDepth,
                                    BitsPerPixel(pScreen->rootDepth),
                                    0, s->pixmap_data);
        /* ModifyPixmapHeader ignores zero arguments, so install rowbytes
           by hand. */
        pPix->devKind = 0;
    }
}
Example #4
0
static void
RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
                  INT16 xSrc, INT16 ySrc, INT16  xMask, INT16  yMask,
                  INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    WindowPtr dstWin;

    dstWin  = (pDst->pDrawable->type  == DRAWABLE_WINDOW) ?
        (WindowPtr)pDst->pDrawable  :  NULL;

    // SCREEN_UNWRAP(ps, Composite);
    ps->Composite = SCREENREC(pScreen)->Composite;

    ps->Composite(op, pSrc, pMask, pDst,
                  xSrc, ySrc, xMask, yMask,
                  xDst, yDst, width, height);

    if (dstWin  && IsFramedWindow(dstWin)) {
        RootlessDamageRect(dstWin, xDst, yDst, width, height);
    }

    ps->Composite = RootlessComposite;
    // SCREEN_WRAP(ps, Composite);
}
Example #5
0
/*
 * RootlessBlockHandler
 *  If the redisplay timer has expired, flush drawing before blocking
 *  on select().
 */
static void
RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
{
    ScreenPtr pScreen = pbdata;
    RootlessScreenRec *screenRec = SCREENREC(pScreen);

    if (screenRec->redisplay_expired) {
        screenRec->redisplay_expired = FALSE;

        RootlessRedisplayScreen(pScreen);
    }
}
Example #6
0
static void
RootlessWrap(ScreenPtr pScreen)
{
    RootlessScreenRec *s = SCREENREC(pScreen);

#define WRAP(a) \
    if (pScreen->a) { \
        s->a = pScreen->a; \
    } else { \
        RL_DEBUG_MSG("null screen fn " #a "\n"); \
        s->a = NULL; \
    } \
    pScreen->a = Rootless##a

    WRAP(CreateScreenResources);
    WRAP(CloseScreen);
    WRAP(CreateGC);
    WRAP(CopyWindow);
    WRAP(GetImage);
    WRAP(SourceValidate);
    WRAP(CreateWindow);
    WRAP(DestroyWindow);
    WRAP(RealizeWindow);
    WRAP(UnrealizeWindow);
    WRAP(MoveWindow);
    WRAP(PositionWindow);
    WRAP(ResizeWindow);
    WRAP(RestackWindow);
    WRAP(ReparentWindow);
    WRAP(ChangeBorderWidth);
    WRAP(MarkOverlappedWindows);
    WRAP(ValidateTree);
    WRAP(ChangeWindowAttributes);
    WRAP(InstallColormap);
    WRAP(UninstallColormap);
    WRAP(StoreColors);

    WRAP(SetShape);

    {
        // Composite and Glyphs don't use normal screen wrapping
        PictureScreenPtr ps = GetPictureScreen(pScreen);
        s->Composite = ps->Composite;
        ps->Composite = RootlessComposite;
        s->Glyphs = ps->Glyphs;
        ps->Glyphs = RootlessGlyphs;
    }

    // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?

#undef WRAP
}
Example #7
0
static Bool
RootlessCloseScreen(int i, ScreenPtr pScreen)
{
    RootlessScreenRec *s;

    s = SCREENREC(pScreen);

    // fixme unwrap everything that was wrapped?
    pScreen->CloseScreen = s->CloseScreen;

    xfree(s);
    return pScreen->CloseScreen(i, pScreen);
}
Example #8
0
static void
RootlessUninstallColormap (ColormapPtr pMap)
{
  ScreenPtr pScreen = pMap->pScreen;
  RootlessScreenRec *s = SCREENREC (pScreen);

  SCREEN_UNWRAP(pScreen, UninstallColormap);

  if (s->colormap == pMap)
    s->colormap = NULL;

  pScreen->UninstallColormap (pMap);

  SCREEN_WRAP(pScreen, UninstallColormap);
}
Example #9
0
/*
 * RootlessQueueRedisplay
 *  Queue a redisplay after a timer delay to ensure we do not redisplay
 *  too frequently.
 */
void
RootlessQueueRedisplay(ScreenPtr pScreen)
{
    RootlessScreenRec *screenRec = SCREENREC(pScreen);

    screenRec->redisplay_queued = TRUE;

    if (screenRec->redisplay_timer_set)
        return;

    screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer,
                                          0, ROOTLESS_REDISPLAY_DELAY,
                                          RootlessRedisplayCallback,
                                          screenRec);
    screenRec->redisplay_timer_set = TRUE;
}
Example #10
0
static void
RootlessStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
{
  ScreenPtr pScreen = pMap->pScreen;
  RootlessScreenRec *s = SCREENREC (pScreen);

  SCREEN_UNWRAP(pScreen, StoreColors);

  if (s->colormap == pMap && ndef > 0) {
    s->colormap_changed = TRUE;
    RootlessQueueRedisplay (pScreen);
  }

  pScreen->StoreColors (pMap, ndef, pdef);

  SCREEN_WRAP(pScreen, StoreColors);
}
Example #11
0
static void
RootlessInstallColormap (ColormapPtr pMap)
{
  ScreenPtr pScreen = pMap->pScreen;
  RootlessScreenRec *s = SCREENREC (pScreen);

  SCREEN_UNWRAP(pScreen, InstallColormap);

  if (s->colormap != pMap) {
    s->colormap = pMap;
    s->colormap_changed = TRUE;
    RootlessQueueRedisplay (pScreen);
  }

  pScreen->InstallColormap (pMap);

  SCREEN_WRAP (pScreen, InstallColormap);
}
Example #12
0
static Bool
RootlessCloseScreen(int i, ScreenPtr pScreen)
{
    RootlessScreenRec *s;

    s = SCREENREC(pScreen);

    // fixme unwrap everything that was wrapped?
    pScreen->CloseScreen = s->CloseScreen;

    if (s->pixmap_data != NULL) {
        free(s->pixmap_data);
        s->pixmap_data = NULL;
        s->pixmap_data_size = 0;
    }

    free(s);
    return pScreen->CloseScreen(i, pScreen);
}
Example #13
0
/*
 * Screen function to create a graphics context
 */
Bool
RootlessCreateGC(GCPtr pGC)
{
    RootlessGCRec *gcrec;
    RootlessScreenRec *s;
    Bool result;

    SCREEN_UNWRAP(pGC->pScreen, CreateGC);
    s = SCREENREC(pGC->pScreen);
    result = s->CreateGC(pGC);

    gcrec = (RootlessGCRec *)
        dixLookupPrivate(&pGC->devPrivates, rootlessGCPrivateKey);
    gcrec->originalOps = NULL;  // don't wrap ops yet
    gcrec->originalFuncs = pGC->funcs;
    pGC->funcs = &rootlessGCFuncs;

    SCREEN_WRAP(pGC->pScreen, CreateGC);
    return result;
}
Example #14
0
static void
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    int x, y;
    int n;
    GlyphPtr glyph;
    WindowPtr dstWin;

    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
        (WindowPtr)pDst->pDrawable  :  NULL;

    //SCREEN_UNWRAP(ps, Glyphs);
    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
    ps->Glyphs = RootlessGlyphs;
    //SCREEN_WRAP(ps, Glyphs);

    if (dstWin && IsFramedWindow(dstWin)) {
        x = xSrc;
        y = ySrc;
        while (nlist--) {
            x += list->xOff;
            y += list->yOff;
            n = list->len;
            while (n--) {
                glyph = *glyphs++;
                RootlessDamageRect(dstWin,
                                   x - glyph->info.x, y - glyph->info.y,
                                   glyph->info.width, glyph->info.height);
                x += glyph->info.xOff;
                y += glyph->info.yOff;
            }
            list++;
        }
    }
}
Example #15
0
/*
 * RootlessInit
 *  Called by the rootless implementation to initialize the rootless layer.
 *  Rootless wraps lots of stuff and needs a bunch of devPrivates.
 */
Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
{
    RootlessScreenRec *s;

    if (!RootlessAllocatePrivates(pScreen))
        return FALSE;

    s = SCREENREC(pScreen);

    s->imp = procs;
    s->colormap = NULL;
    s->redisplay_expired = FALSE;

    RootlessWrap(pScreen);

    if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
                                        RootlessWakeupHandler,
                                        (pointer) pScreen))
    {
        return FALSE;
    }

    return TRUE;
}
/* Optimized version of fbCompositeSolidMask_nx8x8888 */
void
SafeAlphaCompositeSolidMask_nx8x8888(
    CARD8      op,
    PicturePtr pSrc,
    PicturePtr pMask,
    PicturePtr pDst,
    INT16      xSrc,
    INT16      ySrc,
    INT16      xMask,
    INT16      yMask,
    INT16      xDst,
    INT16      yDst,
    CARD16     width,
    CARD16     height)
{
    CARD32	src, srca;
    CARD32	*dstLine, *dst, d, dstMask;
    CARD8	*maskLine, *mask, m;
    FbStride	dstStride, maskStride;
    CARD16	w;

    fbComposeGetSolid(pSrc, src, pDst->format);

    dstMask = FbFullMask (pDst->pDrawable->depth);
    srca = src >> 24;
    if (src == 0)
        return;

    fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);

    if (dstMask == FB_ALLONES && pDst->pDrawable->bitsPerPixel == 32 &&
            width * height > rootless_CompositePixels_threshold &&
            SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels)
    {
        void *srcp[2], *destp[2];
        unsigned int dest_rowbytes[2];
        unsigned int fn;

        srcp[0] = &src;
        srcp[1] = &src;
        /* null rowbytes pointer means use first value as a constant */
        destp[0] = dstLine;
        destp[1] = dstLine;
        dest_rowbytes[0] = dstStride * 4;
        dest_rowbytes[1] = dest_rowbytes[0];
        fn = RL_COMPOSITE_FUNCTION(RL_COMPOSITE_OVER, RL_DEPTH_ARGB8888,
                                   RL_DEPTH_A8, RL_DEPTH_ARGB8888);

        if (SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels(
                    width, height, fn, srcp, NULL,
                    maskLine, maskStride,
                    destp, dest_rowbytes) == Success)
        {
            return;
        }
    }

    while (height--)
    {
        dst = dstLine;
        dstLine += dstStride;
        mask = maskLine;
        maskLine += maskStride;
        w = width;

        while (w--)
        {
            m = *mask++;
            if (m == 0xff)
            {
                if (srca == 0xff)
                    *dst = src & dstMask;
                else
                    *dst = fbOver (src, *dst) & dstMask;
            }
            else if (m)
            {
                d = fbIn (src, m);
                *dst = fbOver (d, *dst) & dstMask;
            }
            dst++;
        }
    }
}
Example #17
0
static void
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    int x, y;
    int n;
    GlyphPtr glyph;
    WindowPtr srcWin, dstWin;

    srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
             (WindowPtr)pSrc->pDrawable  :  NULL;
    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
             (WindowPtr)pDst->pDrawable  :  NULL;

    if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
    if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);

    //SCREEN_UNWRAP(ps, Glyphs);
    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
    ps->Glyphs = RootlessGlyphs;
    //SCREEN_WRAP(ps, Glyphs);

    if (dstWin && IsFramedWindow(dstWin)) {
        x = xSrc;
        y = ySrc;

        while (nlist--) {
            x += list->xOff;
            y += list->yOff;
            n = list->len;

            /* Calling DamageRect for the bounding box of each glyph is
               inefficient. So compute the union of all glyphs in a list
               and damage that. */

            if (n > 0) {
                BoxRec box;

                glyph = *glyphs++;

                box.x1 = x - glyph->info.x;
                box.y1 = y - glyph->info.y;
                box.x2 = box.x1 + glyph->info.width;
                box.y2 = box.y1 + glyph->info.height;

                x += glyph->info.xOff;
                y += glyph->info.yOff;

                while (--n > 0) {
                    short x1, y1, x2, y2;

                    glyph = *glyphs++;

                    x1 = x - glyph->info.x;
                    y1 = y - glyph->info.y;
                    x2 = x1 + glyph->info.width;
                    y2 = y1 + glyph->info.height;

                    box.x1 = max (box.x1, x1);
                    box.y1 = max (box.y1, y1);
                    box.x2 = max (box.x2, x2);
                    box.y2 = max (box.y2, y2);

                    x += glyph->info.xOff;
                    y += glyph->info.yOff;
                }

                RootlessDamageBox(dstWin, &box);
            }
            list++;
        }
    }
}