1 |
578 |
markom |
/*
|
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 (c) 1990-1994 The Regents of the University of California.
|
9 |
|
|
* Copyright (c) 1994-1996 Sun Microsystems, Inc.
|
10 |
|
|
*
|
11 |
|
|
* See the file "license.terms" for information on usage and redistribution
|
12 |
|
|
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
13 |
|
|
*
|
14 |
|
|
* RCS: @(#) $Id: tkBitmap.c,v 1.1.1.1 2002-01-16 10:25:50 markom Exp $
|
15 |
|
|
*/
|
16 |
|
|
|
17 |
|
|
#include "tkPort.h"
|
18 |
|
|
#include "tkInt.h"
|
19 |
|
|
|
20 |
|
|
/*
|
21 |
|
|
* The includes below are for pre-defined bitmaps.
|
22 |
|
|
*
|
23 |
|
|
* Platform-specific issue: Windows complains when the bitmaps are
|
24 |
|
|
* included, because an array of characters is being initialized with
|
25 |
|
|
* integers as elements. For lint purposes, the following pragmas
|
26 |
|
|
* temporarily turn off that warning message.
|
27 |
|
|
*/
|
28 |
|
|
|
29 |
|
|
#if defined(__WIN32__) || defined(_WIN32)
|
30 |
|
|
#pragma warning (disable : 4305)
|
31 |
|
|
#endif
|
32 |
|
|
|
33 |
|
|
#include "error.bmp"
|
34 |
|
|
#include "gray12.bmp"
|
35 |
|
|
#include "gray25.bmp"
|
36 |
|
|
#include "gray50.bmp"
|
37 |
|
|
#include "gray75.bmp"
|
38 |
|
|
#include "hourglass.bmp"
|
39 |
|
|
#include "info.bmp"
|
40 |
|
|
#include "questhead.bmp"
|
41 |
|
|
#include "question.bmp"
|
42 |
|
|
#include "warning.bmp"
|
43 |
|
|
|
44 |
|
|
#if defined(__WIN32__) || defined(_WIN32)
|
45 |
|
|
#pragma warning (default : 4305)
|
46 |
|
|
#endif
|
47 |
|
|
|
48 |
|
|
/*
|
49 |
|
|
* One of the following data structures exists for each bitmap that is
|
50 |
|
|
* currently in use. Each structure is indexed with both "idTable" and
|
51 |
|
|
* "nameTable".
|
52 |
|
|
*/
|
53 |
|
|
|
54 |
|
|
typedef struct {
|
55 |
|
|
Pixmap bitmap; /* X identifier for bitmap. None means this
|
56 |
|
|
* bitmap was created by Tk_DefineBitmap
|
57 |
|
|
* and it isn't currently in use. */
|
58 |
|
|
int width, height; /* Dimensions of bitmap. */
|
59 |
|
|
Display *display; /* Display for which bitmap is valid. */
|
60 |
|
|
int refCount; /* Number of active uses of bitmap. */
|
61 |
|
|
Tcl_HashEntry *hashPtr; /* Entry in nameTable for this structure
|
62 |
|
|
* (needed when deleting). */
|
63 |
|
|
} TkBitmap;
|
64 |
|
|
|
65 |
|
|
/*
|
66 |
|
|
* Hash table to map from a textual description of a bitmap to the
|
67 |
|
|
* TkBitmap record for the bitmap, and key structure used in that
|
68 |
|
|
* hash table:
|
69 |
|
|
*/
|
70 |
|
|
|
71 |
|
|
static Tcl_HashTable nameTable;
|
72 |
|
|
typedef struct {
|
73 |
|
|
Tk_Uid name; /* Textual name for desired bitmap. */
|
74 |
|
|
Screen *screen; /* Screen on which bitmap will be used. */
|
75 |
|
|
} NameKey;
|
76 |
|
|
|
77 |
|
|
/*
|
78 |
|
|
* Hash table that maps from <display + bitmap id> to the TkBitmap structure
|
79 |
|
|
* for the bitmap. This table is used by Tk_FreeBitmap.
|
80 |
|
|
*/
|
81 |
|
|
|
82 |
|
|
static Tcl_HashTable idTable;
|
83 |
|
|
typedef struct {
|
84 |
|
|
Display *display; /* Display for which bitmap was allocated. */
|
85 |
|
|
Pixmap pixmap; /* X identifier for pixmap. */
|
86 |
|
|
} IdKey;
|
87 |
|
|
|
88 |
|
|
/*
|
89 |
|
|
* Hash table create by Tk_DefineBitmap to map from a name to a
|
90 |
|
|
* collection of in-core data about a bitmap. The table is
|
91 |
|
|
* indexed by the address of the data for the bitmap, and the entries
|
92 |
|
|
* contain pointers to TkPredefBitmap structures.
|
93 |
|
|
*/
|
94 |
|
|
|
95 |
|
|
Tcl_HashTable tkPredefBitmapTable;
|
96 |
|
|
|
97 |
|
|
/*
|
98 |
|
|
* Hash table used by Tk_GetBitmapFromData to map from a collection
|
99 |
|
|
* of in-core data about a bitmap to a Tk_Uid giving an automatically-
|
100 |
|
|
* generated name for the bitmap:
|
101 |
|
|
*/
|
102 |
|
|
|
103 |
|
|
static Tcl_HashTable dataTable;
|
104 |
|
|
typedef struct {
|
105 |
|
|
char *source; /* Bitmap bits. */
|
106 |
|
|
int width, height; /* Dimensions of bitmap. */
|
107 |
|
|
} DataKey;
|
108 |
|
|
|
109 |
|
|
static int initialized = 0; /* 0 means static structures haven't been
|
110 |
|
|
* initialized yet. */
|
111 |
|
|
|
112 |
|
|
/*
|
113 |
|
|
* Forward declarations for procedures defined in this file:
|
114 |
|
|
*/
|
115 |
|
|
|
116 |
|
|
static void BitmapInit _ANSI_ARGS_((void));
|
117 |
|
|
|
118 |
|
|
/*
|
119 |
|
|
*----------------------------------------------------------------------
|
120 |
|
|
*
|
121 |
|
|
* Tk_GetBitmap --
|
122 |
|
|
*
|
123 |
|
|
* Given a string describing a bitmap, locate (or create if necessary)
|
124 |
|
|
* a bitmap that fits the description.
|
125 |
|
|
*
|
126 |
|
|
* Results:
|
127 |
|
|
* The return value is the X identifer for the desired bitmap
|
128 |
|
|
* (i.e. a Pixmap with a single plane), unless string couldn't be
|
129 |
|
|
* parsed correctly. In this case, None is returned and an error
|
130 |
|
|
* message is left in interp->result. The caller should never
|
131 |
|
|
* modify the bitmap that is returned, and should eventually call
|
132 |
|
|
* Tk_FreeBitmap when the bitmap is no longer needed.
|
133 |
|
|
*
|
134 |
|
|
* Side effects:
|
135 |
|
|
* The bitmap is added to an internal database with a reference count.
|
136 |
|
|
* For each call to this procedure, there should eventually be a call
|
137 |
|
|
* to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
|
138 |
|
|
* aren't needed anymore.
|
139 |
|
|
*
|
140 |
|
|
*----------------------------------------------------------------------
|
141 |
|
|
*/
|
142 |
|
|
|
143 |
|
|
Pixmap
|
144 |
|
|
Tk_GetBitmap(interp, tkwin, string)
|
145 |
|
|
Tcl_Interp *interp; /* Interpreter to use for error reporting,
|
146 |
|
|
* this may be NULL. */
|
147 |
|
|
Tk_Window tkwin; /* Window in which bitmap will be used. */
|
148 |
|
|
Tk_Uid string; /* Description of bitmap. See manual entry
|
149 |
|
|
* for details on legal syntax. */
|
150 |
|
|
{
|
151 |
|
|
NameKey nameKey;
|
152 |
|
|
IdKey idKey;
|
153 |
|
|
Tcl_HashEntry *nameHashPtr, *idHashPtr, *predefHashPtr;
|
154 |
|
|
register TkBitmap *bitmapPtr;
|
155 |
|
|
TkPredefBitmap *predefPtr;
|
156 |
|
|
int new;
|
157 |
|
|
Pixmap bitmap;
|
158 |
|
|
int width, height;
|
159 |
|
|
int dummy2;
|
160 |
|
|
|
161 |
|
|
if (!initialized) {
|
162 |
|
|
BitmapInit();
|
163 |
|
|
}
|
164 |
|
|
|
165 |
|
|
nameKey.name = string;
|
166 |
|
|
nameKey.screen = Tk_Screen(tkwin);
|
167 |
|
|
nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &nameKey, &new);
|
168 |
|
|
if (!new) {
|
169 |
|
|
bitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr);
|
170 |
|
|
bitmapPtr->refCount++;
|
171 |
|
|
return bitmapPtr->bitmap;
|
172 |
|
|
}
|
173 |
|
|
|
174 |
|
|
/*
|
175 |
|
|
* No suitable bitmap exists. Create a new bitmap from the
|
176 |
|
|
* information contained in the string. If the string starts
|
177 |
|
|
* with "@" then the rest of the string is a file name containing
|
178 |
|
|
* the bitmap. Otherwise the string must refer to a bitmap
|
179 |
|
|
* defined by a call to Tk_DefineBitmap.
|
180 |
|
|
*/
|
181 |
|
|
|
182 |
|
|
if (*string == '@') {
|
183 |
|
|
Tcl_DString buffer;
|
184 |
|
|
int result;
|
185 |
|
|
|
186 |
|
|
if (Tcl_IsSafe(interp)) {
|
187 |
|
|
Tcl_AppendResult(interp, "can't specify bitmap with '@' in a",
|
188 |
|
|
" safe interpreter", (char *) NULL);
|
189 |
|
|
goto error;
|
190 |
|
|
}
|
191 |
|
|
|
192 |
|
|
string = Tcl_TranslateFileName(interp, string + 1, &buffer);
|
193 |
|
|
if (string == NULL) {
|
194 |
|
|
goto error;
|
195 |
|
|
}
|
196 |
|
|
result = TkReadBitmapFile(Tk_Display(tkwin),
|
197 |
|
|
RootWindowOfScreen(nameKey.screen), string,
|
198 |
|
|
(unsigned int *) &width, (unsigned int *) &height,
|
199 |
|
|
&bitmap, &dummy2, &dummy2);
|
200 |
|
|
if (result != BitmapSuccess) {
|
201 |
|
|
if (interp != NULL) {
|
202 |
|
|
Tcl_AppendResult(interp, "error reading bitmap file \"", string,
|
203 |
|
|
"\"", (char *) NULL);
|
204 |
|
|
}
|
205 |
|
|
Tcl_DStringFree(&buffer);
|
206 |
|
|
goto error;
|
207 |
|
|
}
|
208 |
|
|
Tcl_DStringFree(&buffer);
|
209 |
|
|
} else {
|
210 |
|
|
predefHashPtr = Tcl_FindHashEntry(&tkPredefBitmapTable, string);
|
211 |
|
|
if (predefHashPtr == NULL) {
|
212 |
|
|
/*
|
213 |
|
|
* The following platform specific call allows the user to
|
214 |
|
|
* define bitmaps that may only exist during run time. If
|
215 |
|
|
* it returns None nothing was found and we return the error.
|
216 |
|
|
*/
|
217 |
|
|
bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,
|
218 |
|
|
&width, &height);
|
219 |
|
|
|
220 |
|
|
if (bitmap == None) {
|
221 |
|
|
if (interp != NULL) {
|
222 |
|
|
Tcl_AppendResult(interp, "bitmap \"", string,
|
223 |
|
|
"\" not defined", (char *) NULL);
|
224 |
|
|
}
|
225 |
|
|
goto error;
|
226 |
|
|
}
|
227 |
|
|
} else {
|
228 |
|
|
predefPtr = (TkPredefBitmap *) Tcl_GetHashValue(predefHashPtr);
|
229 |
|
|
width = predefPtr->width;
|
230 |
|
|
height = predefPtr->height;
|
231 |
|
|
if (predefPtr->native) {
|
232 |
|
|
bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),
|
233 |
|
|
predefPtr->source);
|
234 |
|
|
if (bitmap == None) {
|
235 |
|
|
panic("native bitmap creation failed");
|
236 |
|
|
}
|
237 |
|
|
} else {
|
238 |
|
|
bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
|
239 |
|
|
RootWindowOfScreen(nameKey.screen), predefPtr->source,
|
240 |
|
|
(unsigned) width, (unsigned) height);
|
241 |
|
|
}
|
242 |
|
|
}
|
243 |
|
|
}
|
244 |
|
|
|
245 |
|
|
/*
|
246 |
|
|
* Add information about this bitmap to our database.
|
247 |
|
|
*/
|
248 |
|
|
|
249 |
|
|
bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap));
|
250 |
|
|
bitmapPtr->bitmap = bitmap;
|
251 |
|
|
bitmapPtr->width = width;
|
252 |
|
|
bitmapPtr->height = height;
|
253 |
|
|
bitmapPtr->display = Tk_Display(tkwin);
|
254 |
|
|
bitmapPtr->refCount = 1;
|
255 |
|
|
bitmapPtr->hashPtr = nameHashPtr;
|
256 |
|
|
idKey.display = bitmapPtr->display;
|
257 |
|
|
idKey.pixmap = bitmap;
|
258 |
|
|
idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) &idKey,
|
259 |
|
|
&new);
|
260 |
|
|
if (!new) {
|
261 |
|
|
panic("bitmap already registered in Tk_GetBitmap");
|
262 |
|
|
}
|
263 |
|
|
Tcl_SetHashValue(nameHashPtr, bitmapPtr);
|
264 |
|
|
Tcl_SetHashValue(idHashPtr, bitmapPtr);
|
265 |
|
|
return bitmapPtr->bitmap;
|
266 |
|
|
|
267 |
|
|
error:
|
268 |
|
|
Tcl_DeleteHashEntry(nameHashPtr);
|
269 |
|
|
return None;
|
270 |
|
|
}
|
271 |
|
|
|
272 |
|
|
/*
|
273 |
|
|
*----------------------------------------------------------------------
|
274 |
|
|
*
|
275 |
|
|
* Tk_DefineBitmap --
|
276 |
|
|
*
|
277 |
|
|
* This procedure associates a textual name with a binary bitmap
|
278 |
|
|
* description, so that the name may be used to refer to the
|
279 |
|
|
* bitmap in future calls to Tk_GetBitmap.
|
280 |
|
|
*
|
281 |
|
|
* Results:
|
282 |
|
|
* A standard Tcl result. If an error occurs then TCL_ERROR is
|
283 |
|
|
* returned and a message is left in interp->result.
|
284 |
|
|
*
|
285 |
|
|
* Side effects:
|
286 |
|
|
* "Name" is entered into the bitmap table and may be used from
|
287 |
|
|
* here on to refer to the given bitmap.
|
288 |
|
|
*
|
289 |
|
|
*----------------------------------------------------------------------
|
290 |
|
|
*/
|
291 |
|
|
|
292 |
|
|
int
|
293 |
|
|
Tk_DefineBitmap(interp, name, source, width, height)
|
294 |
|
|
Tcl_Interp *interp; /* Interpreter to use for error reporting. */
|
295 |
|
|
Tk_Uid name; /* Name to use for bitmap. Must not already
|
296 |
|
|
* be defined as a bitmap. */
|
297 |
|
|
char *source; /* Address of bits for bitmap. */
|
298 |
|
|
int width; /* Width of bitmap. */
|
299 |
|
|
int height; /* Height of bitmap. */
|
300 |
|
|
{
|
301 |
|
|
int new;
|
302 |
|
|
Tcl_HashEntry *predefHashPtr;
|
303 |
|
|
TkPredefBitmap *predefPtr;
|
304 |
|
|
|
305 |
|
|
if (!initialized) {
|
306 |
|
|
BitmapInit();
|
307 |
|
|
}
|
308 |
|
|
|
309 |
|
|
predefHashPtr = Tcl_CreateHashEntry(&tkPredefBitmapTable, name, &new);
|
310 |
|
|
if (!new) {
|
311 |
|
|
Tcl_AppendResult(interp, "bitmap \"", name,
|
312 |
|
|
"\" is already defined", (char *) NULL);
|
313 |
|
|
return TCL_ERROR;
|
314 |
|
|
}
|
315 |
|
|
predefPtr = (TkPredefBitmap *) ckalloc(sizeof(TkPredefBitmap));
|
316 |
|
|
predefPtr->source = source;
|
317 |
|
|
predefPtr->width = width;
|
318 |
|
|
predefPtr->height = height;
|
319 |
|
|
predefPtr->native = 0;
|
320 |
|
|
Tcl_SetHashValue(predefHashPtr, predefPtr);
|
321 |
|
|
return TCL_OK;
|
322 |
|
|
}
|
323 |
|
|
|
324 |
|
|
/*
|
325 |
|
|
*--------------------------------------------------------------
|
326 |
|
|
*
|
327 |
|
|
* Tk_NameOfBitmap --
|
328 |
|
|
*
|
329 |
|
|
* Given a bitmap, return a textual string identifying the
|
330 |
|
|
* bitmap.
|
331 |
|
|
*
|
332 |
|
|
* Results:
|
333 |
|
|
* The return value is the string name associated with bitmap.
|
334 |
|
|
*
|
335 |
|
|
* Side effects:
|
336 |
|
|
* None.
|
337 |
|
|
*
|
338 |
|
|
*--------------------------------------------------------------
|
339 |
|
|
*/
|
340 |
|
|
|
341 |
|
|
Tk_Uid
|
342 |
|
|
Tk_NameOfBitmap(display, bitmap)
|
343 |
|
|
Display *display; /* Display for which bitmap was
|
344 |
|
|
* allocated. */
|
345 |
|
|
Pixmap bitmap; /* Bitmap whose name is wanted. */
|
346 |
|
|
{
|
347 |
|
|
IdKey idKey;
|
348 |
|
|
Tcl_HashEntry *idHashPtr;
|
349 |
|
|
TkBitmap *bitmapPtr;
|
350 |
|
|
|
351 |
|
|
if (!initialized) {
|
352 |
|
|
unknown:
|
353 |
|
|
panic("Tk_NameOfBitmap received unknown bitmap argument");
|
354 |
|
|
}
|
355 |
|
|
|
356 |
|
|
idKey.display = display;
|
357 |
|
|
idKey.pixmap = bitmap;
|
358 |
|
|
idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey);
|
359 |
|
|
if (idHashPtr == NULL) {
|
360 |
|
|
goto unknown;
|
361 |
|
|
}
|
362 |
|
|
bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
|
363 |
|
|
return ((NameKey *) bitmapPtr->hashPtr->key.words)->name;
|
364 |
|
|
}
|
365 |
|
|
|
366 |
|
|
/*
|
367 |
|
|
*--------------------------------------------------------------
|
368 |
|
|
*
|
369 |
|
|
* Tk_SizeOfBitmap --
|
370 |
|
|
*
|
371 |
|
|
* Given a bitmap managed by this module, returns the width
|
372 |
|
|
* and height of the bitmap.
|
373 |
|
|
*
|
374 |
|
|
* Results:
|
375 |
|
|
* The words at *widthPtr and *heightPtr are filled in with
|
376 |
|
|
* the dimenstions of bitmap.
|
377 |
|
|
*
|
378 |
|
|
* Side effects:
|
379 |
|
|
* If bitmap isn't managed by this module then the procedure
|
380 |
|
|
* panics..
|
381 |
|
|
*
|
382 |
|
|
*--------------------------------------------------------------
|
383 |
|
|
*/
|
384 |
|
|
|
385 |
|
|
void
|
386 |
|
|
Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr)
|
387 |
|
|
Display *display; /* Display for which bitmap was
|
388 |
|
|
* allocated. */
|
389 |
|
|
Pixmap bitmap; /* Bitmap whose size is wanted. */
|
390 |
|
|
int *widthPtr; /* Store bitmap width here. */
|
391 |
|
|
int *heightPtr; /* Store bitmap height here. */
|
392 |
|
|
{
|
393 |
|
|
IdKey idKey;
|
394 |
|
|
Tcl_HashEntry *idHashPtr;
|
395 |
|
|
TkBitmap *bitmapPtr;
|
396 |
|
|
|
397 |
|
|
if (!initialized) {
|
398 |
|
|
unknownBitmap:
|
399 |
|
|
panic("Tk_SizeOfBitmap received unknown bitmap argument");
|
400 |
|
|
}
|
401 |
|
|
|
402 |
|
|
idKey.display = display;
|
403 |
|
|
idKey.pixmap = bitmap;
|
404 |
|
|
idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey);
|
405 |
|
|
if (idHashPtr == NULL) {
|
406 |
|
|
goto unknownBitmap;
|
407 |
|
|
}
|
408 |
|
|
bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
|
409 |
|
|
*widthPtr = bitmapPtr->width;
|
410 |
|
|
*heightPtr = bitmapPtr->height;
|
411 |
|
|
}
|
412 |
|
|
|
413 |
|
|
/*
|
414 |
|
|
*----------------------------------------------------------------------
|
415 |
|
|
*
|
416 |
|
|
* Tk_FreeBitmap --
|
417 |
|
|
*
|
418 |
|
|
* This procedure is called to release a bitmap allocated by
|
419 |
|
|
* Tk_GetBitmap or TkGetBitmapFromData.
|
420 |
|
|
*
|
421 |
|
|
* Results:
|
422 |
|
|
* None.
|
423 |
|
|
*
|
424 |
|
|
* Side effects:
|
425 |
|
|
* The reference count associated with bitmap is decremented, and
|
426 |
|
|
* it is officially deallocated if no-one is using it anymore.
|
427 |
|
|
*
|
428 |
|
|
*----------------------------------------------------------------------
|
429 |
|
|
*/
|
430 |
|
|
|
431 |
|
|
void
|
432 |
|
|
Tk_FreeBitmap(display, bitmap)
|
433 |
|
|
Display *display; /* Display for which bitmap was
|
434 |
|
|
* allocated. */
|
435 |
|
|
Pixmap bitmap; /* Bitmap to be released. */
|
436 |
|
|
{
|
437 |
|
|
Tcl_HashEntry *idHashPtr;
|
438 |
|
|
register TkBitmap *bitmapPtr;
|
439 |
|
|
IdKey idKey;
|
440 |
|
|
|
441 |
|
|
if (!initialized) {
|
442 |
|
|
panic("Tk_FreeBitmap called before Tk_GetBitmap");
|
443 |
|
|
}
|
444 |
|
|
|
445 |
|
|
idKey.display = display;
|
446 |
|
|
idKey.pixmap = bitmap;
|
447 |
|
|
idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey);
|
448 |
|
|
if (idHashPtr == NULL) {
|
449 |
|
|
panic("Tk_FreeBitmap received unknown bitmap argument");
|
450 |
|
|
}
|
451 |
|
|
bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
|
452 |
|
|
bitmapPtr->refCount--;
|
453 |
|
|
if (bitmapPtr->refCount == 0) {
|
454 |
|
|
Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap);
|
455 |
|
|
Tcl_DeleteHashEntry(idHashPtr);
|
456 |
|
|
Tcl_DeleteHashEntry(bitmapPtr->hashPtr);
|
457 |
|
|
ckfree((char *) bitmapPtr);
|
458 |
|
|
}
|
459 |
|
|
}
|
460 |
|
|
|
461 |
|
|
/*
|
462 |
|
|
*----------------------------------------------------------------------
|
463 |
|
|
*
|
464 |
|
|
* Tk_GetBitmapFromData --
|
465 |
|
|
*
|
466 |
|
|
* Given a description of the bits for a bitmap, make a bitmap that
|
467 |
|
|
* has the given properties. *** NOTE: this procedure is obsolete
|
468 |
|
|
* and really shouldn't be used anymore. ***
|
469 |
|
|
*
|
470 |
|
|
* Results:
|
471 |
|
|
* The return value is the X identifer for the desired bitmap
|
472 |
|
|
* (a one-plane Pixmap), unless it couldn't be created properly.
|
473 |
|
|
* In this case, None is returned and an error message is left in
|
474 |
|
|
* interp->result. The caller should never modify the bitmap that
|
475 |
|
|
* is returned, and should eventually call Tk_FreeBitmap when the
|
476 |
|
|
* bitmap is no longer needed.
|
477 |
|
|
*
|
478 |
|
|
* Side effects:
|
479 |
|
|
* The bitmap is added to an internal database with a reference count.
|
480 |
|
|
* For each call to this procedure, there should eventually be a call
|
481 |
|
|
* to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
|
482 |
|
|
* aren't needed anymore.
|
483 |
|
|
*
|
484 |
|
|
*----------------------------------------------------------------------
|
485 |
|
|
*/
|
486 |
|
|
|
487 |
|
|
/* ARGSUSED */
|
488 |
|
|
Pixmap
|
489 |
|
|
Tk_GetBitmapFromData(interp, tkwin, source, width, height)
|
490 |
|
|
Tcl_Interp *interp; /* Interpreter to use for error reporting. */
|
491 |
|
|
Tk_Window tkwin; /* Window in which bitmap will be used. */
|
492 |
|
|
char *source; /* Bitmap data for bitmap shape. */
|
493 |
|
|
int width, height; /* Dimensions of bitmap. */
|
494 |
|
|
{
|
495 |
|
|
DataKey nameKey;
|
496 |
|
|
Tcl_HashEntry *dataHashPtr;
|
497 |
|
|
Tk_Uid name;
|
498 |
|
|
int new;
|
499 |
|
|
char string[20];
|
500 |
|
|
static int autoNumber = 0;
|
501 |
|
|
|
502 |
|
|
if (!initialized) {
|
503 |
|
|
BitmapInit();
|
504 |
|
|
}
|
505 |
|
|
|
506 |
|
|
nameKey.source = source;
|
507 |
|
|
nameKey.width = width;
|
508 |
|
|
nameKey.height = height;
|
509 |
|
|
dataHashPtr = Tcl_CreateHashEntry(&dataTable, (char *) &nameKey, &new);
|
510 |
|
|
if (!new) {
|
511 |
|
|
name = (Tk_Uid) Tcl_GetHashValue(dataHashPtr);
|
512 |
|
|
} else {
|
513 |
|
|
autoNumber++;
|
514 |
|
|
sprintf(string, "_tk%d", autoNumber);
|
515 |
|
|
name = Tk_GetUid(string);
|
516 |
|
|
Tcl_SetHashValue(dataHashPtr, name);
|
517 |
|
|
if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
|
518 |
|
|
Tcl_DeleteHashEntry(dataHashPtr);
|
519 |
|
|
return TCL_ERROR;
|
520 |
|
|
}
|
521 |
|
|
}
|
522 |
|
|
return Tk_GetBitmap(interp, tkwin, name);
|
523 |
|
|
}
|
524 |
|
|
|
525 |
|
|
/*
|
526 |
|
|
*----------------------------------------------------------------------
|
527 |
|
|
*
|
528 |
|
|
* BitmapInit --
|
529 |
|
|
*
|
530 |
|
|
* Initialize the structures used for bitmap management.
|
531 |
|
|
*
|
532 |
|
|
* Results:
|
533 |
|
|
* None.
|
534 |
|
|
*
|
535 |
|
|
* Side effects:
|
536 |
|
|
* Read the code.
|
537 |
|
|
*
|
538 |
|
|
*----------------------------------------------------------------------
|
539 |
|
|
*/
|
540 |
|
|
|
541 |
|
|
static void
|
542 |
|
|
BitmapInit()
|
543 |
|
|
{
|
544 |
|
|
Tcl_Interp *dummy;
|
545 |
|
|
|
546 |
|
|
dummy = Tcl_CreateInterp();
|
547 |
|
|
initialized = 1;
|
548 |
|
|
Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int));
|
549 |
|
|
Tcl_InitHashTable(&dataTable, sizeof(DataKey)/sizeof(int));
|
550 |
|
|
Tcl_InitHashTable(&tkPredefBitmapTable, TCL_ONE_WORD_KEYS);
|
551 |
|
|
|
552 |
|
|
/*
|
553 |
|
|
* The call below is tricky: can't use sizeof(IdKey) because it
|
554 |
|
|
* gets padded with extra unpredictable bytes on some 64-bit
|
555 |
|
|
* machines.
|
556 |
|
|
*/
|
557 |
|
|
|
558 |
|
|
Tcl_InitHashTable(&idTable, (sizeof(Display *) + sizeof(Pixmap))
|
559 |
|
|
/sizeof(int));
|
560 |
|
|
|
561 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("error"), (char *) error_bits,
|
562 |
|
|
error_width, error_height);
|
563 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("gray75"), (char *) gray75_bits,
|
564 |
|
|
gray75_width, gray75_height);
|
565 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("gray50"), (char *) gray50_bits,
|
566 |
|
|
gray50_width, gray50_height);
|
567 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("gray25"), (char *) gray25_bits,
|
568 |
|
|
gray25_width, gray25_height);
|
569 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("gray12"), (char *) gray12_bits,
|
570 |
|
|
gray12_width, gray12_height);
|
571 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("hourglass"), (char *) hourglass_bits,
|
572 |
|
|
hourglass_width, hourglass_height);
|
573 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("info"), (char *) info_bits,
|
574 |
|
|
info_width, info_height);
|
575 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("questhead"), (char *) questhead_bits,
|
576 |
|
|
questhead_width, questhead_height);
|
577 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("question"), (char *) question_bits,
|
578 |
|
|
question_width, question_height);
|
579 |
|
|
Tk_DefineBitmap(dummy, Tk_GetUid("warning"), (char *) warning_bits,
|
580 |
|
|
warning_width, warning_height);
|
581 |
|
|
|
582 |
|
|
TkpDefineNativeBitmaps();
|
583 |
|
|
|
584 |
|
|
Tcl_DeleteInterp(dummy);
|
585 |
|
|
}
|
586 |
|
|
|
587 |
|
|
/*
|
588 |
|
|
*----------------------------------------------------------------------
|
589 |
|
|
*
|
590 |
|
|
* TkReadBitmapFile --
|
591 |
|
|
*
|
592 |
|
|
* Loads a bitmap image in X bitmap format into the specified
|
593 |
|
|
* drawable. This is equivelent to the XReadBitmapFile in X.
|
594 |
|
|
*
|
595 |
|
|
* Results:
|
596 |
|
|
* Sets the size, hotspot, and bitmap on success.
|
597 |
|
|
*
|
598 |
|
|
* Side effects:
|
599 |
|
|
* Creates a new bitmap from the file data.
|
600 |
|
|
*
|
601 |
|
|
*----------------------------------------------------------------------
|
602 |
|
|
*/
|
603 |
|
|
|
604 |
|
|
int
|
605 |
|
|
TkReadBitmapFile(display, d, filename, width_return, height_return,
|
606 |
|
|
bitmap_return, x_hot_return, y_hot_return)
|
607 |
|
|
Display* display;
|
608 |
|
|
Drawable d;
|
609 |
|
|
CONST char* filename;
|
610 |
|
|
unsigned int* width_return;
|
611 |
|
|
unsigned int* height_return;
|
612 |
|
|
Pixmap* bitmap_return;
|
613 |
|
|
int* x_hot_return;
|
614 |
|
|
int* y_hot_return;
|
615 |
|
|
{
|
616 |
|
|
char *data;
|
617 |
|
|
|
618 |
|
|
data = TkGetBitmapData(NULL, NULL, (char *) filename,
|
619 |
|
|
(int *) width_return, (int *) height_return, x_hot_return,
|
620 |
|
|
y_hot_return);
|
621 |
|
|
if (data == NULL) {
|
622 |
|
|
return BitmapFileInvalid;
|
623 |
|
|
}
|
624 |
|
|
|
625 |
|
|
*bitmap_return = XCreateBitmapFromData(display, d, data, *width_return,
|
626 |
|
|
*height_return);
|
627 |
|
|
|
628 |
|
|
ckfree(data);
|
629 |
|
|
return BitmapSuccess;
|
630 |
|
|
}
|