/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkbitmap.c
ViewVC logotype

Diff of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkbitmap.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 69 by dashley, Sat Nov 5 10:54:17 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * tkBitmap.c --   * tkBitmap.c --
5   *   *
6   *      This file maintains a database of read-only bitmaps for the Tk   *      This file maintains a database of read-only bitmaps for the Tk
7   *      toolkit.  This allows bitmaps to be shared between widgets and   *      toolkit.  This allows bitmaps to be shared between widgets and
8   *      also avoids interactions with the X server.   *      also avoids interactions with the X server.
9   *   *
10   * Copyright (c) 1990-1994 The Regents of the University of California.   * Copyright (c) 1990-1994 The Regents of the University of California.
11   * Copyright (c) 1994-1998 Sun Microsystems, Inc.   * Copyright (c) 1994-1998 Sun Microsystems, Inc.
12   *   *
13   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
14   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15   *   *
16   * RCS: @(#) $Id: tkbitmap.c,v 1.1.1.1 2001/06/13 04:54:29 dtashley Exp $   * RCS: @(#) $Id: tkbitmap.c,v 1.1.1.1 2001/06/13 04:54:29 dtashley Exp $
17   */   */
18    
19  #include "tkPort.h"  #include "tkPort.h"
20  #include "tkInt.h"  #include "tkInt.h"
21    
22  /*  /*
23   * The includes below are for pre-defined bitmaps.   * The includes below are for pre-defined bitmaps.
24   *   *
25   * Platform-specific issue: Windows complains when the bitmaps are   * Platform-specific issue: Windows complains when the bitmaps are
26   * included, because an array of characters is being initialized with   * included, because an array of characters is being initialized with
27   * integers as elements.  For lint purposes, the following pragmas   * integers as elements.  For lint purposes, the following pragmas
28   * temporarily turn off that warning message.   * temporarily turn off that warning message.
29   */   */
30    
31  #if defined(__WIN32__) || defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32)
32  #pragma warning (disable : 4305)  #pragma warning (disable : 4305)
33  #endif  #endif
34    
35  #include "error.bmp"  #include "error.bmp"
36  #include "gray12.bmp"  #include "gray12.bmp"
37  #include "gray25.bmp"  #include "gray25.bmp"
38  #include "gray50.bmp"  #include "gray50.bmp"
39  #include "gray75.bmp"  #include "gray75.bmp"
40  #include "hourglass.bmp"  #include "hourglass.bmp"
41  #include "info.bmp"  #include "info.bmp"
42  #include "questhead.bmp"  #include "questhead.bmp"
43  #include "question.bmp"  #include "question.bmp"
44  #include "warning.bmp"  #include "warning.bmp"
45    
46  #if defined(__WIN32__) || defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32)
47  #pragma warning (default : 4305)  #pragma warning (default : 4305)
48  #endif  #endif
49    
50  /*  /*
51   * One of the following data structures exists for each bitmap that is   * One of the following data structures exists for each bitmap that is
52   * currently in use.  Each structure is indexed with both "idTable" and   * currently in use.  Each structure is indexed with both "idTable" and
53   * "nameTable".   * "nameTable".
54   */   */
55    
56  typedef struct TkBitmap {  typedef struct TkBitmap {
57      Pixmap bitmap;              /* X identifier for bitmap.  None means this      Pixmap bitmap;              /* X identifier for bitmap.  None means this
58                                   * bitmap was created by Tk_DefineBitmap                                   * bitmap was created by Tk_DefineBitmap
59                                   * and it isn't currently in use. */                                   * and it isn't currently in use. */
60      int width, height;          /* Dimensions of bitmap. */      int width, height;          /* Dimensions of bitmap. */
61      Display *display;           /* Display for which bitmap is valid. */      Display *display;           /* Display for which bitmap is valid. */
62      int resourceRefCount;       /* Number of active uses of this bitmap (each      int resourceRefCount;       /* Number of active uses of this bitmap (each
63                                   * active use corresponds to a call to                                   * active use corresponds to a call to
64                                   * Tk_AllocBitmapFromObj or Tk_GetBitmap).                                   * Tk_AllocBitmapFromObj or Tk_GetBitmap).
65                                   * If this count is 0, then this TkBitmap                                   * If this count is 0, then this TkBitmap
66                                   * structure is no longer valid and it isn't                                   * structure is no longer valid and it isn't
67                                   * present in nameTable: it is being kept                                   * present in nameTable: it is being kept
68                                   * around only because there are objects                                   * around only because there are objects
69                                   * referring to it.  The structure is freed                                   * referring to it.  The structure is freed
70                                   * when resourceRefCount and objRefCount                                   * when resourceRefCount and objRefCount
71                                   * are both 0. */                                   * are both 0. */
72      int objRefCount;            /* Number of Tcl_Obj's that reference      int objRefCount;            /* Number of Tcl_Obj's that reference
73                                   * this structure. */                                   * this structure. */
74      Tcl_HashEntry *nameHashPtr; /* Entry in nameTable for this structure      Tcl_HashEntry *nameHashPtr; /* Entry in nameTable for this structure
75                                   * (needed when deleting). */                                   * (needed when deleting). */
76      Tcl_HashEntry *idHashPtr;   /* Entry in idTable for this structure      Tcl_HashEntry *idHashPtr;   /* Entry in idTable for this structure
77                                   * (needed when deleting). */                                   * (needed when deleting). */
78      struct TkBitmap *nextPtr;   /* Points to the next TkBitmap structure with      struct TkBitmap *nextPtr;   /* Points to the next TkBitmap structure with
79                                   * the same name.  All bitmaps with the                                   * the same name.  All bitmaps with the
80                                   * same name (but different displays) are                                   * same name (but different displays) are
81                                   * chained together off a single entry in                                   * chained together off a single entry in
82                                   * nameTable. */                                   * nameTable. */
83  } TkBitmap;  } TkBitmap;
84    
85  /*  /*
86   * Used in bitmapDataTable, stored in the TkDisplay structure, to map   * Used in bitmapDataTable, stored in the TkDisplay structure, to map
87   * between in-core data about a bitmap to its TkBitmap structure.   * between in-core data about a bitmap to its TkBitmap structure.
88   */   */
89    
90  typedef struct {  typedef struct {
91      char *source;               /* Bitmap bits. */      char *source;               /* Bitmap bits. */
92      int width, height;          /* Dimensions of bitmap. */      int width, height;          /* Dimensions of bitmap. */
93  } DataKey;  } DataKey;
94    
95  typedef struct ThreadSpecificData {  typedef struct ThreadSpecificData {
96      int initialized;            /* 0 means table below needs initializing. */      int initialized;            /* 0 means table below needs initializing. */
97      Tcl_HashTable predefBitmapTable;      Tcl_HashTable predefBitmapTable;
98                                  /* Hash table created by Tk_DefineBitmap                                  /* Hash table created by Tk_DefineBitmap
99                                   * to map from a name to a collection                                   * to map from a name to a collection
100                                   * of in-core data about a bitmap.  The                                   * of in-core data about a bitmap.  The
101                                   * table is indexed by the address of the                                   * table is indexed by the address of the
102                                   * data for the bitmap, and the entries                                   * data for the bitmap, and the entries
103                                   * contain pointers to TkPredefBitmap                                   * contain pointers to TkPredefBitmap
104                                   * structures. */                                   * structures. */
105  } ThreadSpecificData;  } ThreadSpecificData;
106  static Tcl_ThreadDataKey dataKey;  static Tcl_ThreadDataKey dataKey;
107    
108  /*  /*
109   * Forward declarations for procedures defined in this file:   * Forward declarations for procedures defined in this file:
110   */   */
111    
112  static void             BitmapInit _ANSI_ARGS_((TkDisplay *dispPtr));  static void             BitmapInit _ANSI_ARGS_((TkDisplay *dispPtr));
113  static void             DupBitmapObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr,  static void             DupBitmapObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr,
114                              Tcl_Obj *dupObjPtr));                              Tcl_Obj *dupObjPtr));
115  static void             FreeBitmap _ANSI_ARGS_((TkBitmap *bitmapPtr));  static void             FreeBitmap _ANSI_ARGS_((TkBitmap *bitmapPtr));
116  static void             FreeBitmapObjProc _ANSI_ARGS_((Tcl_Obj *objPtr));  static void             FreeBitmapObjProc _ANSI_ARGS_((Tcl_Obj *objPtr));
117  static TkBitmap *       GetBitmap _ANSI_ARGS_((Tcl_Interp *interp,  static TkBitmap *       GetBitmap _ANSI_ARGS_((Tcl_Interp *interp,
118                              Tk_Window tkwin, CONST char *name));                              Tk_Window tkwin, CONST char *name));
119  static TkBitmap *       GetBitmapFromObj _ANSI_ARGS_((Tk_Window tkwin,  static TkBitmap *       GetBitmapFromObj _ANSI_ARGS_((Tk_Window tkwin,
120                              Tcl_Obj *objPtr));                              Tcl_Obj *objPtr));
121  static void             InitBitmapObj _ANSI_ARGS_((Tcl_Obj *objPtr));  static void             InitBitmapObj _ANSI_ARGS_((Tcl_Obj *objPtr));
122    
123  /*  /*
124   * The following structure defines the implementation of the "bitmap" Tcl   * The following structure defines the implementation of the "bitmap" Tcl
125   * object, which maps a string bitmap name to a TkBitmap object.  The   * object, which maps a string bitmap name to a TkBitmap object.  The
126   * ptr1 field of the Tcl_Obj points to a TkBitmap object.   * ptr1 field of the Tcl_Obj points to a TkBitmap object.
127   */   */
128    
129  static Tcl_ObjType bitmapObjType = {  static Tcl_ObjType bitmapObjType = {
130      "bitmap",                   /* name */      "bitmap",                   /* name */
131      FreeBitmapObjProc,          /* freeIntRepProc */      FreeBitmapObjProc,          /* freeIntRepProc */
132      DupBitmapObjProc,           /* dupIntRepProc */      DupBitmapObjProc,           /* dupIntRepProc */
133      NULL,                       /* updateStringProc */      NULL,                       /* updateStringProc */
134      NULL                        /* setFromAnyProc */      NULL                        /* setFromAnyProc */
135  };  };
136    
137  /*  /*
138   *----------------------------------------------------------------------   *----------------------------------------------------------------------
139   *   *
140   * Tk_AllocBitmapFromObj --   * Tk_AllocBitmapFromObj --
141   *   *
142   *      Given a Tcl_Obj *, map the value to a corresponding   *      Given a Tcl_Obj *, map the value to a corresponding
143   *      Pixmap structure based on the tkwin given.   *      Pixmap structure based on the tkwin given.
144   *   *
145   * Results:   * Results:
146   *      The return value is the X identifer for the desired bitmap   *      The return value is the X identifer for the desired bitmap
147   *      (i.e. a Pixmap with a single plane), unless string couldn't be   *      (i.e. a Pixmap with a single plane), unless string couldn't be
148   *      parsed correctly.  In this case, None is returned and an error   *      parsed correctly.  In this case, None is returned and an error
149   *      message is left in the interp's result.  The caller should never   *      message is left in the interp's result.  The caller should never
150   *      modify the bitmap that is returned, and should eventually call   *      modify the bitmap that is returned, and should eventually call
151   *      Tk_FreeBitmapFromObj when the bitmap is no longer needed.   *      Tk_FreeBitmapFromObj when the bitmap is no longer needed.
152   *   *
153   * Side effects:   * Side effects:
154   *      The bitmap is added to an internal database with a reference count.   *      The bitmap is added to an internal database with a reference count.
155   *      For each call to this procedure, there should eventually be a call   *      For each call to this procedure, there should eventually be a call
156   *      to Tk_FreeBitmapFromObj, so that the database can be cleaned up   *      to Tk_FreeBitmapFromObj, so that the database can be cleaned up
157   *      when bitmaps aren't needed anymore.   *      when bitmaps aren't needed anymore.
158   *   *
159   *----------------------------------------------------------------------   *----------------------------------------------------------------------
160   */   */
161    
162  Pixmap  Pixmap
163  Tk_AllocBitmapFromObj(interp, tkwin, objPtr)  Tk_AllocBitmapFromObj(interp, tkwin, objPtr)
164      Tcl_Interp *interp;         /* Interp for error results. This may      Tcl_Interp *interp;         /* Interp for error results. This may
165                                   * be NULL. */                                   * be NULL. */
166      Tk_Window tkwin;            /* Need the screen the bitmap is used on.*/      Tk_Window tkwin;            /* Need the screen the bitmap is used on.*/
167      Tcl_Obj *objPtr;            /* Object describing bitmap; see manual      Tcl_Obj *objPtr;            /* Object describing bitmap; see manual
168                                   * entry for legal syntax of string value. */                                   * entry for legal syntax of string value. */
169  {  {
170      TkBitmap *bitmapPtr;      TkBitmap *bitmapPtr;
171    
172      if (objPtr->typePtr != &bitmapObjType) {      if (objPtr->typePtr != &bitmapObjType) {
173          InitBitmapObj(objPtr);          InitBitmapObj(objPtr);
174      }      }
175      bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;      bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
176    
177      /*      /*
178       * If the object currently points to a TkBitmap, see if it's the       * If the object currently points to a TkBitmap, see if it's the
179       * one we want.  If so, increment its reference count and return.       * one we want.  If so, increment its reference count and return.
180       */       */
181    
182      if (bitmapPtr != NULL) {      if (bitmapPtr != NULL) {
183          if (bitmapPtr->resourceRefCount == 0) {          if (bitmapPtr->resourceRefCount == 0) {
184              /*              /*
185               * This is a stale reference: it refers to a TkBitmap that's               * This is a stale reference: it refers to a TkBitmap that's
186               * no longer in use.  Clear the reference.               * no longer in use.  Clear the reference.
187               */               */
188    
189              FreeBitmapObjProc(objPtr);              FreeBitmapObjProc(objPtr);
190              bitmapPtr = NULL;              bitmapPtr = NULL;
191          } else if (Tk_Display(tkwin) == bitmapPtr->display) {          } else if (Tk_Display(tkwin) == bitmapPtr->display) {
192              bitmapPtr->resourceRefCount++;              bitmapPtr->resourceRefCount++;
193              return bitmapPtr->bitmap;              return bitmapPtr->bitmap;
194          }          }
195      }      }
196    
197      /*      /*
198       * The object didn't point to the TkBitmap that we wanted.  Search       * The object didn't point to the TkBitmap that we wanted.  Search
199       * the list of TkBitmaps with the same name to see if one of the       * the list of TkBitmaps with the same name to see if one of the
200       * others is the right one.       * others is the right one.
201       */       */
202    
203      if (bitmapPtr != NULL) {      if (bitmapPtr != NULL) {
204          TkBitmap *firstBitmapPtr =          TkBitmap *firstBitmapPtr =
205                  (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr);                  (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr);
206          FreeBitmapObjProc(objPtr);          FreeBitmapObjProc(objPtr);
207          for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL;          for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL;
208                  bitmapPtr = bitmapPtr->nextPtr) {                  bitmapPtr = bitmapPtr->nextPtr) {
209              if (Tk_Display(tkwin) == bitmapPtr->display) {              if (Tk_Display(tkwin) == bitmapPtr->display) {
210                  bitmapPtr->resourceRefCount++;                  bitmapPtr->resourceRefCount++;
211                  bitmapPtr->objRefCount++;                  bitmapPtr->objRefCount++;
212                  objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;                  objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
213                  return bitmapPtr->bitmap;                  return bitmapPtr->bitmap;
214              }              }
215          }          }
216      }      }
217    
218      /*      /*
219       * Still no luck.  Call GetBitmap to allocate a new TkBitmap object.       * Still no luck.  Call GetBitmap to allocate a new TkBitmap object.
220       */       */
221    
222      bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr));      bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr));
223      objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;      objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
224      if (bitmapPtr == NULL) {      if (bitmapPtr == NULL) {
225          return None;          return None;
226      }      }
227      bitmapPtr->objRefCount++;      bitmapPtr->objRefCount++;
228      return bitmapPtr->bitmap;      return bitmapPtr->bitmap;
229  }  }
230    
231  /*  /*
232   *----------------------------------------------------------------------   *----------------------------------------------------------------------
233   *   *
234   * Tk_GetBitmap --   * Tk_GetBitmap --
235   *   *
236   *      Given a string describing a bitmap, locate (or create if necessary)   *      Given a string describing a bitmap, locate (or create if necessary)
237   *      a bitmap that fits the description.   *      a bitmap that fits the description.
238   *   *
239   * Results:   * Results:
240   *      The return value is the X identifer for the desired bitmap   *      The return value is the X identifer for the desired bitmap
241   *      (i.e. a Pixmap with a single plane), unless string couldn't be   *      (i.e. a Pixmap with a single plane), unless string couldn't be
242   *      parsed correctly.  In this case, None is returned and an error   *      parsed correctly.  In this case, None is returned and an error
243   *      message is left in the interp's result.  The caller should never   *      message is left in the interp's result.  The caller should never
244   *      modify the bitmap that is returned, and should eventually call   *      modify the bitmap that is returned, and should eventually call
245   *      Tk_FreeBitmap when the bitmap is no longer needed.   *      Tk_FreeBitmap when the bitmap is no longer needed.
246   *   *
247   * Side effects:   * Side effects:
248   *      The bitmap is added to an internal database with a reference count.   *      The bitmap is added to an internal database with a reference count.
249   *      For each call to this procedure, there should eventually be a call   *      For each call to this procedure, there should eventually be a call
250   *      to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps   *      to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
251   *      aren't needed anymore.   *      aren't needed anymore.
252   *   *
253   *----------------------------------------------------------------------   *----------------------------------------------------------------------
254   */   */
255    
256  Pixmap  Pixmap
257  Tk_GetBitmap(interp, tkwin, string)  Tk_GetBitmap(interp, tkwin, string)
258      Tcl_Interp *interp;         /* Interpreter to use for error reporting,      Tcl_Interp *interp;         /* Interpreter to use for error reporting,
259                                   * this may be NULL. */                                   * this may be NULL. */
260      Tk_Window tkwin;            /* Window in which bitmap will be used. */      Tk_Window tkwin;            /* Window in which bitmap will be used. */
261      CONST char *string;         /* Description of bitmap.  See manual entry      CONST char *string;         /* Description of bitmap.  See manual entry
262                                   * for details on legal syntax. */                                   * for details on legal syntax. */
263  {  {
264      TkBitmap *bitmapPtr = GetBitmap(interp, tkwin, string);      TkBitmap *bitmapPtr = GetBitmap(interp, tkwin, string);
265      if (bitmapPtr == NULL) {      if (bitmapPtr == NULL) {
266          return None;          return None;
267      }      }
268      return bitmapPtr->bitmap;      return bitmapPtr->bitmap;
269  }  }
270    
271  /*  /*
272   *----------------------------------------------------------------------   *----------------------------------------------------------------------
273   *   *
274   * GetBitmap --   * GetBitmap --
275   *   *
276   *      Given a string describing a bitmap, locate (or create if necessary)   *      Given a string describing a bitmap, locate (or create if necessary)
277   *      a bitmap that fits the description. This routine returns the   *      a bitmap that fits the description. This routine returns the
278   *      internal data structure for the bitmap. This avoids extra   *      internal data structure for the bitmap. This avoids extra
279   *      hash table lookups in Tk_AllocBitmapFromObj.   *      hash table lookups in Tk_AllocBitmapFromObj.
280   *   *
281   * Results:   * Results:
282   *      The return value is the X identifer for the desired bitmap   *      The return value is the X identifer for the desired bitmap
283   *      (i.e. a Pixmap with a single plane), unless string couldn't be   *      (i.e. a Pixmap with a single plane), unless string couldn't be
284   *      parsed correctly.  In this case, None is returned and an error   *      parsed correctly.  In this case, None is returned and an error
285   *      message is left in the interp's result.  The caller should never   *      message is left in the interp's result.  The caller should never
286   *      modify the bitmap that is returned, and should eventually call   *      modify the bitmap that is returned, and should eventually call
287   *      Tk_FreeBitmap when the bitmap is no longer needed.   *      Tk_FreeBitmap when the bitmap is no longer needed.
288   *   *
289   * Side effects:   * Side effects:
290   *      The bitmap is added to an internal database with a reference count.   *      The bitmap is added to an internal database with a reference count.
291   *      For each call to this procedure, there should eventually be a call   *      For each call to this procedure, there should eventually be a call
292   *      to Tk_FreeBitmap or Tk_FreeBitmapFromObj, so that the database can   *      to Tk_FreeBitmap or Tk_FreeBitmapFromObj, so that the database can
293   *      be cleaned up when bitmaps aren't needed anymore.   *      be cleaned up when bitmaps aren't needed anymore.
294   *   *
295   *----------------------------------------------------------------------   *----------------------------------------------------------------------
296   */   */
297    
298  static TkBitmap *  static TkBitmap *
299  GetBitmap(interp, tkwin, string)  GetBitmap(interp, tkwin, string)
300      Tcl_Interp *interp;         /* Interpreter to use for error reporting,      Tcl_Interp *interp;         /* Interpreter to use for error reporting,
301                                   * this may be NULL. */                                   * this may be NULL. */
302      Tk_Window tkwin;            /* Window in which bitmap will be used. */      Tk_Window tkwin;            /* Window in which bitmap will be used. */
303      CONST char *string;         /* Description of bitmap.  See manual entry      CONST char *string;         /* Description of bitmap.  See manual entry
304                                   * for details on legal syntax. */                                   * for details on legal syntax. */
305  {  {
306      Tcl_HashEntry *nameHashPtr, *predefHashPtr;      Tcl_HashEntry *nameHashPtr, *predefHashPtr;
307      TkBitmap *bitmapPtr, *existingBitmapPtr;      TkBitmap *bitmapPtr, *existingBitmapPtr;
308      TkPredefBitmap *predefPtr;      TkPredefBitmap *predefPtr;
309      int new;      int new;
310      Pixmap bitmap;      Pixmap bitmap;
311      int width, height;      int width, height;
312      int dummy2;      int dummy2;
313      TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;      TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
314      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
315              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
316    
317      if (!dispPtr->bitmapInit) {      if (!dispPtr->bitmapInit) {
318          BitmapInit(dispPtr);          BitmapInit(dispPtr);
319      }      }
320    
321      nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string, &new);      nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string, &new);
322      if (!new) {      if (!new) {
323          existingBitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr);          existingBitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr);
324          for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL;          for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL;
325                  bitmapPtr = bitmapPtr->nextPtr) {                  bitmapPtr = bitmapPtr->nextPtr) {
326              if (Tk_Display(tkwin) == bitmapPtr->display) {              if (Tk_Display(tkwin) == bitmapPtr->display) {
327                  bitmapPtr->resourceRefCount++;                  bitmapPtr->resourceRefCount++;
328                  return bitmapPtr;                  return bitmapPtr;
329              }              }
330          }          }
331      } else {      } else {
332          existingBitmapPtr = NULL;          existingBitmapPtr = NULL;
333      }      }
334    
335      /*      /*
336       * No suitable bitmap exists.  Create a new bitmap from the       * No suitable bitmap exists.  Create a new bitmap from the
337       * information contained in the string.  If the string starts       * information contained in the string.  If the string starts
338       * with "@" then the rest of the string is a file name containing       * with "@" then the rest of the string is a file name containing
339       * the bitmap.  Otherwise the string must refer to a bitmap       * the bitmap.  Otherwise the string must refer to a bitmap
340       * defined by a call to Tk_DefineBitmap.       * defined by a call to Tk_DefineBitmap.
341       */       */
342    
343      if (*string == '@') {       /* INTL: ISO char */      if (*string == '@') {       /* INTL: ISO char */
344          Tcl_DString buffer;          Tcl_DString buffer;
345          int result;          int result;
346    
347          if (Tcl_IsSafe(interp)) {          if (Tcl_IsSafe(interp)) {
348              Tcl_AppendResult(interp, "can't specify bitmap with '@' in a",              Tcl_AppendResult(interp, "can't specify bitmap with '@' in a",
349                      " safe interpreter", (char *) NULL);                      " safe interpreter", (char *) NULL);
350              goto error;              goto error;
351          }          }
352    
353          /*          /*
354           * Note that we need to cast away the CONST from the string because           * Note that we need to cast away the CONST from the string because
355           * Tcl_TranslateFileName is non const, even though it doesn't modify           * Tcl_TranslateFileName is non const, even though it doesn't modify
356           * the string.           * the string.
357           */           */
358    
359          string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer);          string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer);
360          if (string == NULL) {          if (string == NULL) {
361              goto error;              goto error;
362          }          }
363          result = TkReadBitmapFile(Tk_Display(tkwin),          result = TkReadBitmapFile(Tk_Display(tkwin),
364                  RootWindowOfScreen(Tk_Screen(tkwin)), string,                  RootWindowOfScreen(Tk_Screen(tkwin)), string,
365                  (unsigned int *) &width, (unsigned int *) &height,                  (unsigned int *) &width, (unsigned int *) &height,
366                  &bitmap, &dummy2, &dummy2);                  &bitmap, &dummy2, &dummy2);
367          if (result != BitmapSuccess) {          if (result != BitmapSuccess) {
368              if (interp != NULL) {              if (interp != NULL) {
369                  Tcl_AppendResult(interp, "error reading bitmap file \"", string,                  Tcl_AppendResult(interp, "error reading bitmap file \"", string,
370                      "\"", (char *) NULL);                      "\"", (char *) NULL);
371              }              }
372              Tcl_DStringFree(&buffer);              Tcl_DStringFree(&buffer);
373              goto error;              goto error;
374          }          }
375          Tcl_DStringFree(&buffer);          Tcl_DStringFree(&buffer);
376      } else {      } else {
377          predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable,          predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable,
378                  string);                  string);
379          if (predefHashPtr == NULL) {          if (predefHashPtr == NULL) {
380              /*              /*
381               * The following platform specific call allows the user to               * The following platform specific call allows the user to
382               * define bitmaps that may only exist during run time.  If               * define bitmaps that may only exist during run time.  If
383               * it returns None nothing was found and we return the error.               * it returns None nothing was found and we return the error.
384               */               */
385              bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,              bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,
386                      &width, &height);                      &width, &height);
387                            
388              if (bitmap == None) {              if (bitmap == None) {
389                  if (interp != NULL) {                  if (interp != NULL) {
390                      Tcl_AppendResult(interp, "bitmap \"", string,                      Tcl_AppendResult(interp, "bitmap \"", string,
391                          "\" not defined", (char *) NULL);                          "\" not defined", (char *) NULL);
392                  }                  }
393                  goto error;                  goto error;
394              }              }
395          } else {          } else {
396              predefPtr = (TkPredefBitmap *) Tcl_GetHashValue(predefHashPtr);              predefPtr = (TkPredefBitmap *) Tcl_GetHashValue(predefHashPtr);
397              width = predefPtr->width;              width = predefPtr->width;
398              height = predefPtr->height;              height = predefPtr->height;
399              if (predefPtr->native) {              if (predefPtr->native) {
400                  bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),                  bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),
401                      predefPtr->source);                      predefPtr->source);
402                  if (bitmap == None) {                  if (bitmap == None) {
403                      panic("native bitmap creation failed");                      panic("native bitmap creation failed");
404                  }                  }
405              } else {              } else {
406                  bitmap = XCreateBitmapFromData(Tk_Display(tkwin),                  bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
407                      RootWindowOfScreen(Tk_Screen(tkwin)),                      RootWindowOfScreen(Tk_Screen(tkwin)),
408                      predefPtr->source,                      predefPtr->source,
409                      (unsigned) width, (unsigned) height);                      (unsigned) width, (unsigned) height);
410              }              }
411          }          }
412      }      }
413    
414      /*      /*
415       * Add information about this bitmap to our database.       * Add information about this bitmap to our database.
416       */       */
417    
418      bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap));      bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap));
419      bitmapPtr->bitmap = bitmap;      bitmapPtr->bitmap = bitmap;
420      bitmapPtr->width = width;      bitmapPtr->width = width;
421      bitmapPtr->height = height;      bitmapPtr->height = height;
422      bitmapPtr->display = Tk_Display(tkwin);      bitmapPtr->display = Tk_Display(tkwin);
423      bitmapPtr->resourceRefCount = 1;      bitmapPtr->resourceRefCount = 1;
424      bitmapPtr->objRefCount = 0;      bitmapPtr->objRefCount = 0;
425      bitmapPtr->nameHashPtr = nameHashPtr;      bitmapPtr->nameHashPtr = nameHashPtr;
426      bitmapPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapIdTable,      bitmapPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapIdTable,
427              (char *) bitmap, &new);              (char *) bitmap, &new);
428      if (!new) {      if (!new) {
429          panic("bitmap already registered in Tk_GetBitmap");          panic("bitmap already registered in Tk_GetBitmap");
430      }      }
431      bitmapPtr->nextPtr = existingBitmapPtr;      bitmapPtr->nextPtr = existingBitmapPtr;
432      Tcl_SetHashValue(nameHashPtr, bitmapPtr);      Tcl_SetHashValue(nameHashPtr, bitmapPtr);
433      Tcl_SetHashValue(bitmapPtr->idHashPtr, bitmapPtr);      Tcl_SetHashValue(bitmapPtr->idHashPtr, bitmapPtr);
434      return bitmapPtr;      return bitmapPtr;
435    
436      error:      error:
437      if (new) {      if (new) {
438          Tcl_DeleteHashEntry(nameHashPtr);          Tcl_DeleteHashEntry(nameHashPtr);
439      }      }
440      return NULL;      return NULL;
441  }  }
442    
443  /*  /*
444   *----------------------------------------------------------------------   *----------------------------------------------------------------------
445   *   *
446   * Tk_DefineBitmap --   * Tk_DefineBitmap --
447   *   *
448   *      This procedure associates a textual name with a binary bitmap   *      This procedure associates a textual name with a binary bitmap
449   *      description, so that the name may be used to refer to the   *      description, so that the name may be used to refer to the
450   *      bitmap in future calls to Tk_GetBitmap.   *      bitmap in future calls to Tk_GetBitmap.
451   *   *
452   * Results:   * Results:
453   *      A standard Tcl result.  If an error occurs then TCL_ERROR is   *      A standard Tcl result.  If an error occurs then TCL_ERROR is
454   *      returned and a message is left in the interp's result.   *      returned and a message is left in the interp's result.
455   *   *
456   * Side effects:   * Side effects:
457   *      "Name" is entered into the bitmap table and may be used from   *      "Name" is entered into the bitmap table and may be used from
458   *      here on to refer to the given bitmap.   *      here on to refer to the given bitmap.
459   *   *
460   *----------------------------------------------------------------------   *----------------------------------------------------------------------
461   */   */
462    
463  int  int
464  Tk_DefineBitmap(interp, name, source, width, height)  Tk_DefineBitmap(interp, name, source, width, height)
465      Tcl_Interp *interp;         /* Interpreter to use for error reporting. */      Tcl_Interp *interp;         /* Interpreter to use for error reporting. */
466      CONST char *name;           /* Name to use for bitmap.  Must not already      CONST char *name;           /* Name to use for bitmap.  Must not already
467                                   * be defined as a bitmap. */                                   * be defined as a bitmap. */
468      char *source;               /* Address of bits for bitmap. */      char *source;               /* Address of bits for bitmap. */
469      int width;                  /* Width of bitmap. */      int width;                  /* Width of bitmap. */
470      int height;                 /* Height of bitmap. */      int height;                 /* Height of bitmap. */
471  {  {
472      int new;      int new;
473      Tcl_HashEntry *predefHashPtr;      Tcl_HashEntry *predefHashPtr;
474      TkPredefBitmap *predefPtr;      TkPredefBitmap *predefPtr;
475      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
476              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
477    
478      /*      /*
479       * Initialize the Bitmap module if not initialized already for this       * Initialize the Bitmap module if not initialized already for this
480       * thread.  Since the current TkDisplay structure cannot be       * thread.  Since the current TkDisplay structure cannot be
481       * introspected from here, pass a NULL pointer to BitmapInit,       * introspected from here, pass a NULL pointer to BitmapInit,
482       * which will know to initialize only the data in the       * which will know to initialize only the data in the
483       * ThreadSpecificData structure for the current thread.       * ThreadSpecificData structure for the current thread.
484       */       */
485    
486      if (!tsdPtr->initialized) {      if (!tsdPtr->initialized) {
487          BitmapInit((TkDisplay *) NULL);          BitmapInit((TkDisplay *) NULL);
488      }      }
489    
490      predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable,      predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable,
491              name, &new);              name, &new);
492      if (!new) {      if (!new) {
493          Tcl_AppendResult(interp, "bitmap \"", name,          Tcl_AppendResult(interp, "bitmap \"", name,
494                  "\" is already defined", (char *) NULL);                  "\" is already defined", (char *) NULL);
495          return TCL_ERROR;          return TCL_ERROR;
496      }      }
497      predefPtr = (TkPredefBitmap *) ckalloc(sizeof(TkPredefBitmap));      predefPtr = (TkPredefBitmap *) ckalloc(sizeof(TkPredefBitmap));
498      predefPtr->source = source;      predefPtr->source = source;
499      predefPtr->width = width;      predefPtr->width = width;
500      predefPtr->height = height;      predefPtr->height = height;
501      predefPtr->native = 0;      predefPtr->native = 0;
502      Tcl_SetHashValue(predefHashPtr, predefPtr);      Tcl_SetHashValue(predefHashPtr, predefPtr);
503      return TCL_OK;      return TCL_OK;
504  }  }
505    
506  /*  /*
507   *--------------------------------------------------------------   *--------------------------------------------------------------
508   *   *
509   * Tk_NameOfBitmap --   * Tk_NameOfBitmap --
510   *   *
511   *      Given a bitmap, return a textual string identifying the   *      Given a bitmap, return a textual string identifying the
512   *      bitmap.   *      bitmap.
513   *   *
514   * Results:   * Results:
515   *      The return value is the string name associated with bitmap.   *      The return value is the string name associated with bitmap.
516   *   *
517   * Side effects:   * Side effects:
518   *      None.   *      None.
519   *   *
520   *--------------------------------------------------------------   *--------------------------------------------------------------
521   */   */
522    
523  char *  char *
524  Tk_NameOfBitmap(display, bitmap)  Tk_NameOfBitmap(display, bitmap)
525      Display *display;                   /* Display for which bitmap was      Display *display;                   /* Display for which bitmap was
526                                           * allocated. */                                           * allocated. */
527      Pixmap bitmap;                      /* Bitmap whose name is wanted. */      Pixmap bitmap;                      /* Bitmap whose name is wanted. */
528  {  {
529      Tcl_HashEntry *idHashPtr;      Tcl_HashEntry *idHashPtr;
530      TkBitmap *bitmapPtr;      TkBitmap *bitmapPtr;
531      TkDisplay *dispPtr = TkGetDisplay(display);      TkDisplay *dispPtr = TkGetDisplay(display);
532    
533      if (dispPtr == NULL || !dispPtr->bitmapInit) {      if (dispPtr == NULL || !dispPtr->bitmapInit) {
534          unknown:          unknown:
535          panic("Tk_NameOfBitmap received unknown bitmap argument");          panic("Tk_NameOfBitmap received unknown bitmap argument");
536      }      }
537    
538      idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);      idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
539      if (idHashPtr == NULL) {      if (idHashPtr == NULL) {
540          goto unknown;          goto unknown;
541      }      }
542      bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);      bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
543      return bitmapPtr->nameHashPtr->key.string;      return bitmapPtr->nameHashPtr->key.string;
544  }  }
545    
546  /*  /*
547   *--------------------------------------------------------------   *--------------------------------------------------------------
548   *   *
549   * Tk_SizeOfBitmap --   * Tk_SizeOfBitmap --
550   *   *
551   *      Given a bitmap managed by this module, returns the width   *      Given a bitmap managed by this module, returns the width
552   *      and height of the bitmap.   *      and height of the bitmap.
553   *   *
554   * Results:   * Results:
555   *      The words at *widthPtr and *heightPtr are filled in with   *      The words at *widthPtr and *heightPtr are filled in with
556   *      the dimenstions of bitmap.   *      the dimenstions of bitmap.
557   *   *
558   * Side effects:   * Side effects:
559   *      If bitmap isn't managed by this module then the procedure   *      If bitmap isn't managed by this module then the procedure
560   *      panics..   *      panics..
561   *   *
562   *--------------------------------------------------------------   *--------------------------------------------------------------
563   */   */
564    
565  void  void
566  Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr)  Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr)
567      Display *display;                   /* Display for which bitmap was      Display *display;                   /* Display for which bitmap was
568                                           * allocated. */                                           * allocated. */
569      Pixmap bitmap;                      /* Bitmap whose size is wanted. */      Pixmap bitmap;                      /* Bitmap whose size is wanted. */
570      int *widthPtr;                      /* Store bitmap width here. */      int *widthPtr;                      /* Store bitmap width here. */
571      int *heightPtr;                     /* Store bitmap height here. */      int *heightPtr;                     /* Store bitmap height here. */
572  {  {
573      Tcl_HashEntry *idHashPtr;      Tcl_HashEntry *idHashPtr;
574      TkBitmap *bitmapPtr;      TkBitmap *bitmapPtr;
575      TkDisplay *dispPtr = TkGetDisplay(display);      TkDisplay *dispPtr = TkGetDisplay(display);
576    
577      if (!dispPtr->bitmapInit) {      if (!dispPtr->bitmapInit) {
578          unknownBitmap:          unknownBitmap:
579          panic("Tk_SizeOfBitmap received unknown bitmap argument");          panic("Tk_SizeOfBitmap received unknown bitmap argument");
580      }      }
581    
582      idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);      idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
583      if (idHashPtr == NULL) {      if (idHashPtr == NULL) {
584          goto unknownBitmap;          goto unknownBitmap;
585      }      }
586      bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);      bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
587      *widthPtr = bitmapPtr->width;      *widthPtr = bitmapPtr->width;
588      *heightPtr = bitmapPtr->height;      *heightPtr = bitmapPtr->height;
589  }  }
590    
591  /*  /*
592   *----------------------------------------------------------------------   *----------------------------------------------------------------------
593   *   *
594   * FreeBitmap --   * FreeBitmap --
595   *   *
596   *      This procedure does all the work of releasing a bitmap allocated by   *      This procedure does all the work of releasing a bitmap allocated by
597   *      Tk_GetBitmap or TkGetBitmapFromData.  It is invoked by both   *      Tk_GetBitmap or TkGetBitmapFromData.  It is invoked by both
598   *      Tk_FreeBitmap and Tk_FreeBitmapFromObj   *      Tk_FreeBitmap and Tk_FreeBitmapFromObj
599   *   *
600   * Results:   * Results:
601   *      None.   *      None.
602   *   *
603   * Side effects:   * Side effects:
604   *      The reference count associated with bitmap is decremented, and   *      The reference count associated with bitmap is decremented, and
605   *      it is officially deallocated if no-one is using it anymore.   *      it is officially deallocated if no-one is using it anymore.
606   *   *
607   *----------------------------------------------------------------------   *----------------------------------------------------------------------
608   */   */
609    
610  static void  static void
611  FreeBitmap(bitmapPtr)  FreeBitmap(bitmapPtr)
612      TkBitmap *bitmapPtr;                        /* Bitmap to be released. */      TkBitmap *bitmapPtr;                        /* Bitmap to be released. */
613  {  {
614      TkBitmap *prevPtr;      TkBitmap *prevPtr;
615    
616      bitmapPtr->resourceRefCount--;      bitmapPtr->resourceRefCount--;
617      if (bitmapPtr->resourceRefCount > 0) {      if (bitmapPtr->resourceRefCount > 0) {
618          return;          return;
619      }      }
620    
621      Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap);      Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap);
622      Tcl_DeleteHashEntry(bitmapPtr->idHashPtr);      Tcl_DeleteHashEntry(bitmapPtr->idHashPtr);
623      prevPtr = (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr);      prevPtr = (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr);
624      if (prevPtr == bitmapPtr) {      if (prevPtr == bitmapPtr) {
625          if (bitmapPtr->nextPtr == NULL) {          if (bitmapPtr->nextPtr == NULL) {
626              Tcl_DeleteHashEntry(bitmapPtr->nameHashPtr);              Tcl_DeleteHashEntry(bitmapPtr->nameHashPtr);
627          } else {          } else {
628              Tcl_SetHashValue(bitmapPtr->nameHashPtr, bitmapPtr->nextPtr);              Tcl_SetHashValue(bitmapPtr->nameHashPtr, bitmapPtr->nextPtr);
629          }          }
630      } else {      } else {
631          while (prevPtr->nextPtr != bitmapPtr) {          while (prevPtr->nextPtr != bitmapPtr) {
632              prevPtr = prevPtr->nextPtr;              prevPtr = prevPtr->nextPtr;
633          }          }
634          prevPtr->nextPtr = bitmapPtr->nextPtr;          prevPtr->nextPtr = bitmapPtr->nextPtr;
635      }      }
636      if (bitmapPtr->objRefCount == 0) {      if (bitmapPtr->objRefCount == 0) {
637          ckfree((char *) bitmapPtr);          ckfree((char *) bitmapPtr);
638      }      }
639  }  }
640    
641  /*  /*
642   *----------------------------------------------------------------------   *----------------------------------------------------------------------
643   *   *
644   * Tk_FreeBitmap --   * Tk_FreeBitmap --
645   *   *
646   *      This procedure is called to release a bitmap allocated by   *      This procedure is called to release a bitmap allocated by
647   *      Tk_GetBitmap or TkGetBitmapFromData.   *      Tk_GetBitmap or TkGetBitmapFromData.
648   *   *
649   * Results:   * Results:
650   *      None.   *      None.
651   *   *
652   * Side effects:   * Side effects:
653   *      The reference count associated with bitmap is decremented, and   *      The reference count associated with bitmap is decremented, and
654   *      it is officially deallocated if no-one is using it anymore.   *      it is officially deallocated if no-one is using it anymore.
655   *   *
656   *----------------------------------------------------------------------   *----------------------------------------------------------------------
657   */   */
658    
659  void  void
660  Tk_FreeBitmap(display, bitmap)  Tk_FreeBitmap(display, bitmap)
661      Display *display;                   /* Display for which bitmap was      Display *display;                   /* Display for which bitmap was
662                                           * allocated. */                                           * allocated. */
663      Pixmap bitmap;                      /* Bitmap to be released. */      Pixmap bitmap;                      /* Bitmap to be released. */
664  {  {
665      Tcl_HashEntry *idHashPtr;      Tcl_HashEntry *idHashPtr;
666      TkDisplay *dispPtr = TkGetDisplay(display);      TkDisplay *dispPtr = TkGetDisplay(display);
667    
668      if (!dispPtr->bitmapInit) {      if (!dispPtr->bitmapInit) {
669          panic("Tk_FreeBitmap called before Tk_GetBitmap");          panic("Tk_FreeBitmap called before Tk_GetBitmap");
670      }      }
671    
672      idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);      idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
673      if (idHashPtr == NULL) {      if (idHashPtr == NULL) {
674          panic("Tk_FreeBitmap received unknown bitmap argument");          panic("Tk_FreeBitmap received unknown bitmap argument");
675      }      }
676      FreeBitmap((TkBitmap *) Tcl_GetHashValue(idHashPtr));      FreeBitmap((TkBitmap *) Tcl_GetHashValue(idHashPtr));
677  }  }
678    
679  /*  /*
680   *----------------------------------------------------------------------   *----------------------------------------------------------------------
681   *   *
682   * Tk_FreeBitmapFromObj --   * Tk_FreeBitmapFromObj --
683   *   *
684   *      This procedure is called to release a bitmap allocated by   *      This procedure is called to release a bitmap allocated by
685   *      Tk_AllocBitmapFromObj. It does not throw away the Tcl_Obj *;   *      Tk_AllocBitmapFromObj. It does not throw away the Tcl_Obj *;
686   *      it only gets rid of the hash table entry for this bitmap   *      it only gets rid of the hash table entry for this bitmap
687   *      and clears the cached value that is normally stored in the object.   *      and clears the cached value that is normally stored in the object.
688   *   *
689   * Results:   * Results:
690   *      None.   *      None.
691   *   *
692   * Side effects:   * Side effects:
693   *      The reference count associated with the bitmap represented by   *      The reference count associated with the bitmap represented by
694   *      objPtr is decremented, and the bitmap is released to X if there are   *      objPtr is decremented, and the bitmap is released to X if there are
695   *      no remaining uses for it.   *      no remaining uses for it.
696   *   *
697   *----------------------------------------------------------------------   *----------------------------------------------------------------------
698   */   */
699    
700  void  void
701  Tk_FreeBitmapFromObj(tkwin, objPtr)  Tk_FreeBitmapFromObj(tkwin, objPtr)
702      Tk_Window tkwin;            /* The window this bitmap lives in. Needed      Tk_Window tkwin;            /* The window this bitmap lives in. Needed
703                                   * for the display value. */                                   * for the display value. */
704      Tcl_Obj *objPtr;            /* The Tcl_Obj * to be freed. */      Tcl_Obj *objPtr;            /* The Tcl_Obj * to be freed. */
705  {  {
706      FreeBitmap(GetBitmapFromObj(tkwin, objPtr));      FreeBitmap(GetBitmapFromObj(tkwin, objPtr));
707  }  }
708    
709  /*  /*
710   *---------------------------------------------------------------------------   *---------------------------------------------------------------------------
711   *   *
712   * FreeBitmapObjProc --   * FreeBitmapObjProc --
713   *   *
714   *      This proc is called to release an object reference to a bitmap.   *      This proc is called to release an object reference to a bitmap.
715   *      Called when the object's internal rep is released or when   *      Called when the object's internal rep is released or when
716   *      the cached bitmapPtr needs to be changed.   *      the cached bitmapPtr needs to be changed.
717   *   *
718   * Results:   * Results:
719   *      None.   *      None.
720   *   *
721   * Side effects:   * Side effects:
722   *      The object reference count is decremented. When both it   *      The object reference count is decremented. When both it
723   *      and the hash ref count go to zero, the color's resources   *      and the hash ref count go to zero, the color's resources
724   *      are released.   *      are released.
725   *   *
726   *---------------------------------------------------------------------------   *---------------------------------------------------------------------------
727   */   */
728    
729  static void  static void
730  FreeBitmapObjProc(objPtr)  FreeBitmapObjProc(objPtr)
731      Tcl_Obj *objPtr;            /* The object we are releasing. */      Tcl_Obj *objPtr;            /* The object we are releasing. */
732  {  {
733      TkBitmap *bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;      TkBitmap *bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
734    
735      if (bitmapPtr != NULL) {      if (bitmapPtr != NULL) {
736          bitmapPtr->objRefCount--;          bitmapPtr->objRefCount--;
737          if ((bitmapPtr->objRefCount == 0)          if ((bitmapPtr->objRefCount == 0)
738                  && (bitmapPtr->resourceRefCount == 0)) {                  && (bitmapPtr->resourceRefCount == 0)) {
739              ckfree((char *) bitmapPtr);              ckfree((char *) bitmapPtr);
740          }          }
741          objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;          objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
742      }      }
743  }  }
744    
745  /*  /*
746   *---------------------------------------------------------------------------   *---------------------------------------------------------------------------
747   *   *
748   * DupBitmapObjProc --   * DupBitmapObjProc --
749   *   *
750   *      When a cached bitmap object is duplicated, this is called to   *      When a cached bitmap object is duplicated, this is called to
751   *      update the internal reps.   *      update the internal reps.
752   *   *
753   * Results:   * Results:
754   *      None.   *      None.
755   *   *
756   * Side effects:   * Side effects:
757   *      The color's objRefCount is incremented and the internal rep   *      The color's objRefCount is incremented and the internal rep
758   *      of the copy is set to point to it.   *      of the copy is set to point to it.
759   *   *
760   *---------------------------------------------------------------------------   *---------------------------------------------------------------------------
761   */   */
762    
763  static void  static void
764  DupBitmapObjProc(srcObjPtr, dupObjPtr)  DupBitmapObjProc(srcObjPtr, dupObjPtr)
765      Tcl_Obj *srcObjPtr;         /* The object we are copying from. */      Tcl_Obj *srcObjPtr;         /* The object we are copying from. */
766      Tcl_Obj *dupObjPtr;         /* The object we are copying to. */      Tcl_Obj *dupObjPtr;         /* The object we are copying to. */
767  {  {
768      TkBitmap *bitmapPtr = (TkBitmap *) srcObjPtr->internalRep.twoPtrValue.ptr1;      TkBitmap *bitmapPtr = (TkBitmap *) srcObjPtr->internalRep.twoPtrValue.ptr1;
769            
770      dupObjPtr->typePtr = srcObjPtr->typePtr;      dupObjPtr->typePtr = srcObjPtr->typePtr;
771      dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;      dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
772    
773      if (bitmapPtr != NULL) {      if (bitmapPtr != NULL) {
774          bitmapPtr->objRefCount++;          bitmapPtr->objRefCount++;
775      }      }
776  }  }
777    
778  /*  /*
779   *----------------------------------------------------------------------   *----------------------------------------------------------------------
780   *   *
781   * Tk_GetBitmapFromData --   * Tk_GetBitmapFromData --
782   *   *
783   *      Given a description of the bits for a bitmap, make a bitmap that   *      Given a description of the bits for a bitmap, make a bitmap that
784   *      has the given properties. *** NOTE:  this procedure is obsolete   *      has the given properties. *** NOTE:  this procedure is obsolete
785   *      and really shouldn't be used anymore. ***   *      and really shouldn't be used anymore. ***
786   *   *
787   * Results:   * Results:
788   *      The return value is the X identifer for the desired bitmap   *      The return value is the X identifer for the desired bitmap
789   *      (a one-plane Pixmap), unless it couldn't be created properly.   *      (a one-plane Pixmap), unless it couldn't be created properly.
790   *      In this case, None is returned and an error message is left in   *      In this case, None is returned and an error message is left in
791   *      the interp's result.  The caller should never modify the bitmap that   *      the interp's result.  The caller should never modify the bitmap that
792   *      is returned, and should eventually call Tk_FreeBitmap when the   *      is returned, and should eventually call Tk_FreeBitmap when the
793   *      bitmap is no longer needed.   *      bitmap is no longer needed.
794   *   *
795   * Side effects:   * Side effects:
796   *      The bitmap is added to an internal database with a reference count.   *      The bitmap is added to an internal database with a reference count.
797   *      For each call to this procedure, there should eventually be a call   *      For each call to this procedure, there should eventually be a call
798   *      to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps   *      to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
799   *      aren't needed anymore.   *      aren't needed anymore.
800   *   *
801   *----------------------------------------------------------------------   *----------------------------------------------------------------------
802   */   */
803    
804          /* ARGSUSED */          /* ARGSUSED */
805  Pixmap  Pixmap
806  Tk_GetBitmapFromData(interp, tkwin, source, width, height)  Tk_GetBitmapFromData(interp, tkwin, source, width, height)
807      Tcl_Interp *interp;         /* Interpreter to use for error reporting. */      Tcl_Interp *interp;         /* Interpreter to use for error reporting. */
808      Tk_Window tkwin;            /* Window in which bitmap will be used. */      Tk_Window tkwin;            /* Window in which bitmap will be used. */
809      char *source;               /* Bitmap data for bitmap shape. */      char *source;               /* Bitmap data for bitmap shape. */
810      int width, height;          /* Dimensions of bitmap. */      int width, height;          /* Dimensions of bitmap. */
811  {  {
812      DataKey nameKey;      DataKey nameKey;
813      Tcl_HashEntry *dataHashPtr;      Tcl_HashEntry *dataHashPtr;
814      int new;      int new;
815      char string[16 + TCL_INTEGER_SPACE];      char string[16 + TCL_INTEGER_SPACE];
816      char *name;      char *name;
817      TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;      TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
818    
819      BitmapInit(dispPtr);      BitmapInit(dispPtr);
820    
821      nameKey.source = source;      nameKey.source = source;
822      nameKey.width = width;      nameKey.width = width;
823      nameKey.height = height;      nameKey.height = height;
824      dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,      dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
825              (char *) &nameKey, &new);              (char *) &nameKey, &new);
826      if (!new) {      if (!new) {
827          name = (char *) Tcl_GetHashValue(dataHashPtr);          name = (char *) Tcl_GetHashValue(dataHashPtr);
828      } else {      } else {
829          dispPtr->bitmapAutoNumber++;          dispPtr->bitmapAutoNumber++;
830          sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber);          sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber);
831          name = string;          name = string;
832          Tcl_SetHashValue(dataHashPtr, name);          Tcl_SetHashValue(dataHashPtr, name);
833          if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {          if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
834              Tcl_DeleteHashEntry(dataHashPtr);              Tcl_DeleteHashEntry(dataHashPtr);
835              return TCL_ERROR;              return TCL_ERROR;
836          }          }
837      }      }
838      return Tk_GetBitmap(interp, tkwin, name);      return Tk_GetBitmap(interp, tkwin, name);
839  }  }
840    
841  /*  /*
842   *----------------------------------------------------------------------   *----------------------------------------------------------------------
843   *   *
844   * Tk_GetBitmapFromObj --   * Tk_GetBitmapFromObj --
845   *   *
846   *      Returns the bitmap referred to by a Tcl object.  The bitmap must   *      Returns the bitmap referred to by a Tcl object.  The bitmap must
847   *      already have been allocated via a call to Tk_AllocBitmapFromObj   *      already have been allocated via a call to Tk_AllocBitmapFromObj
848   *      or Tk_GetBitmap.   *      or Tk_GetBitmap.
849   *   *
850   * Results:   * Results:
851   *      Returns the Pixmap that matches the tkwin and the string rep   *      Returns the Pixmap that matches the tkwin and the string rep
852   *      of objPtr.   *      of objPtr.
853   *   *
854   * Side effects:   * Side effects:
855   *      If the object is not already a bitmap, the conversion will free   *      If the object is not already a bitmap, the conversion will free
856   *      any old internal representation.   *      any old internal representation.
857   *   *
858   *----------------------------------------------------------------------   *----------------------------------------------------------------------
859   */   */
860    
861  Pixmap  Pixmap
862  Tk_GetBitmapFromObj(tkwin, objPtr)  Tk_GetBitmapFromObj(tkwin, objPtr)
863      Tk_Window tkwin;      Tk_Window tkwin;
864      Tcl_Obj *objPtr;            /* The object from which to get pixels. */      Tcl_Obj *objPtr;            /* The object from which to get pixels. */
865  {  {
866      TkBitmap *bitmapPtr = GetBitmapFromObj(tkwin, objPtr);      TkBitmap *bitmapPtr = GetBitmapFromObj(tkwin, objPtr);
867      return bitmapPtr->bitmap;      return bitmapPtr->bitmap;
868  }  }
869    
870  /*  /*
871   *----------------------------------------------------------------------   *----------------------------------------------------------------------
872   *   *
873   * GetBitmapFromObj --   * GetBitmapFromObj --
874   *   *
875   *      Returns the bitmap referred to by a Tcl object.  The bitmap must   *      Returns the bitmap referred to by a Tcl object.  The bitmap must
876   *      already have been allocated via a call to Tk_AllocBitmapFromObj   *      already have been allocated via a call to Tk_AllocBitmapFromObj
877   *      or Tk_GetBitmap.   *      or Tk_GetBitmap.
878   *   *
879   * Results:   * Results:
880   *      Returns the TkBitmap * that matches the tkwin and the string rep   *      Returns the TkBitmap * that matches the tkwin and the string rep
881   *      of  objPtr.   *      of  objPtr.
882   *   *
883   * Side effects:   * Side effects:
884   *      If the object is not already a bitmap, the conversion will free   *      If the object is not already a bitmap, the conversion will free
885   *      any old internal representation.   *      any old internal representation.
886   *   *
887   *----------------------------------------------------------------------   *----------------------------------------------------------------------
888   */   */
889    
890  static TkBitmap *  static TkBitmap *
891  GetBitmapFromObj(tkwin, objPtr)  GetBitmapFromObj(tkwin, objPtr)
892      Tk_Window tkwin;            /* Window in which the bitmap will be used. */      Tk_Window tkwin;            /* Window in which the bitmap will be used. */
893      Tcl_Obj *objPtr;            /* The object that describes the desired      Tcl_Obj *objPtr;            /* The object that describes the desired
894                                   * bitmap. */                                   * bitmap. */
895  {  {
896      TkBitmap *bitmapPtr;      TkBitmap *bitmapPtr;
897      Tcl_HashEntry *hashPtr;      Tcl_HashEntry *hashPtr;
898      TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;      TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
899    
900      if (objPtr->typePtr != &bitmapObjType) {      if (objPtr->typePtr != &bitmapObjType) {
901          InitBitmapObj(objPtr);          InitBitmapObj(objPtr);
902      }      }
903    
904      bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;      bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
905      if (bitmapPtr != NULL) {      if (bitmapPtr != NULL) {
906          if ((bitmapPtr->resourceRefCount > 0)          if ((bitmapPtr->resourceRefCount > 0)
907                  && (Tk_Display(tkwin) == bitmapPtr->display)) {                  && (Tk_Display(tkwin) == bitmapPtr->display)) {
908              return bitmapPtr;              return bitmapPtr;
909          }          }
910          hashPtr = bitmapPtr->nameHashPtr;          hashPtr = bitmapPtr->nameHashPtr;
911          FreeBitmapObjProc(objPtr);          FreeBitmapObjProc(objPtr);
912      } else {      } else {
913          hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable,          hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable,
914                  Tcl_GetString(objPtr));                  Tcl_GetString(objPtr));
915          if (hashPtr == NULL) {          if (hashPtr == NULL) {
916              goto error;              goto error;
917          }          }
918      }      }
919    
920      /*      /*
921       * At this point we've got a hash table entry, off of which hang       * At this point we've got a hash table entry, off of which hang
922       * one or more TkBitmap structures.  See if any of them will work.       * one or more TkBitmap structures.  See if any of them will work.
923       */       */
924    
925      for (bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);      for (bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);
926              bitmapPtr != NULL;  bitmapPtr = bitmapPtr->nextPtr) {              bitmapPtr != NULL;  bitmapPtr = bitmapPtr->nextPtr) {
927          if (Tk_Display(tkwin) == bitmapPtr->display) {          if (Tk_Display(tkwin) == bitmapPtr->display) {
928              objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;              objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
929              bitmapPtr->objRefCount++;              bitmapPtr->objRefCount++;
930              return bitmapPtr;              return bitmapPtr;
931          }          }
932      }      }
933    
934      error:      error:
935      panic("GetBitmapFromObj called with non-existent bitmap!");      panic("GetBitmapFromObj called with non-existent bitmap!");
936      /*      /*
937       * The following code isn't reached; it's just there to please compilers.       * The following code isn't reached; it's just there to please compilers.
938       */       */
939      return NULL;      return NULL;
940  }  }
941    
942  /*  /*
943   *----------------------------------------------------------------------   *----------------------------------------------------------------------
944   *   *
945   * InitBitmapObj --   * InitBitmapObj --
946   *   *
947   *      Bookeeping procedure to change an objPtr to a bitmap type.   *      Bookeeping procedure to change an objPtr to a bitmap type.
948   *   *
949   * Results:   * Results:
950   *      None.   *      None.
951   *   *
952   * Side effects:   * Side effects:
953   *      The old internal rep of the object is freed. The internal   *      The old internal rep of the object is freed. The internal
954   *      rep is cleared. The final form of the object is set   *      rep is cleared. The final form of the object is set
955   *      by either Tk_AllocBitmapFromObj or GetBitmapFromObj.   *      by either Tk_AllocBitmapFromObj or GetBitmapFromObj.
956   *   *
957   *----------------------------------------------------------------------   *----------------------------------------------------------------------
958   */   */
959    
960  static void  static void
961  InitBitmapObj(objPtr)  InitBitmapObj(objPtr)
962      Tcl_Obj *objPtr;            /* The object to convert. */      Tcl_Obj *objPtr;            /* The object to convert. */
963  {  {
964      Tcl_ObjType *typePtr;      Tcl_ObjType *typePtr;
965    
966      /*      /*
967       * Free the old internalRep before setting the new one.       * Free the old internalRep before setting the new one.
968       */       */
969    
970      Tcl_GetString(objPtr);      Tcl_GetString(objPtr);
971      typePtr = objPtr->typePtr;      typePtr = objPtr->typePtr;
972      if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {      if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
973          (*typePtr->freeIntRepProc)(objPtr);          (*typePtr->freeIntRepProc)(objPtr);
974      }      }
975      objPtr->typePtr = &bitmapObjType;      objPtr->typePtr = &bitmapObjType;
976      objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;      objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
977  }  }
978    
979  /*  /*
980   *----------------------------------------------------------------------   *----------------------------------------------------------------------
981   *   *
982   * BitmapInit --   * BitmapInit --
983   *      Initializes hash tables used by this module.  Initializes   *      Initializes hash tables used by this module.  Initializes
984   *      tables stored in TkDisplay structure if a TkDisplay pointer   *      tables stored in TkDisplay structure if a TkDisplay pointer
985   *      is passed in.  Iinitializes the thread-local data   *      is passed in.  Iinitializes the thread-local data
986   *      in the current thread's ThreadSpecificData structure.   *      in the current thread's ThreadSpecificData structure.
987   *   *
988   * Results:   * Results:
989   *      None.   *      None.
990   *     *  
991   * Side effects:   * Side effects:
992   *      Read the code.   *      Read the code.
993   *   *
994   *----------------------------------------------------------------------   *----------------------------------------------------------------------
995   */   */
996    
997  static void  static void
998  BitmapInit(dispPtr)  BitmapInit(dispPtr)
999      TkDisplay *dispPtr;         /* TkDisplay structure encapsulating      TkDisplay *dispPtr;         /* TkDisplay structure encapsulating
1000                                   * thread-specific data used by this                                   * thread-specific data used by this
1001                                   * module, or NULL if unavailable. */                                   * module, or NULL if unavailable. */
1002  {  {
1003      Tcl_Interp *dummy;      Tcl_Interp *dummy;
1004      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
1005              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
1006    
1007      /*      /*
1008       * First initialize the data in the ThreadSpecificData strucuture,       * First initialize the data in the ThreadSpecificData strucuture,
1009       * if needed.       * if needed.
1010       */       */
1011    
1012      if (!tsdPtr->initialized) {      if (!tsdPtr->initialized) {
1013          tsdPtr->initialized = 1;          tsdPtr->initialized = 1;
1014          dummy = Tcl_CreateInterp();          dummy = Tcl_CreateInterp();
1015          Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);          Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);
1016    
1017          Tk_DefineBitmap(dummy, "error", (char *) error_bits,          Tk_DefineBitmap(dummy, "error", (char *) error_bits,
1018                  error_width, error_height);                  error_width, error_height);
1019          Tk_DefineBitmap(dummy, "gray75", (char *) gray75_bits,          Tk_DefineBitmap(dummy, "gray75", (char *) gray75_bits,
1020                  gray75_width, gray75_height);                  gray75_width, gray75_height);
1021          Tk_DefineBitmap(dummy, "gray50", (char *) gray50_bits,          Tk_DefineBitmap(dummy, "gray50", (char *) gray50_bits,
1022                  gray50_width, gray50_height);                  gray50_width, gray50_height);
1023          Tk_DefineBitmap(dummy, "gray25", (char *) gray25_bits,          Tk_DefineBitmap(dummy, "gray25", (char *) gray25_bits,
1024                  gray25_width, gray25_height);                  gray25_width, gray25_height);
1025          Tk_DefineBitmap(dummy, "gray12", (char *) gray12_bits,          Tk_DefineBitmap(dummy, "gray12", (char *) gray12_bits,
1026                  gray12_width, gray12_height);                  gray12_width, gray12_height);
1027          Tk_DefineBitmap(dummy, "hourglass", (char *) hourglass_bits,          Tk_DefineBitmap(dummy, "hourglass", (char *) hourglass_bits,
1028                  hourglass_width, hourglass_height);                  hourglass_width, hourglass_height);
1029          Tk_DefineBitmap(dummy, "info", (char *) info_bits,          Tk_DefineBitmap(dummy, "info", (char *) info_bits,
1030                  info_width, info_height);                  info_width, info_height);
1031          Tk_DefineBitmap(dummy, "questhead", (char *) questhead_bits,          Tk_DefineBitmap(dummy, "questhead", (char *) questhead_bits,
1032                  questhead_width, questhead_height);                  questhead_width, questhead_height);
1033          Tk_DefineBitmap(dummy, "question", (char *) question_bits,          Tk_DefineBitmap(dummy, "question", (char *) question_bits,
1034                  question_width, question_height);                  question_width, question_height);
1035          Tk_DefineBitmap(dummy, "warning", (char *) warning_bits,          Tk_DefineBitmap(dummy, "warning", (char *) warning_bits,
1036                  warning_width, warning_height);                  warning_width, warning_height);
1037    
1038          TkpDefineNativeBitmaps();          TkpDefineNativeBitmaps();
1039          Tcl_DeleteInterp(dummy);          Tcl_DeleteInterp(dummy);
1040      }      }
1041    
1042      /*      /*
1043       * Was a valid TkDisplay pointer passed?  If so, initialize the       * Was a valid TkDisplay pointer passed?  If so, initialize the
1044       * Bitmap module tables in that structure.       * Bitmap module tables in that structure.
1045       */       */
1046    
1047      if (dispPtr != NULL) {      if (dispPtr != NULL) {
1048          dispPtr->bitmapInit = 1;          dispPtr->bitmapInit = 1;
1049          Tcl_InitHashTable(&dispPtr->bitmapNameTable, TCL_STRING_KEYS);          Tcl_InitHashTable(&dispPtr->bitmapNameTable, TCL_STRING_KEYS);
1050          Tcl_InitHashTable(&dispPtr->bitmapDataTable, sizeof(DataKey)          Tcl_InitHashTable(&dispPtr->bitmapDataTable, sizeof(DataKey)
1051                  /sizeof(int));                  /sizeof(int));
1052    
1053          /*          /*
1054           * The call below is tricky:  can't use sizeof(IdKey) because it           * The call below is tricky:  can't use sizeof(IdKey) because it
1055           * gets padded with extra unpredictable bytes on some 64-bit           * gets padded with extra unpredictable bytes on some 64-bit
1056           * machines.           * machines.
1057           */           */
1058    
1059          /*          /*
1060           * The comment above doesn't make sense...           * The comment above doesn't make sense...
1061           */           */
1062          Tcl_InitHashTable(&dispPtr->bitmapIdTable, TCL_ONE_WORD_KEYS);          Tcl_InitHashTable(&dispPtr->bitmapIdTable, TCL_ONE_WORD_KEYS);
1063      }      }
1064  }  }
1065    
1066  /*  /*
1067   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1068   *   *
1069   * TkReadBitmapFile --   * TkReadBitmapFile --
1070   *   *
1071   *      Loads a bitmap image in X bitmap format into the specified   *      Loads a bitmap image in X bitmap format into the specified
1072   *      drawable.  This is equivelent to the XReadBitmapFile in X.   *      drawable.  This is equivelent to the XReadBitmapFile in X.
1073   *   *
1074   * Results:   * Results:
1075   *      Sets the size, hotspot, and bitmap on success.   *      Sets the size, hotspot, and bitmap on success.
1076   *   *
1077   * Side effects:   * Side effects:
1078   *      Creates a new bitmap from the file data.   *      Creates a new bitmap from the file data.
1079   *   *
1080   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1081   */   */
1082    
1083  int  int
1084  TkReadBitmapFile(display, d, filename, width_return, height_return,  TkReadBitmapFile(display, d, filename, width_return, height_return,
1085          bitmap_return, x_hot_return, y_hot_return)          bitmap_return, x_hot_return, y_hot_return)
1086      Display* display;      Display* display;
1087      Drawable d;      Drawable d;
1088      CONST char* filename;      CONST char* filename;
1089      unsigned int* width_return;      unsigned int* width_return;
1090      unsigned int* height_return;      unsigned int* height_return;
1091      Pixmap* bitmap_return;      Pixmap* bitmap_return;
1092      int* x_hot_return;      int* x_hot_return;
1093      int* y_hot_return;      int* y_hot_return;
1094  {  {
1095      char *data;      char *data;
1096    
1097      data = TkGetBitmapData(NULL, NULL, (char *) filename,      data = TkGetBitmapData(NULL, NULL, (char *) filename,
1098              (int *) width_return, (int *) height_return, x_hot_return,              (int *) width_return, (int *) height_return, x_hot_return,
1099              y_hot_return);              y_hot_return);
1100      if (data == NULL) {      if (data == NULL) {
1101          return BitmapFileInvalid;          return BitmapFileInvalid;
1102      }      }
1103    
1104      *bitmap_return = XCreateBitmapFromData(display, d, data, *width_return,      *bitmap_return = XCreateBitmapFromData(display, d, data, *width_return,
1105              *height_return);              *height_return);
1106    
1107      ckfree(data);      ckfree(data);
1108      return BitmapSuccess;      return BitmapSuccess;
1109    }    }
1110    
1111  /*  /*
1112   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1113   *   *
1114   * TkDebugBitmap --   * TkDebugBitmap --
1115   *   *
1116   *      This procedure returns debugging information about a bitmap.   *      This procedure returns debugging information about a bitmap.
1117   *   *
1118   * Results:   * Results:
1119   *      The return value is a list with one sublist for each TkBitmap   *      The return value is a list with one sublist for each TkBitmap
1120   *      corresponding to "name".  Each sublist has two elements that   *      corresponding to "name".  Each sublist has two elements that
1121   *      contain the resourceRefCount and objRefCount fields from the   *      contain the resourceRefCount and objRefCount fields from the
1122   *      TkBitmap structure.   *      TkBitmap structure.
1123   *   *
1124   * Side effects:   * Side effects:
1125   *      None.   *      None.
1126   *   *
1127   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1128   */   */
1129    
1130  Tcl_Obj *  Tcl_Obj *
1131  TkDebugBitmap(tkwin, name)  TkDebugBitmap(tkwin, name)
1132      Tk_Window tkwin;            /* The window in which the bitmap will be      Tk_Window tkwin;            /* The window in which the bitmap will be
1133                                   * used (not currently used). */                                   * used (not currently used). */
1134      char *name;                 /* Name of the desired color. */      char *name;                 /* Name of the desired color. */
1135  {  {
1136      TkBitmap *bitmapPtr;      TkBitmap *bitmapPtr;
1137      Tcl_HashEntry *hashPtr;      Tcl_HashEntry *hashPtr;
1138      Tcl_Obj *resultPtr, *objPtr;      Tcl_Obj *resultPtr, *objPtr;
1139      TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;      TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
1140    
1141      resultPtr = Tcl_NewObj();      resultPtr = Tcl_NewObj();
1142      hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, name);      hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, name);
1143      if (hashPtr != NULL) {      if (hashPtr != NULL) {
1144          bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);          bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);
1145          if (bitmapPtr == NULL) {          if (bitmapPtr == NULL) {
1146              panic("TkDebugBitmap found empty hash table entry");              panic("TkDebugBitmap found empty hash table entry");
1147          }          }
1148          for ( ; (bitmapPtr != NULL); bitmapPtr = bitmapPtr->nextPtr) {          for ( ; (bitmapPtr != NULL); bitmapPtr = bitmapPtr->nextPtr) {
1149              objPtr = Tcl_NewObj();              objPtr = Tcl_NewObj();
1150              Tcl_ListObjAppendElement(NULL, objPtr,              Tcl_ListObjAppendElement(NULL, objPtr,
1151                      Tcl_NewIntObj(bitmapPtr->resourceRefCount));                      Tcl_NewIntObj(bitmapPtr->resourceRefCount));
1152              Tcl_ListObjAppendElement(NULL, objPtr,              Tcl_ListObjAppendElement(NULL, objPtr,
1153                      Tcl_NewIntObj(bitmapPtr->objRefCount));                      Tcl_NewIntObj(bitmapPtr->objRefCount));
1154              Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);              Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
1155          }          }
1156      }      }
1157      return resultPtr;      return resultPtr;
1158  }  }
1159    
1160    
1161  /*  /*
1162   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1163   *   *
1164   * TkGetBitmapPredefTable --   * TkGetBitmapPredefTable --
1165   *      This procedure is used by tkMacBitmap.c to access the thread-   *      This procedure is used by tkMacBitmap.c to access the thread-
1166   *      specific predefBitmap table that maps from the names of   *      specific predefBitmap table that maps from the names of
1167   *      the predefined bitmaps to data associated with those   *      the predefined bitmaps to data associated with those
1168   *      bitmaps.  It is required because the table is allocated in   *      bitmaps.  It is required because the table is allocated in
1169   *      thread-local storage and is not visible outside this file.   *      thread-local storage and is not visible outside this file.
1170    
1171   * Results:   * Results:
1172   *      Returns a pointer to the predefined bitmap hash table for   *      Returns a pointer to the predefined bitmap hash table for
1173   *      the current thread.   *      the current thread.
1174   *   *
1175   * Side effects:   * Side effects:
1176   *      None.   *      None.
1177   *   *
1178   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1179   */   */
1180  Tcl_HashTable *  Tcl_HashTable *
1181  TkGetBitmapPredefTable()  TkGetBitmapPredefTable()
1182  {  {
1183      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
1184              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
1185    
1186      return &tsdPtr->predefBitmapTable;      return &tsdPtr->predefBitmapTable;
1187  }  }
1188    
1189  /* End of tkbitmap.c */  /* End of tkbitmap.c */

Legend:
Removed from v.69  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25