85
/* dixChangeGC(client, pGC, mask, pC32, pUnion)
87
* This function was created as part of the Security extension
88
* implementation. The client performing the gc change must be passed so
89
* that access checks can be performed on any tiles, stipples, or fonts
90
* that are specified. ddxen can call this too; they should normally
91
* pass NullClient for the client since any access checking should have
86
* ChangeGC/ChangeGCXIDs:
88
* The client performing the gc change must be passed so that access
89
* checks can be performed on any tiles, stipples, or fonts that are
90
* specified. ddxen can call this too; they should normally pass
91
* NullClient for the client since any access checking should have
92
92
* already been done at a higher level.
94
* Since we had to create a new function anyway, we decided to change the
95
* way the list of gc values is passed to eliminate the compiler warnings
96
* caused by the DoChangeGC interface. You can pass the values via pC32
97
* or pUnion, but not both; one of them must be NULL. If you don't need
98
* to pass any pointers, you can use either one:
94
* If you have any XIDs, you must use ChangeGCXIDs:
100
* example calling dixChangeGC using pC32 parameter
105
* dixChangeGC(client, pGC, GCForeground|GCBackground, v, NULL);
107
* example calling dixChangeGC using pUnion parameter;
108
* same effect as above
99
* ChangeGCXIDs(client, pGC, GCFillStyle|GCTile, v);
101
* However, if you need to pass a pointer to a pixmap or font, you must
105
* v[0].val = FillTiled;
106
* v[1].ptr = pPixmap;
107
* ChangeGC(client, pGC, GCFillStyle|GCTile, v);
109
* If you have neither XIDs nor pointers, you can use either function,
110
* but ChangeGC will do less work.
110
112
* ChangeGCVal v[2];
111
113
* v[0].val = foreground;
112
114
* v[1].val = background;
113
* dixChangeGC(client, pGC, GCForeground|GCBackground, NULL, v);
115
* However, if you need to pass a pointer to a pixmap or font, you MUST
116
* use the pUnion parameter.
118
* example calling dixChangeGC passing pointers in the value list
119
* v[1].ptr is a pointer to a pixmap
122
* v[0].val = FillTiled;
123
* v[1].ptr = pPixmap;
124
* dixChangeGC(client, pGC, GCFillStyle|GCTile, NULL, v);
126
* Note: we could have gotten by with just the pUnion parameter, but on
127
* 64 bit machines that would have forced us to copy the value list that
128
* comes in the ChangeGC request.
130
* Ideally, we'd change all the DoChangeGC calls to dixChangeGC, but this
131
* is far too many changes to consider at this time, so we've only
132
* changed the ones that caused compiler warnings. New code should use
115
* ChangeGC(client, pGC, GCForeground|GCBackground, v);
138
118
#define NEXTVAL(_type, _var) { \
139
if (pC32) _var = (_type)*pC32++; \
141
119
_var = (_type)(pUnion->val); pUnion++; \
145
122
#define NEXT_PTR(_type, _var) { \
146
assert(pUnion); _var = (_type)pUnion->ptr; pUnion++; }
123
_var = (_type)pUnion->ptr; pUnion++; }
149
dixChangeGC(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion)
126
ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion)
153
130
PixmapPtr pPixmap;
156
assert( (pC32 && !pUnion) || (!pC32 && pUnion) );
157
134
pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
159
136
maskQ = mask; /* save these for when we walk the GCque */
257
239
pGC->fillRule = newfillrule;
260
clientErrorValue = newfillrule;
243
client->errorValue = newfillrule;
261
244
error = BadValue;
270
NEXT_PTR(PixmapPtr, pPixmap);
275
NEXTVAL(XID, newpix);
276
rc = dixLookupResourceByType((pointer *)&pPixmap, newpix,
277
RT_PIXMAP, client, DixReadAccess);
281
if ((pPixmap->drawable.depth != pGC->depth) ||
282
(pPixmap->drawable.pScreen != pGC->pScreen))
289
if (!pGC->tileIsPixel)
290
(* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
291
pGC->tileIsPixel = FALSE;
292
pGC->tile.pixmap = pPixmap;
297
clientErrorValue = newpix;
298
error = (rc == BadValue) ? BadPixmap : rc;
249
NEXT_PTR(PixmapPtr, pPixmap);
250
if ((pPixmap->drawable.depth != pGC->depth) ||
251
(pPixmap->drawable.pScreen != pGC->pScreen))
258
if (!pGC->tileIsPixel)
259
(* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
260
pGC->tileIsPixel = FALSE;
261
pGC->tile.pixmap = pPixmap;
307
NEXT_PTR(PixmapPtr, pPixmap);
312
NEXTVAL(XID, newstipple)
313
rc = dixLookupResourceByType((pointer *)&pPixmap, newstipple,
314
RT_PIXMAP, client, DixReadAccess);
318
if ((pPixmap->drawable.depth != 1) ||
319
(pPixmap->drawable.pScreen != pGC->pScreen))
327
(* pGC->pScreen->DestroyPixmap)(pGC->stipple);
328
pGC->stipple = pPixmap;
333
clientErrorValue = newstipple;
334
error = (rc == BadValue) ? BadPixmap : rc;
265
NEXT_PTR(PixmapPtr, pPixmap);
266
if ((pPixmap->drawable.depth != 1) ||
267
(pPixmap->drawable.pScreen != pGC->pScreen))
275
(* pGC->pScreen->DestroyPixmap)(pGC->stipple);
276
pGC->stipple = pPixmap;
338
279
case GCTileStipXOrigin:
339
280
NEXTVAL(INT16, pGC->patOrg.x);
403
327
NEXTVAL(INT16, pGC->clipOrg.y);
412
NEXT_PTR(PixmapPtr, pPixmap);
420
pPixmap = NullPixmap;
423
rc = dixLookupResourceByType((pointer *)&pPixmap, pid,
427
clientErrorValue = pid;
428
error = (rc == BadValue) ? BadPixmap : rc;
330
NEXT_PTR(PixmapPtr, pPixmap);
435
333
if ((pPixmap->drawable.depth != 1) ||
436
334
(pPixmap->drawable.pScreen != pGC->pScreen))
438
336
error = BadMatch;
442
clipType = CT_PIXMAP;
448
(*pGC->funcs->ChangeClip)(pGC, clipType,
449
(pointer)pPixmap, 0);
341
(*pGC->funcs->ChangeClip)(pGC, pPixmap ? CT_PIXMAP : CT_NONE,
342
(pointer)pPixmap, 0);
453
344
case GCDashOffset:
454
345
NEXTVAL(INT16, pGC->dashOffset);
528
/* Publically defined entry to ChangeGC. Just calls dixChangeGC and tells
529
* it that all of the entries are constants or IDs */
531
ChangeGC(GC *pGC, BITS32 mask, XID *pval)
533
return (dixChangeGC(NullClient, pGC, mask, pval, NULL));
536
/* DoChangeGC(pGC, mask, pval, fPointer)
537
mask is a set of bits indicating which values to change.
538
pval contains an appropriate value for each mask.
539
fPointer is true if the values for tiles, stipples, fonts or clipmasks
540
are pointers instead of IDs. Note: if you are passing pointers you
541
MUST declare the array of values as type pointer! Other data types
542
may not be large enough to hold pointers on some machines. Yes,
543
this means you have to cast to (XID *) when you pass the array to
544
DoChangeGC. Similarly, if you are not passing pointers (fPointer = 0) you
545
MUST declare the array as type XID (not unsigned long!), or again the wrong
546
size data type may be used. To avoid this cruftiness, use dixChangeGC
549
if there is an error, the value is marked as changed
550
anyway, which is probably wrong, but infrequent.
553
all values sent over the protocol for ChangeGC requests are
557
DoChangeGC(GC *pGC, BITS32 mask, XID *pval, int fPointer)
560
/* XXX might be a problem on 64 bit big-endian servers */
561
return dixChangeGC(NullClient, pGC, mask, NULL, (ChangeGCValPtr)pval);
563
return dixChangeGC(NullClient, pGC, mask, pval, NULL);
422
static const struct {
427
{ GCTile, RT_PIXMAP, DixReadAccess },
428
{ GCStipple, RT_PIXMAP, DixReadAccess },
429
{ GCFont, RT_FONT, DixUseAccess },
430
{ GCClipMask, RT_PIXMAP, DixReadAccess },
434
ChangeGCXIDs(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32)
436
ChangeGCVal vals[GCLastBit + 1];
438
if (mask & ~GCAllBits)
440
client->errorValue = mask;
443
for (i = Ones(mask); i--; )
444
vals[i].val = pC32[i];
445
for (i = 0; i < sizeof(xidfields) / sizeof(*xidfields); ++i)
448
if (!(mask & xidfields[i].mask))
450
offset = Ones(mask & (xidfields[i].mask - 1));
451
if (xidfields[i].mask == GCClipMask && vals[offset].val == None)
453
vals[offset].ptr = NullPixmap;
456
rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val,
457
xidfields[i].type, client, xidfields[i].access_mode);
460
client->errorValue = vals[offset].val;
464
return ChangeGC(client, pGC, mask, vals);
567
467
/* CreateGC(pDrawable, mask, pval, pStatus)
568
468
creates a default GC for the given drawable, using mask to fill
637
536
pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
638
537
pGC->stipple->refcnt++;
539
/* this is not a scratch GC */
540
pGC->scratch_inuse = FALSE;
640
542
/* security creation/labeling check */
641
543
*pStatus = XaceHook(XACE_RESOURCE_ACCESS, client, gcid, RT_GC, pGC,
642
544
RT_NONE, NULL, DixCreateAccess|DixSetAttrAccess);
643
545
if (*pStatus != Success)
646
pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
548
pGC->stateChanges = GCAllBits;
647
549
if (!(*pGC->pScreen->CreateGC)(pGC))
648
550
*pStatus = BadAlloc;
650
*pStatus = ChangeGC(pGC, mask, pval);
552
*pStatus = ChangeGCXIDs(client, pGC, mask, pval);
652
554
*pStatus = Success;
1023
924
(*pScreen->CreatePixmap)(pScreen, w, h, 1, 0)))
1025
926
/* fill stipple with 1 */
1026
tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
927
tmpval[0].val = GXcopy;
929
tmpval[2].val = FillSolid;
1027
930
pgcScratch = GetScratchGC(1, pScreen);
1028
931
if (!pgcScratch)
1030
933
(*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
1033
(void)ChangeGC(pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
936
(void)ChangeGC(NullClient, pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
1034
937
ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);