4 * This file maintains a database of read-only bitmaps for the Tk
5 * toolkit. This allows bitmaps to be shared between widgets and
6 * also avoids interactions with the X server.
8 * Copyright (c) 1990-1994 The Regents of the University of California.
9 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
21 * The includes below are for pre-defined bitmaps.
23 * Platform-specific issue: Windows complains when the bitmaps are
24 * included, because an array of characters is being initialized with
25 * integers as elements. For lint purposes, the following pragmas
26 * temporarily turn off that warning message.
29 #if defined(__WIN32__) || defined(_WIN32)
30 #pragma warning (disable : 4305)
38 #include "hourglass.bmp"
40 #include "questhead.bmp"
41 #include "question.bmp"
42 #include "warning.bmp"
44 #if defined(__WIN32__) || defined(_WIN32)
45 #pragma warning (default : 4305)
49 * One of the following data structures exists for each bitmap that is
50 * currently in use. Each structure is indexed with both "idTable" and
54 typedef struct TkBitmap {
55 Pixmap bitmap; /* X identifier for bitmap. None means this
56 * bitmap was created by Tk_DefineBitmap
57 * and it isn't currently in use. */
58 int width, height; /* Dimensions of bitmap. */
59 Display *display; /* Display for which bitmap is valid. */
60 int resourceRefCount; /* Number of active uses of this bitmap (each
61 * active use corresponds to a call to
62 * Tk_AllocBitmapFromObj or Tk_GetBitmap).
63 * If this count is 0, then this TkBitmap
64 * structure is no longer valid and it isn't
65 * present in nameTable: it is being kept
66 * around only because there are objects
67 * referring to it. The structure is freed
68 * when resourceRefCount and objRefCount
70 int objRefCount; /* Number of Tcl_Obj's that reference
72 Tcl_HashEntry *nameHashPtr; /* Entry in nameTable for this structure
73 * (needed when deleting). */
74 Tcl_HashEntry *idHashPtr; /* Entry in idTable for this structure
75 * (needed when deleting). */
76 struct TkBitmap *nextPtr; /* Points to the next TkBitmap structure with
77 * the same name. All bitmaps with the
78 * same name (but different displays) are
79 * chained together off a single entry in
84 * Used in bitmapDataTable, stored in the TkDisplay structure, to map
85 * between in-core data about a bitmap to its TkBitmap structure.
89 char *source; /* Bitmap bits. */
90 int width, height; /* Dimensions of bitmap. */
93 typedef struct ThreadSpecificData {
94 int initialized; /* 0 means table below needs initializing. */
95 Tcl_HashTable predefBitmapTable;
96 /* Hash table created by Tk_DefineBitmap
97 * to map from a name to a collection
98 * of in-core data about a bitmap. The
99 * table is indexed by the address of the
100 * data for the bitmap, and the entries
101 * contain pointers to TkPredefBitmap
103 } ThreadSpecificData;
104 static Tcl_ThreadDataKey dataKey;
107 * Forward declarations for procedures defined in this file:
110 static void BitmapInit _ANSI_ARGS_((TkDisplay *dispPtr));
111 static void DupBitmapObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr,
112 Tcl_Obj *dupObjPtr));
113 static void FreeBitmap _ANSI_ARGS_((TkBitmap *bitmapPtr));
114 static void FreeBitmapObjProc _ANSI_ARGS_((Tcl_Obj *objPtr));
115 static TkBitmap * GetBitmap _ANSI_ARGS_((Tcl_Interp *interp,
116 Tk_Window tkwin, CONST char *name));
117 static TkBitmap * GetBitmapFromObj _ANSI_ARGS_((Tk_Window tkwin,
119 static void InitBitmapObj _ANSI_ARGS_((Tcl_Obj *objPtr));
122 * The following structure defines the implementation of the "bitmap" Tcl
123 * object, which maps a string bitmap name to a TkBitmap object. The
124 * ptr1 field of the Tcl_Obj points to a TkBitmap object.
127 static Tcl_ObjType bitmapObjType = {
129 FreeBitmapObjProc, /* freeIntRepProc */
130 DupBitmapObjProc, /* dupIntRepProc */
131 NULL, /* updateStringProc */
132 NULL /* setFromAnyProc */
136 *----------------------------------------------------------------------
138 * Tk_AllocBitmapFromObj --
140 * Given a Tcl_Obj *, map the value to a corresponding
141 * Pixmap structure based on the tkwin given.
144 * The return value is the X identifer for the desired bitmap
145 * (i.e. a Pixmap with a single plane), unless string couldn't be
146 * parsed correctly. In this case, None is returned and an error
147 * message is left in the interp's result. The caller should never
148 * modify the bitmap that is returned, and should eventually call
149 * Tk_FreeBitmapFromObj when the bitmap is no longer needed.
152 * The bitmap is added to an internal database with a reference count.
153 * For each call to this procedure, there should eventually be a call
154 * to Tk_FreeBitmapFromObj, so that the database can be cleaned up
155 * when bitmaps aren't needed anymore.
157 *----------------------------------------------------------------------
161 Tk_AllocBitmapFromObj(interp, tkwin, objPtr)
162 Tcl_Interp *interp; /* Interp for error results. This may
164 Tk_Window tkwin; /* Need the screen the bitmap is used on.*/
165 Tcl_Obj *objPtr; /* Object describing bitmap; see manual
166 * entry for legal syntax of string value. */
170 if (objPtr->typePtr != &bitmapObjType) {
171 InitBitmapObj(objPtr);
173 bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
176 * If the object currently points to a TkBitmap, see if it's the
177 * one we want. If so, increment its reference count and return.
180 if (bitmapPtr != NULL) {
181 if (bitmapPtr->resourceRefCount == 0) {
183 * This is a stale reference: it refers to a TkBitmap that's
184 * no longer in use. Clear the reference.
187 FreeBitmapObjProc(objPtr);
189 } else if (Tk_Display(tkwin) == bitmapPtr->display) {
190 bitmapPtr->resourceRefCount++;
191 return bitmapPtr->bitmap;
196 * The object didn't point to the TkBitmap that we wanted. Search
197 * the list of TkBitmaps with the same name to see if one of the
198 * others is the right one.
201 if (bitmapPtr != NULL) {
202 TkBitmap *firstBitmapPtr =
203 (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr);
204 FreeBitmapObjProc(objPtr);
205 for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL;
206 bitmapPtr = bitmapPtr->nextPtr) {
207 if (Tk_Display(tkwin) == bitmapPtr->display) {
208 bitmapPtr->resourceRefCount++;
209 bitmapPtr->objRefCount++;
210 objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
211 return bitmapPtr->bitmap;
217 * Still no luck. Call GetBitmap to allocate a new TkBitmap object.
220 bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr));
221 objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
222 if (bitmapPtr == NULL) {
225 bitmapPtr->objRefCount++;
226 return bitmapPtr->bitmap;
230 *----------------------------------------------------------------------
234 * Given a string describing a bitmap, locate (or create if necessary)
235 * a bitmap that fits the description.
238 * The return value is the X identifer for the desired bitmap
239 * (i.e. a Pixmap with a single plane), unless string couldn't be
240 * parsed correctly. In this case, None is returned and an error
241 * message is left in the interp's result. The caller should never
242 * modify the bitmap that is returned, and should eventually call
243 * Tk_FreeBitmap when the bitmap is no longer needed.
246 * The bitmap is added to an internal database with a reference count.
247 * For each call to this procedure, there should eventually be a call
248 * to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
249 * aren't needed anymore.
251 *----------------------------------------------------------------------
255 Tk_GetBitmap(interp, tkwin, string)
256 Tcl_Interp *interp; /* Interpreter to use for error reporting,
257 * this may be NULL. */
258 Tk_Window tkwin; /* Window in which bitmap will be used. */
259 CONST char *string; /* Description of bitmap. See manual entry
260 * for details on legal syntax. */
262 TkBitmap *bitmapPtr = GetBitmap(interp, tkwin, string);
263 if (bitmapPtr == NULL) {
266 return bitmapPtr->bitmap;
270 *----------------------------------------------------------------------
274 * Given a string describing a bitmap, locate (or create if necessary)
275 * a bitmap that fits the description. This routine returns the
276 * internal data structure for the bitmap. This avoids extra
277 * hash table lookups in Tk_AllocBitmapFromObj.
280 * The return value is the X identifer for the desired bitmap
281 * (i.e. a Pixmap with a single plane), unless string couldn't be
282 * parsed correctly. In this case, None is returned and an error
283 * message is left in the interp's result. The caller should never
284 * modify the bitmap that is returned, and should eventually call
285 * Tk_FreeBitmap when the bitmap is no longer needed.
288 * The bitmap is added to an internal database with a reference count.
289 * For each call to this procedure, there should eventually be a call
290 * to Tk_FreeBitmap or Tk_FreeBitmapFromObj, so that the database can
291 * be cleaned up when bitmaps aren't needed anymore.
293 *----------------------------------------------------------------------
297 GetBitmap(interp, tkwin, string)
298 Tcl_Interp *interp; /* Interpreter to use for error reporting,
299 * this may be NULL. */
300 Tk_Window tkwin; /* Window in which bitmap will be used. */
301 CONST char *string; /* Description of bitmap. See manual entry
302 * for details on legal syntax. */
304 Tcl_HashEntry *nameHashPtr, *predefHashPtr;
305 TkBitmap *bitmapPtr, *existingBitmapPtr;
306 TkPredefBitmap *predefPtr;
311 TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
312 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
313 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
315 if (!dispPtr->bitmapInit) {
319 nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string, &new);
321 existingBitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr);
322 for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL;
323 bitmapPtr = bitmapPtr->nextPtr) {
324 if (Tk_Display(tkwin) == bitmapPtr->display) {
325 bitmapPtr->resourceRefCount++;
330 existingBitmapPtr = NULL;
334 * No suitable bitmap exists. Create a new bitmap from the
335 * information contained in the string. If the string starts
336 * with "@" then the rest of the string is a file name containing
337 * the bitmap. Otherwise the string must refer to a bitmap
338 * defined by a call to Tk_DefineBitmap.
341 if (*string == '@') { /* INTL: ISO char */
345 if (Tcl_IsSafe(interp)) {
346 Tcl_AppendResult(interp, "can't specify bitmap with '@' in a",
347 " safe interpreter", (char *) NULL);
352 * Note that we need to cast away the CONST from the string because
353 * Tcl_TranslateFileName is non const, even though it doesn't modify
357 string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer);
358 if (string == NULL) {
361 result = TkReadBitmapFile(Tk_Display(tkwin),
362 RootWindowOfScreen(Tk_Screen(tkwin)), string,
363 (unsigned int *) &width, (unsigned int *) &height,
364 &bitmap, &dummy2, &dummy2);
365 if (result != BitmapSuccess) {
366 if (interp != NULL) {
367 Tcl_AppendResult(interp, "error reading bitmap file \"", string,
368 "\"", (char *) NULL);
370 Tcl_DStringFree(&buffer);
373 Tcl_DStringFree(&buffer);
375 predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable,
377 if (predefHashPtr == NULL) {
379 * The following platform specific call allows the user to
380 * define bitmaps that may only exist during run time. If
381 * it returns None nothing was found and we return the error.
383 bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,
386 if (bitmap == None) {
387 if (interp != NULL) {
388 Tcl_AppendResult(interp, "bitmap \"", string,
389 "\" not defined", (char *) NULL);
394 predefPtr = (TkPredefBitmap *) Tcl_GetHashValue(predefHashPtr);
395 width = predefPtr->width;
396 height = predefPtr->height;
397 if (predefPtr->native) {
398 bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),
400 if (bitmap == None) {
401 panic("native bitmap creation failed");
404 bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
405 RootWindowOfScreen(Tk_Screen(tkwin)),
407 (unsigned) width, (unsigned) height);
413 * Add information about this bitmap to our database.
416 bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap));
417 bitmapPtr->bitmap = bitmap;
418 bitmapPtr->width = width;
419 bitmapPtr->height = height;
420 bitmapPtr->display = Tk_Display(tkwin);
421 bitmapPtr->resourceRefCount = 1;
422 bitmapPtr->objRefCount = 0;
423 bitmapPtr->nameHashPtr = nameHashPtr;
424 bitmapPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapIdTable,
425 (char *) bitmap, &new);
427 panic("bitmap already registered in Tk_GetBitmap");
429 bitmapPtr->nextPtr = existingBitmapPtr;
430 Tcl_SetHashValue(nameHashPtr, bitmapPtr);
431 Tcl_SetHashValue(bitmapPtr->idHashPtr, bitmapPtr);
436 Tcl_DeleteHashEntry(nameHashPtr);
442 *----------------------------------------------------------------------
446 * This procedure associates a textual name with a binary bitmap
447 * description, so that the name may be used to refer to the
448 * bitmap in future calls to Tk_GetBitmap.
451 * A standard Tcl result. If an error occurs then TCL_ERROR is
452 * returned and a message is left in the interp's result.
455 * "Name" is entered into the bitmap table and may be used from
456 * here on to refer to the given bitmap.
458 *----------------------------------------------------------------------
462 Tk_DefineBitmap(interp, name, source, width, height)
463 Tcl_Interp *interp; /* Interpreter to use for error reporting. */
464 CONST char *name; /* Name to use for bitmap. Must not already
465 * be defined as a bitmap. */
466 char *source; /* Address of bits for bitmap. */
467 int width; /* Width of bitmap. */
468 int height; /* Height of bitmap. */
471 Tcl_HashEntry *predefHashPtr;
472 TkPredefBitmap *predefPtr;
473 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
474 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
477 * Initialize the Bitmap module if not initialized already for this
478 * thread. Since the current TkDisplay structure cannot be
479 * introspected from here, pass a NULL pointer to BitmapInit,
480 * which will know to initialize only the data in the
481 * ThreadSpecificData structure for the current thread.
484 if (!tsdPtr->initialized) {
485 BitmapInit((TkDisplay *) NULL);
488 predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable,
491 Tcl_AppendResult(interp, "bitmap \"", name,
492 "\" is already defined", (char *) NULL);
495 predefPtr = (TkPredefBitmap *) ckalloc(sizeof(TkPredefBitmap));
496 predefPtr->source = source;
497 predefPtr->width = width;
498 predefPtr->height = height;
499 predefPtr->native = 0;
500 Tcl_SetHashValue(predefHashPtr, predefPtr);
505 *--------------------------------------------------------------
509 * Given a bitmap, return a textual string identifying the
513 * The return value is the string name associated with bitmap.
518 *--------------------------------------------------------------
522 Tk_NameOfBitmap(display, bitmap)
523 Display *display; /* Display for which bitmap was
525 Pixmap bitmap; /* Bitmap whose name is wanted. */
527 Tcl_HashEntry *idHashPtr;
529 TkDisplay *dispPtr = TkGetDisplay(display);
531 if (dispPtr == NULL || !dispPtr->bitmapInit) {
533 panic("Tk_NameOfBitmap received unknown bitmap argument");
536 idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
537 if (idHashPtr == NULL) {
540 bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
541 return bitmapPtr->nameHashPtr->key.string;
545 *--------------------------------------------------------------
549 * Given a bitmap managed by this module, returns the width
550 * and height of the bitmap.
553 * The words at *widthPtr and *heightPtr are filled in with
554 * the dimenstions of bitmap.
557 * If bitmap isn't managed by this module then the procedure
560 *--------------------------------------------------------------
564 Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr)
565 Display *display; /* Display for which bitmap was
567 Pixmap bitmap; /* Bitmap whose size is wanted. */
568 int *widthPtr; /* Store bitmap width here. */
569 int *heightPtr; /* Store bitmap height here. */
571 Tcl_HashEntry *idHashPtr;
573 TkDisplay *dispPtr = TkGetDisplay(display);
575 if (!dispPtr->bitmapInit) {
577 panic("Tk_SizeOfBitmap received unknown bitmap argument");
580 idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
581 if (idHashPtr == NULL) {
584 bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
585 *widthPtr = bitmapPtr->width;
586 *heightPtr = bitmapPtr->height;
590 *----------------------------------------------------------------------
594 * This procedure does all the work of releasing a bitmap allocated by
595 * Tk_GetBitmap or TkGetBitmapFromData. It is invoked by both
596 * Tk_FreeBitmap and Tk_FreeBitmapFromObj
602 * The reference count associated with bitmap is decremented, and
603 * it is officially deallocated if no-one is using it anymore.
605 *----------------------------------------------------------------------
609 FreeBitmap(bitmapPtr)
610 TkBitmap *bitmapPtr; /* Bitmap to be released. */
614 bitmapPtr->resourceRefCount--;
615 if (bitmapPtr->resourceRefCount > 0) {
619 Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap);
620 Tcl_DeleteHashEntry(bitmapPtr->idHashPtr);
621 prevPtr = (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr);
622 if (prevPtr == bitmapPtr) {
623 if (bitmapPtr->nextPtr == NULL) {
624 Tcl_DeleteHashEntry(bitmapPtr->nameHashPtr);
626 Tcl_SetHashValue(bitmapPtr->nameHashPtr, bitmapPtr->nextPtr);
629 while (prevPtr->nextPtr != bitmapPtr) {
630 prevPtr = prevPtr->nextPtr;
632 prevPtr->nextPtr = bitmapPtr->nextPtr;
634 if (bitmapPtr->objRefCount == 0) {
635 ckfree((char *) bitmapPtr);
640 *----------------------------------------------------------------------
644 * This procedure is called to release a bitmap allocated by
645 * Tk_GetBitmap or TkGetBitmapFromData.
651 * The reference count associated with bitmap is decremented, and
652 * it is officially deallocated if no-one is using it anymore.
654 *----------------------------------------------------------------------
658 Tk_FreeBitmap(display, bitmap)
659 Display *display; /* Display for which bitmap was
661 Pixmap bitmap; /* Bitmap to be released. */
663 Tcl_HashEntry *idHashPtr;
664 TkDisplay *dispPtr = TkGetDisplay(display);
666 if (!dispPtr->bitmapInit) {
667 panic("Tk_FreeBitmap called before Tk_GetBitmap");
670 idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
671 if (idHashPtr == NULL) {
672 panic("Tk_FreeBitmap received unknown bitmap argument");
674 FreeBitmap((TkBitmap *) Tcl_GetHashValue(idHashPtr));
678 *----------------------------------------------------------------------
680 * Tk_FreeBitmapFromObj --
682 * This procedure is called to release a bitmap allocated by
683 * Tk_AllocBitmapFromObj. It does not throw away the Tcl_Obj *;
684 * it only gets rid of the hash table entry for this bitmap
685 * and clears the cached value that is normally stored in the object.
691 * The reference count associated with the bitmap represented by
692 * objPtr is decremented, and the bitmap is released to X if there are
693 * no remaining uses for it.
695 *----------------------------------------------------------------------
699 Tk_FreeBitmapFromObj(tkwin, objPtr)
700 Tk_Window tkwin; /* The window this bitmap lives in. Needed
701 * for the display value. */
702 Tcl_Obj *objPtr; /* The Tcl_Obj * to be freed. */
704 FreeBitmap(GetBitmapFromObj(tkwin, objPtr));
708 *---------------------------------------------------------------------------
710 * FreeBitmapObjProc --
712 * This proc is called to release an object reference to a bitmap.
713 * Called when the object's internal rep is released or when
714 * the cached bitmapPtr needs to be changed.
720 * The object reference count is decremented. When both it
721 * and the hash ref count go to zero, the color's resources
724 *---------------------------------------------------------------------------
728 FreeBitmapObjProc(objPtr)
729 Tcl_Obj *objPtr; /* The object we are releasing. */
731 TkBitmap *bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
733 if (bitmapPtr != NULL) {
734 bitmapPtr->objRefCount--;
735 if ((bitmapPtr->objRefCount == 0)
736 && (bitmapPtr->resourceRefCount == 0)) {
737 ckfree((char *) bitmapPtr);
739 objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
744 *---------------------------------------------------------------------------
746 * DupBitmapObjProc --
748 * When a cached bitmap object is duplicated, this is called to
749 * update the internal reps.
755 * The color's objRefCount is incremented and the internal rep
756 * of the copy is set to point to it.
758 *---------------------------------------------------------------------------
762 DupBitmapObjProc(srcObjPtr, dupObjPtr)
763 Tcl_Obj *srcObjPtr; /* The object we are copying from. */
764 Tcl_Obj *dupObjPtr; /* The object we are copying to. */
766 TkBitmap *bitmapPtr = (TkBitmap *) srcObjPtr->internalRep.twoPtrValue.ptr1;
768 dupObjPtr->typePtr = srcObjPtr->typePtr;
769 dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
771 if (bitmapPtr != NULL) {
772 bitmapPtr->objRefCount++;
777 *----------------------------------------------------------------------
779 * Tk_GetBitmapFromData --
781 * Given a description of the bits for a bitmap, make a bitmap that
782 * has the given properties. *** NOTE: this procedure is obsolete
783 * and really shouldn't be used anymore. ***
786 * The return value is the X identifer for the desired bitmap
787 * (a one-plane Pixmap), unless it couldn't be created properly.
788 * In this case, None is returned and an error message is left in
789 * the interp's result. The caller should never modify the bitmap that
790 * is returned, and should eventually call Tk_FreeBitmap when the
791 * bitmap is no longer needed.
794 * The bitmap is added to an internal database with a reference count.
795 * For each call to this procedure, there should eventually be a call
796 * to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
797 * aren't needed anymore.
799 *----------------------------------------------------------------------
804 Tk_GetBitmapFromData(interp, tkwin, source, width, height)
805 Tcl_Interp *interp; /* Interpreter to use for error reporting. */
806 Tk_Window tkwin; /* Window in which bitmap will be used. */
807 char *source; /* Bitmap data for bitmap shape. */
808 int width, height; /* Dimensions of bitmap. */
811 Tcl_HashEntry *dataHashPtr;
813 char string[16 + TCL_INTEGER_SPACE];
815 TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
819 nameKey.source = source;
820 nameKey.width = width;
821 nameKey.height = height;
822 dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
823 (char *) &nameKey, &new);
825 name = (char *) Tcl_GetHashValue(dataHashPtr);
827 dispPtr->bitmapAutoNumber++;
828 sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber);
830 Tcl_SetHashValue(dataHashPtr, name);
831 if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
832 Tcl_DeleteHashEntry(dataHashPtr);
836 return Tk_GetBitmap(interp, tkwin, name);
840 *----------------------------------------------------------------------
842 * Tk_GetBitmapFromObj --
844 * Returns the bitmap referred to by a Tcl object. The bitmap must
845 * already have been allocated via a call to Tk_AllocBitmapFromObj
849 * Returns the Pixmap that matches the tkwin and the string rep
853 * If the object is not already a bitmap, the conversion will free
854 * any old internal representation.
856 *----------------------------------------------------------------------
860 Tk_GetBitmapFromObj(tkwin, objPtr)
862 Tcl_Obj *objPtr; /* The object from which to get pixels. */
864 TkBitmap *bitmapPtr = GetBitmapFromObj(tkwin, objPtr);
865 return bitmapPtr->bitmap;
869 *----------------------------------------------------------------------
871 * GetBitmapFromObj --
873 * Returns the bitmap referred to by a Tcl object. The bitmap must
874 * already have been allocated via a call to Tk_AllocBitmapFromObj
878 * Returns the TkBitmap * that matches the tkwin and the string rep
882 * If the object is not already a bitmap, the conversion will free
883 * any old internal representation.
885 *----------------------------------------------------------------------
889 GetBitmapFromObj(tkwin, objPtr)
890 Tk_Window tkwin; /* Window in which the bitmap will be used. */
891 Tcl_Obj *objPtr; /* The object that describes the desired
895 Tcl_HashEntry *hashPtr;
896 TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
898 if (objPtr->typePtr != &bitmapObjType) {
899 InitBitmapObj(objPtr);
902 bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
903 if (bitmapPtr != NULL) {
904 if ((bitmapPtr->resourceRefCount > 0)
905 && (Tk_Display(tkwin) == bitmapPtr->display)) {
908 hashPtr = bitmapPtr->nameHashPtr;
909 FreeBitmapObjProc(objPtr);
911 hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable,
912 Tcl_GetString(objPtr));
913 if (hashPtr == NULL) {
919 * At this point we've got a hash table entry, off of which hang
920 * one or more TkBitmap structures. See if any of them will work.
923 for (bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);
924 bitmapPtr != NULL; bitmapPtr = bitmapPtr->nextPtr) {
925 if (Tk_Display(tkwin) == bitmapPtr->display) {
926 objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
927 bitmapPtr->objRefCount++;
933 panic("GetBitmapFromObj called with non-existent bitmap!");
935 * The following code isn't reached; it's just there to please compilers.
941 *----------------------------------------------------------------------
945 * Bookeeping procedure to change an objPtr to a bitmap type.
951 * The old internal rep of the object is freed. The internal
952 * rep is cleared. The final form of the object is set
953 * by either Tk_AllocBitmapFromObj or GetBitmapFromObj.
955 *----------------------------------------------------------------------
959 InitBitmapObj(objPtr)
960 Tcl_Obj *objPtr; /* The object to convert. */
962 Tcl_ObjType *typePtr;
965 * Free the old internalRep before setting the new one.
968 Tcl_GetString(objPtr);
969 typePtr = objPtr->typePtr;
970 if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
971 (*typePtr->freeIntRepProc)(objPtr);
973 objPtr->typePtr = &bitmapObjType;
974 objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
978 *----------------------------------------------------------------------
981 * Initializes hash tables used by this module. Initializes
982 * tables stored in TkDisplay structure if a TkDisplay pointer
983 * is passed in. Iinitializes the thread-local data
984 * in the current thread's ThreadSpecificData structure.
992 *----------------------------------------------------------------------
997 TkDisplay *dispPtr; /* TkDisplay structure encapsulating
998 * thread-specific data used by this
999 * module, or NULL if unavailable. */
1002 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
1003 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
1006 * First initialize the data in the ThreadSpecificData strucuture,
1010 if (!tsdPtr->initialized) {
1011 tsdPtr->initialized = 1;
1012 dummy = Tcl_CreateInterp();
1013 Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);
1015 Tk_DefineBitmap(dummy, "error", (char *) error_bits,
1016 error_width, error_height);
1017 Tk_DefineBitmap(dummy, "gray75", (char *) gray75_bits,
1018 gray75_width, gray75_height);
1019 Tk_DefineBitmap(dummy, "gray50", (char *) gray50_bits,
1020 gray50_width, gray50_height);
1021 Tk_DefineBitmap(dummy, "gray25", (char *) gray25_bits,
1022 gray25_width, gray25_height);
1023 Tk_DefineBitmap(dummy, "gray12", (char *) gray12_bits,
1024 gray12_width, gray12_height);
1025 Tk_DefineBitmap(dummy, "hourglass", (char *) hourglass_bits,
1026 hourglass_width, hourglass_height);
1027 Tk_DefineBitmap(dummy, "info", (char *) info_bits,
1028 info_width, info_height);
1029 Tk_DefineBitmap(dummy, "questhead", (char *) questhead_bits,
1030 questhead_width, questhead_height);
1031 Tk_DefineBitmap(dummy, "question", (char *) question_bits,
1032 question_width, question_height);
1033 Tk_DefineBitmap(dummy, "warning", (char *) warning_bits,
1034 warning_width, warning_height);
1036 TkpDefineNativeBitmaps();
1037 Tcl_DeleteInterp(dummy);
1041 * Was a valid TkDisplay pointer passed? If so, initialize the
1042 * Bitmap module tables in that structure.
1045 if (dispPtr != NULL) {
1046 dispPtr->bitmapInit = 1;
1047 Tcl_InitHashTable(&dispPtr->bitmapNameTable, TCL_STRING_KEYS);
1048 Tcl_InitHashTable(&dispPtr->bitmapDataTable, sizeof(DataKey)
1052 * The call below is tricky: can't use sizeof(IdKey) because it
1053 * gets padded with extra unpredictable bytes on some 64-bit
1058 * The comment above doesn't make sense...
1060 Tcl_InitHashTable(&dispPtr->bitmapIdTable, TCL_ONE_WORD_KEYS);
1065 *----------------------------------------------------------------------
1067 * TkReadBitmapFile --
1069 * Loads a bitmap image in X bitmap format into the specified
1070 * drawable. This is equivelent to the XReadBitmapFile in X.
1073 * Sets the size, hotspot, and bitmap on success.
1076 * Creates a new bitmap from the file data.
1078 *----------------------------------------------------------------------
1082 TkReadBitmapFile(display, d, filename, width_return, height_return,
1083 bitmap_return, x_hot_return, y_hot_return)
1086 CONST char* filename;
1087 unsigned int* width_return;
1088 unsigned int* height_return;
1089 Pixmap* bitmap_return;
1095 data = TkGetBitmapData(NULL, NULL, (char *) filename,
1096 (int *) width_return, (int *) height_return, x_hot_return,
1099 return BitmapFileInvalid;
1102 *bitmap_return = XCreateBitmapFromData(display, d, data, *width_return,
1106 return BitmapSuccess;
1110 *----------------------------------------------------------------------
1114 * This procedure returns debugging information about a bitmap.
1117 * The return value is a list with one sublist for each TkBitmap
1118 * corresponding to "name". Each sublist has two elements that
1119 * contain the resourceRefCount and objRefCount fields from the
1120 * TkBitmap structure.
1125 *----------------------------------------------------------------------
1129 TkDebugBitmap(tkwin, name)
1130 Tk_Window tkwin; /* The window in which the bitmap will be
1131 * used (not currently used). */
1132 char *name; /* Name of the desired color. */
1134 TkBitmap *bitmapPtr;
1135 Tcl_HashEntry *hashPtr;
1136 Tcl_Obj *resultPtr, *objPtr;
1137 TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
1139 resultPtr = Tcl_NewObj();
1140 hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, name);
1141 if (hashPtr != NULL) {
1142 bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);
1143 if (bitmapPtr == NULL) {
1144 panic("TkDebugBitmap found empty hash table entry");
1146 for ( ; (bitmapPtr != NULL); bitmapPtr = bitmapPtr->nextPtr) {
1147 objPtr = Tcl_NewObj();
1148 Tcl_ListObjAppendElement(NULL, objPtr,
1149 Tcl_NewIntObj(bitmapPtr->resourceRefCount));
1150 Tcl_ListObjAppendElement(NULL, objPtr,
1151 Tcl_NewIntObj(bitmapPtr->objRefCount));
1152 Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
1160 *----------------------------------------------------------------------
1162 * TkGetBitmapPredefTable --
1163 * This procedure is used by tkMacBitmap.c to access the thread-
1164 * specific predefBitmap table that maps from the names of
1165 * the predefined bitmaps to data associated with those
1166 * bitmaps. It is required because the table is allocated in
1167 * thread-local storage and is not visible outside this file.
1170 * Returns a pointer to the predefined bitmap hash table for
1171 * the current thread.
1176 *----------------------------------------------------------------------
1179 TkGetBitmapPredefTable()
1181 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
1182 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
1184 return &tsdPtr->predefBitmapTable;