Ejemplo n.º 1
0
static void
vfbInstallColormap(ColormapPtr pmap)
{
    ColormapPtr oldpmap = GetInstalledmiColormap(pmap->pScreen);

    if (pmap != oldpmap) {
        int entries;
        XWDFileHeader *pXWDHeader;
        VisualPtr pVisual;
        Pixel *ppix;
        xrgb *prgb;
        xColorItem *defs;
        int i;

        miInstallColormap(pmap);

        entries = pmap->pVisual->ColormapEntries;
        pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
        pVisual = pmap->pVisual;

        swapcopy32(pXWDHeader->visual_class, pVisual->class);
        swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
        swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
        swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
        swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
        swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);

        ppix = xallocarray(entries, sizeof(Pixel));
        prgb = xallocarray(entries, sizeof(xrgb));
        defs = xallocarray(entries, sizeof(xColorItem));

        for (i = 0; i < entries; i++)
            ppix[i] = i;
        /* XXX truecolor */
        QueryColors(pmap, entries, ppix, prgb, serverClient);

        for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
            defs[i].pixel = ppix[i] & 0xff;     /* change pixel to index */
            defs[i].red = prgb[i].red;
            defs[i].green = prgb[i].green;
            defs[i].blue = prgb[i].blue;
            defs[i].flags = DoRed | DoGreen | DoBlue;
        }
        (*pmap->pScreen->StoreColors) (pmap, entries, defs);

        free(ppix);
        free(prgb);
        free(defs);
    }
Ejemplo n.º 2
0
static void
xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
                        LOCO * colors, VisualPtr pVisual)
{
    int i, index;
    sbusCmapPtr cmap;
    struct fbcmap fbcmap;
    unsigned char *data;

    cmap = SBUSCMAPPTR(pScrn->pScreen);
    if (!cmap)
        return;
    fbcmap.count = 0;
    fbcmap.index = indices[0];
    fbcmap.red = data = xallocarray(numColors, 3);
    if (!data)
        return;
    fbcmap.green = data + numColors;
    fbcmap.blue = fbcmap.green + numColors;
    for (i = 0; i < numColors; i++) {
        index = indices[i];
        if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
            ioctl(cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
            fbcmap.count = 0;
            fbcmap.index = index;
        }
        fbcmap.red[fbcmap.count] = colors[index].red;
        fbcmap.green[fbcmap.count] = colors[index].green;
        fbcmap.blue[fbcmap.count++] = colors[index].blue;
    }
    ioctl(cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
    free(data);
}
Ejemplo n.º 3
0
void
glamor_solid_boxes(PixmapPtr pixmap,
                   BoxPtr box, int nbox, unsigned long fg_pixel)
{
    DrawablePtr drawable = &pixmap->drawable;
    GCPtr gc;
    xRectangle *rect;
    int n;

    rect = xallocarray(nbox, sizeof(xRectangle));
    if (!rect)
        return;
    for (n = 0; n < nbox; n++) {
        rect[n].x = box[n].x1;
        rect[n].y = box[n].y1;
        rect[n].width = box[n].x2 - box[n].x1;
        rect[n].height = box[n].y2 - box[n].y1;
    }

    gc = GetScratchGC(drawable->depth, drawable->pScreen);
    if (gc) {
        ChangeGCVal vals[1];

        vals[0].val = fg_pixel;
        ChangeGC(NullClient, gc, GCForeground, vals);
        ValidateGC(drawable, gc);
        gc->ops->PolyFillRect(drawable, gc, nbox, rect);
        FreeScratchGC(gc);
    }
    free(rect);
}
Ejemplo n.º 4
0
Bool
fakeMapFramebuffer(KdScreenInfo * screen)
{
    FakeScrPriv *scrpriv = screen->driver;
    KdPointerMatrix m;
    FakePriv *priv = screen->card->driver;

    if (scrpriv->randr != RR_Rotate_0)
        scrpriv->shadow = TRUE;
    else
        scrpriv->shadow = FALSE;

    KdComputePointerMatrix(&m, scrpriv->randr, screen->width, screen->height);

    KdSetPointerMatrix(&m);

    priv->bytes_per_line =
        ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
    free(priv->base);
    priv->base = xallocarray(priv->bytes_per_line, screen->height);

    if (scrpriv->shadow) {
        if (!KdShadowFbAlloc
            (screen, scrpriv->randr & (RR_Rotate_90 | RR_Rotate_270)))
            return FALSE;
    }
    else {
        screen->fb.byteStride = priv->bytes_per_line;
        screen->fb.pixelStride = (priv->bytes_per_line * 8 /
                                  screen->fb.bitsPerPixel);
        screen->fb.frameBuffer = (CARD8 *) (priv->base);
    }

    return TRUE;
}
Ejemplo n.º 5
0
/** Add glyphs to the Glyph Set on each screen. */
static int
dmxProcRenderAddGlyphs(ClientPtr client)
{
    int ret;

    REQUEST(xRenderAddGlyphsReq);

    ret = dmxSaveRenderVector[stuff->renderReqType] (client);

    if (ret == Success) {
        GlyphSetPtr glyphSet;
        dmxGlyphPrivPtr glyphPriv;
        int i;
        int nglyphs;
        CARD32 *gids;
        Glyph *gidsCopy;
        xGlyphInfo *gi;
        CARD8 *bits;
        int nbytes;

        dixLookupResourceByType((void **) &glyphSet,
                                stuff->glyphset, GlyphSetType,
                                client, DixReadAccess);
        glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);

        nglyphs = stuff->nglyphs;
        gids = (CARD32 *) (stuff + 1);
        gi = (xGlyphInfo *) (gids + nglyphs);
        bits = (CARD8 *) (gi + nglyphs);
        nbytes = ((stuff->length << 2) -
                  sizeof(xRenderAddGlyphsReq) -
                  (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs);

        gidsCopy = xallocarray(nglyphs, sizeof(*gidsCopy));
        for (i = 0; i < nglyphs; i++)
            gidsCopy[i] = gids[i];

        /* FIXME: Will this ever fail? */
        for (i = 0; i < dmxNumScreens; i++) {
            DMXScreenInfo *dmxScreen = &dmxScreens[i];

            if (dmxScreen->beDisplay) {
                XRenderAddGlyphs(dmxScreen->beDisplay,
                                 glyphPriv->glyphSets[i],
                                 gidsCopy,
                                 (XGlyphInfo *) gi,
                                 nglyphs, (char *) bits, nbytes);
                dmxSync(dmxScreen, FALSE);
            }
        }
        free(gidsCopy);
    }

    return ret;
}
Ejemplo n.º 6
0
static int
InputLineAddChar(InputLine * line, int ch)
{
    if (line->num_line >= line->sz_line) {
        if (line->line == line->buf) {
            line->line = xallocarray(line->sz_line, 2);
            memcpy(line->line, line->buf, line->sz_line);
        }
        else {
            line->line = reallocarray(line->line, line->sz_line, 2);
        }
        line->sz_line *= 2;
    }
    line->line[line->num_line++] = ch;
    return ch;
}
Ejemplo n.º 7
0
static Bool
miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo)
{
    register int i, j, k;
    register int count;
    DepthPtr pDepth;
    XdbeVisualInfo *visInfo;

    /* Determine number of visuals for this screen. */
    for (i = 0, count = 0; i < pScreen->numDepths; i++) {
        count += pScreen->allowedDepths[i].numVids;
    }

    /* Allocate an array of XdbeVisualInfo items. */
    if (!(visInfo = xallocarray(count, sizeof(XdbeVisualInfo)))) {
        return FALSE;           /* memory alloc failure */
    }

    for (i = 0, k = 0; i < pScreen->numDepths; i++) {
        /* For each depth of this screen, get visual information. */

        pDepth = &pScreen->allowedDepths[i];

        for (j = 0; j < pDepth->numVids; j++) {
            /* For each visual for this depth of this screen, get visual ID
             * and visual depth.  Since this is MI code, we will always return
             * the same performance level for all visuals (0).  A higher
             * performance level value indicates higher performance.
             */
            visInfo[k].visual = pDepth->vids[j];
            visInfo[k].depth = pDepth->depth;
            visInfo[k].perflevel = 0;
            k++;
        }
    }

    /* Record the number of visuals and point visual_depth to
     * the array of visual info.
     */
    pScrVisInfo->count = count;
    pScrVisInfo->visinfo = visInfo;

    return TRUE;                /* success */

}                               /* miDbeGetVisualInfo() */
Ejemplo n.º 8
0
/** This routine adds an event to the motion history.  A similar
 * function is performed by miPointerMove for the mi versions of these
 * routines. */
void
dmxPointerPutMotionEvent(DeviceIntPtr pDevice,
                         int firstAxis, int axesCount, int *v,
                         unsigned long time)
{
    GETDMXLOCALFROMPDEVICE;
    int numAxes = pDevice->valuator->numAxes;
    int i;

    if (!dmxLocal->history) {
        dmxLocal->history = xallocarray(numAxes + 1,
                                 sizeof(*dmxLocal->history) * DMX_MOTION_SIZE);
        dmxLocal->head = 0;
        dmxLocal->tail = 0;
        dmxLocal->valuators = calloc(sizeof(*dmxLocal->valuators), numAxes);
    }
    else {
        if (++dmxLocal->tail >= DMX_MOTION_SIZE)
            dmxLocal->tail = 0;
        if (dmxLocal->head == dmxLocal->tail)
            if (++dmxLocal->head >= DMX_MOTION_SIZE)
                dmxLocal->head = 0;
    }

    dmxLocal->history[OFFSET(dmxLocal->tail, 0)] = time;

    /* Initialize the data from the known
     * values (if Absolute) or to zero (if
     * Relative) */
    for (i = 0; i < numAxes; i++) {
        if (pDevice->valuator->axes[i].mode == Absolute)
            dmxLocal->history[OFFSET(dmxLocal->tail, i + 1)]
                = dmxLocal->valuators[i];
        else
            dmxLocal->history[OFFSET(dmxLocal->tail, i + 1)] = 0;
    }

    for (i = firstAxis; i < axesCount; i++) {
        dmxLocal->history[OFFSET(dmxLocal->tail, i + i)]
            = (unsigned long) v[i - firstAxis];
        dmxLocal->valuators[i] = v[i - firstAxis];
    }
}
Ejemplo n.º 9
0
/** Free glyphs from the Glyph Set for each screen. */
static int
dmxProcRenderFreeGlyphs(ClientPtr client)
{
    GlyphSetPtr glyphSet;

    REQUEST(xRenderFreeGlyphsReq);

    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
    dixLookupResourceByType((void **) &glyphSet,
                            stuff->glyphset, GlyphSetType,
                            client, DixWriteAccess);

    if (glyphSet) {
        dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
        int i;
        int nglyphs;
        Glyph *gids;

        nglyphs = ((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)) >> 2;
        if (nglyphs) {
            gids = xallocarray(nglyphs, sizeof(*gids));
            for (i = 0; i < nglyphs; i++)
                gids[i] = ((CARD32 *) (stuff + 1))[i];

            for (i = 0; i < dmxNumScreens; i++) {
                DMXScreenInfo *dmxScreen = &dmxScreens[i];

                if (dmxScreen->beDisplay) {
                    XRenderFreeGlyphs(dmxScreen->beDisplay,
                                      glyphPriv->glyphSets[i], gids, nglyphs);
                    dmxSync(dmxScreen, FALSE);
                }
            }
            free(gids);
        }
    }

    return dmxSaveRenderVector[stuff->renderReqType] (client);
}
Ejemplo n.º 10
0
int
ProcXFixesExpandRegion(ClientPtr client)
{
    RegionPtr pSource, pDestination;

    REQUEST(xXFixesExpandRegionReq);
    BoxPtr pTmp;
    BoxPtr pSrc;
    int nBoxes;
    int i;

    REQUEST_SIZE_MATCH(xXFixesExpandRegionReq);
    VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
    VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);

    nBoxes = RegionNumRects(pSource);
    pSrc = RegionRects(pSource);
    if (nBoxes) {
        pTmp = xallocarray(nBoxes, sizeof(BoxRec));
        if (!pTmp)
            return BadAlloc;
        for (i = 0; i < nBoxes; i++) {
            pTmp[i].x1 = pSrc[i].x1 - stuff->left;
            pTmp[i].x2 = pSrc[i].x2 + stuff->right;
            pTmp[i].y1 = pSrc[i].y1 - stuff->top;
            pTmp[i].y2 = pSrc[i].y2 + stuff->bottom;
        }
        RegionEmpty(pDestination);
        for (i = 0; i < nBoxes; i++) {
            RegionRec r;

            RegionInit(&r, &pTmp[i], 0);
            RegionUnion(pDestination, pDestination, &r);
        }
        free(pTmp);
    }
    return Success;
}
Ejemplo n.º 11
0
/*
 * Written by Brian Kelleher; Dec. 1985.
 *
 * Fill a convex polygon.  If the given polygon is not convex, then the result
 * is undefined.  The algorithm is to order the edges from smallest y to
 * largest by partitioning the array into a left edge list and a right edge
 * list.  The algorithm used to traverse each edge is an extension of
 * Bresenham's line algorithm with y as the major axis.  For a derivation of
 * the algorithm, see the author of this code.
 */
static Bool
miFillConvexPoly(DrawablePtr dst, GCPtr pgc, int count, DDXPointPtr ptsIn)
{
    int xl = 0, xr = 0;         /* x vals of left and right edges */
    int dl = 0, dr = 0;         /* decision variables             */
    int ml = 0, m1l = 0;        /* left edge slope and slope+1    */
    int mr = 0, m1r = 0;        /* right edge slope and slope+1   */
    int incr1l = 0, incr2l = 0; /* left edge error increments     */
    int incr1r = 0, incr2r = 0; /* right edge error increments    */
    int dy;                     /* delta y                        */
    int y;                      /* current scanline               */
    int left, right;            /* indices to first endpoints     */
    int i;                      /* loop counter                   */
    int nextleft, nextright;    /* indices to second endpoints    */
    DDXPointPtr ptsOut, FirstPoint;     /* output buffer               */
    int *width, *FirstWidth;    /* output buffer                  */
    int imin;                   /* index of smallest vertex (in y) */
    int ymin;                   /* y-extents of polygon            */
    int ymax;

    /*
     *  find leftx, bottomy, rightx, topy, and the index
     *  of bottomy. Also translate the points.
     */
    imin = getPolyYBounds(ptsIn, count, &ymin, &ymax);

    dy = ymax - ymin + 1;
    if ((count < 3) || (dy < 0))
        return TRUE;
    ptsOut = FirstPoint = xallocarray(dy, sizeof(DDXPointRec));
    width = FirstWidth = xallocarray(dy, sizeof(int));
    if (!FirstPoint || !FirstWidth) {
        free(FirstWidth);
        free(FirstPoint);
        return FALSE;
    }

    nextleft = nextright = imin;
    y = ptsIn[nextleft].y;

    /*
     *  loop through all edges of the polygon
     */
    do {
        /*
         *  add a left edge if we need to
         */
        if (ptsIn[nextleft].y == y) {
            left = nextleft;

            /*
             *  find the next edge, considering the end
             *  conditions of the array.
             */
            nextleft++;
            if (nextleft >= count)
                nextleft = 0;

            /*
             *  now compute all of the random information
             *  needed to run the iterative algorithm.
             */
            BRESINITPGON(ptsIn[nextleft].y - ptsIn[left].y,
                         ptsIn[left].x, ptsIn[nextleft].x,
                         xl, dl, ml, m1l, incr1l, incr2l);
        }

        /*
         *  add a right edge if we need to
         */
        if (ptsIn[nextright].y == y) {
            right = nextright;

            /*
             *  find the next edge, considering the end
             *  conditions of the array.
             */
            nextright--;
            if (nextright < 0)
                nextright = count - 1;

            /*
             *  now compute all of the random information
             *  needed to run the iterative algorithm.
             */
            BRESINITPGON(ptsIn[nextright].y - ptsIn[right].y,
                         ptsIn[right].x, ptsIn[nextright].x,
                         xr, dr, mr, m1r, incr1r, incr2r);
        }

        /*
         *  generate scans to fill while we still have
         *  a right edge as well as a left edge.
         */
        i = min(ptsIn[nextleft].y, ptsIn[nextright].y) - y;
        /* in case we're called with non-convex polygon */
        if (i < 0) {
            free(FirstWidth);
            free(FirstPoint);
            return TRUE;
        }
        while (i-- > 0) {
            ptsOut->y = y;

            /*
             *  reverse the edges if necessary
             */
            if (xl < xr) {
                *(width++) = xr - xl;
                (ptsOut++)->x = xl;
            }
            else {
                *(width++) = xl - xr;
                (ptsOut++)->x = xr;
            }
            y++;

            /* increment down the edges */
            BRESINCRPGON(dl, xl, ml, m1l, incr1l, incr2l);
            BRESINCRPGON(dr, xr, mr, m1r, incr1r, incr2r);
        }
    } while (y != ymax);

    /*
     * Finally, fill the <remaining> spans
     */
    (*pgc->ops->FillSpans) (dst, pgc,
                            ptsOut - FirstPoint, FirstPoint, FirstWidth, 1);
    free(FirstWidth);
    free(FirstPoint);
    return TRUE;
}
Ejemplo n.º 12
0
void
__glXScreenInit(GLint numscreens)
{
    int s;
    int c;
    DMXScreenInfo *dmxScreen0 = &dmxScreens[0];

    __glXNumActiveScreens = numscreens;

    CalcServerVersionAndExtensions();

    __glXFBConfigs = NULL;
    __glXNumFBConfigs = 0;

    if ((__glXVersionMajor == 1 && __glXVersionMinor >= 3) ||
        (__glXVersionMajor > 1) ||
        (strstr(ExtensionsString, "GLX_SGIX_fbconfig"))) {

        /*
           // Initialize FBConfig info.
           // find the set of FBConfigs that are present on all back-end
           // servers - only those configs will be supported
         */
        __glXFBConfigs =
            xallocarray(dmxScreen0->numFBConfigs * (numscreens + 1),
                        sizeof(__GLXFBConfig *));
        __glXNumFBConfigs = 0;

        for (c = 0; c < dmxScreen0->numFBConfigs; c++) {
            __GLXFBConfig *cfg = NULL;

            if (numscreens > 1) {
                for (s = 1; s < numscreens; s++) {
                    DMXScreenInfo *dmxScreen = &dmxScreens[s];

                    cfg = FindMatchingFBConfig(&dmxScreen0->fbconfigs[c],
                                               dmxScreen->fbconfigs,
                                               dmxScreen->numFBConfigs);
                    __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + s +
                                   1] = cfg;
                    if (!cfg) {
                        dmxLog(dmxInfo,
                               "screen0 FBConfig 0x%x is missing on screen#%d\n",
                               dmxScreen0->fbconfigs[c].id, s);
                        break;
                    }
                    else {
                        dmxLog(dmxInfo,
                               "screen0 FBConfig 0x%x matched to  0x%x on screen#%d\n",
                               dmxScreen0->fbconfigs[c].id, cfg->id, s);
                    }
                }
            }
            else {
                cfg = &dmxScreen0->fbconfigs[c];
            }

            if (cfg) {

                /* filter out overlay visuals */
                if (cfg->level == 0) {
                    __GLXFBConfig *proxy_cfg;

                    __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + 1] =
                        &dmxScreen0->fbconfigs[c];

                    proxy_cfg = malloc(sizeof(__GLXFBConfig));
                    memcpy(proxy_cfg, cfg, sizeof(__GLXFBConfig));
                    proxy_cfg->id = FakeClientID(0);
                    /* visual will be associated later in __glXGetFBConfigs */
                    proxy_cfg->associatedVisualId = (unsigned int) -1;

                    __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + 0] =
                        proxy_cfg;

                    __glXNumFBConfigs++;
                }

            }

        }

    }

}
Ejemplo n.º 13
0
Bool
DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
{
    GrabPtr grab;
    GrabPtr *deletes, *adds;
    Mask ***updates, **details;
    int i, ndels, nadds, nups;
    Bool ok;
    unsigned int any_modifier;
    unsigned int any_key;

#define UPDATE(mask,exact) \
	if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \
	  ok = FALSE; \
	else \
	  updates[nups++] = &(mask)

    i = 0;
    for (grab = wPassiveGrabs(pMinuendGrab->window); grab; grab = grab->next)
        i++;
    if (!i)
        return TRUE;
    deletes = xallocarray(i, sizeof(GrabPtr));
    adds = xallocarray(i, sizeof(GrabPtr));
    updates = xallocarray(i, sizeof(Mask **));
    details = xallocarray(i, sizeof(Mask *));
    if (!deletes || !adds || !updates || !details) {
        free(details);
        free(updates);
        free(adds);
        free(deletes);
        return FALSE;
    }

    any_modifier = (pMinuendGrab->grabtype == XI2) ?
        (unsigned int) XIAnyModifier : (unsigned int) AnyModifier;
    any_key = (pMinuendGrab->grabtype == XI2) ?
        (unsigned int) XIAnyKeycode : (unsigned int) AnyKey;
    ndels = nadds = nups = 0;
    ok = TRUE;
    for (grab = wPassiveGrabs(pMinuendGrab->window);
         grab && ok; grab = grab->next) {
        if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource))
            || !GrabMatchesSecond(grab, pMinuendGrab, (grab->grabtype == CORE)))
            continue;
        if (GrabSupersedesSecond(pMinuendGrab, grab)) {
            deletes[ndels++] = grab;
        }
        else if ((grab->detail.exact == any_key)
                 && (grab->modifiersDetail.exact != any_modifier)) {
            UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
        }
        else if ((grab->modifiersDetail.exact == any_modifier)
                 && (grab->detail.exact != any_key)) {
            UPDATE(grab->modifiersDetail.pMask,
                   pMinuendGrab->modifiersDetail.exact);
        }
        else if ((pMinuendGrab->detail.exact != any_key)
                 && (pMinuendGrab->modifiersDetail.exact != any_modifier)) {
            GrabPtr pNewGrab;
            GrabParameters param;

            UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);

            memset(&param, 0, sizeof(param));
            param.ownerEvents = grab->ownerEvents;
            param.this_device_mode = grab->keyboardMode;
            param.other_devices_mode = grab->pointerMode;
            param.modifiers = any_modifier;

            pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device,
                                  grab->modifierDevice, grab->window,
                                  grab->grabtype,
                                  (GrabMask *) &grab->eventMask,
                                  &param, (int) grab->type,
                                  pMinuendGrab->detail.exact,
                                  grab->confineTo, grab->cursor);
            if (!pNewGrab)
                ok = FALSE;
            else if (!(pNewGrab->modifiersDetail.pMask =
                       DeleteDetailFromMask(grab->modifiersDetail.pMask,
                                            pMinuendGrab->modifiersDetail.
                                            exact))
                     || (!pNewGrab->window->optional &&
                         !MakeWindowOptional(pNewGrab->window))) {
                FreeGrab(pNewGrab);
                ok = FALSE;
            }
            else if (!AddResource(pNewGrab->resource, RT_PASSIVEGRAB,
                                  (void *) pNewGrab))
                ok = FALSE;
            else
                adds[nadds++] = pNewGrab;
        }
        else if (pMinuendGrab->detail.exact == any_key) {
            UPDATE(grab->modifiersDetail.pMask,
                   pMinuendGrab->modifiersDetail.exact);
        }
        else {
            UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
        }
    }

    if (!ok) {
        for (i = 0; i < nadds; i++)
            FreeResource(adds[i]->resource, RT_NONE);
        for (i = 0; i < nups; i++)
            free(details[i]);
    }
    else {
        for (i = 0; i < ndels; i++)
            FreeResource(deletes[i]->resource, RT_NONE);
        for (i = 0; i < nadds; i++) {
            grab = adds[i];
            grab->next = grab->window->optional->passiveGrabs;
            grab->window->optional->passiveGrabs = grab;
        }
        for (i = 0; i < nups; i++) {
            free(*updates[i]);
            *updates[i] = details[i];
        }
    }
    free(details);
    free(updates);
    free(adds);
    free(deletes);
    return ok;

#undef UPDATE
}
Ejemplo n.º 14
0
/* All caches for a single format share a single pixmap for glyph storage,
 * allowing mixing glyphs of different sizes without paying a penalty
 * for switching between mask pixmaps. (Note that for a size of font
 * right at the border between two sizes, we might be switching for almost
 * every glyph.)
 *
 * This function allocates the storage pixmap, and then fills in the
 * rest of the allocated structures for all caches with the given format.
 */
static Bool
exaRealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
{
    ExaScreenPriv(pScreen);

    int depth = PIXMAN_FORMAT_DEPTH(format);
    PictFormatPtr pPictFormat;
    PixmapPtr pPixmap;
    PicturePtr pPicture;
    CARD32 component_alpha;
    int height;
    int i;
    int error;

    pPictFormat = PictureMatchFormat(pScreen, depth, format);
    if (!pPictFormat)
        return FALSE;

    /* Compute the total vertical size needed for the format */

    height = 0;
    for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
        ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
        int rows;

        if (cache->format != format)
            continue;

        cache->yOffset = height;

        rows = (cache->size + cache->columns - 1) / cache->columns;
        height += rows * cache->glyphHeight;
    }

    /* Now allocate the pixmap and picture */
    pPixmap = (*pScreen->CreatePixmap) (pScreen,
                                        CACHE_PICTURE_WIDTH, height, depth, 0);
    if (!pPixmap)
        return FALSE;

    component_alpha = NeedsComponent(pPictFormat->format);
    pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat,
                             CPComponentAlpha, &component_alpha, serverClient,
                             &error);

    (*pScreen->DestroyPixmap) (pPixmap);        /* picture holds a refcount */

    if (!pPicture)
        return FALSE;

    /* And store the picture in all the caches for the format */
    for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
        ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
        int j;

        if (cache->format != format)
            continue;

        cache->picture = pPicture;
        cache->picture->refcnt++;
        cache->hashEntries = xallocarray(cache->hashSize, sizeof(int));
        cache->glyphs = xallocarray(cache->size, sizeof(ExaCachedGlyphRec));
        cache->glyphCount = 0;

        if (!cache->hashEntries || !cache->glyphs)
            goto bail;

        for (j = 0; j < cache->hashSize; j++)
            cache->hashEntries[j] = -1;

        cache->evictionPosition = rand() % cache->size;
    }

    /* Each cache references the picture individually */
    FreePicture((void *) pPicture, (XID) 0);
    return TRUE;

 bail:
    exaUnrealizeGlyphCaches(pScreen, format);
    return FALSE;
}
Ejemplo n.º 15
0
/** Load the font, \a pFont, on the back-end server associated with \a
 *  pScreen.  When a font is loaded, the font path on back-end server is
 *  first initialized to that specified on the command line with the
 *  -fontpath options, and then the font is loaded. */
Bool
dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
    const char *name;
    char **oldFontPath = NULL;
    int nOldPaths;
    Atom name_atom, value_atom;
    int i;

    /* Make sure we have a font private struct to work with */
    if (!pFontPriv)
        return FALSE;

    /* Don't load a font over top of itself */
    if (pFontPriv->font[pScreen->myNum]) {
        return TRUE;            /* Already loaded font */
    }

    /* Save old font path */
    oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);

    /* Set the font path for the font about to be loaded on the back-end */
    if (dmxSetFontPath(dmxScreen)) {
        char **fp;
        int npaths;
        Bool *goodfps;

        /* This could fail only when first starting the X server and
         * loading the default font.  If it fails here, then the default
         * font path is invalid, no default font path will be set, the
         * DMX server will fail to load the default font, and it will
         * exit with an error unless we remove the offending font paths
         * with the -ignorebadfontpaths command line option.
         */

        fp = dmxGetFontPath(&npaths);
        if (!fp) {
            dmxLog(dmxError, "No default font path set.\n");
            dmxLog(dmxError,
                   "Please see the Xdmx man page for information on how to\n");
            dmxLog(dmxError,
                   "initialize the DMX server's default font path.\n");
            XFreeFontPath(oldFontPath);
            return FALSE;
        }

        if (!dmxFontPath)
            dmxLog(dmxWarning, "No default font path is set.\n");

        goodfps = xallocarray(npaths, sizeof(*goodfps));

        dmxLog(dmxError,
               "The DMX server failed to set the following font paths on "
               "screen #%d:\n", pScreen->myNum);

        for (i = 0; i < npaths; i++)
            if (!(goodfps[i] = dmxCheckFontPathElement(dmxScreen, fp[i])))
                dmxLog(dmxError, "    %s\n", fp[i]);

        if (dmxIgnoreBadFontPaths) {
            char *newfp;
            int newnpaths = 0;
            int len = 0;
            int j = 0;

            dmxLog(dmxError,
                   "These font paths will not be used because the "
                   "\"-ignorebadfontpaths\"\n");
            dmxLog(dmxError, "option is set.\n");

            for (i = 0; i < npaths; i++)
                if (goodfps[i]) {
                    len += strlen(fp[i]) + 1;
                    newnpaths++;
                }

            if (!newnpaths) {
                /* No valid font paths were found */
                dmxLog(dmxError,
                       "After removing the font paths above, no valid font "
                       "paths were\n");
                dmxLog(dmxError,
                       "available.  Please check that the font paths set on "
                       "the command\n");
                dmxLog(dmxError,
                       "line or in the configuration file via the "
                       "\"-fontpath\" option\n");
                dmxLog(dmxError,
                       "are valid on all back-end servers.  See the Xdmx man "
                       "page for\n");
                dmxLog(dmxError, "more information on font paths.\n");
                dmxFreeFontPath(fp);
                XFreeFontPath(oldFontPath);
                free(goodfps);
                return FALSE;
            }

            newfp = xallocarray(len, sizeof(*newfp));
            for (i = 0; i < npaths; i++) {
                if (goodfps[i]) {
                    int n = strlen(fp[i]);

                    newfp[j++] = n;
                    strncpy(&newfp[j], fp[i], n);
                    j += n;
                }
            }

            if (SetFontPath(serverClient, newnpaths, (unsigned char *) newfp)) {
                /* Note that this should never happen since all of the
                 * FPEs were previously valid. */
                dmxLog(dmxError, "Cannot reset the default font path.\n");
            }
        }
        else if (dmxFontPath) {
            dmxLog(dmxError,
                   "Please remove these font paths from the command line "
                   "or\n");
            dmxLog(dmxError,
                   "configuration file, or set the \"-ignorebadfontpaths\" "
                   "option to\n");
            dmxLog(dmxError,
                   "ignore them.  For more information on these options, see "
                   "the\n");
            dmxLog(dmxError, "Xdmx man page.\n");
        }
        else {
            dmxLog(dmxError,
                   "Please specify the font paths that are available on all "
                   "back-end\n");
            dmxLog(dmxError,
                   "servers with the \"-fontpath\" option, or use the "
                   "\"-ignorebadfontpaths\"\n");
            dmxLog(dmxError,
                   "to ignore bad defaults.  For more information on "
                   "these and other\n");
            dmxLog(dmxError,
                   "font-path-related options, see the Xdmx man page.\n");
        }

        free(goodfps);
        if (!dmxIgnoreBadFontPaths ||
            (dmxIgnoreBadFontPaths && dmxSetFontPath(dmxScreen))) {
            /* We still have errors so return with error */
            dmxFreeFontPath(fp);
            XFreeFontPath(oldFontPath);
            return FALSE;
        }
    }

    /* Find requested font on back-end server */
    name_atom = MakeAtom("FONT", 4, TRUE);
    value_atom = 0L;

    for (i = 0; i < pFont->info.nprops; i++) {
        if ((Atom) pFont->info.props[i].name == name_atom) {
            value_atom = pFont->info.props[i].value;
            break;
        }
    }
    if (!value_atom)
        return FALSE;

    name = NameForAtom(value_atom);
    if (!name)
        return FALSE;

    pFontPriv->font[pScreen->myNum] =
        XLoadQueryFont(dmxScreen->beDisplay, name);

    /* Restore old font path */
    XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
    XFreeFontPath(oldFontPath);
    dmxSync(dmxScreen, FALSE);

    if (!pFontPriv->font[pScreen->myNum])
        return FALSE;

    return TRUE;
}
Ejemplo n.º 16
0
void
miPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci,  /* array of character info */
               void *pglyphBase       /* start of array of glyphs */
    )
{
    int width, height;
    PixmapPtr pPixmap;
    int nbyLine;                /* bytes per line of padded pixmap */
    FontPtr pfont;
    GCPtr pGCtmp;
    int i;
    int j;
    unsigned char *pbits;       /* buffer for PutImage */
    unsigned char *pb;          /* temp pointer into buffer */
    CharInfoPtr pci;            /* currect char info */
    unsigned char *pglyph;      /* pointer bits in glyph */
    int gWidth, gHeight;        /* width and height of glyph */
    int nbyGlyphWidth;          /* bytes per scanline of glyph */
    int nbyPadGlyph;            /* server padded line of glyph */

    ChangeGCVal gcvals[3];

    if (pGC->miTranslate) {
        x += pDrawable->x;
        y += pDrawable->y;
    }

    pfont = pGC->font;
    width = FONTMAXBOUNDS(pfont, rightSideBearing) -
        FONTMINBOUNDS(pfont, leftSideBearing);
    height = FONTMAXBOUNDS(pfont, ascent) + FONTMAXBOUNDS(pfont, descent);

    pPixmap = (*pDrawable->pScreen->CreatePixmap) (pDrawable->pScreen,
                                                   width, height, 1,
                                                   CREATE_PIXMAP_USAGE_SCRATCH);
    if (!pPixmap)
        return;

    pGCtmp = GetScratchGC(1, pDrawable->pScreen);
    if (!pGCtmp) {
        (*pDrawable->pScreen->DestroyPixmap) (pPixmap);
        return;
    }

    gcvals[0].val = GXcopy;
    gcvals[1].val = 1;
    gcvals[2].val = 0;

    ChangeGC(NullClient, pGCtmp, GCFunction | GCForeground | GCBackground,
             gcvals);

    nbyLine = BitmapBytePad(width);
    pbits = xallocarray(height, nbyLine);
    if (!pbits) {
        (*pDrawable->pScreen->DestroyPixmap) (pPixmap);
        FreeScratchGC(pGCtmp);
        return;
    }
    while (nglyph--) {
        pci = *ppci++;
        pglyph = FONTGLYPHBITS(pglyphBase, pci);
        gWidth = GLYPHWIDTHPIXELS(pci);
        gHeight = GLYPHHEIGHTPIXELS(pci);
        if (gWidth && gHeight) {
            nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
            nbyPadGlyph = BitmapBytePad(gWidth);

            if (nbyGlyphWidth == nbyPadGlyph
#if GLYPHPADBYTES != 4
                && (((int) pglyph) & 3) == 0
#endif
                ) {
                pb = pglyph;
            }
            else {
                for (i = 0, pb = pbits; i < gHeight;
                     i++, pb = pbits + (i * nbyPadGlyph))
                    for (j = 0; j < nbyGlyphWidth; j++)
                        *pb++ = *pglyph++;
                pb = pbits;
            }

            if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber))
                ValidateGC((DrawablePtr) pPixmap, pGCtmp);
            (*pGCtmp->ops->PutImage) ((DrawablePtr) pPixmap, pGCtmp,
                                      pPixmap->drawable.depth,
                                      0, 0, gWidth, gHeight,
                                      0, XYBitmap, (char *) pb);

            (*pGC->ops->PushPixels) (pGC, pPixmap, pDrawable,
                                     gWidth, gHeight,
                                     x + pci->metrics.leftSideBearing,
                                     y - pci->metrics.ascent);
        }
        x += pci->metrics.characterWidth;
    }
    (*pDrawable->pScreen->DestroyPixmap) (pPixmap);
    free(pbits);
    FreeScratchGC(pGCtmp);
}
Ejemplo n.º 17
0
void
miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
{
    ScreenPtr pScreen = pWin->drawable.pScreen;
    ChangeGCVal gcval[6];
    BITS32 gcmask;
    GCPtr pGC;
    int i;
    BoxPtr pbox;
    xRectangle *prect;
    int numRects;

    /*
     * Distance from screen to destination drawable, use this
     * to adjust rendering coordinates which come in in screen space
     */
    int draw_x_off, draw_y_off;

    /*
     * Tile offset for drawing; these need to align the tile
     * to the appropriate window origin
     */
    int tile_x_off, tile_y_off;
    PixUnion fill;
    Bool solid = TRUE;
    DrawablePtr drawable = &pWin->drawable;

    if (what == PW_BACKGROUND) {
        while (pWin->backgroundState == ParentRelative)
            pWin = pWin->parent;

        draw_x_off = drawable->x;
        draw_y_off = drawable->y;

        tile_x_off = pWin->drawable.x - draw_x_off;
        tile_y_off = pWin->drawable.y - draw_y_off;
        fill = pWin->background;
#ifdef COMPOSITE
        if (pWin->inhibitBGPaint)
            return;
#endif
        switch (pWin->backgroundState) {
        case None:
            return;
        case BackgroundPixmap:
            solid = FALSE;
            break;
        }
    }
    else {
        PixmapPtr pixmap;

        fill = pWin->border;
        solid = pWin->borderIsPixel;

        /* servers without pixmaps draw their own borders */
        if (!pScreen->GetWindowPixmap)
            return;
        pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable);
        drawable = &pixmap->drawable;

        while (pWin->backgroundState == ParentRelative)
            pWin = pWin->parent;

        tile_x_off = pWin->drawable.x;
        tile_y_off = pWin->drawable.y;

#ifdef COMPOSITE
        draw_x_off = pixmap->screen_x;
        draw_y_off = pixmap->screen_y;
        tile_x_off -= draw_x_off;
        tile_y_off -= draw_y_off;
#else
        draw_x_off = 0;
        draw_y_off = 0;
#endif
    }

    gcval[0].val = GXcopy;
    gcmask = GCFunction;

#ifdef ROOTLESS_SAFEALPHA
/* Bit mask for alpha channel with a particular number of bits per
 * pixel. Note that we only care for 32bpp data. Mac OS X uses planar
 * alpha for 16bpp.
 */
#define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0)
#endif

    if (solid) {
#ifdef ROOTLESS_SAFEALPHA
        gcval[1].val =
            fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel);
#else
        gcval[1].val = fill.pixel;
#endif
        gcval[2].val = FillSolid;
        gcmask |= GCForeground | GCFillStyle;
    }
    else {
        int c = 1;

#ifdef ROOTLESS_SAFEALPHA
        gcval[c++].val =
            ((CARD32) -1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel);
        gcmask |= GCPlaneMask;
#endif
        gcval[c++].val = FillTiled;
        gcval[c++].ptr = (void *) fill.pixmap;
        gcval[c++].val = tile_x_off;
        gcval[c++].val = tile_y_off;
        gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
    }

    prect = xallocarray(RegionNumRects(prgn), sizeof(xRectangle));
    if (!prect)
        return;

    pGC = GetScratchGC(drawable->depth, drawable->pScreen);
    if (!pGC) {
        free(prect);
        return;
    }

    ChangeGC(NullClient, pGC, gcmask, gcval);
    ValidateGC(drawable, pGC);

    numRects = RegionNumRects(prgn);
    pbox = RegionRects(prgn);
    for (i = numRects; --i >= 0; pbox++, prect++) {
        prect->x = pbox->x1 - draw_x_off;
        prect->y = pbox->y1 - draw_y_off;
        prect->width = pbox->x2 - pbox->x1;
        prect->height = pbox->y2 - pbox->y1;
    }
    prect -= numRects;
    (*pGC->ops->PolyFillRect) (drawable, pGC, numRects, prect);
    free(prect);

    FreeScratchGC(pGC);
}
Ejemplo n.º 18
0
static Bool
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
                                    int h, int stride, void *bits, int pbo,
                                    PictFormatShort pict_format)
{
    ScreenPtr screen = pixmap->drawable.pScreen;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    GLenum format, type;
    int no_alpha, revert, swap_rb;
    glamor_pixmap_private *pixmap_priv;
    Bool force_clip;

    if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                               pict_format,
                                               &format,
                                               &type,
                                               &no_alpha,
                                               &revert, &swap_rb, 1)) {
        glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
        return FALSE;
    }
    if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
        return FALSE;

    pixmap_priv = glamor_get_pixmap_private(pixmap);
    force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
        && !glamor_check_fbo_size(glamor_priv, w, h);

    if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
        RegionRec region;
        BoxRec box;
        int n_region;
        glamor_pixmap_clipped_regions *clipped_regions;
        void *sub_bits;
        int i, j;

        sub_bits = xallocarray(h, stride);
        if (sub_bits == NULL)
            return FALSE;
        box.x1 = x;
        box.y1 = y;
        box.x2 = x + w;
        box.y2 = y + h;
        RegionInitBoxes(&region, &box, 1);
        if (!force_clip)
            clipped_regions =
                glamor_compute_clipped_regions(pixmap, &region, &n_region,
                                               0, 0, 0);
        else
            clipped_regions =
                glamor_compute_clipped_regions_ext(pixmap, &region,
                                                   &n_region,
                                                   pixmap_priv->block_w,
                                                   pixmap_priv->block_h,
                                                   0,
                                                   0);
        DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
        for (i = 0; i < n_region; i++) {
            BoxPtr boxes;
            int nbox;
            int temp_stride;
            void *temp_bits;

            assert(pbo == 0);

            glamor_set_pixmap_fbo_current(pixmap_priv, clipped_regions[i].block_idx);

            boxes = RegionRects(clipped_regions[i].region);
            nbox = RegionNumRects(clipped_regions[i].region);
            DEBUGF("split to %d boxes\n", nbox);
            for (j = 0; j < nbox; j++) {
                temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
                                            pixmap->drawable.depth);

                if (boxes[j].x1 == x && temp_stride == stride) {
                    temp_bits = (char *) bits + (boxes[j].y1 - y) * stride;
                }
                else {
                    temp_bits = sub_bits;
                    glamor_put_bits(temp_bits, temp_stride, bits, stride,
                                    pixmap->drawable.bitsPerPixel,
                                    boxes[j].x1 - x, boxes[j].y1 - y,
                                    boxes[j].x2 - boxes[j].x1,
                                    boxes[j].y2 - boxes[j].y1);
                }
                DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
                       boxes[j].x1 - x, boxes[j].y1 - y,
                       boxes[j].x2 - boxes[j].x1,
                       boxes[j].y2 - boxes[j].y1, temp_stride);
                if (_glamor_upload_bits_to_pixmap_texture
                    (pixmap, format, type, no_alpha, revert, swap_rb,
                     boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
                     boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits,
                     pbo) == FALSE) {
                    RegionUninit(&region);
                    free(sub_bits);
                    assert(0);
                    return FALSE;
                }
            }
            RegionDestroy(clipped_regions[i].region);
        }
        free(sub_bits);
        free(clipped_regions);
        RegionUninit(&region);
        return TRUE;
    }
    else
        return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
                                                     no_alpha, revert, swap_rb,
                                                     x, y, w, h, stride, bits,
                                                     pbo);
}
Ejemplo n.º 19
0
void
CreateWellKnownSockets(void)
{
    int i;
    int partial;

    FD_ZERO(&AllSockets);
    FD_ZERO(&AllClients);
    FD_ZERO(&LastSelectMask);
    FD_ZERO(&ClientsWithInput);

#if !defined(WIN32)
    for (i = 0; i < MaxClients; i++)
        ConnectionTranslation[i] = 0;
#else
    ClearConnectionTranslation();
#endif

    FD_ZERO(&WellKnownConnections);

    /* display is initialized to "0" by main(). It is then set to the display
     * number if specified on the command line. */

    if (NoListenAll) {
        ListenTransCount = 0;
    }
    else if ((displayfd < 0) || explicit_display) {
        if (TryCreateSocket(atoi(display), &partial) &&
            ListenTransCount >= 1)
            if (!PartialNetwork && partial)
                FatalError ("Failed to establish all listening sockets");
    }
    else { /* -displayfd and no explicit display number */
        Bool found = 0;
        for (i = 0; i < 65536 - X_TCP_PORT; i++) {
            if (TryCreateSocket(i, &partial) && ListenTransCount >= 1 && (PartialNetwork || !partial)) {
                found = 1;
                break;
            }
            else
                CloseWellKnownConnections();
        }
        if (!found)
            FatalError("Failed to find a socket to listen on");
        dynamic_display_id=i;
        snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
        display = dynamic_display;
    }

    ListenTransFds = xallocarray(ListenTransCount, sizeof (int));
    if (ListenTransFds == NULL)
        FatalError ("Failed to create listening socket array");

    for (i = ListenTransCount; i > 0; i--) {
        int fd = _XSERVTransGetConnectionNumber (ListenTransConns[i-1]);

        ListenTransFds[i-1] = fd;
        FD_SET(fd, &WellKnownConnections);

        if (!_XSERVTransIsLocal (ListenTransConns[i-1])) {
            int protocol = 0;
            if (!strcmp("inet", ListenTransConns[i-1]->transptr->TransName)) protocol = 4;
            else if (!strcmp("inet6", ListenTransConns[i-1]->transptr->TransName)) protocol = 6;
            DefineSelf (fd, protocol);
        }
    }

    if (!XFD_ANYSET(&WellKnownConnections) && !NoListenAll)
        FatalError
            ("Cannot establish any listening sockets - Make sure an X server isn't already running");

#if !defined(WIN32)
    OsSignal(SIGPIPE, SIG_IGN);
    OsSignal(SIGHUP, AutoResetServer);
#endif
    OsSignal(SIGINT, GiveUp);
    OsSignal(SIGTERM, GiveUp);
    XFD_COPYSET(&WellKnownConnections, &AllSockets);
    ResetHosts(display);

    InitParentProcess();

#ifdef XDMCP
    XdmcpInit();
#endif
}
Ejemplo n.º 20
0
void
miCopyRegion(DrawablePtr pSrcDrawable,
             DrawablePtr pDstDrawable,
             GCPtr pGC,
             RegionPtr pDstRegion,
             int dx, int dy, miCopyProc copyProc, Pixel bitPlane, void *closure)
{
    int careful;
    Bool reverse;
    Bool upsidedown;
    BoxPtr pbox;
    int nbox;
    BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;

    pbox = RegionRects(pDstRegion);
    nbox = RegionNumRects(pDstRegion);

    /* XXX we have to err on the side of safety when both are windows,
     * because we don't know if IncludeInferiors is being used.
     */
    careful = ((pSrcDrawable == pDstDrawable) ||
               ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
                (pDstDrawable->type == DRAWABLE_WINDOW)));

    pboxNew1 = NULL;
    pboxNew2 = NULL;
    if (careful && dy < 0) {
        upsidedown = TRUE;

        if (nbox > 1) {
            /* keep ordering in each band, reverse order of bands */
            pboxNew1 = xallocarray(nbox, sizeof(BoxRec));
            if (!pboxNew1)
                return;
            pboxBase = pboxNext = pbox + nbox - 1;
            while (pboxBase >= pbox) {
                while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
                    pboxNext--;
                pboxTmp = pboxNext + 1;
                while (pboxTmp <= pboxBase) {
                    *pboxNew1++ = *pboxTmp++;
                }
                pboxBase = pboxNext;
            }
            pboxNew1 -= nbox;
            pbox = pboxNew1;
        }
    }
    else {
        /* walk source top to bottom */
        upsidedown = FALSE;
    }

    if (careful && dx < 0) {
        /* walk source right to left */
        if (dy <= 0)
            reverse = TRUE;
        else
            reverse = FALSE;

        if (nbox > 1) {
            /* reverse order of rects in each band */
            pboxNew2 = xallocarray(nbox, sizeof(BoxRec));
            if (!pboxNew2) {
                free(pboxNew1);
                return;
            }
            pboxBase = pboxNext = pbox;
            while (pboxBase < pbox + nbox) {
                while ((pboxNext < pbox + nbox) &&
                       (pboxNext->y1 == pboxBase->y1))
                    pboxNext++;
                pboxTmp = pboxNext;
                while (pboxTmp != pboxBase) {
                    *pboxNew2++ = *--pboxTmp;
                }
                pboxBase = pboxNext;
            }
            pboxNew2 -= nbox;
            pbox = pboxNew2;
        }
    }
    else {
        /* walk source left to right */
        reverse = FALSE;
    }

    (*copyProc) (pSrcDrawable,
                 pDstDrawable,
                 pGC,
                 pbox, nbox, dx, dy, reverse, upsidedown, bitPlane, closure);

    free(pboxNew1);
    free(pboxNew2);
}
Ejemplo n.º 21
0
/** Change the picture's list of clip rectangles. */
int
dmxChangePictureClip(PicturePtr pPicture, int clipType, void *value, int n)
{
    ScreenPtr pScreen = pPicture->pDrawable->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);

    DMX_UNWRAP(ChangePictureClip, dmxScreen, ps);
#if 1
    if (ps->ChangePictureClip)
        ps->ChangePictureClip(pPicture, clipType, value, n);
#endif

    /* Change picture clip rects on back-end server */
    if (pPictPriv->pict) {
        /* The clip has already been changed into a region by the mi
         * routine called above.
         */
        if (clipType == CT_NONE) {
            /* Disable clipping, show all */
            XFixesSetPictureClipRegion(dmxScreen->beDisplay,
                                       pPictPriv->pict, 0, 0, None);
        }
        else if (pPicture->clientClip) {
            RegionPtr pClip = pPicture->clientClip;
            BoxPtr pBox = RegionRects(pClip);
            int nBox = RegionNumRects(pClip);
            XRectangle *pRects;
            XRectangle *pRect;
            int nRects;

            nRects = nBox;
            pRects = pRect = xallocarray(nRects, sizeof(*pRect));

            while (nBox--) {
                pRect->x = pBox->x1;
                pRect->y = pBox->y1;
                pRect->width = pBox->x2 - pBox->x1;
                pRect->height = pBox->y2 - pBox->y1;
                pBox++;
                pRect++;
            }

            XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
                                            pPictPriv->pict,
                                            0, 0, pRects, nRects);
            free(pRects);
        }
        else {
            XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
                                            pPictPriv->pict, 0, 0, NULL, 0);
        }
        dmxSync(dmxScreen, FALSE);
    }
    else {
        /* FIXME: Handle saving clip region when offscreen */
    }

    DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps);

    return Success;
}
Ejemplo n.º 22
0
int
xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
{
    XModifierKeymap *modifier_keymap;
    KeySym *keymap;
    int mapWidth;
    int min_keycode, max_keycode;
    KeySymsRec keySyms;
    CARD8 modmap[MAP_LENGTH];
    int i, j;
    XKeyboardState values;
    XkbDescPtr xkb;
    int op, event, error, major, minor;

    switch (onoff) {
    case DEVICE_INIT:
        XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
#ifdef _XSERVER64
        {
            KeySym64 *keymap64;
            int len;

            keymap64 = XGetKeyboardMapping(xnestDisplay,
                                           min_keycode,
                                           max_keycode - min_keycode + 1,
                                           &mapWidth);
            len = (max_keycode - min_keycode + 1) * mapWidth;
            keymap = xallocarray(len, sizeof(KeySym));
            for (i = 0; i < len; ++i)
                keymap[i] = keymap64[i];
            XFree(keymap64);
        }
#else
        keymap = XGetKeyboardMapping(xnestDisplay,
                                     min_keycode,
                                     max_keycode - min_keycode + 1, &mapWidth);
#endif

        memset(modmap, 0, sizeof(modmap));
        modifier_keymap = XGetModifierMapping(xnestDisplay);
        for (j = 0; j < 8; j++)
            for (i = 0; i < modifier_keymap->max_keypermod; i++) {
                CARD8 keycode;

                if ((keycode =
                     modifier_keymap->modifiermap[j *
                                                  modifier_keymap->
                                                  max_keypermod + i]))
                    modmap[keycode] |= 1 << j;
            }
        XFreeModifiermap(modifier_keymap);

        keySyms.minKeyCode = min_keycode;
        keySyms.maxKeyCode = max_keycode;
        keySyms.mapWidth = mapWidth;
        keySyms.map = keymap;

        if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor)
            == 0) {
            ErrorF("Unable to initialize XKEYBOARD extension.\n");
            goto XkbError;
        }
        xkb =
            XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask,
                           XkbUseCoreKbd);
        if (xkb == NULL || xkb->geom == NULL) {
            ErrorF("Couldn't get keyboard.\n");
            goto XkbError;
        }
        XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);

        InitKeyboardDeviceStruct(pDev, NULL,
                                 xnestBell, xnestChangeKeyboardControl);

        XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
                              keySyms.maxKeyCode - keySyms.minKeyCode + 1,
                              modmap, serverClient);

        XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
        XkbFreeKeyboard(xkb, 0, False);
        free(keymap);
        break;
    case DEVICE_ON:
        xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
        for (i = 0; i < xnestNumScreens; i++)
            XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
        break;
    case DEVICE_OFF:
        xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
        for (i = 0; i < xnestNumScreens; i++)
            XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
        break;
    case DEVICE_CLOSE:
        break;
    }
    return Success;

 XkbError:
    XGetKeyboardControl(xnestDisplay, &values);
    memmove((char *) defaultKeyboardControl.autoRepeats,
            (char *) values.auto_repeats, sizeof(values.auto_repeats));

    InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl);
    free(keymap);
    return Success;
}
Ejemplo n.º 23
0
static Bool
_glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                      GLenum type, int no_alpha, int revert,
                                      int swap_rb, int x, int y, int w, int h,
                                      int stride, void *bits, int pbo)
{
    ScreenPtr screen = pixmap->drawable.pScreen;
    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
    glamor_screen_private *glamor_priv =
        glamor_get_screen_private(pixmap->drawable.pScreen);
    static float vertices[8];

    static float texcoords_inv[8] = { 0, 0,
        1, 0,
        1, 1,
        0, 1
    };
    float *ptexcoords;
    float dst_xscale, dst_yscale;
    GLuint tex = 0;
    int need_free_bits = 0;

    if (bits == NULL)
        goto ready_to_upload;

    if (revert > REVERT_NORMAL) {
        /* XXX if we are restoring the pixmap, then we may not need to allocate
         * new buffer */
        void *converted_bits;

        if (pixmap->drawable.depth == 1)
            stride = (((w * 8 + 7) / 8) + 3) & ~3;

        converted_bits = xallocarray(h, stride);

        if (converted_bits == NULL)
            return FALSE;
        bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
                                            stride, no_alpha, revert, swap_rb);
        if (bits == NULL) {
            free(converted_bits);
            ErrorF("Failed to convert pixmap no_alpha %d,"
                   "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
            return FALSE;
        }
        no_alpha = 0;
        revert = REVERT_NONE;
        swap_rb = SWAP_NONE_UPLOADING;
        need_free_bits = TRUE;
    }

 ready_to_upload:

    /* Try fast path firstly, upload the pixmap to the texture attached
     * to the fbo directly. */
    if (no_alpha == 0
        && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING
#ifdef WALKAROUND_LARGE_TEXTURE_MAP
        && glamor_pixmap_priv_is_small(pixmap_priv)
#endif
        ) {
        int fbo_x_off, fbo_y_off;

        assert(pixmap_priv->fbo->tex);
        pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);

        assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
        assert(x + fbo_x_off + w <= pixmap_priv->fbo->width);
        assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
        __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
                                          format, type,
                                          x + fbo_x_off, y + fbo_y_off, w, h,
                                          bits, pbo);
    } else {
        ptexcoords = texcoords_inv;

        pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
        glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
                                     dst_yscale,
                                     x, y,
                                     x + w, y + h,
                                     vertices);
        /* Slow path, we need to flip y or wire alpha to 1. */
        glamor_make_current(glamor_priv);
        glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
                              GL_FALSE, 2 * sizeof(float), vertices);
        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
        glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
                              GL_FALSE, 2 * sizeof(float), ptexcoords);
        glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);

        glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
        glamor_set_alu(screen, GXcopy);
        __glamor_upload_pixmap_to_texture(pixmap, &tex,
                                          format, type, 0, 0, w, h, bits, pbo);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, tex);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
        glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
        glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);

        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

        glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
        glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
        glDeleteTextures(1, &tex);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

    if (need_free_bits)
        free(bits);
    return TRUE;
}
Ejemplo n.º 24
0
static void
CalcServerVersionAndExtensions(void)
{
    int s;
    char **be_extensions;
    char *ext;
    char *denied_extensions;

    /*
     * set the server glx version to be the minimum version
     * supported by all back-end servers
     */
    __glXVersionMajor = 0;
    __glXVersionMinor = 0;
    for (s = 0; s < __glXNumActiveScreens; s++) {
        DMXScreenInfo *dmxScreen = &dmxScreens[s];
        Display *dpy = dmxScreen->beDisplay;
        xGLXQueryVersionReq *req;
        xGLXQueryVersionReply reply;

        /* Send the glXQueryVersion request */
        LockDisplay(dpy);
        GetReq(GLXQueryVersion, req);
        req->reqType = dmxScreen->glxMajorOpcode;
        req->glxCode = X_GLXQueryVersion;
        req->majorVersion = GLX_SERVER_MAJOR_VERSION;
        req->minorVersion = GLX_SERVER_MINOR_VERSION;
        _XReply(dpy, (xReply *) &reply, 0, False);
        UnlockDisplay(dpy);
        SyncHandle();

        if (s == 0) {
            __glXVersionMajor = reply.majorVersion;
            __glXVersionMinor = reply.minorVersion;
        }
        else {
            if (reply.majorVersion < __glXVersionMajor) {
                __glXVersionMajor = reply.majorVersion;
                __glXVersionMinor = reply.minorVersion;
            }
            else if ((reply.majorVersion == __glXVersionMajor) &&
                     (reply.minorVersion < __glXVersionMinor)) {
                __glXVersionMinor = reply.minorVersion;
            }
        }

    }

    if (GLX_SERVER_MAJOR_VERSION < __glXVersionMajor) {
        __glXVersionMajor = GLX_SERVER_MAJOR_VERSION;
        __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
    }
    else if ((GLX_SERVER_MAJOR_VERSION == __glXVersionMajor) &&
             (GLX_SERVER_MINOR_VERSION < __glXVersionMinor)) {
        __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
    }

    snprintf(GLXServerVersion, sizeof(GLXServerVersion),
             "%d.%d DMX %d back-end server(s)",
             __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens);
    /*
     * set the ExtensionsString to the minimum extensions string
     */
    ExtensionsString[0] = '\0';

    /*
     * read extensions strings of all back-end servers
     */
    be_extensions = xallocarray(__glXNumActiveScreens, sizeof(char *));
    if (!be_extensions)
        return;

    for (s = 0; s < __glXNumActiveScreens; s++) {
        DMXScreenInfo *dmxScreen = &dmxScreens[s];
        Display *dpy = dmxScreen->beDisplay;
        xGLXQueryServerStringReq *req;
        xGLXQueryServerStringReply reply;
        int length, numbytes;

        /* Send the glXQueryServerString request */
        LockDisplay(dpy);
        GetReq(GLXQueryServerString, req);
        req->reqType = dmxScreen->glxMajorOpcode;
        req->glxCode = X_GLXQueryServerString;
        req->screen = DefaultScreen(dpy);
        req->name = GLX_EXTENSIONS;
        _XReply(dpy, (xReply *) &reply, 0, False);

        length = (int) reply.length;
        numbytes = (int) reply.n;
        be_extensions[s] = (char *) malloc(numbytes);
        if (!be_extensions[s]) {
            /* Throw data on the floor */
            _XEatDataWords(dpy, length);
        }
        else {
            _XReadPad(dpy, (char *) be_extensions[s], numbytes);
        }
        UnlockDisplay(dpy);
        SyncHandle();
    }

    /*
     * extensions string will include only extensions that our
     * server supports as well as all back-end servers supports.
     * extensions that are in the DMX_DENY_EXTENSIONS string will
     * not be supported.
     */
    denied_extensions = getenv("DMX_DENY_GLX_EXTENSIONS");
    ext = strtok(GLXServerExtensions, " ");
    while (ext) {
        int supported = 1;

        if (denied_extensions && strstr(denied_extensions, ext)) {
            supported = 0;
        }
        else {
            for (s = 0; s < __glXNumActiveScreens && supported; s++) {
                if (!strstr(be_extensions[s], ext)) {
                    supported = 0;
                }
            }
        }

        if (supported) {
            strcat(ExtensionsString, ext);
            strcat(ExtensionsString, " ");
        }

        ext = strtok(NULL, " ");
    }

    /*
     * release temporary storage
     */
    for (s = 0; s < __glXNumActiveScreens; s++) {
        free(be_extensions[s]);
    }
    free(be_extensions);

    if (dmxGLXSwapGroupSupport) {
        if (!denied_extensions ||
            !strstr(denied_extensions, "GLX_SGIX_swap_group")) {
            strcat(ExtensionsString, "GLX_SGIX_swap_group");
            if (!denied_extensions ||
                !strstr(denied_extensions, "GLX_SGIX_swap_barrier")) {
                strcat(ExtensionsString, " GLX_SGIX_swap_barrier");
            }
        }
    }

}
Ejemplo n.º 25
0
int
ProcXGetDeviceDontPropagateList(ClientPtr client)
{
    CARD16 count = 0;
    int i, rc;
    XEventClass *buf = NULL, *tbuf;
    WindowPtr pWin;
    xGetDeviceDontPropagateListReply rep;
    OtherInputMasks *others;

    REQUEST(xGetDeviceDontPropagateListReq);
    REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq);

    rep = (xGetDeviceDontPropagateListReply) {
        .repType = X_Reply,
        .RepType = X_GetDeviceDontPropagateList,
        .sequenceNumber = client->sequence,
        .length = 0,
        .count = 0
    };

    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;

    if ((others = wOtherInputMasks(pWin)) != 0) {
        for (i = 0; i < EMASKSIZE; i++)
            ClassFromMask(NULL, others->dontPropagateMask[i], i, &count, COUNT);
        if (count) {
            rep.count = count;
            buf = xallocarray(rep.count, sizeof(XEventClass));
            rep.length = bytes_to_int32(rep.count * sizeof(XEventClass));

            tbuf = buf;
            for (i = 0; i < EMASKSIZE; i++)
                tbuf = ClassFromMask(tbuf, others->dontPropagateMask[i], i,
                                     NULL, CREATE);
        }
    }

    WriteReplyToClient(client, sizeof(xGetDeviceDontPropagateListReply), &rep);

    if (count) {
        client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
        WriteSwappedDataToClient(client, count * sizeof(XEventClass), buf);
        free(buf);
    }
    return Success;
}

/***********************************************************************
 *
 * This procedure gets a list of event classes from a mask word.
 * A single mask may translate to more than one event class.
 *
 */

XEventClass
    * ClassFromMask(XEventClass * buf, Mask mask, int maskndx, CARD16 *count,
                    int mode)
{
    int i, j;
    int id = maskndx;
    Mask tmask = 0x80000000;

    for (i = 0; i < 32; i++, tmask >>= 1)
        if (tmask & mask) {
            for (j = 0; j < ExtEventIndex; j++)
                if (EventInfo[j].mask == tmask) {
                    if (mode == COUNT)
                        (*count)++;
                    else
                        *buf++ = (id << 8) | EventInfo[j].type;
                }
        }
    return buf;
}
Ejemplo n.º 26
0
/** Composite glyphs on each screen into the requested picture.  If
 *  either the src or dest picture has not been allocated due to lazy
 *  window creation, this request will gracefully return. */
static int
dmxProcRenderCompositeGlyphs(ClientPtr client)
{
    int ret;

    REQUEST(xRenderCompositeGlyphsReq);

    ret = dmxSaveRenderVector[stuff->renderReqType] (client);

    /* For the following to work with PanoramiX, it assumes that Render
     * wraps the ProcRenderVector after dmxRenderInit has been called.
     */
    if (ret == Success) {
        PicturePtr pSrc;
        dmxPictPrivPtr pSrcPriv;
        PicturePtr pDst;
        dmxPictPrivPtr pDstPriv;
        PictFormatPtr pFmt;
        XRenderPictFormat *pFormat;
        int size;

        int scrnNum;
        DMXScreenInfo *dmxScreen;

        CARD8 *buffer;
        CARD8 *end;
        int space;

        int nglyph;
        char *glyphs;
        char *curGlyph;

        xGlyphElt *elt;
        int nelt;
        XGlyphElt8 *elts;
        XGlyphElt8 *curElt;

        GlyphSetPtr glyphSet;
        dmxGlyphPrivPtr glyphPriv;

        dixLookupResourceByType((void **) &pSrc,
                                stuff->src, PictureType, client, DixReadAccess);

        pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
        if (!pSrcPriv->pict)
            return ret;

        dixLookupResourceByType((void **) &pDst,
                                stuff->dst, PictureType,
                                client, DixWriteAccess);

        pDstPriv = DMX_GET_PICT_PRIV(pDst);
        if (!pDstPriv->pict)
            return ret;

        scrnNum = pDst->pDrawable->pScreen->myNum;
        dmxScreen = &dmxScreens[scrnNum];

        /* Note: If the back-end display has been detached, then it
         * should not be possible to reach here since the pSrcPriv->pict
         * and pDstPriv->pict will have already been set to 0.
         */
        if (!dmxScreen->beDisplay)
            return ret;

        if (stuff->maskFormat)
            dixLookupResourceByType((void **) &pFmt,
                                    stuff->maskFormat, PictFormatType,
                                    client, DixReadAccess);
        else
            pFmt = NULL;

        pFormat = dmxFindFormat(dmxScreen, pFmt);

        switch (stuff->renderReqType) {
        case X_RenderCompositeGlyphs8:
            size = sizeof(CARD8);
            break;
        case X_RenderCompositeGlyphs16:
            size = sizeof(CARD16);
            break;
        case X_RenderCompositeGlyphs32:
            size = sizeof(CARD32);
            break;
        default:
            return BadPictOp;   /* Can't happen */
        }

        buffer = (CARD8 *) (stuff + 1);
        end = (CARD8 *) stuff + (stuff->length << 2);
        nelt = 0;
        nglyph = 0;
        while (buffer + sizeof(xGlyphElt) < end) {
            elt = (xGlyphElt *) buffer;
            buffer += sizeof(xGlyphElt);

            if (elt->len == 0xff) {
                buffer += 4;
            }
            else {
                nelt++;
                nglyph += elt->len;
                space = size * elt->len;
                if (space & 3)
                    space += 4 - (space & 3);
                buffer += space;
            }
        }

        /* The following only works for Render version > 0.2 */

        /* All of the XGlyphElt* structure sizes are identical */
        elts = xallocarray(nelt, sizeof(XGlyphElt8));
        if (!elts)
            return BadAlloc;

        glyphs = xallocarray(nglyph, size);
        if (!glyphs) {
            free(elts);
            return BadAlloc;
        }

        buffer = (CARD8 *) (stuff + 1);
        end = (CARD8 *) stuff + (stuff->length << 2);
        curGlyph = glyphs;
        curElt = elts;

        dixLookupResourceByType((void **) &glyphSet,
                                stuff->glyphset, GlyphSetType,
                                client, DixReadAccess);
        glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);

        while (buffer + sizeof(xGlyphElt) < end) {
            elt = (xGlyphElt *) buffer;
            buffer += sizeof(xGlyphElt);

            if (elt->len == 0xff) {
                dixLookupResourceByType((void **) &glyphSet,
                                        *((CARD32 *) buffer),
                                        GlyphSetType, client, DixReadAccess);
                glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
                buffer += 4;
            }
            else {
                curElt->glyphset = glyphPriv->glyphSets[scrnNum];
                curElt->xOff = elt->deltax;
                curElt->yOff = elt->deltay;
                curElt->nchars = elt->len;
                curElt->chars = curGlyph;

                memcpy(curGlyph, buffer, size * elt->len);
                curGlyph += size * elt->len;

                curElt++;

                space = size * elt->len;
                if (space & 3)
                    space += 4 - (space & 3);
                buffer += space;
            }
        }

        switch (stuff->renderReqType) {
        case X_RenderCompositeGlyphs8:
            XRenderCompositeText8(dmxScreen->beDisplay, stuff->op,
                                  pSrcPriv->pict, pDstPriv->pict,
                                  pFormat,
                                  stuff->xSrc, stuff->ySrc, 0, 0, elts, nelt);
            break;
        case X_RenderCompositeGlyphs16:
            XRenderCompositeText16(dmxScreen->beDisplay, stuff->op,
                                   pSrcPriv->pict, pDstPriv->pict,
                                   pFormat,
                                   stuff->xSrc, stuff->ySrc,
                                   0, 0, (XGlyphElt16 *) elts, nelt);
            break;
        case X_RenderCompositeGlyphs32:
            XRenderCompositeText32(dmxScreen->beDisplay, stuff->op,
                                   pSrcPriv->pict, pDstPriv->pict,
                                   pFormat,
                                   stuff->xSrc, stuff->ySrc,
                                   0, 0, (XGlyphElt32 *) elts, nelt);
            break;
        }

        dmxSync(dmxScreen, FALSE);

        free(elts);
        free(glyphs);
    }

    return ret;
}
Ejemplo n.º 27
0
void
fbGlyphs(CARD8 op,
	 PicturePtr pSrc,
	 PicturePtr pDst,
	 PictFormatPtr maskFormat,
	 INT16 xSrc,
	 INT16 ySrc, int nlist,
	 GlyphListPtr list,
	 GlyphPtr *glyphs)
{
#define N_STACK_GLYPHS 512
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    pixman_glyph_t stack_glyphs[N_STACK_GLYPHS];
    pixman_glyph_t *pglyphs = stack_glyphs;
    pixman_image_t *srcImage, *dstImage;
    int srcXoff, srcYoff, dstXoff, dstYoff;
    GlyphPtr glyph;
    int n_glyphs;
    int x, y;
    int i, n;
    int xDst = list->xOff, yDst = list->yOff;

    miCompositeSourceValidate(pSrc);

    n_glyphs = 0;
    for (i = 0; i < nlist; ++i)
	n_glyphs += list[i].len;

    if (!glyphCache)
	glyphCache = pixman_glyph_cache_create();

    pixman_glyph_cache_freeze (glyphCache);

    if (n_glyphs > N_STACK_GLYPHS) {
	if (!(pglyphs = xallocarray(n_glyphs, sizeof(pixman_glyph_t))))
	    goto out;
    }

    i = 0;
    x = y = 0;
    while (nlist--) {
        x += list->xOff;
        y += list->yOff;
        n = list->len;
        while (n--) {
	    const void *g;

            glyph = *glyphs++;

	    if (!(g = pixman_glyph_cache_lookup (glyphCache, glyph, NULL))) {
		pixman_image_t *glyphImage;
		PicturePtr pPicture;
		int xoff, yoff;

		pPicture = GetGlyphPicture(glyph, pScreen);
		if (!pPicture) {
		    n_glyphs--;
		    goto next;
		}

		if (!(glyphImage = image_from_pict(pPicture, FALSE, &xoff, &yoff)))
		    goto out;

		g = pixman_glyph_cache_insert(glyphCache, glyph, NULL,
					      glyph->info.x,
					      glyph->info.y,
					      glyphImage);

		free_pixman_pict(pPicture, glyphImage);

		if (!g)
		    goto out;
	    }

	    pglyphs[i].x = x;
	    pglyphs[i].y = y;
	    pglyphs[i].glyph = g;
	    i++;

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

    if (!(srcImage = image_from_pict(pSrc, FALSE, &srcXoff, &srcYoff)))
	goto out;

    if (!(dstImage = image_from_pict(pDst, TRUE, &dstXoff, &dstYoff)))
	goto out_free_src;

    if (maskFormat) {
	pixman_format_code_t format;
	pixman_box32_t extents;

	format = maskFormat->format | (maskFormat->depth << 24);

	pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);

	pixman_composite_glyphs(op, srcImage, dstImage, format,
				xSrc + srcXoff + extents.x1 - xDst, ySrc + srcYoff + extents.y1 - yDst,
				extents.x1, extents.y1,
				extents.x1 + dstXoff, extents.y1 + dstYoff,
				extents.x2 - extents.x1,
				extents.y2 - extents.y1,
				glyphCache, n_glyphs, pglyphs);
    }
    else {
	pixman_composite_glyphs_no_mask(op, srcImage, dstImage,
					xSrc + srcXoff - xDst, ySrc + srcYoff - yDst,
					dstXoff, dstYoff,
					glyphCache, n_glyphs, pglyphs);
    }

    free_pixman_pict(pDst, dstImage);

out_free_src:
    free_pixman_pict(pSrc, srcImage);

out:
    pixman_glyph_cache_thaw(glyphCache);
    if (pglyphs != stack_glyphs)
	free(pglyphs);
}