Annotation of micropolis/src/tk/tkbitmap.c, revision 1.1.1.1

1.1       root        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: 
                    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(interp, tkwin, string)
                    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:     NameKey key;
                    142:     Tcl_HashEntry *nameHashPtr, *idHashPtr, *predefHashPtr;
                    143:     register TkBitmap *bitmapPtr;
                    144:     PredefBitmap *predefPtr;
                    145:     int new;
                    146:     Pixmap bitmap;
                    147:     unsigned int width, height;
                    148:     int dummy2;
                    149: 
                    150:     if (!initialized) {
                    151:        BitmapInit();
                    152:     }
                    153: 
                    154:     key.name = string;
                    155:     key.screen = Tk_Screen(tkwin);
                    156:     nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &key, &new);
                    157:     if (!new) {
                    158:        bitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr);
                    159:        bitmapPtr->refCount++;
                    160:        return bitmapPtr->bitmap;
                    161:     }
                    162: 
                    163:     /*
                    164:      * No suitable bitmap exists.  Create a new bitmap from the
                    165:      * information contained in the string.  If the string starts
                    166:      * with "@" then the rest of the string is a file name containing
                    167:      * the bitmap.  Otherwise the string must refer to a bitmap
                    168:      * defined by a call to Tk_DefineBitmap.
                    169:      */
                    170: 
                    171:     if (*string == '@') {
                    172:        string = Tcl_TildeSubst(interp, string + 1);
                    173:        if (string == NULL) {
                    174:            goto error;
                    175:        }
                    176:        if (XReadBitmapFile(Tk_Display(tkwin),
                    177:                            RootWindowOfScreen(Tk_Screen(tkwin)),
                    178:                string, &width, &height, &bitmap, &dummy2, &dummy2)
                    179:                != BitmapSuccess) {
                    180:            Tcl_AppendResult(interp, "error reading bitmap file \"", string,
                    181:                    "\"", (char *) NULL);
                    182:            goto error;
                    183:        }
                    184:     } else {
                    185:        predefHashPtr = Tcl_FindHashEntry(&predefTable, string);
                    186:        if (predefHashPtr == NULL) {
                    187:            Tcl_AppendResult(interp, "bitmap \"", string,
                    188:                    "\" not defined", (char *) NULL);
                    189:            goto error;
                    190:        }
                    191:        predefPtr = (PredefBitmap *) Tcl_GetHashValue(predefHashPtr);
                    192:        width = predefPtr->width;
                    193:        height = predefPtr->height;
                    194:        bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
                    195:                RootWindowOfScreen(Tk_Screen(tkwin)), predefPtr->source,
                    196:                width, height);
                    197:     }
                    198: 
                    199:     /*
                    200:      * Add information about this bitmap to our database.
                    201:      */
                    202: 
                    203:     bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap));
                    204:     bitmapPtr->bitmap = bitmap;
                    205:     bitmapPtr->width = width;
                    206:     bitmapPtr->height = height;
                    207:     bitmapPtr->display = Tk_Display(tkwin);
                    208:     bitmapPtr->refCount = 1;
                    209:     bitmapPtr->hashPtr = nameHashPtr;
                    210:     idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) bitmapPtr->bitmap,
                    211:            &new);
                    212:     if (!new) {
                    213: /* deh patched to support multiple displays */
                    214: /*     panic("bitmap already registered in Tk_GetBitmap"); */
                    215:         bitmapPtr->refCount = 1000;
                    216:     }
                    217:     Tcl_SetHashValue(nameHashPtr, bitmapPtr);
                    218:     Tcl_SetHashValue(idHashPtr, bitmapPtr);
                    219:     return bitmapPtr->bitmap;
                    220: 
                    221:     error:
                    222:     Tcl_DeleteHashEntry(nameHashPtr);
                    223:     return None;
                    224: }
                    225: 
                    226: /*
                    227:  *----------------------------------------------------------------------
                    228:  *
                    229:  * Tk_DefineBitmap --
                    230:  *
                    231:  *     This procedure associates a textual name with a binary bitmap
                    232:  *     description, so that the name may be used to refer to the
                    233:  *     bitmap in future calls to Tk_GetBitmap.
                    234:  *
                    235:  * Results:
                    236:  *     A standard Tcl result.  If an error occurs then TCL_ERROR is
                    237:  *     returned and a message is left in interp->result.
                    238:  *
                    239:  * Side effects:
                    240:  *     "Name" is entered into the bitmap table and may be used from
                    241:  *     here on to refer to the given bitmap.
                    242:  *
                    243:  *----------------------------------------------------------------------
                    244:  */
                    245: 
                    246: int
                    247: Tk_DefineBitmap(interp, name, source, width, height)
                    248:     Tcl_Interp *interp;                /* Interpreter to use for error reporting. */
                    249:     Tk_Uid name;               /* Name to use for bitmap.  Must not already
                    250:                                 * be defined as a bitmap. */
                    251:     char *source;              /* Address of bits for bitmap. */
                    252:     unsigned int width;                /* Width of bitmap. */
                    253:     unsigned int height;       /* Height of bitmap. */
                    254: {
                    255:     int new;
                    256:     Tcl_HashEntry *predefHashPtr;
                    257:     PredefBitmap *predefPtr;
                    258: 
                    259:     if (!initialized) {
                    260:        BitmapInit();
                    261:     }
                    262: 
                    263:     predefHashPtr = Tcl_CreateHashEntry(&predefTable, name, &new);
                    264:     if (!new) {
                    265:         Tcl_AppendResult(interp, "bitmap \"", name,
                    266:                "\" is already defined", (char *) NULL);
                    267:        return TCL_ERROR;
                    268:     }
                    269:     predefPtr = (PredefBitmap *) malloc(sizeof(PredefBitmap));
                    270:     predefPtr->source = source;
                    271:     predefPtr->width = width;
                    272:     predefPtr->height = height;
                    273:     Tcl_SetHashValue(predefHashPtr, predefPtr);
                    274:     return TCL_OK;
                    275: }
                    276: 
                    277: /*
                    278:  *--------------------------------------------------------------
                    279:  *
                    280:  * Tk_NameOfBitmap --
                    281:  *
                    282:  *     Given a bitmap, return a textual string identifying the
                    283:  *     bitmap.
                    284:  *
                    285:  * Results:
                    286:  *     The return value is the string name associated with bitmap.
                    287:  *
                    288:  * Side effects:
                    289:  *     None.
                    290:  *
                    291:  *--------------------------------------------------------------
                    292:  */
                    293: 
                    294: Tk_Uid
                    295: Tk_NameOfBitmap(bitmap)
                    296:     Pixmap bitmap;                     /* Bitmap whose name is wanted. */
                    297: {
                    298:     Tcl_HashEntry *idHashPtr;
                    299:     TkBitmap *bitmapPtr;
                    300: 
                    301:     if (!initialized) {
                    302:        unknown:
                    303:        panic("Tk_NameOfBitmap received unknown bitmap argument");
                    304:     }
                    305: 
                    306:     idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap);
                    307:     if (idHashPtr == NULL) {
                    308:        goto unknown;
                    309:     }
                    310:     bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
                    311:     return ((NameKey *) bitmapPtr->hashPtr->key.words)->name;
                    312: }
                    313: 
                    314: /*
                    315:  *--------------------------------------------------------------
                    316:  *
                    317:  * Tk_SizeOfBitmap --
                    318:  *
                    319:  *     Given a bitmap managed by this module, returns the width
                    320:  *     and height of the bitmap..
                    321:  *
                    322:  * Results:
                    323:  *     The words at *widthPtr and *heightPtr are filled in with
                    324:  *     the dimenstions of bitmap.
                    325:  *
                    326:  * Side effects:
                    327:  *     If bitmap isn't managed by this module then the procedure
                    328:  *     panics..
                    329:  *
                    330:  *--------------------------------------------------------------
                    331:  */
                    332: 
                    333: void
                    334: Tk_SizeOfBitmap(bitmap, widthPtr, heightPtr)
                    335:     Pixmap bitmap;                     /* Bitmap whose size is wanted. */
                    336:     unsigned int *widthPtr;            /* Store bitmap width here. */
                    337:     unsigned int *heightPtr;           /* Store bitmap height here. */
                    338: {
                    339:     Tcl_HashEntry *idHashPtr;
                    340:     TkBitmap *bitmapPtr;
                    341: 
                    342:     if (!initialized) {
                    343:        unknownBitmap:
                    344:        panic("Tk_SizeOfBitmap received unknown bitmap argument");
                    345:     }
                    346: 
                    347:     idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap);
                    348:     if (idHashPtr == NULL) {
                    349:        goto unknownBitmap;
                    350:     }
                    351:     bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
                    352:     *widthPtr = bitmapPtr->width;
                    353:     *heightPtr = bitmapPtr->height;
                    354: }
                    355: 
                    356: /*
                    357:  *----------------------------------------------------------------------
                    358:  *
                    359:  * Tk_FreeBitmap --
                    360:  *
                    361:  *     This procedure is called to release a bitmap allocated by
                    362:  *     Tk_GetBitmap or TkGetBitmapFromData.
                    363:  *
                    364:  * Results:
                    365:  *     None.
                    366:  *
                    367:  * Side effects:
                    368:  *     The reference count associated with bitmap is decremented, and
                    369:  *     it is officially deallocated if no-one is using it anymore.
                    370:  *
                    371:  *----------------------------------------------------------------------
                    372:  */
                    373: 
                    374: void
                    375: Tk_FreeBitmap(bitmap)
                    376:     Pixmap bitmap;                     /* Bitmap to be released. */
                    377: {
                    378:     Tcl_HashEntry *idHashPtr;
                    379:     register TkBitmap *bitmapPtr;
                    380: 
                    381:     if (!initialized) {
                    382:        panic("Tk_FreeBitmap called before Tk_GetBitmap");
                    383:     }
                    384: 
                    385:     idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap);
                    386:     if (idHashPtr == NULL) {
                    387:        panic("Tk_FreeBitmap received unknown bitmap argument");
                    388:     }
                    389:     bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr);
                    390:     bitmapPtr->refCount--;
                    391:     if (bitmapPtr->refCount == 0) {
                    392:        XFreePixmap(bitmapPtr->display, bitmapPtr->bitmap);
                    393:        Tcl_DeleteHashEntry(idHashPtr);
                    394:        Tcl_DeleteHashEntry(bitmapPtr->hashPtr);
                    395:        ckfree((char *) bitmapPtr);
                    396:     }
                    397: }
                    398: 
                    399: /*
                    400:  *----------------------------------------------------------------------
                    401:  *
                    402:  * Tk_GetBitmapFromData --
                    403:  *
                    404:  *     Given a description of the bits for a bitmap, make a bitmap that
                    405:  *     has the given properties.
                    406:  *
                    407:  * Results:
                    408:  *     The return value is the X identifer for the desired bitmap
                    409:  *     (a one-plane Pixmap), unless it couldn't be created properly.
                    410:  *     In this case, None is returned and an error message is left in
                    411:  *     interp->result.  The caller should never modify the bitmap that
                    412:  *     is returned, and should eventually call Tk_FreeBitmap when the
                    413:  *     bitmap is no longer needed.
                    414:  *
                    415:  * Side effects:
                    416:  *     The bitmap is added to an internal database with a reference count.
                    417:  *     For each call to this procedure, there should eventually be a call
                    418:  *     to Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
                    419:  *     aren't needed anymore.
                    420:  *
                    421:  *----------------------------------------------------------------------
                    422:  */
                    423: 
                    424:        /* ARGSUSED */
                    425: Pixmap
                    426: Tk_GetBitmapFromData(interp, tkwin, source, width, height)
                    427:     Tcl_Interp *interp;                /* Interpreter to use for error reporting. */
                    428:     Tk_Window tkwin;           /* Window in which bitmap will be used. */
                    429:     char *source;              /* Bitmap data for bitmap shape. */
                    430:     unsigned int width, height;        /* Dimensions of bitmap. */
                    431: {
                    432:     DataKey key;
                    433:     Tcl_HashEntry *dataHashPtr;
                    434:     Tk_Uid name = NULL;                /* Initialization need only to prevent
                    435:                                 * compiler warning. */
                    436:     int new;
                    437:     static autoNumber = 0;
                    438:     char string[20];
                    439: 
                    440:     if (!initialized) {
                    441:        BitmapInit();
                    442:     }
                    443: 
                    444:     key.source = source;
                    445:     key.width = width;
                    446:     key.height = height;
                    447:     dataHashPtr = Tcl_CreateHashEntry(&dataTable, (char *) &key, &new);
                    448:     if (!new) {
                    449:        name = (Tk_Uid) Tcl_GetHashValue(dataHashPtr);
                    450:     } else {
                    451:        autoNumber++;
                    452:        sprintf(string, "_tk%d", autoNumber);
                    453:        name = Tk_GetUid(string);
                    454:        Tcl_SetHashValue(dataHashPtr, name);
                    455:        if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
                    456:            Tcl_DeleteHashEntry(dataHashPtr);
                    457:            return TCL_ERROR;
                    458:        }
                    459:     }
                    460:     return Tk_GetBitmap(interp, tkwin, name);
                    461: }
                    462: 
                    463: /*
                    464:  *----------------------------------------------------------------------
                    465:  *
                    466:  * BitmapInit --
                    467:  *
                    468:  *     Initialize the structures used for bitmap management.
                    469:  *
                    470:  * Results:
                    471:  *     None.
                    472:  *
                    473:  * Side effects:
                    474:  *     Read the code.
                    475:  *
                    476:  *----------------------------------------------------------------------
                    477:  */
                    478: 
                    479: static void
                    480: BitmapInit()
                    481: {
                    482:     Tcl_Interp *dummy;
                    483: 
                    484:     dummy = Tcl_CreateInterp();
                    485:     initialized = 1;
                    486:     Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int));
                    487:     Tcl_InitHashTable(&dataTable, sizeof(DataKey)/sizeof(int));
                    488:     Tcl_InitHashTable(&predefTable, TCL_ONE_WORD_KEYS);
                    489:     Tcl_InitHashTable(&idTable, TCL_ONE_WORD_KEYS);
                    490: 
                    491:     Tk_DefineBitmap(dummy, Tk_GetUid("gray50"), (char *)gray50_bits,
                    492:                    gray50_width, gray50_height);
                    493:     Tk_DefineBitmap(dummy, Tk_GetUid("gray25"),
                    494:                    (char *)gray25_bits, gray25_width, gray25_height);
                    495:     Tcl_DeleteInterp(dummy);
                    496: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.