OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [tk/] [generic/] [tkBitmap.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.