]>
Commit | Line | Data |
---|---|---|
6a5fa4e0 MG |
1 | /* |
2 | * tkPixmap.c -- | |
3 | * | |
4 | * This file maintains a database of read-only pixmaps for the Tk | |
5 | * toolkit. This allows pixmaps to be shared between widgets and | |
6 | * also avoids interactions with the X server. | |
7 | * | |
8 | * Copyright 1992 by Sven Delmas | |
9 | * | |
10 | * This source is based upon the file tkBitmap.c from: | |
11 | * | |
12 | * Copyright 1990-1992 Regents of the University of California | |
13 | * Permission to use, copy, modify, and distribute this | |
14 | * software and its documentation for any purpose and without | |
15 | * fee is hereby granted, provided that the above copyright | |
16 | * notice appear in all copies. The University of California | |
17 | * makes no representations about the suitability of this | |
18 | * software for any purpose. It is provided "as is" without | |
19 | * express or implied warranty. | |
20 | * file: /user6/ouster/wish/RCS/tkBitmap.c,v 1.16 | |
21 | * 92/08/24 09:45:43 ouster Exp $ SPRITE (Berkeley); | |
22 | */ | |
23 | ||
24 | #if defined(USE_XPM3) | |
25 | ||
26 | #ifndef lint | |
27 | static char *AtFSid = "$Header: tkPixmap.c[1.1] Mon Sep 28 14:12:35 1992 garfield@cs.tu-berlin.de frozen $"; | |
28 | #endif /* not lint */ | |
29 | ||
30 | #include "tkconfig.h" | |
31 | #include "tk.h" | |
32 | ||
33 | /* | |
34 | * The includes below are for pre-defined bitmaps. | |
35 | */ | |
36 | ||
37 | #include "bitmaps/gray50" | |
38 | #include "bitmaps/gray25" | |
39 | ||
40 | /* | |
41 | * Include the xpm 3 defines for color pixmaps | |
42 | */ | |
43 | //#include "xpmtk.h" | |
112e5018 | 44 | #include <X11/xpm.h> |
6a5fa4e0 MG |
45 | |
46 | /* | |
47 | * One of the following data structures exists for each bitmap that is | |
48 | * currently in use. Each structure is indexed with both "idTable" and | |
49 | * "nameTable". | |
50 | */ | |
51 | ||
52 | typedef struct { | |
53 | Pixmap bitmap; /* X identifier for bitmap. None means this | |
54 | * bitmap was created by Tk_DefinePixmap | |
55 | * and it isn't currently in use. */ | |
56 | unsigned int width, height; /* Dimensions of bitmap. */ | |
57 | Display *display; /* Display for which bitmap is valid. */ | |
58 | int refCount; /* Number of active uses of bitmap. */ | |
59 | Tcl_HashEntry *hashPtr; /* Entry in nameTable for this structure | |
60 | * (needed when deleting). */ | |
61 | } TkBitmap; | |
62 | ||
63 | /* | |
64 | * Hash table to map from a textual description of a bitmap to the | |
65 | * TkBitmap record for the bitmap, and key structure used in that | |
66 | * hash table: | |
67 | */ | |
68 | ||
69 | static Tcl_HashTable nameTable; | |
70 | typedef struct { | |
71 | Tk_Uid name; /* Textual name for desired bitmap. */ | |
72 | Screen *screen; /* Screen for which bitmap will be used. */ | |
73 | } NameKey; | |
74 | ||
75 | /* | |
76 | * Hash table that maps from bitmap identifiers to the TkBitmap structure | |
77 | * for the pixmap. This table is indexed by Bitmap ids, and is used by | |
78 | * Tk_FreePixmap. | |
79 | */ | |
80 | ||
81 | static Tcl_HashTable idTable; | |
82 | ||
83 | /* | |
84 | * For each call to Tk_DefinePixmap one of the following structures is | |
85 | * created to hold information about the pixmap. | |
86 | */ | |
87 | ||
88 | typedef struct { | |
89 | char *source; /* Bits for bitmap. */ | |
90 | Pixmap pixmap; /* Pre-defined pixmap */ | |
91 | unsigned int width, height; /* Dimensions of bitmap. */ | |
92 | } PredefBitmap; | |
93 | ||
94 | /* | |
95 | * Hash table create by Tk_DefinePixmap to map from a name to a | |
96 | * collection of in-core data about a bitmap. The table is | |
97 | * indexed by the address of the data for the bitmap, and the entries | |
98 | * contain pointers to PredefBitmap structures. | |
99 | */ | |
100 | ||
101 | static Tcl_HashTable predefTable; | |
102 | ||
103 | /* | |
104 | * Hash table used by Tk_GetPixmapFromData to map from a collection | |
105 | * of in-core data about a bitmap to a Tk_Uid giving an automatically- | |
106 | * generated name for the bitmap: | |
107 | */ | |
108 | ||
109 | static Tcl_HashTable dataTable; | |
110 | typedef struct { | |
111 | char *source; /* Bitmap bits. */ | |
112 | unsigned int width, height; /* Dimensions of bitmap. */ | |
113 | } DataKey; | |
114 | ||
115 | static int initialized = 0; /* 0 means static structures haven't been | |
116 | * initialized yet. */ | |
117 | ||
118 | /* | |
119 | * Forward declarations for procedures defined in this file: | |
120 | */ | |
121 | ||
122 | static void PixmapInit _ANSI_ARGS_((Tk_Window tkwin)); | |
123 | \f | |
124 | /* | |
125 | *---------------------------------------------------------------------- | |
126 | * | |
127 | * Tk_GetPixmap -- | |
128 | * | |
129 | * Given a string describing a bitmap or pixmap, locate (or create | |
130 | * if necessary) a pixmap that fits the description. | |
131 | * | |
132 | * Results: | |
133 | * The return value is the X identifer for the desired pixmap, | |
134 | * unless string couldn't be parsed correctly. In this case, | |
135 | * None is returned and an error message is left in | |
136 | * interp->result. The caller should never modify the pixmap | |
137 | * that is returned, and should eventually call Tk_FreePixmap | |
138 | * when the pixmap is no longer needed. | |
139 | * | |
140 | * Side effects: | |
141 | * The pixmap is added to an internal database with a reference count. | |
142 | * For each call to this procedure, there should eventually be a call | |
143 | * to Tk_FreePixmap, so that the database can be cleaned up when pixmaps | |
144 | * aren't needed anymore. | |
145 | * | |
146 | *---------------------------------------------------------------------- | |
147 | */ | |
148 | Pixmap | |
149 | Tk_GetPixmap(interp, tkwin, string) | |
150 | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ | |
151 | Tk_Window tkwin; /* Window in which pixmap will be used. */ | |
152 | Tk_Uid string; /* Description of pixmap. See manual entry | |
153 | * for details on legal syntax. */ | |
154 | { | |
155 | NameKey key; | |
156 | Tcl_HashEntry *nameHashPtr, *idHashPtr, *predefHashPtr; | |
157 | register TkBitmap *bitmapPtr; | |
158 | PredefBitmap *predefPtr; | |
159 | int new; | |
160 | Pixmap bitmap; | |
161 | Pixmap bitmap_shape; | |
162 | unsigned int width, height; | |
163 | int dummy2; | |
164 | XpmAttributes xpm_attributes; | |
165 | Display *dpy = Tk_Display(tkwin); | |
166 | ||
167 | if (!initialized) { | |
168 | PixmapInit(tkwin); | |
169 | } | |
170 | ||
171 | key.name = string; | |
172 | key.screen = Tk_Screen(tkwin); | |
173 | nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &key, &new); | |
174 | if (!new) { | |
175 | bitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr); | |
176 | bitmapPtr->refCount++; | |
177 | return bitmapPtr->bitmap; | |
178 | } | |
179 | ||
180 | /* | |
181 | * No suitable bitmap exists. Create a new bitmap from the | |
182 | * information contained in the string. If the string starts | |
183 | * with "@" then the rest of the string is a file name containing | |
184 | * the bitmap. Otherwise the string must refer to a bitmap | |
185 | * defined by a call to Tk_DefinePixmap. | |
186 | */ | |
187 | ||
188 | if (*string == '@') { | |
189 | string = Tcl_TildeSubst(interp, string + 1); | |
190 | if (string == NULL) { | |
191 | goto error; | |
192 | } | |
193 | ||
194 | if (XReadBitmapFile(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), | |
195 | string, &width, &height, &bitmap_shape, &dummy2, &dummy2) | |
196 | != BitmapSuccess) | |
197 | { | |
198 | xpm_attributes.visual = Tk_DefaultVisual(Tk_Screen(tkwin)); | |
199 | xpm_attributes.colormap = Tk_DefaultColormap(Tk_Screen(tkwin)); | |
200 | xpm_attributes.depth = Tk_DefaultDepth(Tk_Screen(tkwin)); | |
201 | xpm_attributes.valuemask = XpmVisual | XpmColormap | XpmDepth; | |
202 | ||
203 | if (XpmReadFileToPixmap(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), | |
204 | string, &bitmap, &bitmap_shape, | |
205 | &xpm_attributes) != BitmapSuccess) { | |
206 | Tcl_AppendResult(interp, "error reading bitmap file \"", | |
207 | string, "\"", (char *) NULL); | |
208 | goto error; | |
209 | } { | |
210 | width = xpm_attributes.width; | |
211 | height = xpm_attributes.height; | |
212 | XpmFreeAttributes(&xpm_attributes); | |
213 | } | |
214 | } else { | |
215 | bitmap = XCreatePixmap(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), | |
216 | width, height, | |
217 | Tk_DefaultDepth(Tk_Screen(tkwin))); | |
218 | XCopyPlane(dpy, bitmap_shape, bitmap, | |
219 | Tk_DefaultGC(Tk_Screen(tkwin)), | |
220 | 0, 0, width, height, 0, 0, 1); | |
221 | } | |
222 | } else { | |
223 | /* first try for a display-specific version */ | |
224 | predefHashPtr = Tcl_FindHashEntry(&predefTable, (char *) &key); | |
225 | if (predefHashPtr == NULL) { | |
226 | /* try for a non-display specific version */ | |
227 | key.screen = (Screen*) NULL; | |
228 | predefHashPtr = Tcl_FindHashEntry(&predefTable, (char *) &key); | |
229 | if (predefHashPtr == NULL) { | |
230 | /* give up */ | |
231 | Tcl_AppendResult(interp, "pixmap \"", string, | |
232 | "\" not defined", (char *) NULL); | |
233 | goto error; | |
234 | } | |
235 | } | |
236 | predefPtr = (PredefBitmap *) Tcl_GetHashValue(predefHashPtr); | |
237 | width = predefPtr->width; | |
238 | height = predefPtr->height; | |
239 | if (predefPtr->source != NULL) { | |
240 | bitmap_shape = | |
241 | XCreateBitmapFromData(dpy, Tk_DefaultRootWindow(dpy), | |
242 | predefPtr->source, width, height); | |
243 | bitmap = XCreatePixmap(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), | |
244 | width, height, | |
245 | Tk_DefaultDepth(Tk_Screen(tkwin))); | |
246 | XCopyPlane(dpy, bitmap_shape, bitmap, | |
247 | Tk_DefaultGC(Tk_Screen(tkwin)), | |
248 | 0, 0, width, height, 0, 0, 1); | |
249 | } else { | |
250 | if (predefPtr->pixmap != None) { | |
251 | bitmap = predefPtr->pixmap; | |
252 | } else { | |
253 | bitmap = | |
254 | XCreatePixmap(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), | |
255 | width, height, | |
256 | Tk_DefaultDepth(Tk_Screen(tkwin))); | |
257 | } | |
258 | } | |
259 | } | |
260 | ||
261 | /* | |
262 | * Add information about this bitmap to our database. | |
263 | */ | |
264 | ||
265 | bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap)); | |
266 | bitmapPtr->bitmap = bitmap; | |
267 | bitmapPtr->width = width; | |
268 | bitmapPtr->height = height; | |
269 | bitmapPtr->display = dpy; | |
270 | bitmapPtr->refCount = 1; | |
271 | bitmapPtr->hashPtr = nameHashPtr; | |
272 | idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) bitmapPtr->bitmap, | |
273 | &new); | |
274 | if (!new) { | |
275 | /* deh patched to support multiple displays */ | |
276 | /* panic("pixmap already registered in Tk_GetPixmap"); */ | |
277 | bitmapPtr->refCount = 1000; | |
278 | } | |
279 | Tcl_SetHashValue(nameHashPtr, bitmapPtr); | |
280 | Tcl_SetHashValue(idHashPtr, bitmapPtr); | |
281 | return bitmapPtr->bitmap; | |
282 | ||
283 | error: | |
284 | Tcl_DeleteHashEntry(nameHashPtr); | |
285 | return None; | |
286 | } | |
287 | \f | |
288 | /* | |
289 | *---------------------------------------------------------------------- | |
290 | * | |
291 | * Tk_DefinePixmap -- | |
292 | * | |
293 | * This procedure associates a textual name with a binary pixmap | |
294 | * description, so that the name may be used to refer to the | |
295 | * pixmap in future calls to Tk_GetPixmap. The pixmap can | |
296 | * be pre-created by the user, or can be created later | |
297 | * by Tk_GetPixmap(). Since pixmaps are display-specific, | |
298 | * a user supplied pixmap will be associated with tkwin's display. | |
299 | * If pixmap is given as None, then a new pixmap will be created | |
300 | * by Tk_GetPixmap for each unique display. | |
301 | * | |
302 | * Results: | |
303 | * A standard Tcl result. If an error occurs then TCL_ERROR is | |
304 | * returned and a message is left in interp->result. | |
305 | * | |
306 | * Side effects: | |
307 | * "Name" is entered into the pixmap table and may be used from | |
308 | * here on to refer to the given pixmap. | |
309 | * | |
310 | *---------------------------------------------------------------------- | |
311 | */ | |
312 | ||
313 | int | |
314 | Tk_DefinePixmap(interp, name, tkwin, pixmap, source, width, height) | |
315 | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ | |
316 | Tk_Uid name; /* Name to use for bitmap. Must not already | |
317 | * be defined as a bitmap. */ | |
318 | Tk_Window tkwin; /* any window on screen where pixmap lives */ | |
319 | Pixmap pixmap; /* pixmap to associate with name, | |
320 | * or None to create a new pixmap */ | |
321 | char *source; /* Address of bits for bitmap. */ | |
322 | unsigned int width; /* Width of bitmap. */ | |
323 | unsigned int height; /* Height of bitmap. */ | |
324 | { | |
325 | int new; | |
326 | Tcl_HashEntry *predefHashPtr; | |
327 | PredefBitmap *predefPtr; | |
328 | NameKey key; | |
329 | ||
330 | if (!initialized) { | |
331 | PixmapInit(tkwin); | |
332 | } | |
333 | ||
334 | key.name = name; | |
335 | key.screen = (pixmap != None) ? Tk_Screen(tkwin) : (Screen *)NULL; | |
336 | predefHashPtr = Tcl_CreateHashEntry(&predefTable, (char *) &key, &new); | |
337 | if (!new) { | |
338 | Tcl_AppendResult(interp, "bitmap \"", name, | |
339 | "\" is already defined", (char *) NULL); | |
340 | return TCL_ERROR; | |
341 | } | |
342 | predefPtr = (PredefBitmap *) malloc(sizeof(PredefBitmap)); | |
343 | predefPtr->source = source; | |
344 | predefPtr->pixmap = pixmap; | |
345 | predefPtr->width = width; | |
346 | predefPtr->height = height; | |
347 | Tcl_SetHashValue(predefHashPtr, predefPtr); | |
348 | return TCL_OK; | |
349 | } | |
350 | \f | |
351 | /* | |
352 | *-------------------------------------------------------------- | |
353 | * | |
354 | * Tk_NameOfPixmap -- | |
355 | * | |
356 | * Given a pixmap, return a textual string identifying the | |
357 | * pixmap. | |
358 | * | |
359 | * Results: | |
360 | * The return value is the string name associated with pixmap. | |
361 | * | |
362 | * Side effects: | |
363 | * None. | |
364 | * | |
365 | *-------------------------------------------------------------- | |
366 | */ | |
367 | ||
368 | Tk_Uid | |
369 | Tk_NameOfPixmap(bitmap) | |
370 | Pixmap bitmap; /* Bitmap whose name is wanted. */ | |
371 | { | |
372 | Tcl_HashEntry *idHashPtr; | |
373 | TkBitmap *bitmapPtr; | |
374 | ||
375 | if (!initialized) { | |
376 | unknown: | |
377 | panic("Tk_NameOfPixmap received unknown pixmap argument"); | |
378 | } | |
379 | ||
380 | idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap); | |
381 | if (idHashPtr == NULL) { | |
382 | goto unknown; | |
383 | } | |
384 | bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); | |
385 | if (bitmapPtr->hashPtr == NULL) { | |
386 | /* the bitmap has been un-defined */ | |
387 | return Tk_GetUid("UndefinedBitmap"); | |
388 | } | |
389 | return ((NameKey *) bitmapPtr->hashPtr->key.words)->name; | |
390 | } | |
391 | \f | |
392 | /* | |
393 | *-------------------------------------------------------------- | |
394 | * | |
395 | * Tk_SizeOfPixmap -- | |
396 | * | |
397 | * Given a pixmap managed by this module, returns the width | |
398 | * and height of the pixmap.. | |
399 | * | |
400 | * Results: | |
401 | * The words at *widthPtr and *heightPtr are filled in with | |
402 | * the dimenstions of pixmap. | |
403 | * | |
404 | * Side effects: | |
405 | * If pixmap isn't managed by this module then the procedure | |
406 | * panics.. | |
407 | * | |
408 | *-------------------------------------------------------------- | |
409 | */ | |
410 | ||
411 | void | |
412 | Tk_SizeOfPixmap(bitmap, widthPtr, heightPtr) | |
413 | Pixmap bitmap; /* Bitmap whose size is wanted. */ | |
414 | unsigned int *widthPtr; /* Store bitmap width here. */ | |
415 | unsigned int *heightPtr; /* Store bitmap height here. */ | |
416 | { | |
417 | Tcl_HashEntry *idHashPtr; | |
418 | TkBitmap *bitmapPtr; | |
419 | ||
420 | if (!initialized) { | |
421 | unknownBitmap: | |
422 | panic("Tk_SizeOfPixmap received unknown pixmap argument"); | |
423 | } | |
424 | ||
425 | idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap); | |
426 | if (idHashPtr == NULL) { | |
427 | goto unknownBitmap; | |
428 | } | |
429 | bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); | |
430 | *widthPtr = bitmapPtr->width; | |
431 | *heightPtr = bitmapPtr->height; | |
432 | } | |
433 | \f | |
434 | /* | |
435 | *---------------------------------------------------------------------- | |
436 | * | |
437 | * Tk_FreePixmap -- | |
438 | * | |
439 | * This procedure is called to release a pixmap allocated by | |
440 | * Tk_GetPixmap. | |
441 | * | |
442 | * Results: | |
443 | * None. | |
444 | * | |
445 | * Side effects: | |
446 | * The reference count associated with bitmap is decremented, and | |
447 | * it is officially deallocated if no-one is using it anymore. | |
448 | * | |
449 | *---------------------------------------------------------------------- | |
450 | */ | |
451 | ||
452 | void | |
453 | Tk_FreePixmap(bitmap) | |
454 | Pixmap bitmap; /* Bitmap to be released. */ | |
455 | { | |
456 | Tcl_HashEntry *idHashPtr; | |
457 | register TkBitmap *bitmapPtr; | |
458 | ||
459 | if (!initialized) { | |
460 | panic("Tk_FreePixmap called before Tk_GetPixmap"); | |
461 | } | |
462 | ||
463 | idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap); | |
464 | if (idHashPtr == NULL) { | |
465 | panic("Tk_FreePixmap received unknown pixmap argument"); | |
466 | } | |
467 | bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); | |
468 | bitmapPtr->refCount--; | |
469 | if (bitmapPtr->refCount == 0) { | |
470 | XFreePixmap(bitmapPtr->display, bitmapPtr->bitmap); | |
471 | Tcl_DeleteHashEntry(idHashPtr); | |
472 | if (bitmapPtr->hashPtr != NULL) { | |
473 | /* If hashPtr is NULL, the bitmap has been undefined, | |
474 | * and already removed from the name table */ | |
475 | Tcl_DeleteHashEntry(bitmapPtr->hashPtr); | |
476 | } | |
477 | ckfree((char *) bitmapPtr); | |
478 | } | |
479 | } | |
480 | \f | |
481 | /* | |
482 | *---------------------------------------------------------------------- | |
483 | * | |
484 | * Tk_GetPixmapFromData -- | |
485 | * | |
486 | * Given a description of the bits for a pixmap, make a pixmap that | |
487 | * has the given properties. | |
488 | * | |
489 | * Results: | |
490 | * The return value is the X identifer for the desired pixmap, | |
491 | * unless it couldn't be created properly. In this case, None is | |
492 | * returned and an error message is left in interp->result. The | |
493 | * caller should never modify the bitmap that is returned, and | |
494 | * should eventually call Tk_FreePixmap when the pixmap is no | |
495 | * longer needed. | |
496 | * | |
497 | * Side effects: | |
498 | * The pixmap is added to an internal database with a reference count. | |
499 | * For each call to this procedure, there should eventually be a call | |
500 | * to Tk_FreePixmap, so that the database can be cleaned up when pixmaps | |
501 | * aren't needed anymore. | |
502 | * | |
503 | *---------------------------------------------------------------------- | |
504 | */ | |
505 | ||
506 | /* ARGSUSED */ | |
507 | Pixmap | |
508 | Tk_GetPixmapFromData(interp, tkwin, source, width, height) | |
509 | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ | |
510 | Tk_Window tkwin; /* Window in which bitmap will be used. */ | |
511 | char *source; /* Bitmap data for bitmap shape. */ | |
512 | unsigned int width, height; /* Dimensions of bitmap. */ | |
513 | { | |
514 | DataKey key; | |
515 | Tcl_HashEntry *dataHashPtr; | |
516 | Tk_Uid name = NULL; /* Initialization need only to prevent | |
517 | * compiler warning. */ | |
518 | int new; | |
519 | static autoNumber = 0; | |
520 | char string[20]; | |
521 | ||
522 | if (!initialized) { | |
523 | PixmapInit(tkwin); | |
524 | } | |
525 | ||
526 | key.source = source; | |
527 | key.width = width; | |
528 | key.height = height; | |
529 | dataHashPtr = Tcl_CreateHashEntry(&dataTable, (char *) &key, &new); | |
530 | if (!new) { | |
531 | name = (Tk_Uid) Tcl_GetHashValue(dataHashPtr); | |
532 | } else { | |
533 | autoNumber++; | |
534 | sprintf(string, "_tk%d", autoNumber); | |
535 | name = Tk_GetUid(string); | |
536 | Tcl_SetHashValue(dataHashPtr, name); | |
537 | if (Tk_DefinePixmap(interp, name, tkwin, None, source, width, | |
538 | height) != TCL_OK) { | |
539 | Tcl_DeleteHashEntry(dataHashPtr); | |
540 | return TCL_ERROR; | |
541 | } | |
542 | } | |
543 | return Tk_GetPixmap(interp, tkwin, name); | |
544 | } | |
545 | \f | |
546 | /* | |
547 | *---------------------------------------------------------------------- | |
548 | * | |
549 | * PixmapInit -- | |
550 | * | |
551 | * Initialize the structures used for pixmap management. | |
552 | * | |
553 | * Results: | |
554 | * None. | |
555 | * | |
556 | * Side effects: | |
557 | * Read the code. | |
558 | * | |
559 | *---------------------------------------------------------------------- | |
560 | */ | |
561 | ||
562 | static void | |
563 | PixmapInit(tkwin) | |
564 | Tk_Window tkwin; /* any window on screen where pixmap lives */ | |
565 | { | |
566 | Tcl_Interp *dummy; | |
567 | ||
568 | dummy = Tcl_CreateInterp(); | |
569 | initialized = 1; | |
570 | Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int)); | |
571 | Tcl_InitHashTable(&dataTable, sizeof(DataKey)/sizeof(int)); | |
572 | Tcl_InitHashTable(&predefTable, sizeof(NameKey)/sizeof(int)); | |
573 | Tcl_InitHashTable(&idTable, TCL_ONE_WORD_KEYS); | |
574 | ||
575 | Tk_DefinePixmap(dummy, Tk_GetUid("gray50"), tkwin, None, | |
576 | (char *)gray50_bits, gray50_width, gray50_height); | |
577 | Tk_DefinePixmap(dummy, Tk_GetUid("gray25"), tkwin, None, | |
578 | (char *)gray25_bits, gray25_width, gray25_height); | |
579 | Tcl_DeleteInterp(dummy); | |
580 | } | |
581 | \f | |
582 | /* | |
583 | *---------------------------------------------------------------------- | |
584 | * | |
585 | * Tk_UndefinePixmap -- | |
586 | * | |
587 | * This procedure removes any association "name" with | |
588 | * a bitmap or pixmap. This can be used to undefine | |
589 | * names defined by either Tk_DefinePixmap or Tk_DefinePixmap. | |
590 | * If tkwin is NULL, only display-independent pixmaps will | |
591 | * be removed, otherwise both display-independent and | |
592 | * the pixmap associated with tkwin will be undefined. | |
593 | * | |
594 | * Results: | |
595 | * A standard Tcl result. If an error occurs then TCL_ERROR is | |
596 | * returned and a message is left in interp->result. | |
597 | * | |
598 | * Side effects: | |
599 | * "Name" is removed from the predef table. | |
600 | * | |
601 | *---------------------------------------------------------------------- | |
602 | */ | |
603 | ||
604 | int | |
605 | Tk_UndefinePixmap(interp, name, tkwin) | |
606 | Tcl_Interp *interp; /* Interpreter to use for error reporting. */ | |
607 | Tk_Uid name; /* Name of bitmap/pixmap to undefine */ | |
608 | Tk_Window tkwin; /* any window on screen where pixmap lives */ | |
609 | { | |
610 | NameKey key; | |
611 | Tcl_HashEntry *predefHashPtr, *nameHashPtr; | |
612 | TkBitmap *bitmapPtr; | |
613 | int cnt = 0; | |
614 | ||
615 | if (!initialized) { | |
616 | PixmapInit(tkwin); | |
617 | } | |
618 | ||
619 | key.name = name; | |
620 | key.screen = (Screen *) NULL; | |
621 | predefHashPtr = Tcl_FindHashEntry(&predefTable, (char*)&key); | |
622 | if (predefHashPtr != NULL) { | |
623 | ++cnt; | |
624 | Tcl_DeleteHashEntry(predefHashPtr); | |
625 | } | |
626 | ||
627 | key.screen = Tk_Screen(tkwin); | |
628 | predefHashPtr = Tcl_FindHashEntry(&predefTable, (char*)&key); | |
629 | if (predefHashPtr != NULL) { | |
630 | ++cnt; | |
631 | Tcl_DeleteHashEntry(predefHashPtr); | |
632 | } | |
633 | if (cnt == 0) { | |
634 | Tcl_AppendResult(interp, "pixmap \"", name, | |
635 | "\" doesn't exist", (char *) NULL); | |
636 | return TCL_ERROR; | |
637 | } | |
638 | ||
639 | /* | |
640 | * Remove it from the name table if it is there (it might not | |
641 | * have been created yet, it which case we wont find it). We | |
642 | * delete it from the name table and mark the hashPtr as NULL | |
643 | * so that we know it has been deleted. The pixmap still exists, | |
644 | * and well later be freed and removed from idTable by Tk_FreeBitmap(). | |
645 | */ | |
646 | nameHashPtr = Tcl_FindHashEntry(&nameTable, (char *) &key); | |
647 | if (nameHashPtr != NULL) { | |
648 | bitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr); | |
649 | /* assert(nameHashPtr == bitmapPtr->hashPtr); */ | |
650 | /* assert(bitmapPtr->refCount > 0); */ | |
651 | bitmapPtr->hashPtr = (Tcl_HashEntry*) NULL; | |
652 | Tcl_DeleteHashEntry(nameHashPtr); | |
653 | } | |
654 | return TCL_OK; | |
655 | } | |
656 | ||
657 | #endif |