/** Free the previously allocated Glyph Sets for each screen. */ static int dmxProcRenderFreeGlyphSet(ClientPtr client) { GlyphSetPtr glyphSet; REQUEST(xRenderFreeGlyphSetReq); REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); glyphSet = SecurityLookupIDByType(client, stuff->glyphset, GlyphSetType, SecurityDestroyAccess); if (glyphSet && glyphSet->refcnt == 1) { dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); int i; for (i = 0; i < dmxNumScreens; i++) { DMXScreenInfo *dmxScreen = &dmxScreens[i]; if (dmxScreen->beDisplay) { if (dmxBEFreeGlyphSet(screenInfo.screens[i], glyphSet)) dmxSync(dmxScreen, FALSE); } } MAXSCREENSFREE(glyphPriv->glyphSets); xfree(glyphPriv); DMX_SET_GLYPH_PRIV(glyphSet, NULL); } return dmxSaveRenderVector[stuff->renderReqType](client); }
static int ProcXagGetAttr( register ClientPtr client) { AppGroupPtr pAppGrp; REQUEST (xXagGetAttrReq); xXagGetAttrReply rep; int n; REQUEST_SIZE_MATCH (xXagGetAttrReq); pAppGrp = (AppGroupPtr)SecurityLookupIDByType (client, (XID)stuff->app_group, RT_APPGROUP, SecurityReadAccess); if (!pAppGrp) return XagBadAppGroup; rep.type = X_Reply; rep.length = 0; rep.sequence_number = client->sequence; rep.default_root = pAppGrp->default_root; rep.root_visual = pAppGrp->root_visual; rep.default_colormap = pAppGrp->default_colormap; rep.black_pixel = pAppGrp->black_pixel; rep.white_pixel = pAppGrp->white_pixel; rep.single_screen = pAppGrp->single_screen; rep.app_group_leader = (pAppGrp->leader) ? 1 : 0; if (client->swapped) { swaps (&rep.sequence_number, n); swapl (&rep.length, n); swapl (&rep.default_root, n); swapl (&rep.root_visual, n); swapl (&rep.default_colormap, n); swapl (&rep.black_pixel, n); swapl (&rep.white_pixel, n); } WriteToClient (client, sizeof (xXagGetAttrReply), (char *)&rep); return client->noClientException; }
int ProcXFixesCreateRegionFromBitmap (ClientPtr client) { RegionPtr pRegion; PixmapPtr pPixmap; REQUEST (xXFixesCreateRegionFromBitmapReq); REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq); LEGAL_NEW_RESOURCE (stuff->region, client); pPixmap = (PixmapPtr) SecurityLookupIDByType (client, stuff->bitmap, RT_PIXMAP, DixReadAccess); if (!pPixmap) { client->errorValue = stuff->bitmap; return BadPixmap; } if (pPixmap->drawable.depth != 1) return BadMatch; pRegion = BITMAP_TO_REGION(pPixmap->drawable.pScreen, pPixmap); if (!pRegion) return BadAlloc; if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) return BadAlloc; return(client->noClientException); }
static int ProcDMXForceWindowCreation(ClientPtr client) { xDMXForceWindowCreationReply rep; REQUEST(xDMXForceWindowCreationReq); WindowPtr pWin; int n; REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq); #ifdef PANORAMIX if (!noPanoramiXExtension) { PanoramiXRes *win; int i; if (!(win = SecurityLookupIDByType(client, stuff->window, XRT_WINDOW, DixReadAccess))) return -1; /* BadWindow */ FOR_NSCREENS(i) { if (Success != dixLookupWindow(&pWin, win->info[i].id, client, DixReadAccess)) return -1; /* BadWindow */ dmxForceWindowCreation(pWin); } goto doreply; }
static int XineramaXvStopVideo(ClientPtr client) { int result = Success, i; PanoramiXRes *draw, *port; REQUEST(xvStopVideoReq); REQUEST_SIZE_MATCH(xvStopVideoReq); if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) return BadDrawable; if(!(port = (PanoramiXRes *)SecurityLookupIDByType( client, stuff->port, XvXRTPort, DixReadAccess))) return _XvBadPort; FOR_NSCREENS_BACKWARD(i) { if(port->info[i].id) { stuff->drawable = draw->info[i].id; stuff->port = port->info[i].id; result = ProcXvStopVideo(client); } } return result; }
static int XineramaXvShmPutImage(ClientPtr client) { REQUEST(xvShmPutImageReq); PanoramiXRes *draw, *gc, *port; Bool send_event = stuff->send_event; Bool isRoot; int result = Success, i, x, y; REQUEST_SIZE_MATCH(xvShmPutImageReq); if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) return BadDrawable; if(!(gc = (PanoramiXRes *)SecurityLookupIDByType( client, stuff->gc, XRT_GC, DixReadAccess))) return BadGC; if(!(port = (PanoramiXRes *)SecurityLookupIDByType( client, stuff->port, XvXRTPort, DixReadAccess))) return _XvBadPort; isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; x = stuff->drw_x; y = stuff->drw_y; FOR_NSCREENS_BACKWARD(i) { if(port->info[i].id) { stuff->drawable = draw->info[i].id; stuff->port = port->info[i].id; stuff->gc = gc->info[i].id; stuff->drw_x = x; stuff->drw_y = y; if(isRoot) { stuff->drw_x -= panoramiXdataPtr[i].x; stuff->drw_y -= panoramiXdataPtr[i].y; } stuff->send_event = (send_event && !i) ? 1 : 0; result = ProcXvShmPutImage(client); } } return result; }
/** 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; glyphSet = SecurityLookupIDByType(client, stuff->glyphset, GlyphSetType, SecurityReadAccess); 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 = xalloc(sizeof(*gidsCopy) * nglyphs); 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); } } xfree(gidsCopy); } return ret; }
/** Create a Glyph Set on each screen. Save the glyphset ID from each * screen in the Glyph Set's private structure. Fail if the format * requested is not available or if the Glyph Set cannot be created on * the screen. */ static int dmxProcRenderCreateGlyphSet(ClientPtr client) { int ret; REQUEST(xRenderCreateGlyphSetReq); ret = dmxSaveRenderVector[stuff->renderReqType](client); if (ret == Success) { GlyphSetPtr glyphSet; dmxGlyphPrivPtr glyphPriv; int i; /* Look up glyphSet that was just created ???? */ /* Store glyphsets from backends in glyphSet->devPrivate ????? */ /* Make sure we handle all errors here!! */ glyphSet = SecurityLookupIDByType(client, stuff->gsid, GlyphSetType, DixDestroyAccess); glyphPriv = xalloc(sizeof(dmxGlyphPrivRec)); if (!glyphPriv) return BadAlloc; glyphPriv->glyphSets = NULL; MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc); DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv); for (i = 0; i < dmxNumScreens; i++) { DMXScreenInfo *dmxScreen = &dmxScreens[i]; int beret; if (!dmxScreen->beDisplay) { glyphPriv->glyphSets[i] = 0; continue; } if ((beret = dmxBECreateGlyphSet(i, glyphSet)) != Success) { int j; /* Free the glyph sets we've allocated thus far */ for (j = 0; j < i; j++) dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet); /* Free the resource created by render */ FreeResource(stuff->gsid, RT_NONE); return beret; } } } return ret; }
/* static */ int ProcXagDestroy( register ClientPtr client) { AppGroupPtr pAppGrp; REQUEST (xXagDestroyReq); REQUEST_SIZE_MATCH (xXagDestroyReq); pAppGrp = (AppGroupPtr)SecurityLookupIDByType (client, (XID)stuff->app_group, RT_APPGROUP, SecurityReadAccess); if (!pAppGrp) return XagBadAppGroup; FreeResource ((XID)stuff->app_group, RT_NONE); if (--XagCallbackRefCount == 0) (void) DeleteCallback (&ClientStateCallback, XagClientStateChange, NULL); return client->noClientException; }
static int XineramaXvSetPortAttribute(ClientPtr client) { REQUEST(xvSetPortAttributeReq); PanoramiXRes *port; int result = Success, i; REQUEST_SIZE_MATCH(xvSetPortAttributeReq); if(!(port = (PanoramiXRes *)SecurityLookupIDByType( client, stuff->port, XvXRTPort, DixReadAccess))) return _XvBadPort; FOR_NSCREENS_BACKWARD(i) { if(port->info[i].id) { stuff->port = port->info[i].id; result = ProcXvSetPortAttribute(client); } } return result; }
/** Free glyphs from the Glyph Set for each screen. */ static int dmxProcRenderFreeGlyphs(ClientPtr client) { GlyphSetPtr glyphSet; REQUEST(xRenderFreeGlyphsReq); REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); glyphSet = SecurityLookupIDByType(client, stuff->glyphset, GlyphSetType, SecurityWriteAccess); 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 = xalloc(sizeof(*gids) * nglyphs); 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); } } xfree(gids); } } return dmxSaveRenderVector[stuff->renderReqType](client); }
static int ProcRRSelectInput (ClientPtr client) { REQUEST(xRRSelectInputReq); rrClientPriv(client); RRTimesPtr pTimes; WindowPtr pWin; RREventPtr pRREvent, *pHead; XID clientResource; int rc; REQUEST_SIZE_MATCH(xRRSelectInputReq); #ifndef NXAGENT_SERVER rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); #else pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess); rc = pWin ? Success : BadWindow; #endif if (rc != Success) return rc; pHead = (RREventPtr *)SecurityLookupIDByType(client, pWin->drawable.id, RREventType, DixWriteAccess); if (stuff->enable & (RRScreenChangeNotifyMask| RRCrtcChangeNotifyMask| RROutputChangeNotifyMask)) { ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv (pScreen); pRREvent = NULL; if (pHead) { /* check for existing entry. */ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) if (pRREvent->client == client) break; } if (!pRREvent) { /* build the entry */ pRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); if (!pRREvent) return BadAlloc; pRREvent->next = 0; pRREvent->client = client; pRREvent->window = pWin; pRREvent->mask = stuff->enable; /* * add a resource that will be deleted when * the client goes away */ clientResource = FakeClientID (client->index); pRREvent->clientResource = clientResource; if (!AddResource (clientResource, RRClientType, (pointer)pRREvent)) return BadAlloc; /* * create a resource to contain a pointer to the list * of clients selecting input. This must be indirect as * the list may be arbitrarily rearranged which cannot be * done through the resource database. */ if (!pHead) { pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); if (!pHead || !AddResource (pWin->drawable.id, RREventType, (pointer)pHead)) { FreeResource (clientResource, RT_NONE); return BadAlloc; } *pHead = 0; } pRREvent->next = *pHead; *pHead = pRREvent; } /* * Now see if the client needs an event */ if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) { pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; if (CompareTimeStamps (pTimes->setTime, pScrPriv->lastSetTime) != 0 || CompareTimeStamps (pTimes->configTime, pScrPriv->lastConfigTime) != 0) { RRDeliverScreenEvent (client, pWin, pScreen); } } } else if (stuff->enable == 0) { /* delete the interest */ if (pHead) { RREventPtr pNewRREvent = 0; for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { if (pRREvent->client == client) break; pNewRREvent = pRREvent; } if (pRREvent) { FreeResource (pRREvent->clientResource, RRClientType); if (pNewRREvent) pNewRREvent->next = pRREvent->next; else *pHead = pRREvent->next; xfree (pRREvent); } } } else { client->errorValue = stuff->enable; return BadValue; } return Success; }
/* static */ void XagClientStateChange( CallbackListPtr* pcbl, pointer nulldata, pointer calldata) { SecurityAuthorizationPtr pAuth; NewClientInfoRec* pci = (NewClientInfoRec*) calldata; ClientPtr pClient = pci->client; AppGroupPtr pAppGrp; XID authId = 0; if (!pClient->appgroup) { switch (pClient->clientState) { case ClientStateAuthenticating: case ClientStateRunning: case ClientStateCheckingSecurity: return; case ClientStateInitial: case ClientStateCheckedSecurity: /* * If the client is connecting via a firewall proxy (which * uses XC-QUERY-SECURITY-1, then the authId is available * during ClientStateCheckedSecurity, otherwise it's * available during ClientStateInitial. * * Don't get it from pClient because can't guarantee the order * of the callbacks and the security extension might not have * plugged it in yet. */ authId = AuthorizationIDOfClient(pClient); break; case ClientStateGone: case ClientStateRetained: /* * Don't get if from AuthorizationIDOfClient because can't * guarantee the order of the callbacks and the security * extension may have torn down the client's private data */ authId = pClient->authId; break; } if (authId == None) return; pAuth = (SecurityAuthorizationPtr)SecurityLookupIDByType(pClient, authId, SecurityAuthorizationResType, SecurityReadAccess); if (pAuth == NULL) return; for (pAppGrp = appGrpList; pAppGrp != NULL; pAppGrp = pAppGrp->next) if (pAppGrp->appgroupId == pAuth->group) break; } else { pAppGrp = pClient->appgroup; } if (!pAppGrp) return; switch (pClient->clientState) { case ClientStateAuthenticating: case ClientStateRunning: case ClientStateCheckingSecurity: break; case ClientStateInitial: case ClientStateCheckedSecurity: /* see the comment above about Initial vs. CheckedSecurity */ { /* if this client already in AppGroup, don't add it again */ int i; for (i = 0; i < pAppGrp->nclients; i++) if (pClient == pAppGrp->clients[i]) return; } pAppGrp->clients = (ClientPtr*) xrealloc (pAppGrp->clients, ++pAppGrp->nclients * sizeof (ClientPtr)); pAppGrp->clients[pAppGrp->nclients - 1] = pClient; pClient->appgroup = pAppGrp; break; case ClientStateGone: case ClientStateRetained: /* client disconnected, dump it */ { int i; for (i = 0; i < pAppGrp->nclients; i++) if (pAppGrp->clients[i] == pClient) { pAppGrp->clients[i] = NULL; break; } for (i = 0; i < pAppGrp->nclients; i++) if (pAppGrp->clients[i] == NULL && i + 1 < pAppGrp->nclients) pAppGrp->clients[i] = pAppGrp->clients[i + 1]; pAppGrp->nclients--; } pClient->appgroup = NULL; /* redundant, pClient will be freed */ break; } }
_X_EXPORT int dixChangeGC(ClientPtr client, register GC *pGC, register BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion) { register BITS32 index2; register int error = 0; PixmapPtr pPixmap; BITS32 maskQ; assert( (pC32 && !pUnion) || (!pC32 && pUnion) ); pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; maskQ = mask; /* save these for when we walk the GCque */ while (mask && !error) { index2 = (BITS32) lowbit (mask); mask &= ~index2; pGC->stateChanges |= index2; switch (index2) { case GCFunction: { CARD8 newalu; NEXTVAL(CARD8, newalu); if (newalu <= GXset) pGC->alu = newalu; else { clientErrorValue = newalu; error = BadValue; } break; } case GCPlaneMask: NEXTVAL(unsigned long, pGC->planemask); break; case GCForeground: NEXTVAL(unsigned long, pGC->fgPixel); /* * this is for CreateGC */ if (!pGC->tileIsPixel && !pGC->tile.pixmap) { pGC->tileIsPixel = TRUE; pGC->tile.pixel = pGC->fgPixel; } break; case GCBackground: NEXTVAL(unsigned long, pGC->bgPixel); break; case GCLineWidth: /* ??? line width is a CARD16 */ NEXTVAL(CARD16, pGC->lineWidth); break; case GCLineStyle: { unsigned int newlinestyle; NEXTVAL(unsigned int, newlinestyle); if (newlinestyle <= LineDoubleDash) pGC->lineStyle = newlinestyle; else { clientErrorValue = newlinestyle; error = BadValue; } break; } case GCCapStyle: { unsigned int newcapstyle; NEXTVAL(unsigned int, newcapstyle); if (newcapstyle <= CapProjecting) pGC->capStyle = newcapstyle; else { clientErrorValue = newcapstyle; error = BadValue; } break; } case GCJoinStyle: { unsigned int newjoinstyle; NEXTVAL(unsigned int, newjoinstyle); if (newjoinstyle <= JoinBevel) pGC->joinStyle = newjoinstyle; else { clientErrorValue = newjoinstyle; error = BadValue; } break; } case GCFillStyle: { unsigned int newfillstyle; NEXTVAL(unsigned int, newfillstyle); if (newfillstyle <= FillOpaqueStippled) pGC->fillStyle = newfillstyle; else { clientErrorValue = newfillstyle; error = BadValue; } break; } case GCFillRule: { unsigned int newfillrule; NEXTVAL(unsigned int, newfillrule); if (newfillrule <= WindingRule) pGC->fillRule = newfillrule; else { clientErrorValue = newfillrule; error = BadValue; } break; } case GCTile: { XID newpix = 0; if (pUnion) { NEXT_PTR(PixmapPtr, pPixmap); } else { NEXTVAL(XID, newpix); pPixmap = (PixmapPtr)SecurityLookupIDByType(client, newpix, RT_PIXMAP, SecurityReadAccess); } if (pPixmap) { if ((pPixmap->drawable.depth != pGC->depth) || (pPixmap->drawable.pScreen != pGC->pScreen)) { error = BadMatch; } else { pPixmap->refcnt++; if (!pGC->tileIsPixel) (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap); pGC->tileIsPixel = FALSE; pGC->tile.pixmap = pPixmap; } } else { clientErrorValue = newpix; error = BadPixmap; } break; } case GCStipple: { XID newstipple = 0; if (pUnion) { NEXT_PTR(PixmapPtr, pPixmap); } else { NEXTVAL(XID, newstipple) pPixmap = (PixmapPtr)SecurityLookupIDByType(client, newstipple, RT_PIXMAP, SecurityReadAccess); } if (pPixmap) { if ((pPixmap->drawable.depth != 1) || (pPixmap->drawable.pScreen != pGC->pScreen)) { error = BadMatch; } else { pPixmap->refcnt++; if (pGC->stipple) (* pGC->pScreen->DestroyPixmap)(pGC->stipple); pGC->stipple = pPixmap; } } else { clientErrorValue = newstipple; error = BadPixmap; } break; } case GCTileStipXOrigin: NEXTVAL(INT16, pGC->patOrg.x); break; case GCTileStipYOrigin: NEXTVAL(INT16, pGC->patOrg.y); break; case GCFont: { FontPtr pFont; XID newfont = 0; if (pUnion) { NEXT_PTR(FontPtr, pFont); } else { NEXTVAL(XID, newfont) pFont = (FontPtr)SecurityLookupIDByType(client, newfont, RT_FONT, SecurityReadAccess); } if (pFont) { pFont->refcnt++; if (pGC->font) CloseFont(pGC->font, (Font)0); pGC->font = pFont; } else { clientErrorValue = newfont; error = BadFont; } break; } case GCSubwindowMode: { unsigned int newclipmode; NEXTVAL(unsigned int, newclipmode); if (newclipmode <= IncludeInferiors) pGC->subWindowMode = newclipmode; else { clientErrorValue = newclipmode; error = BadValue; } break; } case GCGraphicsExposures: { unsigned int newge; NEXTVAL(unsigned int, newge); if (newge <= xTrue) pGC->graphicsExposures = newge; else { clientErrorValue = newge; error = BadValue; } break; } case GCClipXOrigin: NEXTVAL(INT16, pGC->clipOrg.x); break; case GCClipYOrigin: NEXTVAL(INT16, pGC->clipOrg.y); break; case GCClipMask: { Pixmap pid = 0; int clipType = 0; if (pUnion) { NEXT_PTR(PixmapPtr, pPixmap); } else { NEXTVAL(Pixmap, pid) if (pid == None) { clipType = CT_NONE; pPixmap = NullPixmap; } else pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pid, RT_PIXMAP, SecurityReadAccess); } if (pPixmap) { if ((pPixmap->drawable.depth != 1) || (pPixmap->drawable.pScreen != pGC->pScreen)) { error = BadMatch; } else { clipType = CT_PIXMAP; pPixmap->refcnt++; } } else if (!pUnion && (pid != None)) { clientErrorValue = pid; error = BadPixmap; } if(error == Success) { (*pGC->funcs->ChangeClip)(pGC, clipType, (pointer)pPixmap, 0); } break; } case GCDashOffset: NEXTVAL(INT16, pGC->dashOffset); break; case GCDashList: { CARD8 newdash; NEXTVAL(CARD8, newdash); if (newdash == 4) { if (pGC->dash != DefaultDash) { xfree(pGC->dash); pGC->numInDashList = 2; pGC->dash = DefaultDash; } } else if (newdash != 0) { unsigned char *dash; dash = (unsigned char *)xalloc(2 * sizeof(unsigned char)); if (dash) { if (pGC->dash != DefaultDash) xfree(pGC->dash); pGC->numInDashList = 2; pGC->dash = dash; dash[0] = newdash; dash[1] = newdash; } else error = BadAlloc; } else { clientErrorValue = newdash; error = BadValue; } break; } case GCArcMode: { unsigned int newarcmode; NEXTVAL(unsigned int, newarcmode); if (newarcmode <= ArcPieSlice) pGC->arcMode = newarcmode; else { clientErrorValue = newarcmode; error = BadValue; } break; } default: clientErrorValue = maskQ; error = BadValue; break; } } /* end while mask && !error */ if (pGC->fillStyle == FillTiled && pGC->tileIsPixel) { if (!CreateDefaultTile (pGC)) { pGC->fillStyle = FillSolid; error = BadAlloc; } } (*pGC->funcs->ChangeGC)(pGC, maskQ); return error; }
/** 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; pSrc = SecurityLookupIDByType(client, stuff->src, PictureType, SecurityReadAccess); pSrcPriv = DMX_GET_PICT_PRIV(pSrc); if (!pSrcPriv->pict) return ret; pDst = SecurityLookupIDByType(client, stuff->dst, PictureType, SecurityWriteAccess); 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) pFmt = SecurityLookupIDByType(client, stuff->maskFormat, PictFormatType, SecurityReadAccess); 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 = ALLOCATE_LOCAL(nelt * sizeof(XGlyphElt8)); if (!elts) return BadAlloc; glyphs = ALLOCATE_LOCAL(nglyph * size); if (!glyphs) { DEALLOCATE_LOCAL(elts); return BadAlloc; } buffer = (CARD8 *)(stuff + 1); end = (CARD8 *)stuff + (stuff->length << 2); curGlyph = glyphs; curElt = elts; glyphSet = SecurityLookupIDByType(client, stuff->glyphset, GlyphSetType, SecurityReadAccess); glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); while (buffer + sizeof(xGlyphElt) < end) { elt = (xGlyphElt *)buffer; buffer += sizeof(xGlyphElt); if (elt->len == 0xff) { glyphSet = SecurityLookupIDByType(client, *((CARD32 *)buffer), GlyphSetType, SecurityReadAccess); 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); DEALLOCATE_LOCAL(elts); DEALLOCATE_LOCAL(glyphs); } return ret; }
/** Create a Glyph Set on each screen. Save the glyphset ID from each * screen in the Glyph Set's private structure. Fail if the format * requested is not available or if the Glyph Set cannot be created on * the screen. */ static int dmxProcRenderCreateGlyphSet(ClientPtr client) { int ret; REQUEST(xRenderCreateGlyphSetReq); ret = dmxSaveRenderVector[stuff->renderReqType](client); if (ret == Success) { int (*oldErrorHandler)(Display *, XErrorEvent *); GlyphSetPtr glyphSet; dmxGlyphPrivPtr glyphPriv; int i; PictFormatPtr pFmt; XRenderPictFormat *pFormat; /* Look up glyphSet that was just created ???? */ /* Store glyphsets from backends in glyphSet->devPrivate ????? */ /* Make sure we handle all errors here!! */ glyphSet = SecurityLookupIDByType(client, stuff->gsid, GlyphSetType, SecurityDestroyAccess); glyphPriv = xalloc(sizeof(dmxGlyphPrivRec)); if (!glyphPriv) return BadAlloc; glyphPriv->glyphSets = NULL; MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc); DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv); pFmt = SecurityLookupIDByType(client, stuff->format, PictFormatType, SecurityReadAccess); oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler); for (i = 0; i < dmxNumScreens; i++) { DMXScreenInfo *dmxScreen = &dmxScreens[i]; if (!dmxScreen->beDisplay) { glyphPriv->glyphSets[i] = 0; continue; } pFormat = dmxFindFormat(dmxScreen, pFmt); if (!pFormat) { int j; /* Free the glyph sets we've allocated thus far */ for (j = 0; j < i; j++) dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet); /* Free the resource created by render */ FreeResource(stuff->gsid, RT_NONE); ret = BadMatch; break; } /* Catch when this fails */ glyphPriv->glyphSets[i] = XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat); if (dmxGlyphLastError) { int j; /* Free the glyph sets we've allocated thus far */ for (j = 0; j < i; j++) dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet); /* Free the resource created by render */ FreeResource(stuff->gsid, RT_NONE); ret = dmxGlyphLastError; break; } } XSetErrorHandler(oldErrorHandler); } return ret; }
static int ProcXF86BigfontQueryFont( ClientPtr client) { FontPtr pFont; REQUEST(xXF86BigfontQueryFontReq); CARD32 stuff_flags; xCharInfo* pmax; xCharInfo* pmin; int nCharInfos; int shmid; #ifdef HAS_SHM ShmDescPtr pDesc; #else #define pDesc 0 #endif xCharInfo* pCI; CARD16* pIndex2UniqIndex; CARD16* pUniqIndex2Index; CARD32 nUniqCharInfos; #if 0 REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq); #else switch (client->req_len) { case 2: /* client with version 1.0 libX11 */ stuff_flags = (LocalClient(client) && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0); break; case 3: /* client with version 1.1 libX11 */ stuff_flags = stuff->flags; break; default: return BadLength; } #endif client->errorValue = stuff->id; /* EITHER font or gc */ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT, SecurityReadAccess); if (!pFont) { /* can't use VERIFY_GC because it might return BadGC */ GC *pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC, SecurityReadAccess); if (!pGC) { client->errorValue = stuff->id; return BadFont; /* procotol spec says only error is BadFont */ } pFont = pGC->font; } pmax = FONTINKMAX(pFont); pmin = FONTINKMIN(pFont); nCharInfos = (pmax->rightSideBearing == pmin->rightSideBearing && pmax->leftSideBearing == pmin->leftSideBearing && pmax->descent == pmin->descent && pmax->ascent == pmin->ascent && pmax->characterWidth == pmin->characterWidth) ? 0 : N2dChars(pFont); shmid = -1; pCI = NULL; pIndex2UniqIndex = NULL; pUniqIndex2Index = NULL; nUniqCharInfos = 0; if (nCharInfos > 0) { #ifdef HAS_SHM pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex); if (pDesc) { pCI = (xCharInfo *) pDesc->attach_addr; if (stuff_flags & XF86Bigfont_FLAGS_Shm) shmid = pDesc->shmid; } else { if (stuff_flags & XF86Bigfont_FLAGS_Shm) pDesc = shmalloc(nCharInfos * sizeof(xCharInfo) + sizeof(CARD32)); if (pDesc) { pCI = (xCharInfo *) pDesc->attach_addr; shmid = pDesc->shmid; } else { #endif pCI = (xCharInfo *) ALLOCATE_LOCAL(nCharInfos * sizeof(xCharInfo)); if (!pCI) return BadAlloc; #ifdef HAS_SHM } #endif /* Fill nCharInfos starting at pCI. */ { xCharInfo* prCI = pCI; int ninfos = 0; int ncols = pFont->info.lastCol - pFont->info.firstCol + 1; int row; for (row = pFont->info.firstRow; row <= pFont->info.lastRow && ninfos < nCharInfos; row++) { unsigned char chars[512]; xCharInfo* tmpCharInfos[256]; unsigned long count; int col; unsigned long i; i = 0; for (col = pFont->info.firstCol; col <= pFont->info.lastCol; col++) { chars[i++] = row; chars[i++] = col; } (*pFont->get_metrics) (pFont, ncols, chars, TwoD16Bit, &count, tmpCharInfos); for (i = 0; i < count && ninfos < nCharInfos; i++) { *prCI++ = *tmpCharInfos[i]; ninfos++; } } } #ifdef HAS_SHM if (pDesc) { *(CARD32 *)(pCI + nCharInfos) = signature; if (!FontSetPrivate(pFont, FontShmdescIndex, pDesc)) { shmdealloc(pDesc); return BadAlloc; } } } #endif if (shmid == -1) { /* Cannot use shared memory, so remove-duplicates the xCharInfos using a temporary hash table. */ /* Note that CARD16 is suitable as index type, because nCharInfos <= 0x10000. */ CARD32 hashModulus; CARD16* pHash2UniqIndex; CARD16* pUniqIndex2NextUniqIndex; CARD32 NextIndex; CARD32 NextUniqIndex; CARD16* tmp; CARD32 i, j; hashModulus = 67; if (hashModulus > nCharInfos+1) hashModulus = nCharInfos+1; tmp = (CARD16*) ALLOCATE_LOCAL((4*nCharInfos+1) * sizeof(CARD16)); if (!tmp) { if (!pDesc) DEALLOCATE_LOCAL(pCI); return BadAlloc; } pIndex2UniqIndex = tmp; /* nCharInfos elements */ pUniqIndex2Index = tmp + nCharInfos; /* max. nCharInfos elements */ pUniqIndex2NextUniqIndex = tmp + 2*nCharInfos; /* max. nCharInfos elements */ pHash2UniqIndex = tmp + 3*nCharInfos; /* hashModulus (<= nCharInfos+1) elements */ /* Note that we can use 0xffff as end-of-list indicator, because even if nCharInfos = 0x10000, 0xffff can not occur as valid entry before the last element has been inserted. And once the last element has been inserted, we don't need the hash table any more. */ for (j = 0; j < hashModulus; j++) pHash2UniqIndex[j] = (CARD16)(-1); NextUniqIndex = 0; for (NextIndex = 0; NextIndex < nCharInfos; NextIndex++) { xCharInfo* p = &pCI[NextIndex]; CARD32 hashCode = hashCI(p) % hashModulus; for (i = pHash2UniqIndex[hashCode]; i != (CARD16)(-1); i = pUniqIndex2NextUniqIndex[i]) { j = pUniqIndex2Index[i]; if (pCI[j].leftSideBearing == p->leftSideBearing && pCI[j].rightSideBearing == p->rightSideBearing && pCI[j].characterWidth == p->characterWidth && pCI[j].ascent == p->ascent && pCI[j].descent == p->descent && pCI[j].attributes == p->attributes) break; } if (i != (CARD16)(-1)) { /* Found *p at Index j, UniqIndex i */ pIndex2UniqIndex[NextIndex] = i; } else { /* Allocate a new entry in the Uniq table */ if (hashModulus <= 2*NextUniqIndex && hashModulus < nCharInfos+1) { /* Time to increate hash table size */ hashModulus = 2*hashModulus+1; if (hashModulus > nCharInfos+1) hashModulus = nCharInfos+1; for (j = 0; j < hashModulus; j++) pHash2UniqIndex[j] = (CARD16)(-1); for (i = 0; i < NextUniqIndex; i++) pUniqIndex2NextUniqIndex[i] = (CARD16)(-1); for (i = 0; i < NextUniqIndex; i++) { j = pUniqIndex2Index[i]; p = &pCI[j]; hashCode = hashCI(p) % hashModulus; pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode]; pHash2UniqIndex[hashCode] = i; } p = &pCI[NextIndex]; hashCode = hashCI(p) % hashModulus; } i = NextUniqIndex++; pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode]; pHash2UniqIndex[hashCode] = i; pUniqIndex2Index[i] = NextIndex; pIndex2UniqIndex[NextIndex] = i; } } nUniqCharInfos = NextUniqIndex; /* fprintf(stderr, "font metrics: nCharInfos = %d, nUniqCharInfos = %d, hashModulus = %d\n", nCharInfos, nUniqCharInfos, hashModulus); */ } } { int nfontprops = pFont->info.nprops; int rlength = sizeof(xXF86BigfontQueryFontReply) + nfontprops * sizeof(xFontProp) + (nCharInfos > 0 && shmid == -1 ? nUniqCharInfos * sizeof(xCharInfo) + (nCharInfos+1)/2 * 2 * sizeof(CARD16) : 0); xXF86BigfontQueryFontReply* reply = (xXF86BigfontQueryFontReply *) ALLOCATE_LOCAL(rlength); char* p; if (!reply) { if (nCharInfos > 0) { if (shmid == -1) DEALLOCATE_LOCAL(pIndex2UniqIndex); if (!pDesc) DEALLOCATE_LOCAL(pCI); } return BadAlloc; } reply->type = X_Reply; reply->length = (rlength - sizeof(xGenericReply)) >> 2; reply->sequenceNumber = client->sequence; reply->minBounds = pFont->info.ink_minbounds; reply->maxBounds = pFont->info.ink_maxbounds; reply->minCharOrByte2 = pFont->info.firstCol; reply->maxCharOrByte2 = pFont->info.lastCol; reply->defaultChar = pFont->info.defaultCh; reply->nFontProps = pFont->info.nprops; reply->drawDirection = pFont->info.drawDirection; reply->minByte1 = pFont->info.firstRow; reply->maxByte1 = pFont->info.lastRow; reply->allCharsExist = pFont->info.allExist; reply->fontAscent = pFont->info.fontAscent; reply->fontDescent = pFont->info.fontDescent; reply->nCharInfos = nCharInfos; reply->nUniqCharInfos = nUniqCharInfos; reply->shmid = shmid; reply->shmsegoffset = 0; if (client->swapped) { char tmp; swaps(&reply->sequenceNumber, tmp); swapl(&reply->length, tmp); swapCharInfo(&reply->minBounds); swapCharInfo(&reply->maxBounds); swaps(&reply->minCharOrByte2, tmp); swaps(&reply->maxCharOrByte2, tmp); swaps(&reply->defaultChar, tmp); swaps(&reply->nFontProps, tmp); swaps(&reply->fontAscent, tmp); swaps(&reply->fontDescent, tmp); swapl(&reply->nCharInfos, tmp); swapl(&reply->nUniqCharInfos, tmp); swapl(&reply->shmid, tmp); swapl(&reply->shmsegoffset, tmp); } p = (char*) &reply[1]; { FontPropPtr pFP; xFontProp* prFP; int i; for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) p; i < nfontprops; i++, pFP++, prFP++) { prFP->name = pFP->name; prFP->value = pFP->value; if (client->swapped) { char tmp; swapl(&prFP->name, tmp); swapl(&prFP->value, tmp); } } p = (char*) prFP; } if (nCharInfos > 0 && shmid == -1) { xCharInfo* pci; CARD16* ps; int i, j; pci = (xCharInfo*) p; for (i = 0; i < nUniqCharInfos; i++, pci++) { *pci = pCI[pUniqIndex2Index[i]]; if (client->swapped) swapCharInfo(pci); } ps = (CARD16*) pci; for (j = 0; j < nCharInfos; j++, ps++) { *ps = pIndex2UniqIndex[j]; if (client->swapped) { char tmp; swaps(ps, tmp); } } } WriteToClient(client, rlength, (char *)reply); DEALLOCATE_LOCAL(reply); if (nCharInfos > 0) { if (shmid == -1) DEALLOCATE_LOCAL(pIndex2UniqIndex); if (!pDesc) DEALLOCATE_LOCAL(pCI); } return (client->noClientException); } }