~ubuntu-branches/ubuntu/dapper/perl-tk/dapper

« back to all changes in this revision

Viewing changes to pTk/mTk/generic/tkGC.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael C. Schultheiss
  • Date: 2006-01-16 16:54:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060116165402-1ppygm8hh8ahel2x
Tags: 1:804.027-2
* Incorporate changes from NMU (Thanks to Steve Kowalik.
  Closes: #348086)
* debian/control: Update Standards-Version (no changes needed)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
 
1
/*
2
2
 * tkGC.c --
3
3
 *
4
 
 *      This file maintains a database of read-only graphics contexts 
 
4
 *      This file maintains a database of read-only graphics contexts
5
5
 *      for the Tk toolkit, in order to allow GC's to be shared.
6
6
 *
7
7
 * Copyright (c) 1990-1994 The Regents of the University of California.
10
10
 * See the file "license.terms" for information on usage and redistribution
11
11
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
12
 *
13
 
 * RCS: @(#) $Id: tkGC.c,v 1.2 1998/09/14 18:23:11 stanton Exp $
 
13
 * RCS: @(#) $Id: tkGC.c,v 1.4 2002/04/12 10:02:40 hobbs Exp $
14
14
 */
15
15
 
16
16
#include "tkPort.h"
17
 
#include "tk.h"
 
17
#include "tkInt.h"
18
18
 
19
19
/*
20
20
 * One of the following data structures exists for each GC that is
31
31
                                 * this structure). */
32
32
} TkGC;
33
33
 
34
 
/*
35
 
 * Hash table to map from a GC's values to a TkGC structure describing
36
 
 * a GC with those values (used by Tk_GetGC).
37
 
 */
38
 
 
39
 
static Tcl_HashTable valueTable;
40
34
typedef struct {
41
35
    XGCValues values;           /* Desired values for GC. */
42
36
    Display *display;           /* Display for which GC is valid. */
45
39
} ValueKey;
46
40
 
47
41
/*
48
 
 * Hash table for <display + GC> -> TkGC mapping. This table is used by
49
 
 * Tk_FreeGC.
50
 
 */
51
 
 
52
 
static Tcl_HashTable idTable;
53
 
typedef struct {
54
 
    Display *display;           /* Display for which GC was allocated. */
55
 
    GC gc;                      /* X's identifier for GC. */
56
 
} IdKey;
57
 
 
58
 
static int initialized = 0;     /* 0 means static structures haven't been
59
 
                                 * initialized yet. */
60
 
 
61
 
/*
62
42
 * Forward declarations for procedures defined in this file:
63
43
 */
64
44
 
65
 
static void             GCInit _ANSI_ARGS_((void));
66
 
 
 
45
static void             GCInit _ANSI_ARGS_((TkDisplay *dispPtr));
 
46
 
67
47
/*
68
48
 *----------------------------------------------------------------------
69
49
 *
98
78
                                 * in valueMask. */
99
79
{
100
80
    ValueKey valueKey;
101
 
    IdKey idKey;
102
81
    Tcl_HashEntry *valueHashPtr, *idHashPtr;
103
82
    register TkGC *gcPtr;
104
83
    int new;
105
84
    Drawable d, freeDrawable;
 
85
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
106
86
 
107
 
    if (!initialized) {
108
 
        GCInit();
 
87
    if (dispPtr->gcInit <= 0) {
 
88
        GCInit(dispPtr);
109
89
    }
110
90
 
111
91
    /*
238
218
    valueKey.display = Tk_Display(tkwin);
239
219
    valueKey.screenNum = Tk_ScreenNumber(tkwin);
240
220
    valueKey.depth = Tk_Depth(tkwin);
241
 
    valueHashPtr = Tcl_CreateHashEntry(&valueTable, (char *) &valueKey, &new);
 
221
    valueHashPtr = Tcl_CreateHashEntry(&dispPtr->gcValueTable,
 
222
            (char *) &valueKey, &new);
242
223
    if (!new) {
243
224
        gcPtr = (TkGC *) Tcl_GetHashValue(valueHashPtr);
244
225
        gcPtr->refCount++;
275
256
    gcPtr->display = valueKey.display;
276
257
    gcPtr->refCount = 1;
277
258
    gcPtr->valueHashPtr = valueHashPtr;
278
 
    idKey.display = valueKey.display;
279
 
    idKey.gc = gcPtr->gc;
280
 
    idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) &idKey, &new);
 
259
    idHashPtr = Tcl_CreateHashEntry(&dispPtr->gcIdTable,
 
260
            (char *) gcPtr->gc, &new);
281
261
    if (!new) {
282
262
        panic("GC already registered in Tk_GetGC");
283
263
    }
289
269
 
290
270
    return gcPtr->gc;
291
271
}
292
 
 
 
272
 
293
273
/*
294
274
 *----------------------------------------------------------------------
295
275
 *
313
293
    Display *display;           /* Display for which gc was allocated. */
314
294
    GC gc;                      /* Graphics context to be released. */
315
295
{
316
 
    IdKey idKey;
317
296
    Tcl_HashEntry *idHashPtr;
318
297
    register TkGC *gcPtr;
 
298
    TkDisplay *dispPtr = TkGetDisplay(display);
319
299
 
320
 
    if (!initialized) {
 
300
    if (!dispPtr->gcInit) {
321
301
        panic("Tk_FreeGC called before Tk_GetGC");
322
302
    }
 
303
    if (dispPtr->gcInit < 0) {
 
304
        /*
 
305
         * The GCCleanup has been called, and remaining GCs have been
 
306
         * freed.  This may still get called by other things shutting
 
307
         * down, but the GCs should no longer be in use.
 
308
         */
 
309
        return;
 
310
    }
323
311
 
324
 
    idKey.display = display;
325
 
    idKey.gc = gc;
326
 
    idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey);
 
312
    idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, (char *) gc);
327
313
    if (idHashPtr == NULL) {
328
314
        panic("Tk_FreeGC received unknown gc argument");
329
315
    }
337
323
        ckfree((char *) gcPtr);
338
324
    }
339
325
}
340
 
 
 
326
 
 
327
/*
 
328
 *----------------------------------------------------------------------
 
329
 *
 
330
 * TkGCCleanup --
 
331
 *
 
332
 *      Frees the structures used for GC management.
 
333
 *      We need to have it called near the end, when other cleanup that
 
334
 *      calls Tk_FreeGC is all done.
 
335
 *
 
336
 * Results:
 
337
 *      None.
 
338
 *
 
339
 * Side effects:
 
340
 *      GC resources are freed.
 
341
 *
 
342
 *----------------------------------------------------------------------
 
343
 */
 
344
 
 
345
void
 
346
TkGCCleanup(dispPtr)
 
347
    TkDisplay *dispPtr; /* display to clean up resources in */
 
348
{
 
349
    Tcl_HashEntry *entryPtr;
 
350
    Tcl_HashSearch search;
 
351
    TkGC *gcPtr;
 
352
 
 
353
    for (entryPtr = Tcl_FirstHashEntry(&dispPtr->gcIdTable, &search);
 
354
         entryPtr != NULL;
 
355
         entryPtr = Tcl_NextHashEntry(&search)) {
 
356
        gcPtr = (TkGC *) Tcl_GetHashValue(entryPtr);
 
357
        /*
 
358
         * This call is not needed, as it is only used on Unix to restore
 
359
         * the Id to the stack pool, and we don't want to use them anymore.
 
360
         *   Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc));
 
361
         */
 
362
        XFreeGC(gcPtr->display, gcPtr->gc);
 
363
        Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
 
364
        Tcl_DeleteHashEntry(entryPtr);
 
365
        ckfree((char *) gcPtr);
 
366
    }
 
367
    Tcl_DeleteHashTable(&dispPtr->gcValueTable);
 
368
    Tcl_DeleteHashTable(&dispPtr->gcIdTable);
 
369
    dispPtr->gcInit = -1;
 
370
}
 
371
 
341
372
/*
342
373
 *----------------------------------------------------------------------
343
374
 *
355
386
 */
356
387
 
357
388
static void
358
 
GCInit()
 
389
GCInit(dispPtr)
 
390
    TkDisplay *dispPtr;
359
391
{
360
 
    initialized = 1;
361
 
    Tcl_InitHashTable(&valueTable, sizeof(ValueKey)/sizeof(int));
362
 
    Tcl_InitHashTable(&idTable, sizeof(IdKey)/sizeof(int));
 
392
    if (dispPtr->gcInit < 0) {
 
393
        panic("called GCInit after GCCleanup");
 
394
    }
 
395
    dispPtr->gcInit = 1;
 
396
    Tcl_InitHashTable(&dispPtr->gcValueTable, sizeof(ValueKey)/sizeof(int));
 
397
    Tcl_InitHashTable(&dispPtr->gcIdTable, TCL_ONE_WORD_KEYS);
363
398
}