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); }
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); }
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); }
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; }
/** 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; }
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; }
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() */
/** 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]; } }
/** 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); }
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; }
/* * 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; }
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++; } } } } }
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(¶m, 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, ¶m, (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 }
/* 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; }
/** 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; }
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); }
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 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(®ion, &box, 1); if (!force_clip) clipped_regions = glamor_compute_clipped_regions(pixmap, ®ion, &n_region, 0, 0, 0); else clipped_regions = glamor_compute_clipped_regions_ext(pixmap, ®ion, &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(®ion); free(sub_bits); assert(0); return FALSE; } } RegionDestroy(clipped_regions[i].region); } free(sub_bits); free(clipped_regions); RegionUninit(®ion); 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); }
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 }
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); }
/** 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; }
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; }
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; }
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"); } } } }
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; }
/** 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; }
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); }