Bug Summary

File:dix/gc.c
Location:line 929, column 13
Description:Call to 'malloc' has an allocation size of 0 bytes

Annotated Source Code

1/***********************************************************
2
3Copyright 1987, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
26
27 All Rights Reserved
28
29Permission to use, copy, modify, and distribute this software and its
30documentation for any purpose and without fee is hereby granted,
31provided that the above copyright notice appear in all copies and that
32both that copyright notice and this permission notice appear in
33supporting documentation, and that the name of Digital not be
34used in advertising or publicity pertaining to distribution of the
35software without specific, written prior permission.
36
37DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43SOFTWARE.
44
45******************************************************************/
46
47#ifdef HAVE_DIX_CONFIG_H1
48#include <dix-config.h>
49#endif
50
51#include <X11/X.h>
52#include <X11/Xmd.h>
53#include <X11/Xproto.h>
54#include "misc.h"
55#include "resource.h"
56#include "gcstruct.h"
57#include "pixmapstr.h"
58#include "dixfontstr.h"
59#include "scrnintstr.h"
60#include "region.h"
61#include "dixstruct.h"
62
63#include "privates.h"
64#include "dix.h"
65#include "xace.h"
66#include <assert.h>
67
68extern FontPtr defaultFont;
69
70static Bool CreateDefaultTile(GCPtr pGC);
71
72static unsigned char DefaultDash[2] = { 4, 4 };
73
74void
75ValidateGC(DrawablePtr pDraw, GC * pGC)
76{
77 (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
78 pGC->stateChanges = 0;
79 pGC->serialNumber = pDraw->serialNumber;
80}
81
82/*
83 * ChangeGC/ChangeGCXIDs:
84 *
85 * The client performing the gc change must be passed so that access
86 * checks can be performed on any tiles, stipples, or fonts that are
87 * specified. ddxen can call this too; they should normally pass
88 * NullClient for the client since any access checking should have
89 * already been done at a higher level.
90 *
91 * If you have any XIDs, you must use ChangeGCXIDs:
92 *
93 * CARD32 v[2];
94 * v[0] = FillTiled;
95 * v[1] = pid;
96 * ChangeGCXIDs(client, pGC, GCFillStyle|GCTile, v);
97 *
98 * However, if you need to pass a pointer to a pixmap or font, you must
99 * use ChangeGC:
100 *
101 * ChangeGCVal v[2];
102 * v[0].val = FillTiled;
103 * v[1].ptr = pPixmap;
104 * ChangeGC(client, pGC, GCFillStyle|GCTile, v);
105 *
106 * If you have neither XIDs nor pointers, you can use either function,
107 * but ChangeGC will do less work.
108 *
109 * ChangeGCVal v[2];
110 * v[0].val = foreground;
111 * v[1].val = background;
112 * ChangeGC(client, pGC, GCForeground|GCBackground, v);
113 */
114
115#define NEXTVAL(_type, _var) { \
116 _var = (_type)(pUnion->val); pUnion++; \
117 }
118
119#define NEXT_PTR(_type, _var) { \
120 _var = (_type)pUnion->ptr; pUnion++; }
121
122int
123ChangeGC(ClientPtr client, GC * pGC, BITS32 mask, ChangeGCValPtr pUnion)
124{
125 BITS32 index2;
126 int error = 0;
127 PixmapPtr pPixmap;
128 BITS32 maskQ;
129
130 assert(pUnion)(__builtin_expect(!(pUnion), 0) ? __assert_rtn(__func__, "gc.c"
, 130, "pUnion") : (void)0)
;
131 pGC->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
132
133 maskQ = mask; /* save these for when we walk the GCque */
134 while (mask && !error) {
135 index2 = (BITS32) lowbit(mask)((mask) & (~(mask) + 1));
136 mask &= ~index2;
137 pGC->stateChanges |= index2;
138 switch (index2) {
139 case GCFunction(1L<<0):
140 {
141 CARD8 newalu;
142 NEXTVAL(CARD8, newalu);
143
144 if (newalu <= GXset0xf)
145 pGC->alu = newalu;
146 else {
147 if (client)
148 client->errorValue = newalu;
149 error = BadValue2;
150 }
151 break;
152 }
153 case GCPlaneMask(1L<<1):
154 NEXTVAL(unsigned long, pGC->planemask);
155
156 break;
157 case GCForeground(1L<<2):
158 NEXTVAL(unsigned long, pGC->fgPixel);
159
160 /*
161 * this is for CreateGC
162 */
163 if (!pGC->tileIsPixel && !pGC->tile.pixmap) {
164 pGC->tileIsPixel = TRUE1;
165 pGC->tile.pixel = pGC->fgPixel;
166 }
167 break;
168 case GCBackground(1L<<3):
169 NEXTVAL(unsigned long, pGC->bgPixel);
170
171 break;
172 case GCLineWidth(1L<<4): /* ??? line width is a CARD16 */
173 NEXTVAL(CARD16, pGC->lineWidth);
174
175 break;
176 case GCLineStyle(1L<<5):
177 {
178 unsigned int newlinestyle;
179 NEXTVAL(unsigned int, newlinestyle);
180
181 if (newlinestyle <= LineDoubleDash2)
182 pGC->lineStyle = newlinestyle;
183 else {
184 if (client)
185 client->errorValue = newlinestyle;
186 error = BadValue2;
187 }
188 break;
189 }
190 case GCCapStyle(1L<<6):
191 {
192 unsigned int newcapstyle;
193 NEXTVAL(unsigned int, newcapstyle);
194
195 if (newcapstyle <= CapProjecting3)
196 pGC->capStyle = newcapstyle;
197 else {
198 if (client)
199 client->errorValue = newcapstyle;
200 error = BadValue2;
201 }
202 break;
203 }
204 case GCJoinStyle(1L<<7):
205 {
206 unsigned int newjoinstyle;
207 NEXTVAL(unsigned int, newjoinstyle);
208
209 if (newjoinstyle <= JoinBevel2)
210 pGC->joinStyle = newjoinstyle;
211 else {
212 if (client)
213 client->errorValue = newjoinstyle;
214 error = BadValue2;
215 }
216 break;
217 }
218 case GCFillStyle(1L<<8):
219 {
220 unsigned int newfillstyle;
221 NEXTVAL(unsigned int, newfillstyle);
222
223 if (newfillstyle <= FillOpaqueStippled3)
224 pGC->fillStyle = newfillstyle;
225 else {
226 if (client)
227 client->errorValue = newfillstyle;
228 error = BadValue2;
229 }
230 break;
231 }
232 case GCFillRule(1L<<9):
233 {
234 unsigned int newfillrule;
235 NEXTVAL(unsigned int, newfillrule);
236
237 if (newfillrule <= WindingRule1)
238 pGC->fillRule = newfillrule;
239 else {
240 if (client)
241 client->errorValue = newfillrule;
242 error = BadValue2;
243 }
244 break;
245 }
246 case GCTile(1L<<10):
247 NEXT_PTR(PixmapPtr, pPixmap);
248
249 if ((pPixmap->drawable.depth != pGC->depth) ||
250 (pPixmap->drawable.pScreen != pGC->pScreen)) {
251 error = BadMatch8;
252 }
253 else {
254 pPixmap->refcnt++;
255 if (!pGC->tileIsPixel)
256 (*pGC->pScreen->DestroyPixmap) (pGC->tile.pixmap);
257 pGC->tileIsPixel = FALSE0;
258 pGC->tile.pixmap = pPixmap;
259 }
260 break;
261 case GCStipple(1L<<11):
262 NEXT_PTR(PixmapPtr, pPixmap);
263
264 if (pPixmap && ((pPixmap->drawable.depth != 1) ||
265 (pPixmap->drawable.pScreen != pGC->pScreen)))
266 {
267 error = BadMatch8;
268 }
269 else {
270 if (pPixmap)
271 pPixmap->refcnt++;
272 if (pGC->stipple)
273 (*pGC->pScreen->DestroyPixmap) (pGC->stipple);
274 pGC->stipple = pPixmap;
275 }
276 break;
277 case GCTileStipXOrigin(1L<<12):
278 NEXTVAL(INT16, pGC->patOrg.x);
279
280 break;
281 case GCTileStipYOrigin(1L<<13):
282 NEXTVAL(INT16, pGC->patOrg.y);
283
284 break;
285 case GCFont(1L<<14):
286 {
287 FontPtr pFont;
288 NEXT_PTR(FontPtr, pFont);
289
290 pFont->refcnt++;
291 if (pGC->font)
292 CloseFont(pGC->font, (Font) 0);
293 pGC->font = pFont;
294 break;
295 }
296 case GCSubwindowMode(1L<<15):
297 {
298 unsigned int newclipmode;
299 NEXTVAL(unsigned int, newclipmode);
300
301 if (newclipmode <= IncludeInferiors1)
302 pGC->subWindowMode = newclipmode;
303 else {
304 if (client)
305 client->errorValue = newclipmode;
306 error = BadValue2;
307 }
308 break;
309 }
310 case GCGraphicsExposures(1L<<16):
311 {
312 unsigned int newge;
313 NEXTVAL(unsigned int, newge);
314
315 if (newge <= xTrue1)
316 pGC->graphicsExposures = newge;
317 else {
318 if (client)
319 client->errorValue = newge;
320 error = BadValue2;
321 }
322 break;
323 }
324 case GCClipXOrigin(1L<<17):
325 NEXTVAL(INT16, pGC->clipOrg.x);
326
327 break;
328 case GCClipYOrigin(1L<<18):
329 NEXTVAL(INT16, pGC->clipOrg.y);
330
331 break;
332 case GCClipMask(1L<<19):
333 NEXT_PTR(PixmapPtr, pPixmap);
334
335 if (pPixmap) {
336 if ((pPixmap->drawable.depth != 1) ||
337 (pPixmap->drawable.pScreen != pGC->pScreen)) {
338 error = BadMatch8;
339 break;
340 }
341 pPixmap->refcnt++;
342 }
343 (*pGC->funcs->ChangeClip) (pGC, pPixmap ? CT_PIXMAP1 : CT_NONE0,
344 (void *) pPixmap, 0);
345 break;
346 case GCDashOffset(1L<<20):
347 NEXTVAL(INT16, pGC->dashOffset);
348
349 break;
350 case GCDashList(1L<<21):
351 {
352 CARD8 newdash;
353 NEXTVAL(CARD8, newdash);
354
355 if (newdash == 4) {
356 if (pGC->dash != DefaultDash) {
357 free(pGC->dash);
358 pGC->numInDashList = 2;
359 pGC->dash = DefaultDash;
360 }
361 }
362 else if (newdash != 0) {
363 unsigned char *dash;
364
365 dash = malloc(2 * sizeof(unsigned char));
366 if (dash) {
367 if (pGC->dash != DefaultDash)
368 free(pGC->dash);
369 pGC->numInDashList = 2;
370 pGC->dash = dash;
371 dash[0] = newdash;
372 dash[1] = newdash;
373 }
374 else
375 error = BadAlloc11;
376 }
377 else {
378 if (client)
379 client->errorValue = newdash;
380 error = BadValue2;
381 }
382 break;
383 }
384 case GCArcMode(1L<<22):
385 {
386 unsigned int newarcmode;
387 NEXTVAL(unsigned int, newarcmode);
388
389 if (newarcmode <= ArcPieSlice1)
390 pGC->arcMode = newarcmode;
391 else {
392 if (client)
393 client->errorValue = newarcmode;
394 error = BadValue2;
395 }
396 break;
397 }
398 default:
399 if (client)
400 client->errorValue = maskQ;
401 error = BadValue2;
402 break;
403 }
404 } /* end while mask && !error */
405
406 if (pGC->fillStyle == FillTiled1 && pGC->tileIsPixel) {
407 if (!CreateDefaultTile(pGC)) {
408 pGC->fillStyle = FillSolid0;
409 error = BadAlloc11;
410 }
411 }
412 (*pGC->funcs->ChangeGC) (pGC, maskQ);
413 return error;
414}
415
416#undef NEXTVAL
417#undef NEXT_PTR
418
419static const struct {
420 BITS32 mask;
421 RESTYPE type;
422 Mask access_mode;
423} xidfields[] = {
424 {GCTile(1L<<10), RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), DixReadAccess(1<<0)},
425 {GCStipple(1L<<11), RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), DixReadAccess(1<<0)},
426 {GCFont(1L<<14), RT_FONT((RESTYPE)4), DixUseAccess(1<<24)},
427 {GCClipMask(1L<<19), RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), DixReadAccess(1<<0)},
428};
429
430int
431ChangeGCXIDs(ClientPtr client, GC * pGC, BITS32 mask, CARD32 *pC32)
432{
433 ChangeGCVal vals[GCLastBit22 + 1];
434 int i;
435
436 if (mask & ~GCAllBits((1 << (22 + 1)) - 1)) {
437 client->errorValue = mask;
438 return BadValue2;
439 }
440 for (i = Ones(mask); i--;)
441 vals[i].val = pC32[i];
442 for (i = 0; i < sizeof(xidfields) / sizeof(*xidfields); ++i) {
443 int offset, rc;
444
445 if (!(mask & xidfields[i].mask))
446 continue;
447 offset = Ones(mask & (xidfields[i].mask - 1));
448 if (xidfields[i].mask == GCClipMask(1L<<19) && vals[offset].val == None0L) {
449 vals[offset].ptr = NullPixmap((PixmapPtr)0);
450 continue;
451 }
452 rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val,
453 xidfields[i].type, client,
454 xidfields[i].access_mode);
455 if (rc != Success0) {
456 client->errorValue = vals[offset].val;
457 return rc;
458 }
459 }
460 return ChangeGC(client, pGC, mask, vals);
461}
462
463static GCPtr
464NewGCObject(ScreenPtr pScreen, int depth)
465{
466 GCPtr pGC;
467
468 pGC = dixAllocateScreenObjectWithPrivates(pScreen, GC, PRIVATE_GC)_dixAllocateScreenObjectWithPrivates(pScreen, sizeof(GC), sizeof
(GC), __builtin_offsetof(GC, devPrivates), PRIVATE_GC)
;
469 if (!pGC) {
470 return (GCPtr) NULL((void*)0);
471 }
472
473 pGC->pScreen = pScreen;
474 pGC->depth = depth;
475 pGC->alu = GXcopy0x3; /* dst <- src */
476 pGC->planemask = ~0;
477 pGC->serialNumber = 0;
478 pGC->funcs = 0;
479 pGC->fgPixel = 0;
480 pGC->bgPixel = 1;
481 pGC->lineWidth = 0;
482 pGC->lineStyle = LineSolid0;
483 pGC->capStyle = CapButt1;
484 pGC->joinStyle = JoinMiter0;
485 pGC->fillStyle = FillSolid0;
486 pGC->fillRule = EvenOddRule0;
487 pGC->arcMode = ArcPieSlice1;
488 pGC->tile.pixel = 0;
489 pGC->tile.pixmap = NullPixmap((PixmapPtr)0);
490
491 pGC->tileIsPixel = TRUE1;
492 pGC->patOrg.x = 0;
493 pGC->patOrg.y = 0;
494 pGC->subWindowMode = ClipByChildren0;
495 pGC->graphicsExposures = TRUE1;
496 pGC->clipOrg.x = 0;
497 pGC->clipOrg.y = 0;
498 pGC->clientClip = (void *) NULL((void*)0);
499 pGC->numInDashList = 2;
500 pGC->dash = DefaultDash;
501 pGC->dashOffset = 0;
502
503 /* use the default font and stipple */
504 pGC->font = defaultFont;
505 if (pGC->font) /* necessary, because open of default font could fail */
506 pGC->font->refcnt++;
507 pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
508 if (pGC->stipple)
509 pGC->stipple->refcnt++;
510
511 /* this is not a scratch GC */
512 pGC->scratch_inuse = FALSE0;
513 return pGC;
514}
515
516/* CreateGC(pDrawable, mask, pval, pStatus)
517 creates a default GC for the given drawable, using mask to fill
518 in any non-default values.
519 Returns a pointer to the new GC on success, NULL otherwise.
520 returns status of non-default fields in pStatus
521BUG:
522 should check for failure to create default tile
523
524*/
525GCPtr
526CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus,
527 XID gcid, ClientPtr client)
528{
529 GCPtr pGC;
530
531 pGC = NewGCObject(pDrawable->pScreen, pDrawable->depth);
532 if (!pGC) {
533 *pStatus = BadAlloc11;
534 return (GCPtr) NULL((void*)0);
535 }
536
537 pGC->serialNumber = GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
538 if (mask & GCForeground(1L<<2)) {
539 /*
540 * magic special case -- ChangeGC checks for this condition
541 * and snags the Foreground value to create a pseudo default-tile
542 */
543 pGC->tileIsPixel = FALSE0;
544 }
545 else {
546 pGC->tileIsPixel = TRUE1;
547 }
548
549 /* security creation/labeling check */
550 *pStatus = XaceHook(XACE_RESOURCE_ACCESS2, client, gcid, RT_GC((RESTYPE)3), pGC,
551 RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3) | DixSetAttrAccess(1<<5));
552 if (*pStatus != Success0)
553 goto out;
554
555 pGC->stateChanges = GCAllBits((1 << (22 + 1)) - 1);
556 if (!(*pGC->pScreen->CreateGC) (pGC))
557 *pStatus = BadAlloc11;
558 else if (mask)
559 *pStatus = ChangeGCXIDs(client, pGC, mask, pval);
560 else
561 *pStatus = Success0;
562
563 out:
564 if (*pStatus != Success0) {
565 if (!pGC->tileIsPixel && !pGC->tile.pixmap)
566 pGC->tileIsPixel = TRUE1; /* undo special case */
567 FreeGC(pGC, (XID) 0);
568 pGC = (GCPtr) NULL((void*)0);
569 }
570
571 return pGC;
572}
573
574static Bool
575CreateDefaultTile(GCPtr pGC)
576{
577 ChangeGCVal tmpval[3];
578 PixmapPtr pTile;
579 GCPtr pgcScratch;
580 xRectangle rect;
581 CARD16 w, h;
582
583 w = 1;
584 h = 1;
585 (*pGC->pScreen->QueryBestSize) (TileShape1, &w, &h, pGC->pScreen);
586 pTile = (PixmapPtr)
587 (*pGC->pScreen->CreatePixmap) (pGC->pScreen, w, h, pGC->depth, 0);
588 pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
589 if (!pTile || !pgcScratch) {
590 if (pTile)
591 (*pTile->drawable.pScreen->DestroyPixmap) (pTile);
592 if (pgcScratch)
593 FreeScratchGC(pgcScratch);
594 return FALSE0;
595 }
596 tmpval[0].val = GXcopy0x3;
597 tmpval[1].val = pGC->tile.pixel;
598 tmpval[2].val = FillSolid0;
599 (void) ChangeGC(NullClient((ClientPtr) 0), pgcScratch,
600 GCFunction(1L<<0) | GCForeground(1L<<2) | GCFillStyle(1L<<8), tmpval);
601 ValidateGC((DrawablePtr) pTile, pgcScratch);
602 rect.x = 0;
603 rect.y = 0;
604 rect.width = w;
605 rect.height = h;
606 (*pgcScratch->ops->PolyFillRect) ((DrawablePtr) pTile, pgcScratch, 1,
607 &rect);
608 /* Always remember to free the scratch graphics context after use. */
609 FreeScratchGC(pgcScratch);
610
611 pGC->tileIsPixel = FALSE0;
612 pGC->tile.pixmap = pTile;
613 return TRUE1;
614}
615
616int
617CopyGC(GC * pgcSrc, GC * pgcDst, BITS32 mask)
618{
619 BITS32 index2;
620 BITS32 maskQ;
621 int error = 0;
622
623 if (pgcSrc == pgcDst)
624 return Success0;
625 pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
626 pgcDst->stateChanges |= mask;
627 maskQ = mask;
628 while (mask) {
629 index2 = (BITS32) lowbit(mask)((mask) & (~(mask) + 1));
630 mask &= ~index2;
631 switch (index2) {
632 case GCFunction(1L<<0):
633 pgcDst->alu = pgcSrc->alu;
634 break;
635 case GCPlaneMask(1L<<1):
636 pgcDst->planemask = pgcSrc->planemask;
637 break;
638 case GCForeground(1L<<2):
639 pgcDst->fgPixel = pgcSrc->fgPixel;
640 break;
641 case GCBackground(1L<<3):
642 pgcDst->bgPixel = pgcSrc->bgPixel;
643 break;
644 case GCLineWidth(1L<<4):
645 pgcDst->lineWidth = pgcSrc->lineWidth;
646 break;
647 case GCLineStyle(1L<<5):
648 pgcDst->lineStyle = pgcSrc->lineStyle;
649 break;
650 case GCCapStyle(1L<<6):
651 pgcDst->capStyle = pgcSrc->capStyle;
652 break;
653 case GCJoinStyle(1L<<7):
654 pgcDst->joinStyle = pgcSrc->joinStyle;
655 break;
656 case GCFillStyle(1L<<8):
657 pgcDst->fillStyle = pgcSrc->fillStyle;
658 break;
659 case GCFillRule(1L<<9):
660 pgcDst->fillRule = pgcSrc->fillRule;
661 break;
662 case GCTile(1L<<10):
663 {
664 if (EqualPixUnion(pgcDst->tileIsPixel,((pgcDst->tileIsPixel) == (pgcSrc->tileIsPixel) &&
(((pgcDst->tileIsPixel) ? (pgcDst->tile).pixel == (pgcSrc
->tile).pixel : (pgcDst->tile).pixmap == (pgcSrc->tile
).pixmap)))
665 pgcDst->tile,((pgcDst->tileIsPixel) == (pgcSrc->tileIsPixel) &&
(((pgcDst->tileIsPixel) ? (pgcDst->tile).pixel == (pgcSrc
->tile).pixel : (pgcDst->tile).pixmap == (pgcSrc->tile
).pixmap)))
666 pgcSrc->tileIsPixel, pgcSrc->tile)((pgcDst->tileIsPixel) == (pgcSrc->tileIsPixel) &&
(((pgcDst->tileIsPixel) ? (pgcDst->tile).pixel == (pgcSrc
->tile).pixel : (pgcDst->tile).pixmap == (pgcSrc->tile
).pixmap)))
) {
667 break;
668 }
669 if (!pgcDst->tileIsPixel)
670 (*pgcDst->pScreen->DestroyPixmap) (pgcDst->tile.pixmap);
671 pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
672 pgcDst->tile = pgcSrc->tile;
673 if (!pgcDst->tileIsPixel)
674 pgcDst->tile.pixmap->refcnt++;
675 break;
676 }
677 case GCStipple(1L<<11):
678 {
679 if (pgcDst->stipple == pgcSrc->stipple)
680 break;
681 if (pgcDst->stipple)
682 (*pgcDst->pScreen->DestroyPixmap) (pgcDst->stipple);
683 pgcDst->stipple = pgcSrc->stipple;
684 if (pgcDst->stipple)
685 pgcDst->stipple->refcnt++;
686 break;
687 }
688 case GCTileStipXOrigin(1L<<12):
689 pgcDst->patOrg.x = pgcSrc->patOrg.x;
690 break;
691 case GCTileStipYOrigin(1L<<13):
692 pgcDst->patOrg.y = pgcSrc->patOrg.y;
693 break;
694 case GCFont(1L<<14):
695 if (pgcDst->font == pgcSrc->font)
696 break;
697 if (pgcDst->font)
698 CloseFont(pgcDst->font, (Font) 0);
699 if ((pgcDst->font = pgcSrc->font) != NullFont((FontPtr) 0))
700 (pgcDst->font)->refcnt++;
701 break;
702 case GCSubwindowMode(1L<<15):
703 pgcDst->subWindowMode = pgcSrc->subWindowMode;
704 break;
705 case GCGraphicsExposures(1L<<16):
706 pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
707 break;
708 case GCClipXOrigin(1L<<17):
709 pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
710 break;
711 case GCClipYOrigin(1L<<18):
712 pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
713 break;
714 case GCClipMask(1L<<19):
715 (*pgcDst->funcs->CopyClip) (pgcDst, pgcSrc);
716 break;
717 case GCDashOffset(1L<<20):
718 pgcDst->dashOffset = pgcSrc->dashOffset;
719 break;
720 case GCDashList(1L<<21):
721 if (pgcSrc->dash == DefaultDash) {
722 if (pgcDst->dash != DefaultDash) {
723 free(pgcDst->dash);
724 pgcDst->numInDashList = pgcSrc->numInDashList;
725 pgcDst->dash = pgcSrc->dash;
726 }
727 }
728 else {
729 unsigned char *dash;
730 unsigned int i;
731
732 dash = malloc(pgcSrc->numInDashList * sizeof(unsigned char));
733 if (dash) {
734 if (pgcDst->dash != DefaultDash)
735 free(pgcDst->dash);
736 pgcDst->numInDashList = pgcSrc->numInDashList;
737 pgcDst->dash = dash;
738 for (i = 0; i < pgcSrc->numInDashList; i++)
739 dash[i] = pgcSrc->dash[i];
740 }
741 else
742 error = BadAlloc11;
743 }
744 break;
745 case GCArcMode(1L<<22):
746 pgcDst->arcMode = pgcSrc->arcMode;
747 break;
748 default:
749 FatalError("CopyGC: Unhandled mask!\n");
750 }
751 }
752 if (pgcDst->fillStyle == FillTiled1 && pgcDst->tileIsPixel) {
753 if (!CreateDefaultTile(pgcDst)) {
754 pgcDst->fillStyle = FillSolid0;
755 error = BadAlloc11;
756 }
757 }
758 (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
759 return error;
760}
761
762/**
763 * does the diX part of freeing the characteristics in the GC.
764 *
765 * \param value must conform to DeleteType
766 */
767int
768FreeGC(void *value, XID gid)
769{
770 GCPtr pGC = (GCPtr) value;
771
772 CloseFont(pGC->font, (Font) 0);
773 (*pGC->funcs->DestroyClip) (pGC);
774
775 if (!pGC->tileIsPixel)
776 (*pGC->pScreen->DestroyPixmap) (pGC->tile.pixmap);
777 if (pGC->stipple)
778 (*pGC->pScreen->DestroyPixmap) (pGC->stipple);
779
780 (*pGC->funcs->DestroyGC) (pGC);
781 if (pGC->dash != DefaultDash)
782 free(pGC->dash);
783 dixFreeObjectWithPrivates(pGC, PRIVATE_GC)_dixFreeObjectWithPrivates(pGC, (pGC)->devPrivates, PRIVATE_GC
)
;
784 return Success0;
785}
786
787/* CreateScratchGC(pScreen, depth)
788 like CreateGC, but doesn't do the default tile or stipple,
789since we can't create them without already having a GC. any code
790using the tile or stipple has to set them explicitly anyway,
791since the state of the scratch gc is unknown. This is OK
792because ChangeGC() has to be able to deal with NULL tiles and
793stipples anyway (in case the CreateGC() call has provided a
794value for them -- we can't set the default tile until the
795client-supplied attributes are installed, since the fgPixel
796is what fills the default tile. (maybe this comment should
797go with CreateGC() or ChangeGC().)
798*/
799
800static GCPtr
801CreateScratchGC(ScreenPtr pScreen, unsigned depth)
802{
803 GCPtr pGC;
804
805 pGC = NewGCObject(pScreen, depth);
806 if (!pGC)
807 return (GCPtr) NULL((void*)0);
808
809 pGC->stateChanges = GCAllBits((1 << (22 + 1)) - 1);
810 if (!(*pScreen->CreateGC) (pGC)) {
811 FreeGC(pGC, (XID) 0);
812 pGC = (GCPtr) NULL((void*)0);
813 }
814 return pGC;
815}
816
817void
818FreeGCperDepth(int screenNum)
819{
820 int i;
821 ScreenPtr pScreen;
822 GCPtr *ppGC;
823
824 pScreen = screenInfo.screens[screenNum];
825 ppGC = pScreen->GCperDepth;
826
827 for (i = 0; i <= pScreen->numDepths; i++) {
828 (void) FreeGC(ppGC[i], (XID) 0);
829 ppGC[i] = NULL((void*)0);
830 }
831}
832
833Bool
834CreateGCperDepth(int screenNum)
835{
836 int i;
837 ScreenPtr pScreen;
838 DepthPtr pDepth;
839 GCPtr *ppGC;
840
841 pScreen = screenInfo.screens[screenNum];
842 ppGC = pScreen->GCperDepth;
843 /* do depth 1 separately because it's not included in list */
844 if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
845 return FALSE0;
846 ppGC[0]->graphicsExposures = FALSE0;
847 /* Make sure we don't overflow GCperDepth[] */
848 if (pScreen->numDepths > MAXFORMATS8)
849 return FALSE0;
850
851 pDepth = pScreen->allowedDepths;
852 for (i = 0; i < pScreen->numDepths; i++, pDepth++) {
853 if (!(ppGC[i + 1] = CreateScratchGC(pScreen, pDepth->depth))) {
854 for (; i >= 0; i--)
855 (void) FreeGC(ppGC[i], (XID) 0);
856 return FALSE0;
857 }
858 ppGC[i + 1]->graphicsExposures = FALSE0;
859 }
860 return TRUE1;
861}
862
863Bool
864CreateDefaultStipple(int screenNum)
865{
866 ScreenPtr pScreen;
867 ChangeGCVal tmpval[3];
868 xRectangle rect;
869 CARD16 w, h;
870 GCPtr pgcScratch;
871
872 pScreen = screenInfo.screens[screenNum];
873
874 w = 16;
875 h = 16;
876 (*pScreen->QueryBestSize) (StippleShape2, &w, &h, pScreen);
877 if (!(pScreen->PixmapPerDepth[0] =
878 (*pScreen->CreatePixmap) (pScreen, w, h, 1, 0)))
879 return FALSE0;
880 /* fill stipple with 1 */
881 tmpval[0].val = GXcopy0x3;
882 tmpval[1].val = 1;
883 tmpval[2].val = FillSolid0;
884 pgcScratch = GetScratchGC(1, pScreen);
885 if (!pgcScratch) {
886 (*pScreen->DestroyPixmap) (pScreen->PixmapPerDepth[0]);
887 return FALSE0;
888 }
889 (void) ChangeGC(NullClient((ClientPtr) 0), pgcScratch,
890 GCFunction(1L<<0) | GCForeground(1L<<2) | GCFillStyle(1L<<8), tmpval);
891 ValidateGC((DrawablePtr) pScreen->PixmapPerDepth[0], pgcScratch);
892 rect.x = 0;
893 rect.y = 0;
894 rect.width = w;
895 rect.height = h;
896 (*pgcScratch->ops->PolyFillRect) ((DrawablePtr) pScreen->PixmapPerDepth[0],
897 pgcScratch, 1, &rect);
898 FreeScratchGC(pgcScratch);
899 return TRUE1;
900}
901
902void
903FreeDefaultStipple(int screenNum)
904{
905 ScreenPtr pScreen = screenInfo.screens[screenNum];
906
907 (*pScreen->DestroyPixmap) (pScreen->PixmapPerDepth[0]);
908}
909
910int
911SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
912{
913 long i;
914 unsigned char *p, *indash;
915 BITS32 maskQ = 0;
916
917 i = ndash;
918 p = pdash;
919 while (i--) {
1
Loop condition is false. Execution continues on line 926
920 if (!*p++) {
921 /* dash segment must be > 0 */
922 return BadValue2;
923 }
924 }
925
926 if (ndash & 1)
2
Taking false branch
927 p = malloc(2 * ndash * sizeof(unsigned char));
928 else
929 p = malloc(ndash * sizeof(unsigned char));
3
Call to 'malloc' has an allocation size of 0 bytes
930 if (!p)
931 return BadAlloc11;
932
933 pGC->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
934 if (offset != pGC->dashOffset) {
935 pGC->dashOffset = offset;
936 pGC->stateChanges |= GCDashOffset(1L<<20);
937 maskQ |= GCDashOffset(1L<<20);
938 }
939
940 if (pGC->dash != DefaultDash)
941 free(pGC->dash);
942 pGC->numInDashList = ndash;
943 pGC->dash = p;
944 if (ndash & 1) {
945 pGC->numInDashList += ndash;
946 indash = pdash;
947 i = ndash;
948 while (i--)
949 *p++ = *indash++;
950 }
951 while (ndash--)
952 *p++ = *pdash++;
953 pGC->stateChanges |= GCDashList(1L<<21);
954 maskQ |= GCDashList(1L<<21);
955
956 if (pGC->funcs->ChangeGC)
957 (*pGC->funcs->ChangeGC) (pGC, maskQ);
958 return Success0;
959}
960
961int
962VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
963{
964 xRectangle *prectP, *prectN;
965 int i;
966
967 switch (ordering) {
968 case Unsorted0:
969 return CT_UNSORTED6;
970 case YSorted1:
971 if (nrects > 1) {
972 for (i = 1, prectP = prects, prectN = prects + 1;
973 i < nrects; i++, prectP++, prectN++)
974 if (prectN->y < prectP->y)
975 return -1;
976 }
977 return CT_YSORTED10;
978 case YXSorted2:
979 if (nrects > 1) {
980 for (i = 1, prectP = prects, prectN = prects + 1;
981 i < nrects; i++, prectP++, prectN++)
982 if ((prectN->y < prectP->y) ||
983 ((prectN->y == prectP->y) && (prectN->x < prectP->x)))
984 return -1;
985 }
986 return CT_YXSORTED14;
987 case YXBanded3:
988 if (nrects > 1) {
989 for (i = 1, prectP = prects, prectN = prects + 1;
990 i < nrects; i++, prectP++, prectN++)
991 if ((prectN->y != prectP->y &&
992 prectN->y < prectP->y + (int) prectP->height) ||
993 ((prectN->y == prectP->y) &&
994 (prectN->height != prectP->height ||
995 prectN->x < prectP->x + (int) prectP->width)))
996 return -1;
997 }
998 return CT_YXBANDED18;
999 }
1000 return -1;
1001}
1002
1003int
1004SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
1005 xRectangle *prects, int ordering)
1006{
1007 int newct, size;
1008 xRectangle *prectsNew;
1009
1010 newct = VerifyRectOrder(nrects, prects, ordering);
1011 if (newct < 0)
1012 return BadMatch8;
1013 size = nrects * sizeof(xRectangle);
1014 prectsNew = malloc(size);
1015 if (!prectsNew && size)
1016 return BadAlloc11;
1017
1018 pGC->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1019 pGC->clipOrg.x = xOrigin;
1020 pGC->stateChanges |= GCClipXOrigin(1L<<17);
1021
1022 pGC->clipOrg.y = yOrigin;
1023 pGC->stateChanges |= GCClipYOrigin(1L<<18);
1024
1025 if (size)
1026 memmove((char *) prectsNew, (char *) prects, size)__builtin___memmove_chk ((char *) prectsNew, (char *) prects,
size, __builtin_object_size ((char *) prectsNew, 0))
;
1027 (*pGC->funcs->ChangeClip) (pGC, newct, (void *) prectsNew, nrects);
1028 if (pGC->funcs->ChangeGC)
1029 (*pGC->funcs->ChangeGC) (pGC,
1030 GCClipXOrigin(1L<<17) | GCClipYOrigin(1L<<18) | GCClipMask(1L<<19));
1031 return Success0;
1032}
1033
1034/*
1035 sets reasonable defaults
1036 if we can get a pre-allocated one, use it and mark it as used.
1037 if we can't, create one out of whole cloth (The Velveteen GC -- if
1038 you use it often enough it will become real.)
1039*/
1040GCPtr
1041GetScratchGC(unsigned depth, ScreenPtr pScreen)
1042{
1043 int i;
1044 GCPtr pGC;
1045
1046 for (i = 0; i <= pScreen->numDepths; i++) {
1047 pGC = pScreen->GCperDepth[i];
1048 if (pGC && pGC->depth == depth && !pGC->scratch_inuse) {
1049 pGC->scratch_inuse = TRUE1;
1050
1051 pGC->alu = GXcopy0x3;
1052 pGC->planemask = ~0;
1053 pGC->serialNumber = 0;
1054 pGC->fgPixel = 0;
1055 pGC->bgPixel = 1;
1056 pGC->lineWidth = 0;
1057 pGC->lineStyle = LineSolid0;
1058 pGC->capStyle = CapButt1;
1059 pGC->joinStyle = JoinMiter0;
1060 pGC->fillStyle = FillSolid0;
1061 pGC->fillRule = EvenOddRule0;
1062 pGC->arcMode = ArcChord0;
1063 pGC->patOrg.x = 0;
1064 pGC->patOrg.y = 0;
1065 pGC->subWindowMode = ClipByChildren0;
1066 pGC->graphicsExposures = FALSE0;
1067 pGC->clipOrg.x = 0;
1068 pGC->clipOrg.y = 0;
1069 if (pGC->clientClip)
1070 (*pGC->funcs->ChangeClip) (pGC, CT_NONE0, NULL((void*)0), 0);
1071 pGC->stateChanges = GCAllBits((1 << (22 + 1)) - 1);
1072 return pGC;
1073 }
1074 }
1075 /* if we make it this far, need to roll our own */
1076 pGC = CreateScratchGC(pScreen, depth);
1077 if (pGC)
1078 pGC->graphicsExposures = FALSE0;
1079 return pGC;
1080}
1081
1082/*
1083 if the gc to free is in the table of pre-existing ones,
1084mark it as available.
1085 if not, free it for real
1086*/
1087void
1088FreeScratchGC(GCPtr pGC)
1089{
1090 if (pGC->scratch_inuse)
1091 pGC->scratch_inuse = FALSE0;
1092 else
1093 FreeGC(pGC, (GContext) 0);
1094}