void miImageGlyphBlt( DrawablePtr pDrawable, GC *pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, /* array of character info */ pointer pglyphBase /* start of array of glyphs */ ) { ExtentInfoRec info; /* used by QueryGlyphExtents() */ ChangeGCVal gcvals[3]; int oldAlu, oldFS; unsigned long oldFG; xRectangle backrect; QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info); if (info.overallWidth >= 0) { backrect.x = x; backrect.width = info.overallWidth; } else { backrect.x = x + info.overallWidth; backrect.width = -info.overallWidth; } backrect.y = y - FONTASCENT(pGC->font); backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); oldAlu = pGC->alu; oldFG = pGC->fgPixel; oldFS = pGC->fillStyle; /* fill in the background */ gcvals[0].val = GXcopy; gcvals[1].val = pGC->bgPixel; gcvals[2].val = FillSolid; ChangeGC(NullClient, pGC, GCFunction|GCForeground|GCFillStyle, gcvals); ValidateGC(pDrawable, pGC); (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &backrect); /* put down the glyphs */ gcvals[0].val = oldFG; ChangeGC(NullClient, pGC, GCForeground, gcvals); ValidateGC(pDrawable, pGC); (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); /* put all the toys away when done playing */ gcvals[0].val = oldAlu; gcvals[1].val = oldFG; gcvals[2].val = oldFS; ChangeGC(NullClient, pGC, GCFunction|GCForeground|GCFillStyle, gcvals); ValidateGC(pDrawable, pGC); }
static void miDCPutBits ( DrawablePtr pDrawable, miDCCursorPtr pPriv, GCPtr sourceGC, GCPtr maskGC, int x_org, int y_org, unsigned w, unsigned h, unsigned long source, unsigned long mask) { ChangeGCVal gcval; int x, y; if (sourceGC->fgPixel != source) { gcval.val = source; ChangeGC (NullClient, sourceGC, GCForeground, &gcval); } if (sourceGC->serialNumber != pDrawable->serialNumber) ValidateGC (pDrawable, sourceGC); if(sourceGC->miTranslate) { x = pDrawable->x + x_org; y = pDrawable->y + y_org; } else { x = x_org; y = y_org; } (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y); if (maskGC->fgPixel != mask) { gcval.val = mask; ChangeGC (NullClient, maskGC, GCForeground, &gcval); } if (maskGC->serialNumber != pDrawable->serialNumber) ValidateGC (pDrawable, maskGC); if(maskGC->miTranslate) { x = pDrawable->x + x_org; y = pDrawable->y + y_org; } else { x = x_org; y = y_org; } (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y); }
/** * Sets up a scratch GC for fbFill, and saves other parameters for the * ephyrSolid implementation. */ static Bool ephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) { ScreenPtr pScreen = pPix->drawable.pScreen; KdScreenPriv(pScreen); KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; EphyrFakexaPriv *fakexa = scrpriv->fakexa; CARD32 tmpval[3]; ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST); fakexa->pDst = pPix; fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen); tmpval[0] = alu; tmpval[1] = pm; tmpval[2] = fg; ChangeGC(fakexa->pGC, GCFunction | GCPlaneMask | GCForeground, tmpval); ValidateGC(&pPix->drawable, fakexa->pGC); TRACE_DRAW(); return TRUE; }
static void miColorRects (PicturePtr pDst, PicturePtr pClipPict, xRenderColor *color, int nRect, xRectangle *rects, int xoff, int yoff) { ScreenPtr pScreen = pDst->pDrawable->pScreen; CARD32 pixel; GCPtr pGC; CARD32 tmpval[5]; RegionPtr pClip; unsigned long mask; miRenderColorToPixel (pDst->pFormat, color, &pixel); pGC = GetScratchGC (pDst->pDrawable->depth, pScreen); if (!pGC) return; tmpval[0] = GXcopy; tmpval[1] = pixel; tmpval[2] = pDst->subWindowMode; mask = GCFunction | GCForeground | GCSubwindowMode; if (pClipPict->clientClipType == CT_REGION) { tmpval[3] = pDst->clipOrigin.x - xoff; tmpval[4] = pDst->clipOrigin.y - yoff; mask |= GCClipXOrigin|GCClipYOrigin; pClip = REGION_CREATE (pScreen, NULL, 1); REGION_COPY (pScreen, pClip, (RegionPtr) pClipPict->clientClip); (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0); } ChangeGC (pGC, mask, tmpval); ValidateGC (pDst->pDrawable, pGC); if (xoff || yoff) { int i; for (i = 0; i < nRect; i++) { rects[i].x -= xoff; rects[i].y -= yoff; } } (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects); if (xoff || yoff) { int i; for (i = 0; i < nRect; i++) { rects[i].x += xoff; rects[i].y += yoff; } } FreeScratchGC (pGC); }
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); }
int ChangeGCXIDs(ClientPtr client, GC * pGC, BITS32 mask, CARD32 *pC32) { ChangeGCVal vals[GCLastBit + 1]; int i; if (mask & ~GCAllBits) { client->errorValue = mask; return BadValue; } for (i = Ones(mask); i--;) vals[i].val = pC32[i]; for (i = 0; i < ARRAY_SIZE(xidfields); ++i) { int offset, rc; if (!(mask & xidfields[i].mask)) continue; offset = Ones(mask & (xidfields[i].mask - 1)); if (xidfields[i].mask == GCClipMask && vals[offset].val == None) { vals[offset].ptr = NullPixmap; continue; } rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val, xidfields[i].type, client, xidfields[i].access_mode); if (rc != Success) { client->errorValue = vals[offset].val; return rc; } } return ChangeGC(client, pGC, mask, vals); }
int ProcXFixesSetGCClipRegion(ClientPtr client) { GCPtr pGC; RegionPtr pRegion; ChangeGCVal vals[2]; int rc; REQUEST(xXFixesSetGCClipRegionReq); REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); rc = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); if (rc != Success) return rc; VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); if (pRegion) { pRegion = XFixesRegionCopy(pRegion); if (!pRegion) return BadAlloc; } vals[0].val = stuff->xOrigin; vals[1].val = stuff->yOrigin; ChangeGC(NullClient, pGC, GCClipXOrigin | GCClipYOrigin, vals); (*pGC->funcs->ChangeClip) (pGC, pRegion ? CT_REGION : CT_NONE, (void *) pRegion, 0); return Success; }
/** * Sets up a scratch GC for fbCopyArea, and saves other parameters for the * ephyrCopy implementation. */ static Bool ephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm) { ScreenPtr pScreen = pDst->drawable.pScreen; KdScreenPriv(pScreen); KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; EphyrFakexaPriv *fakexa = scrpriv->fakexa; CARD32 tmpval[2]; ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); fakexa->pSrc = pSrc; fakexa->pDst = pDst; fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen); tmpval[0] = alu; tmpval[1] = pm; ChangeGC (fakexa->pGC, GCFunction | GCPlaneMask, tmpval); ValidateGC(&pDst->drawable, fakexa->pGC); TRACE_DRAW(); return TRUE; }
void compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap) { ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pParent = pWin->parent; if (pParent->drawable.depth == pWin->drawable.depth) { GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen); int bw = (int) pWin->borderWidth; int x = bw; int y = bw; int w = pWin->drawable.width; int h = pWin->drawable.height; if (pGC) { ChangeGCVal val; val.val = IncludeInferiors; ChangeGC(NullClient, pGC, GCSubwindowMode, &val); ValidateGC(&pWin->drawable, pGC); (*pGC->ops->CopyArea) (&pPixmap->drawable, &pWin->drawable, pGC, x, y, w, h, 0, 0); FreeScratchGC(pGC); } } }
static PixmapPtr glamor_get_stipple_pixmap(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); ScreenPtr screen = gc->pScreen; PixmapPtr bitmap; PixmapPtr pixmap; GCPtr scratch_gc; ChangeGCVal changes[2]; if (gc_priv->stipple) return gc_priv->stipple; bitmap = gc->stipple; if (!bitmap) goto bail; pixmap = glamor_create_pixmap(screen, bitmap->drawable.width, bitmap->drawable.height, 8, GLAMOR_CREATE_NO_LARGE); if (!pixmap) goto bail; scratch_gc = GetScratchGC(8, screen); if (!scratch_gc) goto bail_pixmap; changes[0].val = 0xff; changes[1].val = 0x00; if (ChangeGC(NullClient, scratch_gc, GCForeground|GCBackground, changes) != Success) goto bail_gc; ValidateGC(&pixmap->drawable, scratch_gc); (*scratch_gc->ops->CopyPlane)(&bitmap->drawable, &pixmap->drawable, scratch_gc, 0, 0, bitmap->drawable.width, bitmap->drawable.height, 0, 0, 0x1); FreeScratchGC(scratch_gc); gc_priv->stipple = pixmap; glamor_track_stipple(gc); return pixmap; bail_gc: FreeScratchGC(scratch_gc); bail_pixmap: glamor_destroy_pixmap(pixmap); bail: return NULL; }
/* MICLEARDRAWABLE -- sets the entire drawable to the background color of * the GC. Useful when we have a scratch drawable and need to initialize * it. */ void miClearDrawable(DrawablePtr pDraw, GCPtr pGC) { ChangeGCVal fg, bg; xRectangle rect; fg.val = pGC->fgPixel; bg.val = pGC->bgPixel; rect.x = 0; rect.y = 0; rect.width = pDraw->width; rect.height = pDraw->height; ChangeGC(NullClient, pGC, GCForeground, &bg); ValidateGC(pDraw, pGC); (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); ChangeGC(NullClient, pGC, GCForeground, &fg); ValidateGC(pDraw, pGC); }
static PixmapPtr glamor_get_dash_pixmap(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); ScreenPtr screen = gc->pScreen; PixmapPtr pixmap; int offset; int d; uint32_t pixel; GCPtr scratch_gc; if (gc_priv->dash) return gc_priv->dash; offset = 0; for (d = 0; d < gc->numInDashList; d++) offset += gc->dash[d]; pixmap = glamor_create_pixmap(screen, offset, 1, 8, 0); if (!pixmap) goto bail; scratch_gc = GetScratchGC(8, screen); if (!scratch_gc) goto bail_pixmap; pixel = 0xffffffff; offset = 0; for (d = 0; d < gc->numInDashList; d++) { xRectangle rect; ChangeGCVal changes; changes.val = pixel; (void) ChangeGC(NullClient, scratch_gc, GCForeground, &changes); ValidateGC(&pixmap->drawable, scratch_gc); rect.x = offset; rect.y = 0; rect.width = gc->dash[d]; rect.height = 1; scratch_gc->ops->PolyFillRect (&pixmap->drawable, scratch_gc, 1, &rect); offset += gc->dash[d]; pixel = ~pixel; } FreeScratchGC(scratch_gc); gc_priv->dash = pixmap; return pixmap; bail_pixmap: glamor_destroy_pixmap(pixmap); bail: return NULL; }
static void fbSetFg(DrawablePtr pDrawable, GCPtr pGC, Pixel fg) { if (fg != pGC->fgPixel) { ChangeGCVal val; val.val = fg; ChangeGC(NullClient, pGC, GCForeground, &val); ValidateGC(pDrawable, pGC); } }
static Bool CreateDefaultTile (GCPtr pGC) { XID tmpval[3]; PixmapPtr pTile; GCPtr pgcScratch; xRectangle rect; CARD16 w, h; w = 1; h = 1; (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen); pTile = (PixmapPtr) (*pGC->pScreen->CreatePixmap)(pGC->pScreen, w, h, pGC->depth); pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen); if (!pTile || !pgcScratch) { if (pTile) (*pTile->drawable.pScreen->DestroyPixmap)(pTile); if (pgcScratch) FreeScratchGC(pgcScratch); return FALSE; } tmpval[0] = GXcopy; tmpval[1] = pGC->tile.pixel; tmpval[2] = FillSolid; (void)ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval); ValidateGC((DrawablePtr)pTile, pgcScratch); rect.x = 0; rect.y = 0; rect.width = w; rect.height = h; (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect); /* Always remember to free the scratch graphics context after use. */ FreeScratchGC(pgcScratch); pGC->tileIsPixel = FALSE; pGC->tile.pixmap = pTile; return TRUE; }
static void xf86_dga_fill_rect(ScrnInfoPtr scrn, int x, int y, int w, int h, unsigned long color) { GCPtr pGC; DrawablePtr pDrawable; XID vals[1]; xRectangle r; if (!xf86_dga_get_drawable_and_gc (scrn, &pDrawable, &pGC)) return; vals[0] = color; ChangeGC (pGC, GCForeground, vals); ValidateGC (pDrawable, pGC); r.x = x; r.y = y; r.width = w; r.height = h; pGC->ops->PolyFillRect (pDrawable, pGC, 1, &r); xf86_dga_release_drawable_and_gc (scrn, pDrawable, pGC); }
void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, unsigned long fg_pixel) { DrawablePtr drawable = &pixmap->drawable; GCPtr gc; ChangeGCVal vals[1]; xRectangle rect; vals[0].val = fg_pixel; gc = GetScratchGC(drawable->depth, drawable->pScreen); if (!gc) return; ChangeGC(NullClient, gc, GCForeground, vals); ValidateGC(drawable, gc); rect.x = x; rect.y = y; rect.width = width; rect.height = height; gc->ops->PolyFillRect(drawable, gc, 1, &rect); FreeScratchGC(gc); }
Bool CreateDefaultStipple(int screenNum) { ScreenPtr pScreen; ChangeGCVal tmpval[3]; xRectangle rect; CARD16 w, h; GCPtr pgcScratch; pScreen = screenInfo.screens[screenNum]; w = 16; h = 16; (*pScreen->QueryBestSize) (StippleShape, &w, &h, pScreen); if (!(pScreen->defaultStipple = pScreen->CreatePixmap(pScreen, w, h, 1, 0))) return FALSE; /* fill stipple with 1 */ tmpval[0].val = GXcopy; tmpval[1].val = 1; tmpval[2].val = FillSolid; pgcScratch = GetScratchGC(1, pScreen); if (!pgcScratch) { (*pScreen->DestroyPixmap) (pScreen->defaultStipple); return FALSE; } (void) ChangeGC(NullClient, pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval); ValidateGC((DrawablePtr) pScreen->defaultStipple, pgcScratch); rect.x = 0; rect.y = 0; rect.width = w; rect.height = h; (*pgcScratch->ops->PolyFillRect) ((DrawablePtr) pScreen->defaultStipple, pgcScratch, 1, &rect); FreeScratchGC(pgcScratch); return TRUE; }
void miPolyPoint( DrawablePtr pDrawable, GCPtr pGC, int mode, /* Origin or Previous */ int npt, xPoint *pptInit ) { int xorg; int yorg; int nptTmp; ChangeGCVal fsOld, fsNew; int *pwidthInit, *pwidth; int i; xPoint *ppt; if(!(pwidthInit = malloc(npt * sizeof(int)))) return; /* make pointlist origin relative */ if (mode == CoordModePrevious) { ppt = pptInit; nptTmp = npt; nptTmp--; while(nptTmp--) { ppt++; ppt->x += (ppt-1)->x; ppt->y += (ppt-1)->y; } } if(pGC->miTranslate) { ppt = pptInit; nptTmp = npt; xorg = pDrawable->x; yorg = pDrawable->y; while(nptTmp--) { ppt->x += xorg; ppt++->y += yorg; } } fsOld.val = pGC->fillStyle; fsNew.val = FillSolid; if(pGC->fillStyle != FillSolid) { ChangeGC(NullClient, pGC, GCFillStyle, &fsNew); ValidateGC(pDrawable, pGC); } pwidth = pwidthInit; for(i = 0; i < npt; i++) *pwidth++ = 1; (*pGC->ops->FillSpans)(pDrawable, pGC, npt, pptInit, pwidthInit, FALSE); if(fsOld.val != FillSolid) { ChangeGC(NullClient, pGC, GCFillStyle, &fsOld); ValidateGC(pDrawable, pGC); } free(pwidthInit); }
void miPolyGlyphBlt( DrawablePtr pDrawable, GC *pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, /* array of character info */ pointer 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 = malloc(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); }
_X_EXPORT GCPtr CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus) { register GCPtr pGC; pGC = AllocateGC(pDrawable->pScreen); if (!pGC) { *pStatus = BadAlloc; return (GCPtr)NULL; } pGC->pScreen = pDrawable->pScreen; pGC->depth = pDrawable->depth; pGC->alu = GXcopy; /* dst <- src */ pGC->planemask = ~0; pGC->serialNumber = GC_CHANGE_SERIAL_BIT; pGC->funcs = 0; pGC->fgPixel = 0; pGC->bgPixel = 1; pGC->lineWidth = 0; pGC->lineStyle = LineSolid; pGC->capStyle = CapButt; pGC->joinStyle = JoinMiter; pGC->fillStyle = FillSolid; pGC->fillRule = EvenOddRule; pGC->arcMode = ArcPieSlice; if (mask & GCForeground) { /* * magic special case -- ChangeGC checks for this condition * and snags the Foreground value to create a pseudo default-tile */ pGC->tileIsPixel = FALSE; pGC->tile.pixmap = NullPixmap; } else { pGC->tileIsPixel = TRUE; pGC->tile.pixel = 0; } pGC->patOrg.x = 0; pGC->patOrg.y = 0; pGC->subWindowMode = ClipByChildren; pGC->graphicsExposures = TRUE; pGC->clipOrg.x = 0; pGC->clipOrg.y = 0; pGC->clientClipType = CT_NONE; pGC->clientClip = (pointer)NULL; pGC->numInDashList = 2; pGC->dash = DefaultDash; pGC->dashOffset = 0; pGC->lastWinOrg.x = 0; pGC->lastWinOrg.y = 0; /* use the default font and stipple */ pGC->font = defaultFont; defaultFont->refcnt++; pGC->stipple = pGC->pScreen->PixmapPerDepth[0]; pGC->stipple->refcnt++; pGC->stateChanges = (1 << (GCLastBit+1)) - 1; if (!(*pGC->pScreen->CreateGC)(pGC)) *pStatus = BadAlloc; else if (mask) *pStatus = ChangeGC(pGC, mask, pval); else *pStatus = Success; if (*pStatus != Success) { if (!pGC->tileIsPixel && !pGC->tile.pixmap) pGC->tileIsPixel = TRUE; /* undo special case */ FreeGC(pGC, (XID)0); pGC = (GCPtr)NULL; } return (pGC); }
_X_EXPORT void miCompositeRects (CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect, xRectangle *rects) { ScreenPtr pScreen = pDst->pDrawable->pScreen; if (color->alpha == 0xffff) { if (op == PictOpOver) op = PictOpSrc; } if (op == PictOpClear) color->red = color->green = color->blue = color->alpha = 0; if (op == PictOpSrc || op == PictOpClear) { miColorRects (pDst, pDst, color, nRect, rects, 0, 0); if (pDst->alphaMap) miColorRects (pDst->alphaMap, pDst, color, nRect, rects, pDst->alphaOrigin.x, pDst->alphaOrigin.y); } else { PictFormatPtr rgbaFormat; PixmapPtr pPixmap; PicturePtr pSrc; xRectangle one; int error; Pixel pixel; GCPtr pGC; CARD32 tmpval[2]; rgbaFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); if (!rgbaFormat) goto bail1; pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, rgbaFormat->depth); if (!pPixmap) goto bail2; miRenderColorToPixel (rgbaFormat, color, &pixel); pGC = GetScratchGC (rgbaFormat->depth, pScreen); if (!pGC) goto bail3; tmpval[0] = GXcopy; tmpval[1] = pixel; ChangeGC (pGC, GCFunction | GCForeground, tmpval); ValidateGC (&pPixmap->drawable, pGC); one.x = 0; one.y = 0; one.width = 1; one.height = 1; (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one); tmpval[0] = xTrue; pSrc = CreatePicture (0, &pPixmap->drawable, rgbaFormat, CPRepeat, tmpval, 0, &error); if (!pSrc) goto bail4; while (nRect--) { CompositePicture (op, pSrc, 0, pDst, 0, 0, 0, 0, rects->x, rects->y, rects->width, rects->height); rects++; } FreePicture ((pointer) pSrc, 0); bail4: FreeScratchGC (pGC); bail3: (*pScreen->DestroyPixmap) (pPixmap); bail2: bail1: ; } }
static PixmapPtr compNewPixmap (WindowPtr pWin, int x, int y, int w, int h, Bool map) { ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pParent = pWin->parent; PixmapPtr pPixmap; pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth, CREATE_PIXMAP_USAGE_BACKING_PIXMAP); if (!pPixmap) return 0; pPixmap->screen_x = x; pPixmap->screen_y = y; /* resize allocations will update later in compCopyWindow, not here */ if (!map) return pPixmap; if (pParent->drawable.depth == pWin->drawable.depth) { GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen); if (pGC) { ChangeGCVal val; val.val = IncludeInferiors; ChangeGC (NullClient, pGC, GCSubwindowMode, &val); ValidateGC(&pPixmap->drawable, pGC); (*pGC->ops->CopyArea) (&pParent->drawable, &pPixmap->drawable, pGC, x - pParent->drawable.x, y - pParent->drawable.y, w, h, 0, 0); FreeScratchGC (pGC); } } else { PictFormatPtr pSrcFormat = compWindowFormat (pParent); PictFormatPtr pDstFormat = compWindowFormat (pWin); XID inferiors = IncludeInferiors; int error; PicturePtr pSrcPicture = CreatePicture (None, &pParent->drawable, pSrcFormat, CPSubwindowMode, &inferiors, serverClient, &error); PicturePtr pDstPicture = CreatePicture (None, &pPixmap->drawable, pDstFormat, 0, 0, serverClient, &error); if (pSrcPicture && pDstPicture) { CompositePicture (PictOpSrc, pSrcPicture, NULL, pDstPicture, x - pParent->drawable.x, y - pParent->drawable.y, 0, 0, 0, 0, w, h); } if (pSrcPicture) FreePicture (pSrcPicture, 0); if (pDstPicture) FreePicture (pDstPicture, 0); } return pPixmap; }
static Bool miDCRealize(ScreenPtr pScreen, CursorPtr pCursor) { miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey); GCPtr pGC; ChangeGCVal gcvals; PixmapPtr sourceBits, maskBits; if (pScreenPriv->pCursor == pCursor) return TRUE; #ifdef ARGB_CURSOR if (pCursor->bits->argb) { PixmapPtr pPixmap; PictFormatPtr pFormat; int error; PicturePtr pPicture; pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8); if (!pFormat) return FALSE; pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 32, CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) return FALSE; pGC = GetScratchGC(32, pScreen); if (!pGC) { (*pScreen->DestroyPixmap) (pPixmap); return FALSE; } ValidateGC(&pPixmap->drawable, pGC); (*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, ZPixmap, (char *) pCursor->bits->argb); FreeScratchGC(pGC); pPicture = CreatePicture(0, &pPixmap->drawable, pFormat, 0, 0, serverClient, &error); (*pScreen->DestroyPixmap) (pPixmap); if (!pPicture) return FALSE; miDCSwitchScreenCursor(pScreen, pCursor, NULL, NULL, pPicture); return TRUE; } #endif sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); if (!sourceBits) return FALSE; maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); if (!maskBits) { (*pScreen->DestroyPixmap) (sourceBits); return FALSE; } /* create the two sets of bits, clipping as appropriate */ pGC = GetScratchGC(1, pScreen); if (!pGC) { (*pScreen->DestroyPixmap) (sourceBits); (*pScreen->DestroyPixmap) (maskBits); return FALSE; } ValidateGC((DrawablePtr) sourceBits, pGC); (*pGC->ops->PutImage) ((DrawablePtr) sourceBits, pGC, 1, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, XYPixmap, (char *) pCursor->bits->source); gcvals.val = GXand; ChangeGC(NullClient, pGC, GCFunction, &gcvals); ValidateGC((DrawablePtr) sourceBits, pGC); (*pGC->ops->PutImage) ((DrawablePtr) sourceBits, pGC, 1, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, XYPixmap, (char *) pCursor->bits->mask); /* mask bits -- pCursor->mask & ~pCursor->source */ gcvals.val = GXcopy; ChangeGC(NullClient, pGC, GCFunction, &gcvals); ValidateGC((DrawablePtr) maskBits, pGC); (*pGC->ops->PutImage) ((DrawablePtr) maskBits, pGC, 1, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, XYPixmap, (char *) pCursor->bits->mask); gcvals.val = GXandInverted; ChangeGC(NullClient, pGC, GCFunction, &gcvals); ValidateGC((DrawablePtr) maskBits, pGC); (*pGC->ops->PutImage) ((DrawablePtr) maskBits, pGC, 1, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, XYPixmap, (char *) pCursor->bits->source); FreeScratchGC(pGC); miDCSwitchScreenCursor(pScreen, pCursor, sourceBits, maskBits, NULL); return TRUE; }
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); }
static PixmapPtr compNewPixmap (WindowPtr pWin, int x, int y, int w, int h) { ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pParent = pWin->parent; PixmapPtr pPixmap; pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth, CREATE_PIXMAP_USAGE_BACKING_PIXMAP); if (!pPixmap) return 0; pPixmap->screen_x = x; pPixmap->screen_y = y; if (pParent->drawable.depth == pWin->drawable.depth) { GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen); /* * Copy bits from the parent into the new pixmap so that it will * have "reasonable" contents in case for background None areas. */ if (pGC) { ChangeGCVal val; val.val = IncludeInferiors; ValidateGC(&pPixmap->drawable, pGC); ChangeGC (serverClient, pGC, GCSubwindowMode, &val); (*pGC->ops->CopyArea) (&pParent->drawable, &pPixmap->drawable, pGC, x - pParent->drawable.x, y - pParent->drawable.y, w, h, 0, 0); FreeScratchGC (pGC); } } else { PictFormatPtr pSrcFormat = compWindowFormat (pParent); PictFormatPtr pDstFormat = compWindowFormat (pWin); XID inferiors = IncludeInferiors; int error; PicturePtr pSrcPicture = CreatePicture (None, &pParent->drawable, pSrcFormat, CPSubwindowMode, &inferiors, serverClient, &error); PicturePtr pDstPicture = CreatePicture (None, &pPixmap->drawable, pDstFormat, 0, 0, serverClient, &error); if (pSrcPicture && pDstPicture) { CompositePicture (PictOpSrc, pSrcPicture, NULL, pDstPicture, x - pParent->drawable.x, y - pParent->drawable.y, 0, 0, 0, 0, w, h); } if (pSrcPicture) FreePicture (pSrcPicture, 0); if (pDstPicture) FreePicture (pDstPicture, 0); } return pPixmap; }
static miDCCursorPtr miDCRealize (ScreenPtr pScreen, CursorPtr pCursor) { miDCCursorPtr pPriv; GCPtr pGC; ChangeGCVal gcvals; pPriv = malloc(sizeof (miDCCursorRec)); if (!pPriv) return NULL; #ifdef ARGB_CURSOR if (pCursor->bits->argb) { PixmapPtr pPixmap; PictFormatPtr pFormat; int error; pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); if (!pFormat) { free((pointer) pPriv); return NULL; } pPriv->sourceBits = 0; pPriv->maskBits = 0; pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 32, CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) { free((pointer) pPriv); return NULL; } pGC = GetScratchGC (32, pScreen); if (!pGC) { (*pScreen->DestroyPixmap) (pPixmap); free((pointer) pPriv); return NULL; } ValidateGC (&pPixmap->drawable, pGC); (*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, ZPixmap, (char *) pCursor->bits->argb); FreeScratchGC (pGC); pPriv->pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, serverClient, &error); (*pScreen->DestroyPixmap) (pPixmap); if (!pPriv->pPicture) { free((pointer) pPriv); return NULL; } dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, pPriv); return pPriv; } pPriv->pPicture = 0; #endif pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); if (!pPriv->sourceBits) { free((pointer) pPriv); return NULL; } pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); if (!pPriv->maskBits) { (*pScreen->DestroyPixmap) (pPriv->sourceBits); free((pointer) pPriv); return NULL; } dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, pPriv); /* create the two sets of bits, clipping as appropriate */ pGC = GetScratchGC (1, pScreen); if (!pGC) { (void) miDCUnrealizeCursor (pScreen, pCursor); return NULL; } ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC); (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, XYPixmap, (char *)pCursor->bits->source); gcvals.val = GXand; ChangeGC (NullClient, pGC, GCFunction, &gcvals); ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC); (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, XYPixmap, (char *)pCursor->bits->mask); /* mask bits -- pCursor->mask & ~pCursor->source */ gcvals.val = GXcopy; ChangeGC (NullClient, pGC, GCFunction, &gcvals); ValidateGC ((DrawablePtr)pPriv->maskBits, pGC); (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, XYPixmap, (char *)pCursor->bits->mask); gcvals.val = GXandInverted; ChangeGC (NullClient, pGC, GCFunction, &gcvals); ValidateGC ((DrawablePtr)pPriv->maskBits, pGC); (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1, 0, 0, pCursor->bits->width, pCursor->bits->height, 0, XYPixmap, (char *)pCursor->bits->source); FreeScratchGC (pGC); return pPriv; }
static inline void glamor_copy_glyph(PixmapPtr glyph_pixmap, DrawablePtr atlas_draw, int16_t x, int16_t y) { DrawablePtr glyph_draw = &glyph_pixmap->drawable; BoxRec box = { .x1 = 0, .y1 = 0, .x2 = glyph_draw->width, .y2 = glyph_draw->height, }; PixmapPtr upload_pixmap = glyph_pixmap; if (glyph_pixmap->drawable.bitsPerPixel != atlas_draw->bitsPerPixel) { /* If we're dealing with 1-bit glyphs, we copy them to a * temporary 8-bit pixmap and upload them from there, since * that's what GL can handle. */ ScreenPtr screen = atlas_draw->pScreen; GCPtr scratch_gc; ChangeGCVal changes[2]; upload_pixmap = glamor_create_pixmap(screen, glyph_draw->width, glyph_draw->height, atlas_draw->depth, GLAMOR_CREATE_PIXMAP_CPU); if (!upload_pixmap) return; scratch_gc = GetScratchGC(upload_pixmap->drawable.depth, screen); if (!scratch_gc) { glamor_destroy_pixmap(upload_pixmap); return; } changes[0].val = 0xff; changes[1].val = 0x00; if (ChangeGC(NullClient, scratch_gc, GCForeground|GCBackground, changes) != Success) { glamor_destroy_pixmap(upload_pixmap); FreeScratchGC(scratch_gc); return; } ValidateGC(&upload_pixmap->drawable, scratch_gc); (*scratch_gc->ops->CopyPlane)(glyph_draw, &upload_pixmap->drawable, scratch_gc, 0, 0, glyph_draw->width, glyph_draw->height, 0, 0, 0x1); } glamor_upload_boxes((PixmapPtr) atlas_draw, &box, 1, 0, 0, x, y, upload_pixmap->devPrivate.ptr, upload_pixmap->devKind); if (upload_pixmap != glyph_pixmap) glamor_destroy_pixmap(upload_pixmap); } static Bool glamor_glyph_atlas_init(ScreenPtr screen, struct glamor_glyph_atlas *atlas) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PictFormatPtr format = atlas->format; atlas->atlas = glamor_create_pixmap(screen, glamor_priv->glyph_atlas_dim, glamor_priv->glyph_atlas_dim, format->depth, GLAMOR_CREATE_FBO_NO_FBO); if (!glamor_pixmap_has_fbo(atlas->atlas)) { glamor_destroy_pixmap(atlas->atlas); atlas->atlas = NULL; } atlas->x = 0; atlas->y = 0; atlas->row_height = 0; atlas->serial++; atlas->nglyph = 0; return TRUE; }
static void cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) { GCPtr pBackingGC; cwGCPtr pPriv; DrawablePtr pBackingDrawable; int x_off, y_off; pPriv = (cwGCPtr) getCwGC (pGC); FUNC_PROLOGUE(pGC, pPriv); /* * Must call ValidateGC to ensure pGC->pCompositeClip is valid */ (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable); if (!cwDrawableIsRedirWindow(pDrawable)) { cwDestroyBackingGC(pGC); FUNC_EPILOGUE(pGC, pPriv); return; } else { if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) { FUNC_EPILOGUE(pGC, pPriv); return; } } pBackingGC = pPriv->pBackingGC; pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); pPriv->stateChanges |= stateChanges; /* * Copy the composite clip into the backing GC if either * the drawable clip list has changed or the client has changed * the client clip data */ if (pDrawable->serialNumber != pPriv->serialNumber || (pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask))) { ChangeGCVal vals[2]; RegionPtr pCompositeClip; pCompositeClip = RegionCreate(NULL, 0); RegionCopy(pCompositeClip, pGC->pCompositeClip); /* Either the drawable has changed, or the clip list in the drawable has * changed. Copy the new clip list over and set the new translated * offset for it. */ (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, (pointer) pCompositeClip, 0); vals[0].val = x_off - pDrawable->x; vals[1].val = y_off - pDrawable->y; ChangeGC(NullClient, pBackingGC, (GCClipXOrigin | GCClipYOrigin), vals); pPriv->serialNumber = pDrawable->serialNumber; /* * Mask off any client clip changes to make sure * the clip list set above remains in effect */ pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask); } if (pPriv->stateChanges) { CopyGC(pGC, pBackingGC, pPriv->stateChanges); pPriv->stateChanges = 0; } if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x || (pGC->patOrg.y + y_off) != pBackingGC->patOrg.y) { ChangeGCVal vals[2]; vals[0].val = pGC->patOrg.x + x_off; vals[1].val = pGC->patOrg.y + y_off; ChangeGC(NullClient, pBackingGC, (GCTileStipXOrigin | GCTileStipYOrigin), vals); } ValidateGC(pBackingDrawable, pBackingGC); FUNC_EPILOGUE(pGC, pPriv); }