~ubuntu-branches/ubuntu/maverick/xorg-server/maverick-security

« back to all changes in this revision

Viewing changes to dix/gc.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2010-08-05 11:25:14 UTC
  • mfrom: (1.1.35 upstream) (0.1.14 experimental)
  • Revision ID: james.westby@ubuntu.com-20100805112514-q4efdgj3nblevos2
Tags: 2:1.8.99.905-1ubuntu1
* Merge from (unreleased) Debian experimental.  Remaining Ubuntu changes:
  - rules, control:
    + Disable SELinux, libaudit-dev is not in main yet (LP 406226).
      Drop libaudit-dev from build-deps.
  - rules: Enable xcsecurity (LP 247537).
  - local/xvfb-run*: Add correct docs about error codes (LP 328205)
  - rules: Add --with-extra-module-dir to support GL alternatives.
  - control: Xvfb depends on xauth, x11-xkb-utils. (LP 500102)
  - rules, local/64-xorg-xkb.rules: Don't use keyboard-configuration
    until it's available.
  - control: Update some versioned Breaks for Ubuntu versions.
  - debian/patches:
    + 100_rethrow_signals.patch:
      When aborting, re-raise signals for apport
    + 109_fix-swcursor-crash.patch:
      Avoid dereferencing null pointer while reloading cursors during
      resume. (LP 371405)
    + 111_armel-drv-fallbacks.patch:
      Add support for armel driver fallbacks.
    + 121_only_switch_vt_when_active.diff:
      Add a check to prevent the X server from changing the VT when killing
      GDM from the console.
    + 122_xext_fix_card32_overflow_in_xauth.patch:
      Fix server crash when “xauth generate” is called with large timeout.
    + 157_check_null_modes.patch, 162_null_crtc_in_rotation.patch,
      166_nullptr_xinerama_keyrepeat.patch, 167_nullptr_xisbread.patch
      169_mipointer_nullptr_checks.patch,
      172_cwgetbackingpicture_nullptr_check.patch:
      Fix various segfaults in xserver by checking pointers for NULL
      values before dereferencing them.
    + 165_man_xorg_conf_no_device_ident.patch
      Correct man page
    + 168_glibc_trace_to_stderr.patch:
      Report abort traces to stderr instead of terminal
    + 184_virtual_devices_autodetect.patch:
      Use vesa for qemu device, which is not supported by cirrus
    + 187_edid_quirk_hp_nc8430.patch:
      Quirk for another LPL monitor (LP 380009)
    + 188_default_primary_to_first_busid.patch:
      Pick the first device and carry on (LP 459512)
    + 189_xserver_1.5.0_bg_none_root.patch:
      Create a root window with no background.
    + 190_cache-xkbcomp_output_for_fast_start_up.patch:
      Cache keyboard settings.
    + 191-Xorg-add-an-extra-module-path.patch:
      Add support for the alternatives module path.
    + 197_xvfb-randr.patch:
      Adds xrandr support to xvfb. (LP 516123)
    + 198_nohwaccess.patch:
      Adds a -nohwaccess argument to make X not access the hardware
      ports directly.
    + 200_randr-null.patch:
      Clarify a pointer initialization.
* Update changelog entries for 1.8.1.902-1 which became 1.8.99.904-1
* Drop 196_xvfbscreeninit-handling.patch: it's semantically empty, and now 
  doesn't apply.  Merge remaining #include change into 197_xvfb-randr.patch
* New upstream version will start correctly when no outputs are connected,
  as long as the video driver can dynamically resize the framebuffer
  (true for all KMS drivers) (LP: #337889)
* New upstream version fixes crash on non-admin logout with KDE (LP: #569879)
* Refresh 111_armel-drv-fallbacks.patch to fix the build on armel

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
#include "dixfontstr.h"
61
61
#include "scrnintstr.h"
62
62
#include "region.h"
 
63
#include "dixstruct.h"
63
64
 
64
65
#include "privates.h"
65
66
#include "dix.h"
66
67
#include "xace.h"
67
68
#include <assert.h>
68
69
 
69
 
extern XID clientErrorValue;
70
70
extern FontPtr defaultFont;
71
71
 
72
72
static Bool CreateDefaultTile(GCPtr pGC);
82
82
}
83
83
 
84
84
 
85
 
/* dixChangeGC(client, pGC, mask, pC32, pUnion)
86
 
 * 
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
 
85
/*
 
86
 * ChangeGC/ChangeGCXIDs:
 
87
 *
 
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.
93
93
 * 
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:
99
95
 * 
100
 
 *     example calling dixChangeGC using pC32 parameter
101
 
 *
102
96
 *     CARD32 v[2];
103
 
 *     v[0] = foreground;
104
 
 *     v[1] = background;
105
 
 *     dixChangeGC(client, pGC, GCForeground|GCBackground, v, NULL);
106
 
 * 
107
 
 *     example calling dixChangeGC using pUnion parameter;
108
 
 *     same effect as above
 
97
 *     v[0] = FillTiled;
 
98
 *     v[1] = pid;
 
99
 *     ChangeGCXIDs(client, pGC, GCFillStyle|GCTile, v);
 
100
 * 
 
101
 * However, if you need to pass a pointer to a pixmap or font, you must
 
102
 * use ChangeGC:
 
103
 * 
 
104
 *     ChangeGCVal v[2];
 
105
 *     v[0].val = FillTiled;
 
106
 *     v[1].ptr = pPixmap;
 
107
 *     ChangeGC(client, pGC, GCFillStyle|GCTile, v);
 
108
 * 
 
109
 * If you have neither XIDs nor pointers, you can use either function,
 
110
 * but ChangeGC will do less work.
109
111
 *
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);
114
 
 * 
115
 
 * However, if you need to pass a pointer to a pixmap or font, you MUST
116
 
 * use the pUnion parameter.
117
 
 * 
118
 
 *     example calling dixChangeGC passing pointers in the value list
119
 
 *     v[1].ptr is a pointer to a pixmap
120
 
 *
121
 
 *     ChangeGCVal v[2];
122
 
 *     v[0].val = FillTiled;
123
 
 *     v[1].ptr = pPixmap;
124
 
 *     dixChangeGC(client, pGC, GCFillStyle|GCTile, NULL, v);
125
 
 * 
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.
129
 
 * 
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
133
 
 * dixChangeGC.
134
 
 * 
135
 
 * dpw
 
115
 *     ChangeGC(client, pGC, GCForeground|GCBackground, v);
136
116
 */
137
117
 
138
118
#define NEXTVAL(_type, _var) { \
139
 
      if (pC32) _var = (_type)*pC32++; \
140
 
      else { \
141
119
        _var = (_type)(pUnion->val); pUnion++; \
142
 
      } \
143
120
    }
144
121
 
145
122
#define NEXT_PTR(_type, _var) { \
146
 
    assert(pUnion); _var = (_type)pUnion->ptr; pUnion++; }
 
123
    _var = (_type)pUnion->ptr; pUnion++; }
147
124
 
148
125
int
149
 
dixChangeGC(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion)
 
126
ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion)
150
127
{
151
128
    BITS32      index2;
152
 
    int         rc, error = 0;
 
129
    int         error = 0;
153
130
    PixmapPtr   pPixmap;
154
131
    BITS32      maskQ;
155
132
 
156
 
    assert( (pC32 && !pUnion) || (!pC32 && pUnion) );
 
133
    assert(pUnion);
157
134
    pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
158
135
 
159
136
    maskQ = mask;       /* save these for when we walk the GCque */
172
149
                    pGC->alu = newalu;
173
150
                else
174
151
                {
175
 
                    clientErrorValue = newalu;
 
152
                    if (client)
 
153
                        client->errorValue = newalu;
176
154
                    error = BadValue;
177
155
                }
178
156
                break;
205
183
                    pGC->lineStyle = newlinestyle;
206
184
                else
207
185
                {
208
 
                    clientErrorValue = newlinestyle;
 
186
                    if (client)
 
187
                        client->errorValue = newlinestyle;
209
188
                    error = BadValue;
210
189
                }
211
190
                break;
218
197
                    pGC->capStyle = newcapstyle;
219
198
                else
220
199
                {
221
 
                    clientErrorValue = newcapstyle;
 
200
                    if (client)
 
201
                        client->errorValue = newcapstyle;
222
202
                    error = BadValue;
223
203
                }
224
204
                break;
231
211
                    pGC->joinStyle = newjoinstyle;
232
212
                else
233
213
                {
234
 
                    clientErrorValue = newjoinstyle;
 
214
                    if (client)
 
215
                        client->errorValue = newjoinstyle;
235
216
                    error = BadValue;
236
217
                }
237
218
                break;
244
225
                    pGC->fillStyle = newfillstyle;
245
226
                else
246
227
                {
247
 
                    clientErrorValue = newfillstyle;
 
228
                    if (client)
 
229
                        client->errorValue = newfillstyle;
248
230
                    error = BadValue;
249
231
                }
250
232
                break;
257
239
                    pGC->fillRule = newfillrule;
258
240
                else
259
241
                {
260
 
                    clientErrorValue = newfillrule;
 
242
                    if (client)
 
243
                        client->errorValue = newfillrule;
261
244
                    error = BadValue;
262
245
                }
263
246
                break;
264
247
            }
265
248
            case GCTile:
266
 
            {
267
 
                XID newpix = 0;
268
 
                if (pUnion)
269
 
                {
270
 
                    NEXT_PTR(PixmapPtr, pPixmap);
271
 
                    rc = Success;
272
 
                }
273
 
                else
274
 
                {
275
 
                    NEXTVAL(XID, newpix);
276
 
                    rc = dixLookupResourceByType((pointer *)&pPixmap, newpix,
277
 
                                           RT_PIXMAP, client, DixReadAccess);
278
 
                }
279
 
                if (rc == Success)
280
 
                {
281
 
                    if ((pPixmap->drawable.depth != pGC->depth) ||
282
 
                        (pPixmap->drawable.pScreen != pGC->pScreen))
283
 
                    {
284
 
                        error = BadMatch;
285
 
                    }
286
 
                    else
287
 
                    {
288
 
                        pPixmap->refcnt++;
289
 
                        if (!pGC->tileIsPixel)
290
 
                            (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
291
 
                        pGC->tileIsPixel = FALSE;
292
 
                        pGC->tile.pixmap = pPixmap;
293
 
                    }
294
 
                }
295
 
                else
296
 
                {
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))
 
252
                {
 
253
                    error = BadMatch;
 
254
                }
 
255
                else
 
256
                {
 
257
                    pPixmap->refcnt++;
 
258
                    if (!pGC->tileIsPixel)
 
259
                        (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
 
260
                    pGC->tileIsPixel = FALSE;
 
261
                    pGC->tile.pixmap = pPixmap;
299
262
                }
300
263
                break;
301
 
            }
302
264
            case GCStipple:
303
 
            {
304
 
                XID newstipple = 0;
305
 
                if (pUnion)
306
 
                {
307
 
                    NEXT_PTR(PixmapPtr, pPixmap);
308
 
                    rc = Success;
309
 
                }
310
 
                else
311
 
                {
312
 
                    NEXTVAL(XID, newstipple)
313
 
                    rc = dixLookupResourceByType((pointer *)&pPixmap, newstipple,
314
 
                                           RT_PIXMAP, client, DixReadAccess);
315
 
                }
316
 
                if (rc == Success)
317
 
                {
318
 
                    if ((pPixmap->drawable.depth != 1) ||
319
 
                        (pPixmap->drawable.pScreen != pGC->pScreen))
320
 
                    {
321
 
                        error = BadMatch;
322
 
                    }
323
 
                    else
324
 
                    {
325
 
                        pPixmap->refcnt++;
326
 
                        if (pGC->stipple)
327
 
                            (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
328
 
                        pGC->stipple = pPixmap;
329
 
                    }
330
 
                }
331
 
                else
332
 
                {
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))
 
268
                {
 
269
                    error = BadMatch;
 
270
                }
 
271
                else
 
272
                {
 
273
                    pPixmap->refcnt++;
 
274
                    if (pGC->stipple)
 
275
                        (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
 
276
                    pGC->stipple = pPixmap;
335
277
                }
336
278
                break;
337
 
            }
338
279
            case GCTileStipXOrigin:
339
280
                NEXTVAL(INT16, pGC->patOrg.x);
340
281
                break;
344
285
            case GCFont:
345
286
            {
346
287
                FontPtr pFont;
347
 
                XID newfont = 0;
348
 
                if (pUnion)
349
 
                {
350
 
                    NEXT_PTR(FontPtr, pFont);
351
 
                    rc = Success;
352
 
                }
353
 
                else
354
 
                {
355
 
                    NEXTVAL(XID, newfont)
356
 
                    rc = dixLookupResourceByType((pointer *)&pFont, newfont,
357
 
                                           RT_FONT, client, DixUseAccess);
358
 
                }
359
 
                if (rc == Success)
360
 
                {
361
 
                    pFont->refcnt++;
362
 
                    if (pGC->font)
363
 
                        CloseFont(pGC->font, (Font)0);
364
 
                    pGC->font = pFont;
365
 
                 }
366
 
                else
367
 
                {
368
 
                    clientErrorValue = newfont;
369
 
                    error = (rc == BadValue) ? BadFont : rc;
370
 
                }
 
288
                NEXT_PTR(FontPtr, pFont);
 
289
                pFont->refcnt++;
 
290
                if (pGC->font)
 
291
                    CloseFont(pGC->font, (Font)0);
 
292
                pGC->font = pFont;
371
293
                break;
372
294
            }
373
295
            case GCSubwindowMode:
378
300
                    pGC->subWindowMode = newclipmode;
379
301
                else
380
302
                {
381
 
                    clientErrorValue = newclipmode;
 
303
                    if (client)
 
304
                        client->errorValue = newclipmode;
382
305
                    error = BadValue;
383
306
                }
384
307
                break;
391
314
                    pGC->graphicsExposures = newge;
392
315
                else
393
316
                {
394
 
                    clientErrorValue = newge;
 
317
                    if (client)
 
318
                        client->errorValue = newge;
395
319
                    error = BadValue;
396
320
                }
397
321
                break;
403
327
                NEXTVAL(INT16, pGC->clipOrg.y);
404
328
                break;
405
329
            case GCClipMask:
406
 
            {
407
 
                Pixmap pid = 0;
408
 
                int    clipType = 0;
409
 
 
410
 
                if (pUnion)
411
 
                {
412
 
                    NEXT_PTR(PixmapPtr, pPixmap);
413
 
                }
414
 
                else
415
 
                {
416
 
                    NEXTVAL(Pixmap, pid)
417
 
                    if (pid == None)
418
 
                    {
419
 
                        clipType = CT_NONE;
420
 
                        pPixmap = NullPixmap;
421
 
                    }
422
 
                    else {
423
 
                        rc = dixLookupResourceByType((pointer *)&pPixmap, pid,
424
 
                                               RT_PIXMAP, client,
425
 
                                               DixReadAccess);
426
 
                        if (rc != Success) {
427
 
                            clientErrorValue = pid;
428
 
                            error = (rc == BadValue) ? BadPixmap : rc;
429
 
                        }
430
 
                    }
431
 
                }
432
 
 
 
330
                NEXT_PTR(PixmapPtr, pPixmap);
433
331
                if (pPixmap)
434
332
                {
435
333
                    if ((pPixmap->drawable.depth != 1) ||
436
334
                        (pPixmap->drawable.pScreen != pGC->pScreen))
437
335
                    {
438
336
                        error = BadMatch;
439
 
                    }
440
 
                    else
441
 
                    {
442
 
                        clipType = CT_PIXMAP;
443
 
                        pPixmap->refcnt++;
444
 
                    }
445
 
                }
446
 
                if(error == Success)
447
 
                {
448
 
                    (*pGC->funcs->ChangeClip)(pGC, clipType,
449
 
                                              (pointer)pPixmap, 0);
450
 
                }
 
337
                        break;
 
338
                    }
 
339
                    pPixmap->refcnt++;
 
340
                }
 
341
                (*pGC->funcs->ChangeClip)(pGC, pPixmap ? CT_PIXMAP : CT_NONE,
 
342
                                          (pointer)pPixmap, 0);
451
343
                break;
452
 
            }
453
344
            case GCDashOffset:
454
345
                NEXTVAL(INT16, pGC->dashOffset);
455
346
                break;
461
352
                {
462
353
                    if (pGC->dash != DefaultDash)
463
354
                    {
464
 
                        xfree(pGC->dash);
 
355
                        free(pGC->dash);
465
356
                        pGC->numInDashList = 2;
466
357
                        pGC->dash = DefaultDash;
467
358
                    }
470
361
                {
471
362
                    unsigned char *dash;
472
363
 
473
 
                    dash = xalloc(2 * sizeof(unsigned char));
 
364
                    dash = malloc(2 * sizeof(unsigned char));
474
365
                    if (dash)
475
366
                    {
476
367
                        if (pGC->dash != DefaultDash)
477
 
                            xfree(pGC->dash);
 
368
                            free(pGC->dash);
478
369
                        pGC->numInDashList = 2;
479
370
                        pGC->dash = dash;
480
371
                        dash[0] = newdash;
485
376
                }
486
377
                else
487
378
                {
488
 
                   clientErrorValue = newdash;
 
379
                   if (client)
 
380
                        client->errorValue = newdash;
489
381
                   error = BadValue;
490
382
                }
491
383
                break;
498
390
                    pGC->arcMode = newarcmode;
499
391
                else
500
392
                {
501
 
                    clientErrorValue = newarcmode;
 
393
                    if (client)
 
394
                        client->errorValue = newarcmode;
502
395
                    error = BadValue;
503
396
                }
504
397
                break;
505
398
            }
506
399
            default:
507
 
                clientErrorValue = maskQ;
 
400
                if (client)
 
401
                    client->errorValue = maskQ;
508
402
                error = BadValue;
509
403
                break;
510
404
        }
525
419
#undef NEXTVAL
526
420
#undef NEXT_PTR
527
421
 
528
 
/* Publically defined entry to ChangeGC.  Just calls dixChangeGC and tells
529
 
 * it that all of the entries are constants or IDs */
530
 
int
531
 
ChangeGC(GC *pGC, BITS32 mask, XID *pval)
532
 
{
533
 
    return (dixChangeGC(NullClient, pGC, mask, pval, NULL));
534
 
}
535
 
 
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
547
 
   above.
548
 
 
549
 
   if there is an error, the value is marked as changed 
550
 
   anyway, which is probably wrong, but infrequent.
551
 
 
552
 
NOTE:
553
 
        all values sent over the protocol for ChangeGC requests are
554
 
32 bits long
555
 
*/
556
 
int
557
 
DoChangeGC(GC *pGC, BITS32 mask, XID *pval, int fPointer)
558
 
{
559
 
    if (fPointer)
560
 
    /* XXX might be a problem on 64 bit big-endian servers */
561
 
        return dixChangeGC(NullClient, pGC, mask, NULL, (ChangeGCValPtr)pval);
562
 
    else
563
 
        return dixChangeGC(NullClient, pGC, mask, pval, NULL);
564
 
}
565
 
 
 
422
static const struct {
 
423
    BITS32 mask;
 
424
    RESTYPE type;
 
425
    Mask access_mode;
 
426
} xidfields[] = {
 
427
    { GCTile, RT_PIXMAP, DixReadAccess },
 
428
    { GCStipple, RT_PIXMAP, DixReadAccess },
 
429
    { GCFont, RT_FONT, DixUseAccess },
 
430
    { GCClipMask, RT_PIXMAP, DixReadAccess },
 
431
};
 
432
 
 
433
int
 
434
ChangeGCXIDs(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32)
 
435
{
 
436
    ChangeGCVal vals[GCLastBit + 1];
 
437
    int i;
 
438
    if (mask & ~GCAllBits)
 
439
    {
 
440
        client->errorValue = mask;
 
441
        return BadValue;
 
442
    }
 
443
    for (i = Ones(mask); i--; )
 
444
        vals[i].val = pC32[i];
 
445
    for (i = 0; i < sizeof(xidfields) / sizeof(*xidfields); ++i)
 
446
    {
 
447
        int offset, rc;
 
448
        if (!(mask & xidfields[i].mask))
 
449
            continue;
 
450
        offset = Ones(mask & (xidfields[i].mask - 1));
 
451
        if (xidfields[i].mask == GCClipMask && vals[offset].val == None)
 
452
        {
 
453
            vals[offset].ptr = NullPixmap;
 
454
            continue;
 
455
        }
 
456
        rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val,
 
457
                xidfields[i].type, client, xidfields[i].access_mode);
 
458
        if (rc != Success)
 
459
        {
 
460
            client->errorValue = vals[offset].val;
 
461
            return rc;
 
462
        }
 
463
    }
 
464
    return ChangeGC(client, pGC, mask, vals);
 
465
}
566
466
 
567
467
/* CreateGC(pDrawable, mask, pval, pStatus)
568
468
   creates a default GC for the given drawable, using mask to fill
579
479
{
580
480
    GCPtr pGC;
581
481
 
582
 
    pGC = xalloc(sizeof(GC));
 
482
    pGC = dixAllocateObjectWithPrivates(GC, PRIVATE_GC);
583
483
    if (!pGC)
584
484
    {
585
485
        *pStatus = BadAlloc;
592
492
    pGC->planemask = ~0;
593
493
    pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
594
494
    pGC->funcs = 0;
595
 
    pGC->devPrivates = NULL;
596
495
    pGC->fgPixel = 0;
597
496
    pGC->bgPixel = 1;
598
497
    pGC->lineWidth = 0;
637
536
    pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
638
537
    pGC->stipple->refcnt++;
639
538
 
 
539
    /* this is not a scratch GC */
 
540
    pGC->scratch_inuse = FALSE;
 
541
 
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)
644
546
        goto out;
645
547
 
646
 
    pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
 
548
    pGC->stateChanges = GCAllBits;
647
549
    if (!(*pGC->pScreen->CreateGC)(pGC))
648
550
        *pStatus = BadAlloc;
649
551
    else if (mask)
650
 
        *pStatus = ChangeGC(pGC, mask, pval);
 
552
        *pStatus = ChangeGCXIDs(client, pGC, mask, pval);
651
553
    else
652
554
        *pStatus = Success;
653
555
 
660
562
        pGC = (GCPtr)NULL;
661
563
    }
662
564
 
663
 
    return (pGC);
 
565
    return pGC;
664
566
}
665
567
 
666
568
static Bool
667
569
CreateDefaultTile (GCPtr pGC)
668
570
{
669
 
    XID         tmpval[3];
 
571
    ChangeGCVal tmpval[3];
670
572
    PixmapPtr   pTile;
671
573
    GCPtr       pgcScratch;
672
574
    xRectangle  rect;
687
589
            FreeScratchGC(pgcScratch);
688
590
        return FALSE;
689
591
    }
690
 
    tmpval[0] = GXcopy;
691
 
    tmpval[1] = pGC->tile.pixel;
692
 
    tmpval[2] = FillSolid;
693
 
    (void)ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle, 
694
 
                   tmpval);
 
592
    tmpval[0].val = GXcopy;
 
593
    tmpval[1].val = pGC->tile.pixel;
 
594
    tmpval[2].val = FillSolid;
 
595
    (void)ChangeGC(NullClient, pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval);
695
596
    ValidateGC((DrawablePtr)pTile, pgcScratch);
696
597
    rect.x = 0;
697
598
    rect.y = 0;
819
720
                {
820
721
                    if (pgcDst->dash != DefaultDash)
821
722
                    {
822
 
                        xfree(pgcDst->dash);
 
723
                        free(pgcDst->dash);
823
724
                        pgcDst->numInDashList = pgcSrc->numInDashList;
824
725
                        pgcDst->dash = pgcSrc->dash;
825
726
                    }
829
730
                    unsigned char *dash;
830
731
                    unsigned int i;
831
732
 
832
 
                    dash = xalloc(pgcSrc->numInDashList * sizeof(unsigned char));
 
733
                    dash = malloc(pgcSrc->numInDashList * sizeof(unsigned char));
833
734
                    if (dash)
834
735
                    {
835
736
                        if (pgcDst->dash != DefaultDash)
836
 
                            xfree(pgcDst->dash);
 
737
                            free(pgcDst->dash);
837
738
                        pgcDst->numInDashList = pgcSrc->numInDashList;
838
739
                        pgcDst->dash = dash;
839
740
                        for (i=0; i<pgcSrc->numInDashList; i++)
847
748
                pgcDst->arcMode = pgcSrc->arcMode;
848
749
                break;
849
750
            default:
850
 
                clientErrorValue = maskQ;
851
 
                error = BadValue;
852
 
                break;
 
751
                FatalError ("CopyGC: Unhandled mask!\n");
853
752
        }
854
753
    }
855
754
    if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
884
783
 
885
784
    (*pGC->funcs->DestroyGC) (pGC);
886
785
    if (pGC->dash != DefaultDash)
887
 
        xfree(pGC->dash);
888
 
    dixFreePrivates(pGC->devPrivates);
889
 
    xfree(pGC);
890
 
    return(Success);
 
786
        free(pGC->dash);
 
787
    dixFreeObjectWithPrivates(pGC, PRIVATE_GC);
 
788
    return Success;
891
789
}
892
790
 
893
791
/* CreateScratchGC(pScreen, depth)
908
806
{
909
807
    GCPtr pGC;
910
808
 
911
 
    pGC = xalloc(sizeof(GC));
 
809
    pGC = dixAllocateObjectWithPrivates(GC, PRIVATE_GC);
912
810
    if (!pGC)
913
811
        return (GCPtr)NULL;
914
812
 
917
815
    pGC->alu = GXcopy; /* dst <- src */
918
816
    pGC->planemask = ~0;
919
817
    pGC->serialNumber = 0;
920
 
    pGC->devPrivates = NULL;
921
818
    pGC->fgPixel = 0;
922
819
    pGC->bgPixel = 1;
923
820
    pGC->lineWidth = 0;
947
844
    pGC->lastWinOrg.x = 0;
948
845
    pGC->lastWinOrg.y = 0;
949
846
 
950
 
    pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
 
847
    /* scratch GCs in the GCperDepth pool start off unused */
 
848
    pGC->scratch_inuse = FALSE;
 
849
 
 
850
    pGC->stateChanges = GCAllBits;
951
851
    if (!(*pScreen->CreateGC)(pGC))
952
852
    {
953
853
        FreeGC(pGC, (XID)0);
967
867
    ppGC = pScreen->GCperDepth;
968
868
 
969
869
    for (i = 0; i <= pScreen->numDepths; i++)
 
870
    {
970
871
        (void)FreeGC(ppGC[i], (XID)0);
971
 
    pScreen->rgf = ~0L;
 
872
        ppGC[i] = NULL;
 
873
    }
972
874
}
973
875
 
974
876
 
981
883
    GCPtr *ppGC;
982
884
 
983
885
    pScreen = screenInfo.screens[screenNum];
984
 
    pScreen->rgf = 0;
985
886
    ppGC = pScreen->GCperDepth;
986
887
    /* do depth 1 separately because it's not included in list */
987
888
    if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
1009
910
CreateDefaultStipple(int screenNum)
1010
911
{
1011
912
    ScreenPtr pScreen;
1012
 
    XID tmpval[3];
 
913
    ChangeGCVal tmpval[3];
1013
914
    xRectangle rect;
1014
915
    CARD16 w, h;
1015
916
    GCPtr pgcScratch;
1023
924
                        (*pScreen->CreatePixmap)(pScreen, w, h, 1, 0)))
1024
925
        return FALSE;
1025
926
    /* fill stipple with 1 */
1026
 
    tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
 
927
    tmpval[0].val = GXcopy;
 
928
    tmpval[1].val = 1;
 
929
    tmpval[2].val = FillSolid;
1027
930
    pgcScratch = GetScratchGC(1, pScreen);
1028
931
    if (!pgcScratch)
1029
932
    {
1030
933
        (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
1031
934
        return FALSE;
1032
935
    }
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);
1035
938
    rect.x = 0;
1036
939
    rect.y = 0;
1063
966
        if (!*p++)
1064
967
        {
1065
968
            /* dash segment must be > 0 */
1066
 
            clientErrorValue = 0;
1067
969
            return BadValue;
1068
970
        }
1069
971
    }
1070
972
 
1071
973
    if (ndash & 1)
1072
 
        p = xalloc(2 * ndash * sizeof(unsigned char));
 
974
        p = malloc(2 * ndash * sizeof(unsigned char));
1073
975
    else
1074
 
        p = xalloc(ndash * sizeof(unsigned char));
 
976
        p = malloc(ndash * sizeof(unsigned char));
1075
977
    if (!p)
1076
978
        return BadAlloc;
1077
979
 
1084
986
    }
1085
987
 
1086
988
    if (pGC->dash != DefaultDash)
1087
 
        xfree(pGC->dash);
 
989
        free(pGC->dash);
1088
990
    pGC->numInDashList = ndash;
1089
991
    pGC->dash = p;
1090
992
    if (ndash & 1)
1164
1066
 
1165
1067
    newct = VerifyRectOrder(nrects, prects, ordering);
1166
1068
    if (newct < 0)
1167
 
        return(BadMatch);
 
1069
        return BadMatch;
1168
1070
    size = nrects * sizeof(xRectangle);
1169
 
    prectsNew = xalloc(size);
 
1071
    prectsNew = malloc(size);
1170
1072
    if (!prectsNew && size)
1171
1073
        return BadAlloc;
1172
1074
 
1199
1101
    GCPtr pGC;
1200
1102
 
1201
1103
    for (i=0; i<=pScreen->numDepths; i++)
1202
 
        if ( pScreen->GCperDepth[i]->depth == depth &&
1203
 
             !(pScreen->rgf & (1L << (i+1)))
1204
 
           )
 
1104
    {
 
1105
        pGC = pScreen->GCperDepth[i];
 
1106
        if (pGC && pGC->depth == depth && !pGC->scratch_inuse)
1205
1107
        {
1206
 
            pScreen->rgf |= (1L << (i+1));
1207
 
            pGC = (pScreen->GCperDepth[i]);
 
1108
            pGC->scratch_inuse = TRUE;
1208
1109
 
1209
1110
            pGC->alu = GXcopy;
1210
1111
            pGC->planemask = ~0;
1226
1127
            pGC->clipOrg.y = 0;
1227
1128
            if (pGC->clientClipType != CT_NONE)
1228
1129
                (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
1229
 
            pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
 
1130
            pGC->stateChanges = GCAllBits;
1230
1131
            return pGC;
1231
1132
        }
 
1133
    }
1232
1134
    /* if we make it this far, need to roll our own */
1233
1135
    pGC = CreateScratchGC(pScreen, depth);
1234
1136
    if (pGC)
1244
1146
void
1245
1147
FreeScratchGC(GCPtr pGC)
1246
1148
{
1247
 
    ScreenPtr pScreen = pGC->pScreen;
1248
 
    int i;
1249
 
 
1250
 
    for (i=0; i<=pScreen->numDepths; i++)
1251
 
    {
1252
 
        if ( pScreen->GCperDepth[i] == pGC)
1253
 
        {
1254
 
            pScreen->rgf &= ~(1L << (i+1));
1255
 
            return;
1256
 
        }
1257
 
    }
1258
 
    (void)FreeGC(pGC, (GContext)0);
 
1149
    if (pGC->scratch_inuse)
 
1150
        pGC->scratch_inuse = FALSE;
 
1151
    else
 
1152
        FreeGC(pGC, (GContext)0);
1259
1153
}