]> cvs.zerfleddert.de Git - micropolis/blob - src/tk/tkbitmap.c
Fixes for compilation with gcc 15
[micropolis] / src / tk / tkbitmap.c
1 /*
2 * tkBitmap.c --
3 *
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.
7 *
8 * Copyright 1990-1992 Regents of the University of California
9 * Permission to use, copy, modify, and distribute this
10 * software and its documentation for any purpose and without
11 * fee is hereby granted, provided that the above copyright
12 * notice appear in all copies. The University of California
13 * makes no representations about the suitability of this
14 * software for any purpose. It is provided "as is" without
15 * express or implied warranty.
16 */
17
18 #ifndef lint
19 static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkBitmap.c,v 1.16 92/08/24 09:45:43 ouster Exp $ SPRITE (Berkeley)";
20 #endif /* not lint */
21
22 #include "tkconfig.h"
23 #include "tk.h"
24
25 /*
26 * The includes below are for pre-defined bitmaps.
27 */
28
29 #include "bitmaps/gray50"
30 #include "bitmaps/gray25"
31
32 /*
33 * One of the following data structures exists for each bitmap that is
34 * currently in use. Each structure is indexed with both "idTable" and
35 * "nameTable".
36 */
37
38 typedef struct {
39 Pixmap bitmap; /* X identifier for bitmap. None means this
40 * bitmap was created by Tk_DefineBitmap
41 * and it isn't currently in use. */
42 unsigned int width, height; /* Dimensions of bitmap. */
43 Display *display; /* Display for which bitmap is valid. */
44 int refCount; /* Number of active uses of bitmap. */
45 Tcl_HashEntry *hashPtr; /* Entry in nameTable for this structure
46 * (needed when deleting). */
47 } TkBitmap;
48
49 /*
50 * Hash table to map from a textual description of a bitmap to the
51 * TkBitmap record for the bitmap, and key structure used in that
52 * hash table:
53 */
54
55 static Tcl_HashTable nameTable;
56 typedef struct {
57 Tk_Uid name; /* Textual name for desired bitmap. */
58 Screen *screen; /* Screen for which bitmap will be used. */
59 } NameKey;
60
61 /*
62 * Hash table that maps from bitmap identifiers to the TkBitmap structure
63 * for the bitmap. This table is indexed by Bitmap ids, and is used by
64 * Tk_FreeBitmap.
65 */
66
67 static Tcl_HashTable idTable;
68
69 /*
70 * For each call to Tk_DefineBitmap one of the following structures is
71 * created to hold information about the bitmap.
72 */
73
74 typedef struct {
75 char *source; /* Bits for bitmap. */
76 unsigned int width, height; /* Dimensions of bitmap. */
77 } PredefBitmap;
78
79 /*
80 * Hash table create by Tk_DefineBitmap to map from a name to a
81 * collection of in-core data about a bitmap. The table is
82 * indexed by the address of the data for the bitmap, and the entries
83 * contain pointers to PredefBitmap structures.
84 */
85
86 static Tcl_HashTable predefTable;
87
88 /*
89 * Hash table used by Tk_GetBitmapFromData to map from a collection
90 * of in-core data about a bitmap to a Tk_Uid giving an automatically-
91 * generated name for the bitmap:
92 */
93
94 static Tcl_HashTable dataTable;
95 typedef struct {
96 char *source; /* Bitmap bits. */
97 unsigned int width, height; /* Dimensions of bitmap. */
98 } DataKey;
99
100 static int initialized = 0; /* 0 means static structures haven't been
101 * initialized yet. */
102
103 /*
104 * Forward declarations for procedures defined in this file:
105 */
106
107 static void BitmapInit _ANSI_ARGS_((void));
108 \f
109 /*
110 *----------------------------------------------------------------------
111 *
112 * Tk_GetBitmap --
113 *
114 * Given a string describing a bitmap, locate (or create if necessary)
115 * a bitmap that fits the description.
116 *
117 * Results:
118 * The return value is the X identifer for the desired bitmap
119 * (i.e. a Pixmap with a single plane), unless string couldn't be
120 * parsed correctly. In this case, None is returned and an error
121 * message is left in interp->result. The caller should never
122 * modify the bitmap that is returned, and should eventually call
123 * Tk_FreeBitmap when the bitmap is no longer needed.
124 *
125 * Side effects:
126 * The bitmap is added to an internal database with a reference count.
127 * For each call to this procedure, there should eventually be a call
128 * to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
129 * aren't needed anymore.
130 *
131 *----------------------------------------------------------------------
132 */
133
134 Pixmap
135 Tk_GetBitmap (
136 Tcl_Interp *interp, /* Interpreter to use for error reporting. */
137 Tk_Window tkwin, /* Window in which bitmap will be used. */
138 Tk_Uid string /* Description of bitmap. See manual entry
139 * for details on legal syntax. */
140 )
141 {
142 NameKey key;
143 Tcl_HashEntry *nameHashPtr, *idHashPtr, *predefHashPtr;
144 register TkBitmap *bitmapPtr;
145 PredefBitmap *predefPtr;
146 int new;
147 Pixmap bitmap;
148 unsigned int width, height;
149 int dummy2;
150
151 if (!initialized) {
152 BitmapInit();
153 }
154
155 key.name = string;
156 key.screen = Tk_Screen(tkwin);
157 nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &key, &new);
158 if (!new) {
159 bitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr);
160 bitmapPtr->refCount++;
161 return bitmapPtr->bitmap;
162 }
163
164 /*
165 * No suitable bitmap exists. Create a new bitmap from the
166 * information contained in the string. If the string starts
167 * with "@" then the rest of the string is a file name containing
168 * the bitmap. Otherwise the string must refer to a bitmap
169 * defined by a call to Tk_DefineBitmap.
170 */
171
172 if (*string == '@') {
173 string = Tcl_TildeSubst(interp, string + 1);
174 if (string == NULL) {
175 goto error;
176 }
177 if (XReadBitmapFile(Tk_Display(tkwin),
178 RootWindowOfScreen(Tk_Screen(tkwin)),
179 string, &width, &height, &bitmap, &dummy2, &dummy2)
180 != BitmapSuccess) {
181 Tcl_AppendResult(interp, "error reading bitmap file \"", string,
182 "\"", (char *) NULL);
183 goto error;
184 }
185 } else {
186 predefHashPtr = Tcl_FindHashEntry(&predefTable, string);
187 if (predefHashPtr == NULL) {
188 Tcl_AppendResult(interp, "bitmap \"", string,
189 "\" not defined", (char *) NULL);
190 goto error;
191 }
192 predefPtr = (PredefBitmap *) Tcl_GetHashValue(predefHashPtr);
193 width = predefPtr->width;
194 height = predefPtr->height;
195 bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
196 RootWindowOfScreen(Tk_Screen(tkwin)), predefPtr->source,
197 width, height);
198 }
199
200 /*
201 * Add information about this bitmap to our database.
202 */
203
204 bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap));
205 bitmapPtr->bitmap = bitmap;
206 bitmapPtr->width = width;
207 bitmapPtr->height = height;
208 bitmapPtr->display = Tk_Display(tkwin);
209 bitmapPtr->refCount = 1;
210 bitmapPtr->hashPtr = nameHashPtr;
211 idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) bitmapPtr->bitmap,
212 &new);
213 if (!new) {
214 /* deh patched to support multiple displays */
215 /* panic("bitmap already registered in Tk_GetBitmap"); */
216 bitmapPtr->refCount = 1000;
217 }
218 Tcl_SetHashValue(nameHashPtr, bitmapPtr);
219 Tcl_SetHashValue(idHashPtr, bitmapPtr);
220 return bitmapPtr->bitmap;
221
222 error:
223 Tcl_DeleteHashEntry(nameHashPtr);
224 return None;
225 }
226 \f
227 /*
228 *----------------------------------------------------------------------
229 *
230 * Tk_DefineBitmap --
231 *
232 * This procedure associates a textual name with a binary bitmap
233 * description, so that the name may be used to refer to the
234 * bitmap in future calls to Tk_GetBitmap.
235 *
236 * Results:
237 * A standard Tcl result. If an error occurs then TCL_ERROR is
238 * returned and a message is left in interp->result.
239 *
240 * Side effects:
241 * "Name" is entered into the bitmap table and may be used from
242 * here on to refer to the given bitmap.
243 *
244 *----------------------------------------------------------------------
245 */
246
247 int
248 Tk_DefineBitmap (
249 Tcl_Interp *interp, /* Interpreter to use for error reporting. */
250 Tk_Uid name, /* Name to use for bitmap. Must not already
251 * be defined as a bitmap. */
252 char *source, /* Address of bits for bitmap. */
253 unsigned int width, /* Width of bitmap. */
254 unsigned int height /* Height of bitmap. */
255 )
256 {
257 int new;
258 Tcl_HashEntry *predefHashPtr;
259 PredefBitmap *predefPtr;
260
261 if (!initialized) {
262 BitmapInit();
263 }
264
265 predefHashPtr = Tcl_CreateHashEntry(&predefTable, name, &new);
266 if (!new) {
267 Tcl_AppendResult(interp, "bitmap \"", name,
268 "\" is already defined", (char *) NULL);
269 return TCL_ERROR;
270 }
271 predefPtr = (PredefBitmap *) malloc(sizeof(PredefBitmap));
272 predefPtr->source = source;
273 predefPtr->width = width;
274 predefPtr->height = height;
275 Tcl_SetHashValue(predefHashPtr, predefPtr);
276 return TCL_OK;
277 }
278 \f
279 /*
280 *--------------------------------------------------------------
281 *
282 * Tk_NameOfBitmap --
283 *
284 * Given a bitmap, return a textual string identifying the
285 * bitmap.
286 *
287 * Results:
288 * The return value is the string name associated with bitmap.
289 *
290 * Side effects:
291 * None.
292 *
293 *--------------------------------------------------------------
294 */
295
296 Tk_Uid
297 Tk_NameOfBitmap (
298 Pixmap bitmap /* Bitmap whose name is wanted. */
299 )
300 {
301 Tcl_HashEntry *idHashPtr;
302 TkBitmap *bitmapPtr;
303
304 if (!initialized) {
305 unknown:
306 panic("Tk_NameOfBitmap received unknown bitmap argument");
307 }
308
309 idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap);
310 if (idHashPtr == NULL) {
311 goto unknown;
312 }
313 bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
314 return ((NameKey *) bitmapPtr->hashPtr->key.words)->name;
315 }
316 \f
317 /*
318 *--------------------------------------------------------------
319 *
320 * Tk_SizeOfBitmap --
321 *
322 * Given a bitmap managed by this module, returns the width
323 * and height of the bitmap..
324 *
325 * Results:
326 * The words at *widthPtr and *heightPtr are filled in with
327 * the dimenstions of bitmap.
328 *
329 * Side effects:
330 * If bitmap isn't managed by this module then the procedure
331 * panics..
332 *
333 *--------------------------------------------------------------
334 */
335
336 void
337 Tk_SizeOfBitmap (
338 Pixmap bitmap, /* Bitmap whose size is wanted. */
339 unsigned int *widthPtr, /* Store bitmap width here. */
340 unsigned int *heightPtr /* Store bitmap height here. */
341 )
342 {
343 Tcl_HashEntry *idHashPtr;
344 TkBitmap *bitmapPtr;
345
346 if (!initialized) {
347 unknownBitmap:
348 panic("Tk_SizeOfBitmap received unknown bitmap argument");
349 }
350
351 idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap);
352 if (idHashPtr == NULL) {
353 goto unknownBitmap;
354 }
355 bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
356 *widthPtr = bitmapPtr->width;
357 *heightPtr = bitmapPtr->height;
358 }
359 \f
360 /*
361 *----------------------------------------------------------------------
362 *
363 * Tk_FreeBitmap --
364 *
365 * This procedure is called to release a bitmap allocated by
366 * Tk_GetBitmap or TkGetBitmapFromData.
367 *
368 * Results:
369 * None.
370 *
371 * Side effects:
372 * The reference count associated with bitmap is decremented, and
373 * it is officially deallocated if no-one is using it anymore.
374 *
375 *----------------------------------------------------------------------
376 */
377
378 void
379 Tk_FreeBitmap (
380 Pixmap bitmap /* Bitmap to be released. */
381 )
382 {
383 Tcl_HashEntry *idHashPtr;
384 register TkBitmap *bitmapPtr;
385
386 if (!initialized) {
387 panic("Tk_FreeBitmap called before Tk_GetBitmap");
388 }
389
390 idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap);
391 if (idHashPtr == NULL) {
392 panic("Tk_FreeBitmap received unknown bitmap argument");
393 }
394 bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
395 bitmapPtr->refCount--;
396 if (bitmapPtr->refCount == 0) {
397 XFreePixmap(bitmapPtr->display, bitmapPtr->bitmap);
398 Tcl_DeleteHashEntry(idHashPtr);
399 Tcl_DeleteHashEntry(bitmapPtr->hashPtr);
400 ckfree((char *) bitmapPtr);
401 }
402 }
403 \f
404 /*
405 *----------------------------------------------------------------------
406 *
407 * Tk_GetBitmapFromData --
408 *
409 * Given a description of the bits for a bitmap, make a bitmap that
410 * has the given properties.
411 *
412 * Results:
413 * The return value is the X identifer for the desired bitmap
414 * (a one-plane Pixmap), unless it couldn't be created properly.
415 * In this case, None is returned and an error message is left in
416 * interp->result. The caller should never modify the bitmap that
417 * is returned, and should eventually call Tk_FreeBitmap when the
418 * bitmap is no longer needed.
419 *
420 * Side effects:
421 * The bitmap is added to an internal database with a reference count.
422 * For each call to this procedure, there should eventually be a call
423 * to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
424 * aren't needed anymore.
425 *
426 *----------------------------------------------------------------------
427 */
428
429 /* ARGSUSED */
430 Pixmap
431 Tk_GetBitmapFromData (
432 Tcl_Interp *interp, /* Interpreter to use for error reporting. */
433 Tk_Window tkwin, /* Window in which bitmap will be used. */
434 char *source, /* Bitmap data for bitmap shape. */
435 unsigned int width,
436 unsigned int height /* Dimensions of bitmap. */
437 )
438 {
439 DataKey key;
440 Tcl_HashEntry *dataHashPtr;
441 Tk_Uid name = NULL; /* Initialization need only to prevent
442 * compiler warning. */
443 int new;
444 static int autoNumber = 0;
445 char string[20];
446
447 if (!initialized) {
448 BitmapInit();
449 }
450
451 key.source = source;
452 key.width = width;
453 key.height = height;
454 dataHashPtr = Tcl_CreateHashEntry(&dataTable, (char *) &key, &new);
455 if (!new) {
456 name = (Tk_Uid) Tcl_GetHashValue(dataHashPtr);
457 } else {
458 autoNumber++;
459 sprintf(string, "_tk%d", autoNumber);
460 name = Tk_GetUid(string);
461 Tcl_SetHashValue(dataHashPtr, name);
462 if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
463 Tcl_DeleteHashEntry(dataHashPtr);
464 return TCL_ERROR;
465 }
466 }
467 return Tk_GetBitmap(interp, tkwin, name);
468 }
469 \f
470 /*
471 *----------------------------------------------------------------------
472 *
473 * BitmapInit --
474 *
475 * Initialize the structures used for bitmap management.
476 *
477 * Results:
478 * None.
479 *
480 * Side effects:
481 * Read the code.
482 *
483 *----------------------------------------------------------------------
484 */
485
486 static void
487 BitmapInit (void)
488 {
489 Tcl_Interp *dummy;
490
491 dummy = Tcl_CreateInterp();
492 initialized = 1;
493 Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int));
494 Tcl_InitHashTable(&dataTable, sizeof(DataKey)/sizeof(int));
495 Tcl_InitHashTable(&predefTable, TCL_ONE_WORD_KEYS);
496 Tcl_InitHashTable(&idTable, TCL_ONE_WORD_KEYS);
497
498 Tk_DefineBitmap(dummy, Tk_GetUid("gray50"), (char *)gray50_bits,
499 gray50_width, gray50_height);
500 Tk_DefineBitmap(dummy, Tk_GetUid("gray25"),
501 (char *)gray25_bits, gray25_width, gray25_height);
502 Tcl_DeleteInterp(dummy);
503 }
Impressum, Datenschutz