Esempio n. 1
0
/** 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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
File: dmx.c Progetto: mozyg/xorg
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;
    }
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
/** Add glyphs to the Glyph Set on each screen. */
static int dmxProcRenderAddGlyphs(ClientPtr client)
{
    int  ret;
    REQUEST(xRenderAddGlyphsReq);

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

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

	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;
}
Esempio n. 9
0
/* 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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
/** 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);
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
/* 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;
    }
}
Esempio n. 14
0
_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;
}
Esempio n. 15
0
/** Composite glyphs on each screen into the requested picture.  If
 *  either the src or dest picture has not been allocated due to lazy
 *  window creation, this request will gracefully return. */
static int dmxProcRenderCompositeGlyphs(ClientPtr client)
{
    int  ret;
    REQUEST(xRenderCompositeGlyphsReq);

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

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

	int                scrnNum;
	DMXScreenInfo     *dmxScreen;

	CARD8             *buffer;
	CARD8             *end;
	int                space;

	int                nglyph;
	char              *glyphs;
	char              *curGlyph;

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

	GlyphSetPtr        glyphSet;
	dmxGlyphPrivPtr    glyphPriv;

	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;
}
Esempio n. 16
0
/** 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;
}
Esempio n. 17
0
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);
    }
}