示例#1
0
static void CallExtensionSelector(
    Widget widget,
    ExtSelectRec* rec,
    Boolean forceCall)
{
    XtEventRec* p;
    XtPointer* data;
    int* types;
    Cardinal i, count = 0;

    for (p = widget->core.event_table; p != NULL; p = p->next)
	if (p->has_type_specifier &&
	    EXT_TYPE(p) >= rec->min && EXT_TYPE(p) <= rec->max)
	    count += p->mask;

    if (count == 0 && !forceCall) return;

    data = (XtPointer *) ALLOCATE_LOCAL(count * sizeof (XtPointer));
    types = (int *) ALLOCATE_LOCAL(count * sizeof (int));
    count = 0;

    for (p = widget->core.event_table; p != NULL; p = p->next)
	if (p->has_type_specifier &&
	    EXT_TYPE(p) >= rec->min && EXT_TYPE(p) <= rec->max)
	    for (i =0; i < p->mask; i++) {
		types[count] = EXT_TYPE(p);
		data[count++] = EXT_SELECT_DATA(p, i);
	    }

    (*rec->proc)(widget, types, data, count, rec->client_data);
    DEALLOCATE_LOCAL((char*) types);
    DEALLOCATE_LOCAL((char*) data);
}
示例#2
0
Widget XtNameToWidget(
    Widget root,
    _Xconst char* name)
{
    XrmName *names;
    XrmBinding *bindings;
    int len, depth, found = 10000;
    Widget result;
    WIDGET_TO_APPCON(root);

    len = strlen(name);
    if (len == 0) return NULL;

    LOCK_APP(app);
    names = (XrmName *) ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmName));
    bindings = (XrmBinding *)
               ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmBinding));
    if (names == NULL || bindings == NULL) _XtAllocError(NULL);

    XrmStringToBindingQuarkList(name, bindings, names);
    if (names[0] == NULLQUARK) {
        DEALLOCATE_LOCAL((char *) bindings);
        DEALLOCATE_LOCAL((char *) names);
        UNLOCK_APP(app);
        return NULL;
    }

    result = NameListToWidget(root, names, bindings, 0, &depth, &found);

    DEALLOCATE_LOCAL((char *) bindings);
    DEALLOCATE_LOCAL((char *) names);
    UNLOCK_APP(app);
    return result;
} /* XtNameToWidget */
示例#3
0
static void
xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
			LOCO *colors, VisualPtr pVisual)
{
    int i, index;
    sbusCmapPtr cmap;
    struct fbcmap fbcmap;
    unsigned char *data = ALLOCATE_LOCAL(numColors*3);
                             
    cmap = SBUSCMAPPTR(pScrn->pScreen);
    if (!cmap) return;
    fbcmap.count = 0;
    fbcmap.index = indices[0];
    fbcmap.red = data;
    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);
    DEALLOCATE_LOCAL(data);
}
示例#4
0
static Bool
xf86RandR12CrtcNotify (RRCrtcPtr	randr_crtc)
{
    ScreenPtr		pScreen = randr_crtc->pScreen;
    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
    RRModePtr		randr_mode = NULL;
    int			x;
    int			y;
    Rotation		rotation;
    int			numOutputs;
    RROutputPtr		*randr_outputs;
    RROutputPtr		randr_output;
    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
    xf86OutputPtr	output;
    int			i, j;
    DisplayModePtr	mode = &crtc->mode;
    Bool		ret;

    randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
    if (!randr_outputs)
	return FALSE;
    x = crtc->x;
    y = crtc->y;
    rotation = crtc->rotation;
    numOutputs = 0;
    randr_mode = NULL;
    for (i = 0; i < config->num_output; i++)
    {
	output = config->output[i];
	if (output->crtc == crtc)
	{
	    randr_output = output->randr_output;
	    randr_outputs[numOutputs++] = randr_output;
	    /*
	     * We make copies of modes, so pointer equality 
	     * isn't sufficient
	     */
	    for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
	    {
		RRModePtr   m = (j < randr_output->numModes ?
				 randr_output->modes[j] :
				 randr_output->userModes[j-randr_output->numModes]);
					 
		if (xf86RandRModeMatches (m, mode))
		{
		    randr_mode = m;
		    break;
		}
	    }
	}
    }
    ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
			rotation, numOutputs, randr_outputs);
    DEALLOCATE_LOCAL(randr_outputs);
    return ret;
}
示例#5
0
void
LbxWriteSConnectionInfo(ClientPtr	pClient,
			unsigned long	size,
			char 		*pInfo)
{
    int		i, j, k;
    ScreenPtr	pScreen;
    DepthPtr	pDepth;
    char	*pInfoT, *pInfoTBase;
    xConnSetup	*pConnSetup = (xConnSetup *)pInfo;

    pInfoT = pInfoTBase = (char *) ALLOCATE_LOCAL(size);
    if (!pInfoTBase)
    {
	pClient->noClientException = -1;
	return;
    }
    SwapConnSetup(pConnSetup, (xConnSetup *)pInfoT);
    pInfo += sizeof(xConnSetup);
    pInfoT += sizeof(xConnSetup);

    /* Copy the vendor string */
    i = (pConnSetup->nbytesVendor + 3) & ~3;
    memmove(pInfoT, pInfo, i);
    pInfo += i;
    pInfoT += i;

    /* The Pixmap formats don't need to be swapped, just copied. */
    i = sizeof(xPixmapFormat) * screenInfo.numPixmapFormats;
    memmove(pInfoT, pInfo, i);
    pInfo += i;
    pInfoT += i;

    for(i = 0; i < screenInfo.numScreens; i++)
    {
	pScreen = screenInfo.screens[i];
	SwapWinRoot((xWindowRoot *)pInfo, (xWindowRoot *)pInfoT);
	pInfo += sizeof(xWindowRoot);
	pInfoT += sizeof(xWindowRoot);
	pDepth = pScreen->allowedDepths;
	for(j = 0; j < pScreen->numDepths; j++, pDepth++)
	{
            ((xDepth *)pInfoT)->depth = ((xDepth *)pInfo)->depth;
	    cpswaps(((xDepth *)pInfo)->nVisuals, ((xDepth *)pInfoT)->nVisuals);
	    pInfo += sizeof(xDepth);
	    pInfoT += sizeof(xDepth);
	    for(k = 0; k < pDepth->numVids; k++)
	    {
		SwapVisual((xVisualType *)pInfo, (xVisualType *)pInfoT);
		pInfo += sizeof(xVisualType);
		pInfoT += sizeof(xVisualType);
	    }
	}
    }
    (void)WriteToClient(pClient, (int)size, (char *) pInfoTBase);
    DEALLOCATE_LOCAL(pInfoTBase);
}
int
ProcListExtensions(ClientPtr client)
{
    fsListExtensionsReply reply;
    char       *bufptr,
               *buffer;
    int         total_length = 0;

    REQUEST(fsListExtensionsReq);
    REQUEST_SIZE_MATCH(fsListExtensionsReq);

    reply.type = FS_Reply;
    reply.nExtensions = NumExtensions;
    reply.length = SIZEOF(fsListExtensionsReply) >> 2;
    reply.sequenceNumber = client->sequence;
    buffer = NULL;

    if (NumExtensions) {
	int         i,
	            j;

	for (i = 0; i < NumExtensions; i++) {
	    total_length += strlen(extensions[i]->name) + 1;
	    reply.nExtensions += extensions[i]->num_aliases;
	    for (j = extensions[i]->num_aliases; --j >= 0;)
		total_length += strlen(extensions[i]->aliases[j]) + 1;
	}
	reply.length += (total_length + 3) >> 2;
	buffer = bufptr = (char *) ALLOCATE_LOCAL(total_length);
	if (!buffer) {
	    SendErrToClient(client, FSBadAlloc, NULL);
	    return FSBadAlloc;
	}
	for (i = 0; i < NumExtensions; i++) {
	    int         len;

	    *bufptr++ = len = strlen(extensions[i]->name);
	    memmove( bufptr, extensions[i]->name, len);
	    bufptr += len;
	    for (j = extensions[i]->num_aliases; --j >= 0;) {
		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
		memmove( bufptr, extensions[i]->aliases[j], len);
		bufptr += len;
	    }
	}
    }
    WriteReplyToClient(client, SIZEOF(fsListExtensionsReply), &reply);
    if (total_length) {
	WriteToClient(client, total_length, buffer);
	DEALLOCATE_LOCAL(buffer);
    }
    return client->noClientException;
}
示例#7
0
static void CombineAppUserDefaults(
    Display *dpy,
    XrmDatabase *pdb)
{
    char* filename;
    char* path;
    Boolean deallocate = False;

    if (!(path = getenv("XUSERFILESEARCHPATH"))) {
	char *old_path;
	char homedir[PATH_MAX];
	GetRootDirName(homedir, PATH_MAX);
	if (!(old_path = getenv("XAPPLRESDIR"))) {
	    char *path_default = "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N";
	    if (!(path =
		  ALLOCATE_LOCAL(6*strlen(homedir) + strlen(path_default))))
		_XtAllocError(NULL);
	    sprintf( path, path_default,
		    homedir, homedir, homedir, homedir, homedir, homedir );
	} else {
	    char *path_default = "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N";
	    if (!(path =
		  ALLOCATE_LOCAL( 6*strlen(old_path) + 2*strlen(homedir)
				 + strlen(path_default))))
		_XtAllocError(NULL);
	    sprintf(path, path_default, old_path, old_path, old_path, homedir,
		    old_path, old_path, old_path, homedir );
	}
	deallocate = True;
    }

    filename = XtResolvePathname(dpy, NULL, NULL, NULL, path, NULL, 0, NULL);
    if (filename) {
	(void)XrmCombineFileDatabase(filename, pdb, False);
	XtFree(filename);
    }

    if (deallocate) DEALLOCATE_LOCAL(path);
}
void
xf4bppPolyRectangle(DrawablePtr pDraw, GCPtr pGC, int nrects,
		    xRectangle *pRects)
{
    int i;
    xRectangle *pR = pRects;
    xRectangle *tmprects, *tmprectsinit;
    int lw, fs, ss;

    if ( ! ( tmprectsinit = tmprects = (xRectangle *)ALLOCATE_LOCAL( ( sizeof ( xRectangle ) * nrects ) << 2 ) ) )
	return;

    lw = pGC->lineWidth;
    ss = lw >> 1;		/* skinny side of line */
    fs = ( lw + 1 ) >> 1;	/* fat side of line */

    for (i=0; i<nrects; i++)
    {
	tmprects->x = pR->x - ss;
	tmprects->y = pR->y - ss;
	tmprects->width = pR->width + lw;
	tmprects->height = lw;
	tmprects++;

	tmprects->x = pR->x - ss;
	tmprects->y = pR->y + fs;
	tmprects->width = lw;
	tmprects->height = pR->height - lw;
	tmprects++;

	tmprects->x = pR->x + pR->width - ss;
	tmprects->y = pR->y + fs;
	tmprects->width = lw;
	tmprects->height = pR->height - lw;
	tmprects++;

	tmprects->x = pR->x - ss;
	tmprects->y = pR->y + pR->height - ss;
	tmprects->width = pR->width + lw;
	tmprects->height = lw;
	tmprects++;

	pR++;
    }

    (* pGC->ops->PolyFillRect)( pDraw, pGC, nrects << 2, tmprectsinit );

    DEALLOCATE_LOCAL( tmprectsinit );
    return ;
}
示例#9
0
void
cfb8_32RestoreAreas(
    PixmapPtr	  	pPixmap, 
    RegionPtr	  	prgnRestore,
    int	    	  	xorg,
    int	    	  	yorg,
    WindowPtr		pWin
){
    DDXPointPtr pPt;
    DDXPointPtr pPtsInit;
    BoxPtr	pBox;
    int		i;
    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
    PixmapPtr	pScrPix;

    i = REGION_NUM_RECTS(prgnRestore);
    pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec));
    if (!pPtsInit)
	return;
    
    pBox = REGION_RECTS(prgnRestore);
    pPt = pPtsInit;
    while (--i >= 0) {
	pPt->x = pBox->x1 - xorg;
	pPt->y = pBox->y1 - yorg;
	pPt++;
	pBox++;
    }

    pScrPix = (PixmapPtr) pScreen->devPrivate;

    if(pPixmap->drawable.bitsPerPixel == 32) {
	if(pWin->drawable.depth == 24)
	    cfb32DoBitbltCopy((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
		    GXcopy, prgnRestore, pPtsInit, 0x00ffffff);
	else
	    cfb32DoBitbltCopy((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
		    GXcopy, prgnRestore, pPtsInit, ~0);
    } else {
	cfbDoBitblt8To32((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
		    GXcopy, prgnRestore, pPtsInit, ~0L, 0);
    }

    DEALLOCATE_LOCAL (pPtsInit);
}
示例#10
0
文件: swaprep.c 项目: narenas/nx-libs
/**
 *
 * \param size size in bytes
 */
void
CopySwap32Write(ClientPtr pClient, int size, CARD32 *pbuf)
{
    int bufsize = size;
    CARD32 *pbufT;
    register CARD32 *from, *to, *fromLast, *toLast;
    CARD32 tmpbuf[1];
    
    /* Allocate as big a buffer as we can... */
    while (!(pbufT = (CARD32 *) ALLOCATE_LOCAL(bufsize)))
    {
        bufsize >>= 1;
	if (bufsize == 4)
	{
	    pbufT = tmpbuf;
	    break;
	}
    }
    
    /* convert lengths from # of bytes to # of longs */
    size >>= 2;
    bufsize >>= 2;

    from = pbuf;
    fromLast = from + size;
    while (from < fromLast) {
	int nbytes;
        to = pbufT;
        toLast = to + min (bufsize, fromLast - from);
        nbytes = (toLast - to) << 2;
        while (to < toLast) {
            /* can't write "cpswapl(*from++, *to++)" because cpswapl is a macro
	       that evaulates its args more than once */
	    cpswapl(*from, *to);
            from++;
            to++;
	    }
	(void)WriteToClient (pClient, nbytes, (char *) pbufT);
	}

    if (pbufT != tmpbuf)
	DEALLOCATE_LOCAL ((char *) pbufT);
}
示例#11
0
static void
LeoCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
	ScreenPtr pScreen = pWin->drawable.pScreen;
	LeoPtr pLeo = LeoGetScreenPrivate (pScreen);
	DDXPointPtr pptSrc;
	DDXPointPtr ppt;
	RegionPtr prgnDst;
	BoxPtr pbox;
	int dx, dy;
	int i, nbox;
	WindowPtr pwinRoot;

	if (pLeo->vtSema)
		return;

	dx = ptOldOrg.x - pWin->drawable.x;
	dy = ptOldOrg.y - pWin->drawable.y;

	pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];

	prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);

	REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
	REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip, prgnSrc);

	pbox = REGION_RECTS(prgnDst);
	nbox = REGION_NUM_RECTS(prgnDst);
	if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
		return;
	ppt = pptSrc;

	for (i = nbox; --i >= 0; ppt++, pbox++) {
		ppt->x = pbox->x1 + dx;
		ppt->y = pbox->y1 + dy;
	}

	LeoDoBitblt ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
		     GXcopy, prgnDst, pptSrc, ~0L);
	DEALLOCATE_LOCAL(pptSrc);
	REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
}
示例#12
0
void
cfb8_32SaveAreas(
    PixmapPtr	  	pPixmap,
    RegionPtr	  	prgnSave, 
    int	    	  	xorg,
    int	    	  	yorg,
    WindowPtr		pWin
){
    DDXPointPtr pPt;
    DDXPointPtr	pPtsInit;
    BoxPtr	pBox;
    int		i;
    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
    PixmapPtr	pScrPix;

    if(pPixmap->drawable.bitsPerPixel == 32) {
	cfb32SaveAreas(pPixmap, prgnSave, xorg, yorg, pWin);
	return;
    }
    
    i = REGION_NUM_RECTS(prgnSave);
    pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec));
    if (!pPtsInit)
	return;
    
    pBox = REGION_RECTS(prgnSave);
    pPt = pPtsInit;
    while (--i >= 0) {
	pPt->x = pBox->x1 + xorg;
	pPt->y = pBox->y1 + yorg;
	pPt++;
	pBox++;
    }

    pScrPix = (PixmapPtr) pScreen->devPrivate;

    cfbDoBitblt32To8((DrawablePtr) pScrPix, (DrawablePtr)pPixmap,
		    GXcopy, prgnSave, pPtsInit, ~0L, 0);

    DEALLOCATE_LOCAL (pPtsInit);
}
示例#13
0
void 
cfbCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    DDXPointPtr pptSrc;
    DDXPointPtr ppt;
    RegionRec rgnDst;
    BoxPtr pbox;
    int dx, dy;
    int i, nbox;
    WindowPtr pwinRoot;

    pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];

    REGION_NULL(pWin->drawable.pScreen, &rgnDst);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
    REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);

    pbox = REGION_RECTS(&rgnDst);
    nbox = REGION_NUM_RECTS(&rgnDst);
    if(!nbox || !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
    {
	REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
	return;
    }
    ppt = pptSrc;

    for (i = nbox; --i >= 0; ppt++, pbox++)
    {
	ppt->x = pbox->x1 + dx;
	ppt->y = pbox->y1 + dy;
    }

    cfbDoBitbltCopy((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
		GXcopy, &rgnDst, pptSrc, ~0L);
    DEALLOCATE_LOCAL(pptSrc);
    REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
}
示例#14
0
文件: oscolor.c 项目: aosm/X11
static dbEntryPtr
lookup(char *name, int len, Bool create)
{
  unsigned int h = 0, g;
  dbEntryPtr   entry, *prev = NULL;
  char         *str = name;

  if (!(name = (char*)ALLOCATE_LOCAL(len +1))) return NULL;
  CopyISOLatin1Lowered((unsigned char *)name, (unsigned char *)str, len);
  name[len] = '\0';

  for(str = name; *str; str++) {
    h = (h << 4) + *str;
    if ((g = h) & 0xf0000000) h ^= (g >> 24);
    h &= g;
  }
  h %= HASHSIZE;

  if ( (entry = hashTab[h]) )
    {
      for( ; entry; prev = (dbEntryPtr*)entry, entry = entry->link )
	if (! strcmp(name, entry->name) ) break;
    }
  else
    prev = &(hashTab[h]);

  if (!entry && create && (entry = (dbEntryPtr)xalloc(sizeof(dbEntry) +len)))
    {
      *prev = entry;
      entry->link = NULL;
      strcpy( entry->name, name );
    }

  DEALLOCATE_LOCAL(name);

  return entry;
}
示例#15
0
文件: cfbbstore.c 项目: aosm/X11
void
cfb24_32RestoreAreas(
    PixmapPtr	  	pPixmap, 
    RegionPtr	  	prgnRestore,
    int	    	  	xorg,
    int	    	  	yorg,
    WindowPtr		pWin
){
    DDXPointPtr pPt;
    DDXPointPtr pPtsInit;
    BoxPtr	pBox;
    int		i;
    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
    PixmapPtr	pScrPix;

    i = REGION_NUM_RECTS(prgnRestore);
    pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec));
    if (!pPtsInit)
	return;
    
    pBox = REGION_RECTS(prgnRestore);
    pPt = pPtsInit;
    while (--i >= 0) {
	pPt->x = pBox->x1 - xorg;
	pPt->y = pBox->y1 - yorg;
	pPt++;
	pBox++;
    }

    pScrPix = (PixmapPtr) pScreen->devPrivate;

    cfbDoBitblt32To24((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
		    GXcopy, prgnRestore, pPtsInit, ~0L, 0);

    DEALLOCATE_LOCAL (pPtsInit);
}
示例#16
0
void
PsPaintWindow(
  WindowPtr pWin,
  RegionPtr pRegion,
  int       what)
{
  int       status;
  WindowPtr pRoot;

#define FUNCTION        0
#define FOREGROUND      1
#define TILE            2
#define FILLSTYLE       3
#define ABSX            4
#define ABSY            5
#define CLIPMASK        6
#define SUBWINDOW       7
#define COUNT_BITS      8

  pointer              gcval[7];
  pointer              newValues [COUNT_BITS];

  BITS32               gcmask, index, mask;
  RegionRec            prgnWin;
  DDXPointRec          oldCorner;
  BoxRec               box;
  WindowPtr            pBgWin;
  GCPtr                pGC;
  register int         i;
  register BoxPtr      pbox;
  register ScreenPtr   pScreen = pWin->drawable.pScreen;
  register xRectangle *prect;
  int                  numRects;

  gcmask = 0;

  /*
   * We don't want to paint a window that has no place to put the
   * PS output.
   */
  if( PsGetContextFromWindow(pWin)==(XpContextPtr)NULL ) return;

  if( what==PW_BACKGROUND )
  {
    switch(pWin->backgroundState)
    {
      case None: return;
      case ParentRelative:
        (*pWin->parent->drawable.pScreen->PaintWindowBackground)
          (pWin->parent, pRegion, what);
        return;
      case BackgroundPixel:
        newValues[FOREGROUND] = (pointer)pWin->background.pixel;
        newValues[FILLSTYLE] = (pointer)FillSolid;
        gcmask |= GCForeground | GCFillStyle;
        break;
      case BackgroundPixmap:
        newValues[TILE] = (pointer)pWin->background.pixmap;
        newValues[FILLSTYLE] = (pointer)FillTiled;
        gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
        break;
    }
  }
  else
  {
    if( pWin->borderIsPixel )
    {
      newValues[FOREGROUND] = (pointer)pWin->border.pixel;
      newValues[FILLSTYLE] = (pointer)FillSolid;
      gcmask |= GCForeground | GCFillStyle;
    }
    else
    {
      newValues[TILE] = (pointer)pWin->border.pixmap;
      newValues[FILLSTYLE] = (pointer)FillTiled;
      gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
    }
  }

  prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(pRegion) *
                                         sizeof(xRectangle));
  if( !prect ) return;

  newValues[FUNCTION] = (pointer)GXcopy;
  gcmask |= GCFunction | GCClipMask;

  i = pScreen->myNum;
  pRoot = WindowTable[i];

  pBgWin = pWin;
  if (what == PW_BORDER)
  {
    while( pBgWin->backgroundState==ParentRelative ) pBgWin = pBgWin->parent;
  }

  pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
  if( !pGC )
  {
    DEALLOCATE_LOCAL(prect);
    return;
  }
  /*
   * mash the clip list so we can paint the border by
   * mangling the window in place, pretending it
   * spans the entire screen
   */
  if( what==PW_BORDER )
  {
    prgnWin = pWin->clipList;
    oldCorner.x = pWin->drawable.x;
    oldCorner.y = pWin->drawable.y;
    pWin->drawable.x = pWin->drawable.y = 0;
    box.x1 = 0;
    box.y1 = 0;
    box.x2 = pScreen->width;
    box.y2 = pScreen->height;
    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
    newValues[ABSX] = (pointer)(long)pBgWin->drawable.x;
    newValues[ABSY] = (pointer)(long)pBgWin->drawable.y;
  }
  else
  {
    newValues[ABSX] = (pointer)0;
    newValues[ABSY] = (pointer)0;
  }

/*
 * XXX Backing store is turned off for the PS driver

  if( pWin->backStorage )
    (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
 */

  mask = gcmask;
  gcmask = 0;
  i = 0;
  while( mask )
  {
    index = lowbit (mask);
    mask &= ~index;
    switch(index)
    {
      case GCFunction:
        if( (pointer)(long)pGC->alu!=newValues[FUNCTION] )
        {
          gcmask |= index;
          gcval[i++] = newValues[FUNCTION];
        }
        break;
      case GCTileStipXOrigin:
        if( (pointer)(long)pGC->patOrg.x!=newValues[ABSX] )
        {
          gcmask |= index;
          gcval[i++] = newValues[ABSX];
        }
        break;
      case GCTileStipYOrigin:
        if( (pointer)(long)pGC->patOrg.y!=newValues[ABSY] )
        {
          gcmask |= index;
          gcval[i++] = newValues[ABSY];
        }
        break;
      case GCClipMask:
        if( (pointer)pGC->clientClipType!=(pointer)CT_NONE )
        {
          gcmask |= index;
          gcval[i++] = (pointer)CT_NONE;
        }
        break;
      case GCSubwindowMode:
        if( (pointer)pGC->subWindowMode!=newValues[SUBWINDOW] )
        {
          gcmask |= index;
          gcval[i++] = newValues[SUBWINDOW];
        }
        break;
      case GCTile:
        if( pGC->tileIsPixel || (pointer)pGC->tile.pixmap!=newValues[TILE] )
        {
          gcmask |= index;
          gcval[i++] = newValues[TILE];
        }
        break;
      case GCFillStyle:
        if( (pointer)pGC->fillStyle!=newValues[FILLSTYLE] )
        {
          gcmask |= index;
          gcval[i++] = newValues[FILLSTYLE];
        }
        break;
      case GCForeground:
        if( (pointer)pGC->fgPixel!=newValues[FOREGROUND] )
        {
          gcmask |= index;
          gcval[i++] = newValues[FOREGROUND];
        }
        break;
    }
  }

  if( gcmask ) DoChangeGC(pGC, gcmask, (XID *)gcval, 1);

  if( pWin->drawable.serialNumber!=pGC->serialNumber )
    ValidateGC((DrawablePtr)pWin, pGC);

  numRects = REGION_NUM_RECTS(pRegion);
  pbox = REGION_RECTS(pRegion);
  for( i=numRects ; --i >= 0 ; pbox++,prect++ )
  {
    prect->x = pbox->x1 - pWin->drawable.x;
    prect->y = pbox->y1 - pWin->drawable.y;
    prect->width = pbox->x2 - pbox->x1;
    prect->height = pbox->y2 - pbox->y1;
  }
  prect -= numRects;
  (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
  DEALLOCATE_LOCAL(prect);

/*
 * XXX Backing store is turned off for the PS driver

  if( pWin->backStorage )
    (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
 */

  if( what==PW_BORDER )
  {
    REGION_UNINIT(pScreen, &pWin->clipList);
    pWin->clipList = prgnWin;
    pWin->drawable.x = oldCorner.x;
    pWin->drawable.y = oldCorner.y;
    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  }
  FreeScratchGC(pGC);
}
示例#17
0
void
LeoFillSpansStippled (DrawablePtr pDrawable, GCPtr pGC,
		      int n, DDXPointPtr ppt,
		      int *pwidth, int fSorted)
{
	LeoPrivGCPtr gcPriv = LeoGetGCPrivate (pGC);
	LeoPtr pLeo = LeoGetScreenPrivate (pGC->pScreen);
	LeoCommand0 *lc0 = pLeo->lc0;
	LeoDraw *ld0 = pLeo->ld0;
	int numRects, *pwidthFree;
	DDXPointPtr pptFree;
	RegionPtr clip;
	unsigned char *fb;
	unsigned int *bits, msk;
	int cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0;

	clip = cfbGetCompositeClip(pGC);
	numRects = REGION_NUM_RECTS(clip);
	
	if (!numRects)
		return;
		
	if (numRects == 1) {
		cx1 = clip->extents.x1;
		cx2 = clip->extents.x2;
		cy1 = clip->extents.y1;
		cy2 = clip->extents.y2;
	} else {
		int nTmp = n * miFindMaxBand(clip);

		pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
		pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
		if (!pptFree || !pwidthFree) {
			if (pptFree) DEALLOCATE_LOCAL(pptFree);
			if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
			return;
		}
		n = miClipSpans(clip,
				ppt, pwidth, n,
				pptFree, pwidthFree, fSorted);
		pwidth = pwidthFree;
		ppt = pptFree;
	}
	
	if (pGC->alu != GXcopy)
		ld0->rop = leoRopTable[pGC->alu];
	if (pGC->planemask != 0xffffff)
		ld0->planemask = pGC->planemask;
	ld0->fg = gcPriv->stipple->fg;
	fb = (unsigned char *)pLeo->fb;
	lc0->addrspace = LEO_ADDRSPC_FONT_OBGR;
	if (gcPriv->stipple->alu & 0x80) {
		lc0->fontt = 1;
	} else {
		lc0->fontt = 0;
		ld0->bg = gcPriv->stipple->bg;
	}
	lc0->fontmsk = 0xffffffff;
	msk = 0xffffffff;
	bits = &gcPriv->stipple->bits[0];
	while (n--) {
		int x, y, w;
		unsigned int *dst, s, i, sw, sm;
		
		w = *pwidth++;
		x = ppt->x;
		y = ppt->y;
		ppt++;
		if (numRects == 1) {
			if (y < cy1 || y >= cy2) continue;
			if (x < cx1) {
				w -= (cx1 - x);
				if (w <= 0) continue;
				x = cx1;
			}
			if (x + w > cx2) {
				if (x >= cx2) continue;
				w = cx2 - x;
			}
		}
		s = bits[y & 31];
		dst = (unsigned int *)(fb + (y << 13) + ((x & ~31) << 2));
		if (x & 31) {
			sw = 32 - (x & 31);
			sm = 0xffffffff >> (x & 31);
			w -= sw;
			if (w <= 0) {
				if (w) sm &= 0xffffffff << (32 - (w & 31));
				if (msk != sm) {
					msk = sm;
					lc0->fontmsk = sm;
				}
				*dst = s;
				continue;
			}
			if (msk != sm) {
				msk = sm;
				lc0->fontmsk = sm;
			}
			*dst = s;
			dst += 32;
		} else {
示例#18
0
RegionPtr
XAABitBlt(
    DrawablePtr pSrcDrawable,
    DrawablePtr pDstDrawable,
    GC *pGC,
    int srcx, int srcy,
    int width, int height,
    int dstx, int dsty,
    void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
    unsigned long bitPlane )
{

    RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
    RegionPtr prgnExposed;
    Bool freeSrcClip = FALSE;
    RegionRec rgnDst;
    DDXPointPtr pptSrc, ppt;
    DDXPointRec origDest;
    BoxPtr pbox;
    BoxRec fastBox;
    int i, dx, dy, numRects;
    xRectangle origSource;
    int fastClip = 0;		/* for fast clipping with pixmap source */
    int fastExpose = 0;		/* for fast exposures with pixmap source */

    origSource.x = srcx;
    origSource.y = srcy;
    origSource.width = width;
    origSource.height = height;
    origDest.x = dstx;
    origDest.y = dsty;

    if((pSrcDrawable != pDstDrawable) && 
			pSrcDrawable->pScreen->SourceValidate) {
	(*pSrcDrawable->pScreen->SourceValidate) (
			pSrcDrawable, srcx, srcy, width, height);
    }

    srcx += pSrcDrawable->x;
    srcy += pSrcDrawable->y;

    /* clip the source */
    if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
	if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
	    prgnSrcClip = pGC->pCompositeClip;
	else
	    fastClip = 1;
    } else {	/* Window */
	if (pGC->subWindowMode == IncludeInferiors) {
	    if (!((WindowPtr) pSrcDrawable)->parent) {
		/*
		 * special case bitblt from root window in
		 * IncludeInferiors mode; just like from a pixmap
		 */
		fastClip = 1;
	    } else if ((pSrcDrawable == pDstDrawable) &&
		(pGC->clientClipType == CT_NONE)) {
		prgnSrcClip = pGC->pCompositeClip;
	    } else {
		prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
		freeSrcClip = TRUE;
	    }
	} else {
	    prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
	}
    }

    fastBox.x1 = srcx;
    fastBox.y1 = srcy;
    fastBox.x2 = srcx + width;
    fastBox.y2 = srcy + height;

    /* Don't create a source region if we are doing a fast clip */
    if (fastClip) {
	fastExpose = 1;
	/*
	 * clip the source; if regions extend beyond the source size,
 	 * make sure exposure events get sent
	 */
	if (fastBox.x1 < pSrcDrawable->x) {
	    fastBox.x1 = pSrcDrawable->x;
	    fastExpose = 0;
	} 
	if (fastBox.y1 < pSrcDrawable->y) {
	    fastBox.y1 = pSrcDrawable->y;
	    fastExpose = 0;
	}
	if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) {
	    fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
	    fastExpose = 0;
	}
	if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) {
	    fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
	    fastExpose = 0;
	}
    } else {
	REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
	REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
    }

    dstx += pDstDrawable->x;
    dsty += pDstDrawable->y;

    if (pDstDrawable->type == DRAWABLE_WINDOW) {
	if (!((WindowPtr)pDstDrawable)->realized) {
	    if (!fastClip)
		REGION_UNINIT(pGC->pScreen, &rgnDst);
	    if (freeSrcClip)
		REGION_DESTROY(pGC->pScreen, prgnSrcClip);
	    return NULL;
	}
    }

    dx = srcx - dstx;
    dy = srcy - dsty;

    /* Translate and clip the dst to the destination composite clip */
    if (fastClip) {
	RegionPtr cclip;

        /* Translate the region directly */
        fastBox.x1 -= dx;
        fastBox.x2 -= dx;
        fastBox.y1 -= dy;
        fastBox.y2 -= dy;

	/* If the destination composite clip is one rectangle we can
	   do the clip directly.  Otherwise we have to create a full
	   blown region and call intersect */

	cclip = pGC->pCompositeClip;
        if (REGION_NUM_RECTS(cclip) == 1) {
	    BoxPtr pBox = REGION_RECTS(cclip);

	    if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
	    if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
	    if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
	    if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;

	    /* Check to see if the region is empty */
	    if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {
		REGION_NULL(pGC->pScreen, &rgnDst);
	    } else {
		REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
	    }
	} else {
	    /* We must turn off fastClip now, since we must create
	       a full blown region.  It is intersected with the
	       composite clip below. */
	    fastClip = 0;
	    REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
	}
    } else {
        REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
    }

    if (!fastClip) {
	REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
				 pGC->pCompositeClip);
    }

    /* Do bit blitting */
    numRects = REGION_NUM_RECTS(&rgnDst);
    if (numRects && width && height) {
	if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
						  sizeof(DDXPointRec)))) {
	    REGION_UNINIT(pGC->pScreen, &rgnDst);
	    if (freeSrcClip)
		REGION_DESTROY(pGC->pScreen, prgnSrcClip);
	    return NULL;
	}
	pbox = REGION_RECTS(&rgnDst);
	ppt = pptSrc;
	for (i = numRects; --i >= 0; pbox++, ppt++) {
	    ppt->x = pbox->x1 + dx;
	    ppt->y = pbox->y1 + dy;
	}

	(*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc);
	DEALLOCATE_LOCAL(pptSrc);
    }

    prgnExposed = NULL;
    if (pGC->fExpose) {
        /* Pixmap sources generate a NoExposed (we return NULL to do this) */
        if (!fastExpose)
	    prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
				  origSource.x, origSource.y,
				  (int)origSource.width,
				  (int)origSource.height,
				  origDest.x, origDest.y, bitPlane);
    }
    REGION_UNINIT(pGC->pScreen, &rgnDst);
    if (freeSrcClip)
	REGION_DESTROY(pGC->pScreen, prgnSrcClip);
    return prgnExposed;
}
示例#19
0
/*
 * Graft in the DoBitblt from cfb. It does everything correctly.
 */
static void
vga16DoBitblt
(
    DrawablePtr	    pSrc,
    DrawablePtr	    pDst,
    int		    alu,
    RegionPtr	    prgnDst,
    DDXPointPtr	    pptSrc,
    unsigned long   planemask
)
{
    int widthSrc, widthDst;	/* add to get to same position in next line */
    BoxPtr pbox;
    int nbox;
    BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
				/* temporaries for shuffling rectangles */
    DDXPointPtr pptTmp, pptNew1, pptNew2;
				/* shuffling boxes entails shuffling the
				   source points too */
    int w, h;
    int careful;

    widthSrc = cfbGetLongWidth(pSrc);
    widthDst = cfbGetLongWidth(pDst);

    /* 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 = ((pSrc == pDst) ||
	       ((pSrc->type == DRAWABLE_WINDOW) &&
		(pDst->type == DRAWABLE_WINDOW)));

    pbox = REGION_RECTS(prgnDst);
    nbox = REGION_NUM_RECTS(prgnDst);

    pboxNew1 = NULL;
    pptNew1 = NULL;
    pboxNew2 = NULL;
    pptNew2 = NULL;
    if (careful && (pptSrc->y < pbox->y1))
    {
        /* walk source botttom to top */
	widthSrc = -widthSrc;
	widthDst = -widthDst;

	if (nbox > 1)
	{
	    /* keep ordering in each band, reverse order of bands */
	    pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
	    if(!pboxNew1)
		return;
	    pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
	    if(!pptNew1)
	    {
	        DEALLOCATE_LOCAL(pboxNew1);
	        return;
	    }
	    pboxBase = pboxNext = pbox+nbox-1;
	    while (pboxBase >= pbox)
	    {
	        while ((pboxNext >= pbox) &&
		       (pboxBase->y1 == pboxNext->y1))
		    pboxNext--;
	        pboxTmp = pboxNext+1;
	        pptTmp = pptSrc + (pboxTmp - pbox);
	        while (pboxTmp <= pboxBase)
	        {
		    *pboxNew1++ = *pboxTmp++;
		    *pptNew1++ = *pptTmp++;
	        }
	        pboxBase = pboxNext;
	    }
	    pboxNew1 -= nbox;
	    pbox = pboxNew1;
	    pptNew1 -= nbox;
	    pptSrc = pptNew1;
        }
    }

    if (careful && (pptSrc->x < pbox->x1))
    {
	if (nbox > 1)
	{
	    /* reverse order of rects in each band */
	    pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
	    pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
	    if(!pboxNew2 || !pptNew2)
	    {
		if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
		if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
		if (pboxNew1)
		{
		    DEALLOCATE_LOCAL(pptNew1);
		    DEALLOCATE_LOCAL(pboxNew1);
		}
	        return;
	    }
	    pboxBase = pboxNext = pbox;
	    while (pboxBase < pbox+nbox)
	    {
	        while ((pboxNext < pbox+nbox) &&
		       (pboxNext->y1 == pboxBase->y1))
		    pboxNext++;
	        pboxTmp = pboxNext;
	        pptTmp = pptSrc + (pboxTmp - pbox);
	        while (pboxTmp != pboxBase)
	        {
		    *pboxNew2++ = *--pboxTmp;
		    *pptNew2++ = *--pptTmp;
	        }
	        pboxBase = pboxNext;
	    }
	    pboxNew2 -= nbox;
	    pbox = pboxNew2;
	    pptNew2 -= nbox;
	    pptSrc = pptNew2;
	}
    }

    while(nbox--)
    {
	w = pbox->x2 - pbox->x1;
	h = pbox->y2 - pbox->y1;
	
	if( pSrc->type == DRAWABLE_WINDOW )
		xf4bppBitBlt( (WindowPtr)pDst, alu, planemask,
			pptSrc->x,		/* x0 */
			pptSrc->y,		/* y0 */
			pbox->x1,		/* x1 */
			pbox->y1,		/* y1 */
			w, h );			/* w, h */
	    else /* DRAWABLE_PIXMAP */
		xf4bppDrawColorImage( (WindowPtr)pDst,
			pbox->x1, pbox->y1,
			w,
			h,
			((unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr
			 + pptSrc->x + (pptSrc->y*((PixmapPtr)pSrc)->devKind)),
			((PixmapPtr)pSrc)->devKind,
			alu, planemask ) ;
	pbox++;
	pptSrc++;
    }
    if (pboxNew2)
    {
	DEALLOCATE_LOCAL(pptNew2);
	DEALLOCATE_LOCAL(pboxNew2);
    }
    if (pboxNew1)
    {
	DEALLOCATE_LOCAL(pptNew1);
	DEALLOCATE_LOCAL(pboxNew1);
    }
}
示例#20
0
/*
 * Mirror the current mode configuration to RandR
 */
static Bool
xf86RandR12SetInfo12 (ScreenPtr pScreen)
{
    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
    RROutputPtr		*clones;
    RRCrtcPtr		*crtcs;
    int			ncrtc;
    int			o, c, l;
    RRCrtcPtr		randr_crtc;
    int			nclone;
    
    clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
    crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr));
    for (o = 0; o < config->num_output; o++)
    {
	xf86OutputPtr	output = config->output[o];
	
	ncrtc = 0;
	for (c = 0; c < config->num_crtc; c++)
	    if (output->possible_crtcs & (1 << c))
		crtcs[ncrtc++] = config->crtc[c]->randr_crtc;

	if (output->crtc)
	    randr_crtc = output->crtc->randr_crtc;
	else
	    randr_crtc = NULL;

	if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
	{
	    DEALLOCATE_LOCAL (crtcs);
	    DEALLOCATE_LOCAL (clones);
	    return FALSE;
	}

	RROutputSetPhysicalSize(output->randr_output, 
				output->mm_width,
				output->mm_height);
	xf86RROutputSetModes (output->randr_output, output->probed_modes);

	switch (output->status) {
	case XF86OutputStatusConnected:
	    RROutputSetConnection (output->randr_output, RR_Connected);
	    break;
	case XF86OutputStatusDisconnected:
	    RROutputSetConnection (output->randr_output, RR_Disconnected);
	    break;
	case XF86OutputStatusUnknown:
	    RROutputSetConnection (output->randr_output, RR_UnknownConnection);
	    break;
	}

	RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);

	/*
	 * Valid clones
	 */
	nclone = 0;
	for (l = 0; l < config->num_output; l++)
	{
	    xf86OutputPtr	    clone = config->output[l];
	    
	    if (l != o && (output->possible_clones & (1 << l)))
		clones[nclone++] = clone->randr_output;
	}
	if (!RROutputSetClones (output->randr_output, clones, nclone))
	{
	    DEALLOCATE_LOCAL (crtcs);
	    DEALLOCATE_LOCAL (clones);
	    return FALSE;
	}
    }
    DEALLOCATE_LOCAL (crtcs);
    DEALLOCATE_LOCAL (clones);
    return TRUE;
}
示例#21
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);
    }
}
示例#22
0
static Bool
xf86RandR12CrtcSet (ScreenPtr	pScreen,
		  RRCrtcPtr	randr_crtc,
		  RRModePtr	randr_mode,
		  int		x,
		  int		y,
		  Rotation	rotation,
		  int		num_randr_outputs,
		  RROutputPtr	*randr_outputs)
{
    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
    Bool		changed = FALSE;
    int			o, ro;
    xf86CrtcPtr		*save_crtcs;
    Bool		save_enabled = crtc->enabled;

    save_crtcs = ALLOCATE_LOCAL(config->num_output * sizeof (xf86CrtcPtr));
    if ((randr_mode != NULL) != crtc->enabled)
	changed = TRUE;
    else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
	changed = TRUE;
    
    if (rotation != crtc->rotation)
	changed = TRUE;

    if (x != crtc->x || y != crtc->y)
	changed = TRUE;
    for (o = 0; o < config->num_output; o++) 
    {
	xf86OutputPtr  output = config->output[o];
	xf86CrtcPtr    new_crtc;

	save_crtcs[o] = output->crtc;
	
	if (output->crtc == crtc)
	    new_crtc = NULL;
	else
	    new_crtc = output->crtc;
	for (ro = 0; ro < num_randr_outputs; ro++) 
	    if (output->randr_output == randr_outputs[ro])
	    {
		new_crtc = crtc;
		break;
	    }
	if (new_crtc != output->crtc)
	{
	    changed = TRUE;
	    output->crtc = new_crtc;
	}
    }
    for (ro = 0; ro < num_randr_outputs; ro++) 
        if (randr_outputs[ro]->pendingProperties)
	    changed = TRUE;

    /* XXX need device-independent mode setting code through an API */
    if (changed)
    {
	crtc->enabled = randr_mode != NULL;

	if (randr_mode)
	{
	    DisplayModeRec  mode;

	    xf86RandRModeConvert (pScrn, randr_mode, &mode);
	    if (!xf86CrtcSetMode (crtc, &mode, rotation, x, y))
	    {
		crtc->enabled = save_enabled;
		for (o = 0; o < config->num_output; o++)
		{
		    xf86OutputPtr	output = config->output[o];
		    output->crtc = save_crtcs[o];
		}
		DEALLOCATE_LOCAL(save_crtcs);
		return FALSE;
	    }
	    /*
	     * Save the last successful setting for EnterVT
	     */
	    crtc->desiredMode = mode;
	    crtc->desiredRotation = rotation;
	    crtc->desiredX = x;
	    crtc->desiredY = y;
	}
	xf86DisableUnusedFunctions (pScrn);
    }
    DEALLOCATE_LOCAL(save_crtcs);
    return xf86RandR12CrtcNotify (randr_crtc);
}
示例#23
0
static void
cfb8_32DoBitBlt(
    DrawablePtr	    pSrc, 
    DrawablePtr	    pDst,
    RegionPtr	    prgnDst,
    DDXPointPtr	    pptSrc,
    void	    (*DoBlt)() 
){
    int nbox, careful, SrcPitch, DstPitch;
    BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
    DDXPointPtr pptTmp, pptNew1, pptNew2;
    int xdir, ydir;
    unsigned char *SrcPtr, *DstPtr;

    /* 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 = ((pSrc == pDst) ||
               ((pSrc->type == DRAWABLE_WINDOW) &&
                (pDst->type == DRAWABLE_WINDOW)));

    pbox = REGION_RECTS(prgnDst);
    nbox = REGION_NUM_RECTS(prgnDst);

    pboxNew1 = NULL;
    pptNew1 = NULL;
    pboxNew2 = NULL;
    pptNew2 = NULL;
    if (careful && (pptSrc->y < pbox->y1)) {
        /* walk source botttom to top */
	ydir = -1;

	if (nbox > 1) {
	    /* keep ordering in each band, reverse order of bands */
	    pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
	    if(!pboxNew1)
		return;
	    pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
	    if(!pptNew1) {
	        DEALLOCATE_LOCAL(pboxNew1);
	        return;
	    }
	    pboxBase = pboxNext = pbox+nbox-1;
	    while (pboxBase >= pbox) {
	        while ((pboxNext >= pbox) &&
		       (pboxBase->y1 == pboxNext->y1))
		    pboxNext--;
	        pboxTmp = pboxNext+1;
	        pptTmp = pptSrc + (pboxTmp - pbox);
	        while (pboxTmp <= pboxBase) {
		    *pboxNew1++ = *pboxTmp++;
		    *pptNew1++ = *pptTmp++;
	        }
	        pboxBase = pboxNext;
	    }
	    pboxNew1 -= nbox;
	    pbox = pboxNew1;
	    pptNew1 -= nbox;
	    pptSrc = pptNew1;
        }
    } else {
	/* walk source top to bottom */
	ydir = 1;
    }

    if (careful && (pptSrc->x < pbox->x1)) {
	/* walk source right to left */
        xdir = -1;

	if (nbox > 1) {
	    /* reverse order of rects in each band */
	    pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
	    pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
	    if(!pboxNew2 || !pptNew2) {
		if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
		if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
		if (pboxNew1) {
		    DEALLOCATE_LOCAL(pptNew1);
		    DEALLOCATE_LOCAL(pboxNew1);
		}
	        return;
	    }
	    pboxBase = pboxNext = pbox;
	    while (pboxBase < pbox+nbox) {
	        while ((pboxNext < pbox+nbox) &&
		       (pboxNext->y1 == pboxBase->y1))
		    pboxNext++;
	        pboxTmp = pboxNext;
	        pptTmp = pptSrc + (pboxTmp - pbox);
	        while (pboxTmp != pboxBase) {
		    *pboxNew2++ = *--pboxTmp;
		    *pptNew2++ = *--pptTmp;
	        }
	        pboxBase = pboxNext;
	    }
	    pboxNew2 -= nbox;
	    pbox = pboxNew2;
	    pptNew2 -= nbox;
	    pptSrc = pptNew2;
	}
    } else {
	/* walk source left to right */
        xdir = 1;
    }

    cfbGetByteWidthAndPointer(pSrc, SrcPitch, SrcPtr);
    cfbGetByteWidthAndPointer(pDst, DstPitch, DstPtr);

    (*DoBlt)(SrcPtr,SrcPitch,DstPtr,DstPitch,nbox,pptSrc,pbox,xdir,ydir);
 
    if (pboxNew2) {
	DEALLOCATE_LOCAL(pptNew2);
	DEALLOCATE_LOCAL(pboxNew2);
    }
    if (pboxNew1) {
	DEALLOCATE_LOCAL(pptNew1);
	DEALLOCATE_LOCAL(pboxNew1);
    }

}
示例#24
0
void
miPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
	       unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase)
{
    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 */

    XID 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);
    if (!pPixmap)
	return;

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

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

    DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0);

    nbyLine = BitmapBytePad(width);
    pbits = (unsigned char *)ALLOCATE_LOCAL(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);

	    if ((pGC->serialNumber) != (pDrawable->serialNumber))
		ValidateGC(pDrawable, pGC);
	    (*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable,
			       gWidth, gHeight,
			       x + pci->metrics.leftSideBearing,
			       y - pci->metrics.ascent);
	}
	x += pci->metrics.characterWidth;
    }
    (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
    DEALLOCATE_LOCAL(pbits);
    FreeScratchGC(pGCtmp);
}
示例#25
0
ICEILTEMPDECL
#endif

/*
 *        Written by Todd Newman; April. 1987.
 *
 *        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 digital differencing analyzer
 *        line algorithm with y as the major axis. There's some funny linear
 *        interpolation involved because of the subpixel postioning.
 * 
 * count:               number of points
 * ptsIn:               the points
 * xTrans, yTrans:      Translate each point by this
 * xFtrans, yFtrans:    translate before conversion
 *                      by this amount.  This provides
 *                      a mechanism to match rounding
 *                      errors with any shape that must
 *                      meet the polygon exactly.
 */
void miFillSppPoly (PDC pdc, int count, SppPointPtr ptsIn, int xTrans, int yTrans, double xFtrans, double yFtrans)
{
    double          xl = 0, xr = 0, /* x vals of left and right edges */
                    ml = 0,         /* left edge slope */
                    mr = 0,         /* right edge slope */
                    dy,             /* delta y */
                    i;              /* loop counter */
    int             y,              /* current scanline */
                    j,
                    imin,           /* index of vertex with smallest y */
                    ymin,           /* y-extents of polygon */
                    ymax,
                    *Marked;        /* set if this vertex has been used */
    register int    left, right,    /* indices to first endpoints */
                    nextleft,
                    nextright;      /* indices to second endpoints */
    Span            *ptsOut, *FirstPoint;   /* output buffer */

    imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax);

    y = ymax - ymin + 1;
    if ((count < 3) || (y <= 0))
        return;

    ptsOut = FirstPoint = (Span*)ALLOCATE_LOCAL(sizeof(Span) * y);
    Marked = (int *) ALLOCATE_LOCAL(sizeof(int) * count);

    if(!ptsOut || !Marked)
    {
        if (Marked) DEALLOCATE_LOCAL(Marked);
        if (ptsOut) DEALLOCATE_LOCAL(ptsOut);
        return;
    }

    for(j = 0; j < count; j++)
        Marked[j] = 0;
    nextleft = nextright = imin;
    Marked[imin] = -1;
    y = ICEIL(ptsIn[nextleft].y + yFtrans);

    /*
     *  loop through all edges of the polygon
     */
    do
    {
        /* add a left edge if we need to */
        if ((y > (ptsIn[nextleft].y + yFtrans) ||
              ISEQUAL(y, ptsIn[nextleft].y + yFtrans)) &&
             Marked[nextleft] != 1)
        {
            Marked[nextleft]++;
            left = nextleft++;

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

            /* now compute the starting point and slope */
            dy = ptsIn[nextleft].y - ptsIn[left].y;
            if (dy != 0.0)
            { 
                ml = (ptsIn[nextleft].x - ptsIn[left].x) / dy;
                dy = y - (ptsIn[left].y + yFtrans);
                xl = (ptsIn[left].x + xFtrans) + ml * MAX(dy, 0); 
            }
        }

        /* add a right edge if we need to */
        if ((y > ptsIn[nextright].y + yFtrans) ||
              (ISEQUAL(y, ptsIn[nextright].y + yFtrans)
              && Marked[nextright] != 1))
        {
            Marked[nextright]++;
            right = nextright--;

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

            /* now compute the starting point and slope */
            dy = ptsIn[nextright].y - ptsIn[right].y;
            if (dy != 0.0) 
            { 
                mr = (ptsIn[nextright].x - ptsIn[right].x) / dy;
                dy = y - (ptsIn[right].y + yFtrans); 
                xr = (ptsIn[right].x + xFtrans) + mr * MAX(dy, 0);
            }
        }


        /*
         *  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) + yFtrans) - y;

        if (i < EPSILON)
        {
            if(Marked[nextleft] && Marked[nextright])
            {
                /* Arrgh, we're trapped! (no more points) 
                 * Out, we've got to get out of here before this decadence saps
                 * our will completely! */
                break;
            }
            continue;
        }
        else
        {
                j = (int) i;
                if(!j)
                    j++;
        }
        while (j > 0) 
        {
            int cxl, cxr;

            ptsOut->y = (y) + yTrans;

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

            /* increment down the edges */
            xl += ml;
            xr += mr;
            j--;
        }
    }  while (y <= ymax);

    /* Finally, fill the spans we've collected */
    _dc_fill_spans (pdc, FirstPoint, ptsOut-FirstPoint, FALSE);
    DEALLOCATE_LOCAL(Marked);
    DEALLOCATE_LOCAL(FirstPoint);
}
示例#26
0
static void
XAACopyWindow8_32(
    WindowPtr pWin,
    DDXPointRec ptOldOrg,
    RegionPtr prgnSrc
){
    DDXPointPtr pptSrc, ppt;
    RegionRec rgnDst;
    BoxPtr pbox;
    int dx, dy, nbox;
    WindowPtr pwinRoot;
    ScreenPtr pScreen = pWin->drawable.pScreen;
    XAAInfoRecPtr infoRec = 
	GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
    Bool doUnderlay = miOverlayCopyUnderlay(pScreen);
    RegionPtr borderClip = &pWin->borderClip;
    Bool freeReg = FALSE;

    if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt ||
	(infoRec->ScreenToScreenBitBltFlags & NO_PLANEMASK)) 
    { 
	XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
	if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
	    (*infoRec->Sync)(infoRec->pScrn);
	    infoRec->NeedToSync = FALSE;
	}
        (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
	XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow8_32);
    	return;
    }

    pwinRoot = WindowTable[pScreen->myNum];

    if(doUnderlay)
	freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip);

    REGION_NULL(pScreen, &rgnDst);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
    REGION_INTERSECT(pScreen, &rgnDst, borderClip, prgnSrc);

    pbox = REGION_RECTS(&rgnDst);
    nbox = REGION_NUM_RECTS(&rgnDst);
    if(!nbox || 
      !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
	REGION_UNINIT(pScreen, &rgnDst);
	return;
    }
    ppt = pptSrc;

    while(nbox--) {
	ppt->x = pbox->x1 + dx;
	ppt->y = pbox->y1 + dy;
	ppt++; pbox++;
    }
    
    infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000;
    infoRec->ScratchGC.alu = GXcopy;

    XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
        		&(infoRec->ScratchGC), &rgnDst, pptSrc);

    DEALLOCATE_LOCAL(pptSrc);
    REGION_UNINIT(pScreen, &rgnDst);
    if(freeReg) 
	REGION_DESTROY(pScreen, borderClip);
}
示例#27
0
void
cfb8_16CopyWindow(
    WindowPtr pWin,
    DDXPointRec ptOldOrg,
    RegionPtr prgnSrc
){
    ScreenPtr pScreen = pWin->drawable.pScreen;
    cfb8_16ScreenPtr pScreenPriv = 
		CFB8_16_GET_SCREEN_PRIVATE(pWin->drawable.pScreen);
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    DDXPointPtr ppt, pptSrc;
    RegionRec rgnDst;
    BoxPtr pbox;
    int i, nbox, dx, dy;
    WindowPtr pRoot = WindowTable[pScreen->myNum];

    REGION_INIT(pScreen, &rgnDst, NullBox, 0);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
    REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);

    nbox = REGION_NUM_RECTS(&rgnDst);
    if(nbox &&
	(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {

	pbox = REGION_RECTS(&rgnDst);
	for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
	    ppt->x = pbox->x1 + dx;
	    ppt->y = pbox->y1 + dy;
	}
	cfbDoBitbltCopy((DrawablePtr)pRoot, (DrawablePtr)pRoot,
                		GXcopy, &rgnDst, pptSrc, ~0L);
	if(pWin->drawable.bitsPerPixel == 16)
	    cfb16DoBitbltCopy((DrawablePtr)pScreenPriv->pix16, 
			      (DrawablePtr)pScreenPriv->pix16,
                		GXcopy, &rgnDst, pptSrc, ~0L);

	DEALLOCATE_LOCAL(pptSrc);
    }

    REGION_UNINIT(pScreen, &rgnDst);

    if(pWin->drawable.depth == 8) {
      REGION_INIT(pScreen, &rgnDst, NullBox, 0);
      miSegregateChildren(pWin, &rgnDst, pScrn->depth);
      if(REGION_NOTEMPTY(pScreen, &rgnDst)) {
	REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrc);
	nbox = REGION_NUM_RECTS(&rgnDst);
	if(nbox &&
	  (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))){

	    pbox = REGION_RECTS(&rgnDst);
	    for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
		ppt->x = pbox->x1 + dx;
		ppt->y = pbox->y1 + dy;
	    }

	    cfb16DoBitbltCopy((DrawablePtr)pScreenPriv->pix16, 
			      (DrawablePtr)pScreenPriv->pix16,
			      GXcopy, &rgnDst, pptSrc, ~0L);
	    DEALLOCATE_LOCAL(pptSrc);
	}
      }
      REGION_UNINIT(pScreen, &rgnDst);
    }
}
示例#28
0
文件: winwindow.c 项目: aosm/X11
void 
winCopyWindowNativeGDI (WindowPtr pWin,
			DDXPointRec ptOldOrg,
			RegionPtr prgnSrc)
{
  DDXPointPtr		pptSrc;
  DDXPointPtr		ppt;
  RegionPtr		prgnDst;
  BoxPtr		pBox;
  int			dx, dy;
  int			i, nbox;
  WindowPtr		pwinRoot;
  BoxPtr		pBoxDst;
  ScreenPtr		pScreen = pWin->drawable.pScreen;
  winScreenPriv(pScreen);

#if 0
  ErrorF ("winCopyWindow\n");
#endif

  /* Get a pointer to the root window */
  pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];

  /* Create a region for the destination */
  prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);

  /* Calculate the shift from the source to the destination */
  dx = ptOldOrg.x - pWin->drawable.x;
  dy = ptOldOrg.y - pWin->drawable.y;

  /* Translate the region from the destination to the source? */
  REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
  REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip,
		   prgnSrc);

  /* Get a pointer to the first box in the region to be copied */
  pBox = REGION_RECTS(prgnDst);
  
  /* Get the number of boxes in the region */
  nbox = REGION_NUM_RECTS(prgnDst);

  /* Allocate source points for each box */
  if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
    return;

  /* Set an iterator pointer */
  ppt = pptSrc;

  /* Calculate the source point of each box? */
  for (i = nbox; --i >= 0; ppt++, pBox++)
    {
      ppt->x = pBox->x1 + dx;
      ppt->y = pBox->y1 + dy;
    }

  /* Setup loop pointers again */
  pBoxDst = REGION_RECTS(prgnDst);
  ppt = pptSrc;

#if 0
  ErrorF ("winCopyWindow - x1\tx2\ty1\ty2\tx\ty\n");
#endif

  /* BitBlt each source to the destination point */
  for (i = nbox; --i >= 0; pBoxDst++, ppt++)
    {
#if 0
      ErrorF ("winCopyWindow - %d\t%d\t%d\t%d\t%d\t%d\n",
	      pBoxDst->x1, pBoxDst->x2, pBoxDst->y1, pBoxDst->y2,
	      ppt->x, ppt->y);
#endif

      BitBlt (pScreenPriv->hdcScreen,
	      pBoxDst->x1, pBoxDst->y1,
	      pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1,
	      pScreenPriv->hdcScreen,
	      ppt->x, ppt->y,
	      SRCCOPY);
    }

  /* Cleanup the regions, etc. */
  DEALLOCATE_LOCAL(pptSrc);
  REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
}
示例#29
0
void
cfb8_32WidCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
	ScreenPtr pScreen = pWin->drawable.pScreen;
	cfb8_32WidScreenPtr pScreenPriv = 
		CFB8_32WID_GET_SCREEN_PRIVATE(pScreen);
	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
	PixmapPtr pPixChildren;
	DDXPointPtr ppt, pptSrc;
	RegionRec rgnDst, rgnOther, rgnPixmap;
	BoxPtr pbox;
	int i, nbox, dx, dy, other_bpp;

	REGION_NULL(pScreen, &rgnDst);

	dx = ptOldOrg.x - pWin->drawable.x;
	dy = ptOldOrg.y - pWin->drawable.y;
	REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
	REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);

	if ((nbox = REGION_NUM_RECTS(&rgnDst)) == 0) {
		/* Nothing to render. */
		REGION_UNINIT(pScreen, &rgnDst);
		return;
	}

	/* First, copy the WID plane for the whole area. */
	pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec));
	if(pptSrc) {
		pbox = REGION_RECTS(&rgnDst);
		for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
			ppt->x = pbox->x1 + dx;
			ppt->y = pbox->y1 + dy;
		}

		pScreenPriv->WIDOps->WidCopyArea((DrawablePtr)pScreenPriv->pixWid,
						 &rgnDst, pptSrc);

		DEALLOCATE_LOCAL(pptSrc);
	}

	/* Next, we copy children which have a different
	 * bpp than pWin into a temporary pixmap.  We will
	 * toss this pixmap back onto the framebuffer before
	 * we return.
	 */
	if (pWin->drawable.bitsPerPixel == 8)
		other_bpp = pScrn->bitsPerPixel;
	else
		other_bpp = 8;

	REGION_NULL(pScreen, &rgnOther);
	SegregateChildrenBpp(pWin, &rgnOther, 0,
			     other_bpp, pWin->drawable.bitsPerPixel);
	pPixChildren = NULL;
	if (REGION_NOTEMPTY(pScreen, &rgnOther)) {
		REGION_INTERSECT(pScreen, &rgnOther, &rgnOther, prgnSrc);
		nbox = REGION_NUM_RECTS(&rgnOther);
		if (nbox) {
			int width = rgnOther.extents.x2 - rgnOther.extents.x1;
			int height = rgnOther.extents.y2 - rgnOther.extents.y1;
			int depth = (other_bpp == 8) ? 8 : pScrn->depth;

			if (other_bpp == 8)
				pPixChildren = cfbCreatePixmap(pScreen, width, height, depth);
			else
				pPixChildren = cfb32CreatePixmap(pScreen, width, height, depth);
		}
		if (nbox &&
		    pPixChildren &&
		    (pptSrc = (DDXPointPtr) ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
			pbox = REGION_RECTS(&rgnOther);
			for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
				ppt->x = pbox->x1 + dx;
				ppt->y = pbox->y1 + dy;
			}

			REGION_NULL(pScreen, &rgnPixmap);
			REGION_COPY(pScreen, &rgnPixmap, &rgnOther);
			REGION_TRANSLATE(pScreen, &rgnPixmap, -(rgnOther.extents.x1), -(rgnOther.extents.y1));

			if (other_bpp == 8)
				cfbDoBitbltCopy((DrawablePtr)pScreenPriv->pix8,
						(DrawablePtr)pPixChildren,
						GXcopy, &rgnPixmap, pptSrc, ~0L);
			else
				cfb32DoBitbltCopy((DrawablePtr)pScreenPriv->pix32,
						  (DrawablePtr)pPixChildren,
						  GXcopy, &rgnPixmap, pptSrc, ~0L);

			REGION_UNINIT(pScreen, &rgnPixmap);

			DEALLOCATE_LOCAL(pptSrc);
		}

		REGION_SUBTRACT(pScreen, &rgnDst, &rgnDst, &rgnOther);
	}

	/* Now copy the parent along with all child windows using the same depth. */
	nbox = REGION_NUM_RECTS(&rgnDst);
	if(nbox &&
	   (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
		pbox = REGION_RECTS(&rgnDst);
		for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
			ppt->x = pbox->x1 + dx;
			ppt->y = pbox->y1 + dy;
		}

		if (pWin->drawable.bitsPerPixel == 8)
			cfbDoBitbltCopy((DrawablePtr)pScreenPriv->pix8,
					(DrawablePtr)pScreenPriv->pix8,
					GXcopy, &rgnDst, pptSrc, ~0L);
		else
			cfb32DoBitbltCopy((DrawablePtr)pScreenPriv->pix32,
					  (DrawablePtr)pScreenPriv->pix32,
					  GXcopy, &rgnDst, pptSrc, ~0L);

		DEALLOCATE_LOCAL(pptSrc);
	}

	REGION_UNINIT(pScreen, &rgnDst);

	if (pPixChildren) {
		nbox = REGION_NUM_RECTS(&rgnOther);
		pptSrc = (DDXPointPtr) ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec));
		if (pptSrc) {
			pbox = REGION_RECTS(&rgnOther);
			for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
				ppt->x = pbox->x1 - rgnOther.extents.x1;
				ppt->y = pbox->y1 - rgnOther.extents.y1;
			}

			if (other_bpp == 8)
				cfbDoBitbltCopy((DrawablePtr)pPixChildren,
						(DrawablePtr)pScreenPriv->pix8,
						GXcopy, &rgnOther, pptSrc, ~0L);
			else
				cfb32DoBitbltCopy((DrawablePtr)pPixChildren,
						  (DrawablePtr)pScreenPriv->pix32,
						  GXcopy, &rgnOther, pptSrc, ~0L);

			DEALLOCATE_LOCAL(pptSrc);
		}

		if (other_bpp == 8)
			cfbDestroyPixmap(pPixChildren);
		else
			cfb32DestroyPixmap(pPixChildren);
	}
	REGION_UNINIT(pScreen, &rgnOther);
}
示例#30
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;
}