diff options
Diffstat (limited to 'tk8.6/generic/tkBitmap.c')
-rw-r--r-- | tk8.6/generic/tkBitmap.c | 1205 |
1 files changed, 0 insertions, 1205 deletions
diff --git a/tk8.6/generic/tkBitmap.c b/tk8.6/generic/tkBitmap.c deleted file mode 100644 index 88f3e2b..0000000 --- a/tk8.6/generic/tkBitmap.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* - * tkBitmap.c -- - * - * This file maintains a database of read-only bitmaps for the Tk - * toolkit. This allows bitmaps to be shared between widgets and also - * avoids interactions with the X server. - * - * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1998 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkInt.h" - -/* - * The includes below are for pre-defined bitmaps. - * - * Platform-specific issue: Windows complains when the bitmaps are included, - * because an array of characters is being initialized with integers as - * elements. For lint purposes, the following pragmas temporarily turn off - * that warning message. - */ - -#if defined(_MSC_VER) -#pragma warning (disable : 4305) -#endif - -#include "error.xbm" -#include "gray12.xbm" -#include "gray25.xbm" -#include "gray50.xbm" -#include "gray75.xbm" -#include "hourglass.xbm" -#include "info.xbm" -#include "questhead.xbm" -#include "question.xbm" -#include "warning.xbm" - -#if defined(_MSC_VER) -#pragma warning (default : 4305) -#endif - -/* - * One of the following data structures exists for each bitmap that is - * currently in use. Each structure is indexed with both "idTable" and - * "nameTable". - */ - -typedef struct TkBitmap { - Pixmap bitmap; /* X identifier for bitmap. None means this - * bitmap was created by Tk_DefineBitmap and - * it isn't currently in use. */ - int width, height; /* Dimensions of bitmap. */ - Display *display; /* Display for which bitmap is valid. */ - int screenNum; /* Screen on which bitmap is valid. */ - int resourceRefCount; /* Number of active uses of this bitmap (each - * active use corresponds to a call to - * Tk_AllocBitmapFromObj or Tk_GetBitmap). If - * this count is 0, then this TkBitmap - * structure is no longer valid and it isn't - * present in nameTable: it is being kept - * around only because there are objects - * referring to it. The structure is freed - * when resourceRefCount and objRefCount are - * both 0. */ - int objRefCount; /* Number of Tcl_Obj's that reference this - * structure. */ - Tcl_HashEntry *nameHashPtr; /* Entry in nameTable for this structure - * (needed when deleting). */ - Tcl_HashEntry *idHashPtr; /* Entry in idTable for this structure (needed - * when deleting). */ - struct TkBitmap *nextPtr; /* Points to the next TkBitmap structure with - * the same name. All bitmaps with the same - * name (but different displays or screens) - * are chained together off a single entry in - * nameTable. */ -} TkBitmap; - -/* - * Used in bitmapDataTable, stored in the TkDisplay structure, to map between - * in-core data about a bitmap to its TkBitmap structure. - */ - -typedef struct { - const char *source; /* Bitmap bits. */ - int width, height; /* Dimensions of bitmap. */ -} DataKey; - -typedef struct ThreadSpecificData { - int initialized; /* 0 means table below needs initializing. */ - Tcl_HashTable predefBitmapTable; - /* Hash table created by Tk_DefineBitmap to - * map from a name to a collection of in-core - * data about a bitmap. The table is indexed - * by the address of the data for the bitmap, - * and the entries contain pointers to - * TkPredefBitmap structures. */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -/* - * Forward declarations for functions defined in this file: - */ - -static void BitmapInit(TkDisplay *dispPtr); -static void DupBitmapObjProc(Tcl_Obj *srcObjPtr, - Tcl_Obj *dupObjPtr); -static void FreeBitmap(TkBitmap *bitmapPtr); -static void FreeBitmapObj(Tcl_Obj *objPtr); -static void FreeBitmapObjProc(Tcl_Obj *objPtr); -static TkBitmap * GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, - const char *name); -static TkBitmap * GetBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -static void InitBitmapObj(Tcl_Obj *objPtr); - -/* - * The following structure defines the implementation of the "bitmap" Tcl - * object, which maps a string bitmap name to a TkBitmap object. The ptr1 - * field of the Tcl_Obj points to a TkBitmap object. - */ - -const Tcl_ObjType tkBitmapObjType = { - "bitmap", /* name */ - FreeBitmapObjProc, /* freeIntRepProc */ - DupBitmapObjProc, /* dupIntRepProc */ - NULL, /* updateStringProc */ - NULL /* setFromAnyProc */ -}; - -/* - *---------------------------------------------------------------------- - * - * Tk_AllocBitmapFromObj -- - * - * Given a Tcl_Obj *, map the value to a corresponding Pixmap structure - * based on the tkwin given. - * - * Results: - * The return value is the X identifer for the desired bitmap (i.e. a - * Pixmap with a single plane), unless string couldn't be parsed - * correctly. In this case, None is returned and an error message is left - * in the interp's result. The caller should never modify the bitmap that - * is returned, and should eventually call Tk_FreeBitmapFromObj when the - * bitmap is no longer needed. - * - * Side effects: - * The bitmap is added to an internal database with a reference count. - * For each call to this function, there should eventually be a call to - * Tk_FreeBitmapFromObj, so that the database can be cleaned up when - * bitmaps aren't needed anymore. - * - *---------------------------------------------------------------------- - */ - -Pixmap -Tk_AllocBitmapFromObj( - Tcl_Interp *interp, /* Interp for error results. This may be - * NULL. */ - Tk_Window tkwin, /* Need the screen the bitmap is used on.*/ - Tcl_Obj *objPtr) /* Object describing bitmap; see manual entry - * for legal syntax of string value. */ -{ - TkBitmap *bitmapPtr; - - if (objPtr->typePtr != &tkBitmapObjType) { - InitBitmapObj(objPtr); - } - bitmapPtr = objPtr->internalRep.twoPtrValue.ptr1; - - /* - * If the object currently points to a TkBitmap, see if it's the one we - * want. If so, increment its reference count and return. - */ - - if (bitmapPtr != NULL) { - if (bitmapPtr->resourceRefCount == 0) { - /* - * This is a stale reference: it refers to a TkBitmap that's no - * longer in use. Clear the reference. - */ - - FreeBitmapObj(objPtr); - bitmapPtr = NULL; - } else if ((Tk_Display(tkwin) == bitmapPtr->display) - && (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) { - bitmapPtr->resourceRefCount++; - return bitmapPtr->bitmap; - } - } - - /* - * The object didn't point to the TkBitmap that we wanted. Search the list - * of TkBitmaps with the same name to see if one of the others is the - * right one. - */ - - if (bitmapPtr != NULL) { - TkBitmap *firstBitmapPtr = Tcl_GetHashValue(bitmapPtr->nameHashPtr); - - FreeBitmapObj(objPtr); - for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL; - bitmapPtr = bitmapPtr->nextPtr) { - if ((Tk_Display(tkwin) == bitmapPtr->display) && - (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) { - bitmapPtr->resourceRefCount++; - bitmapPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr; - return bitmapPtr->bitmap; - } - } - } - - /* - * Still no luck. Call GetBitmap to allocate a new TkBitmap object. - */ - - bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr)); - objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr; - if (bitmapPtr == NULL) { - return None; - } - bitmapPtr->objRefCount++; - return bitmapPtr->bitmap; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetBitmap -- - * - * Given a string describing a bitmap, locate (or create if necessary) a - * bitmap that fits the description. - * - * Results: - * The return value is the X identifer for the desired bitmap (i.e. a - * Pixmap with a single plane), unless string couldn't be parsed - * correctly. In this case, None is returned and an error message is left - * in the interp's result. The caller should never modify the bitmap that - * is returned, and should eventually call Tk_FreeBitmap when the bitmap - * is no longer needed. - * - * Side effects: - * The bitmap is added to an internal database with a reference count. - * For each call to this function, there should eventually be a call to - * Tk_FreeBitmap, so that the database can be cleaned up when bitmaps - * aren't needed anymore. - * - *---------------------------------------------------------------------- - */ - -Pixmap -Tk_GetBitmap( - Tcl_Interp *interp, /* Interpreter to use for error reporting, - * this may be NULL. */ - Tk_Window tkwin, /* Window in which bitmap will be used. */ - const char *string) /* Description of bitmap. See manual entry for - * details on legal syntax. */ -{ - TkBitmap *bitmapPtr = GetBitmap(interp, tkwin, string); - - if (bitmapPtr == NULL) { - return None; - } - return bitmapPtr->bitmap; -} - -/* - *---------------------------------------------------------------------- - * - * GetBitmap -- - * - * Given a string describing a bitmap, locate (or create if necessary) a - * bitmap that fits the description. This routine returns the internal - * data structure for the bitmap. This avoids extra hash table lookups in - * Tk_AllocBitmapFromObj. - * - * Results: - * The return value is the X identifer for the desired bitmap (i.e. a - * Pixmap with a single plane), unless string couldn't be parsed - * correctly. In this case, None is returned and an error message is left - * in the interp's result. The caller should never modify the bitmap that - * is returned, and should eventually call Tk_FreeBitmap when the bitmap - * is no longer needed. - * - * Side effects: - * The bitmap is added to an internal database with a reference count. - * For each call to this function, there should eventually be a call to - * Tk_FreeBitmap or Tk_FreeBitmapFromObj, so that the database can be - * cleaned up when bitmaps aren't needed anymore. - * - *---------------------------------------------------------------------- - */ - -static TkBitmap * -GetBitmap( - Tcl_Interp *interp, /* Interpreter to use for error reporting, - * this may be NULL. */ - Tk_Window tkwin, /* Window in which bitmap will be used. */ - const char *string) /* Description of bitmap. See manual entry for - * details on legal syntax. */ -{ - Tcl_HashEntry *nameHashPtr, *predefHashPtr; - TkBitmap *bitmapPtr, *existingBitmapPtr; - TkPredefBitmap *predefPtr; - Pixmap bitmap; - int isNew, width = 0, height = 0, dummy2; - TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (!dispPtr->bitmapInit) { - BitmapInit(dispPtr); - } - - nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string, - &isNew); - if (!isNew) { - existingBitmapPtr = Tcl_GetHashValue(nameHashPtr); - for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL; - bitmapPtr = bitmapPtr->nextPtr) { - if ((Tk_Display(tkwin) == bitmapPtr->display) && - (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) { - bitmapPtr->resourceRefCount++; - return bitmapPtr; - } - } - } else { - existingBitmapPtr = NULL; - } - - /* - * No suitable bitmap exists. Create a new bitmap from the information - * contained in the string. If the string starts with "@" then the rest of - * the string is a file name containing the bitmap. Otherwise the string - * must refer to a bitmap defined by a call to Tk_DefineBitmap. - */ - - if (*string == '@') { /* INTL: ISO char */ - Tcl_DString buffer; - int result; - - if (Tcl_IsSafe(interp)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "can't specify bitmap with '@' in a safe interpreter", - -1)); - Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL); - goto error; - } - - /* - * Note that we need to cast away the const from the string because - * Tcl_TranslateFileName is non-const, even though it doesn't modify - * the string. - */ - - string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer); - if (string == NULL) { - goto error; - } - result = TkReadBitmapFile(Tk_Display(tkwin), - RootWindowOfScreen(Tk_Screen(tkwin)), string, - (unsigned int *) &width, (unsigned int *) &height, - &bitmap, &dummy2, &dummy2); - if (result != BitmapSuccess) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error reading bitmap file \"%s\"", string)); - Tcl_SetErrorCode(interp, "TK", "BITMAP", "FILE_ERROR", NULL); - } - Tcl_DStringFree(&buffer); - goto error; - } - Tcl_DStringFree(&buffer); - } else { - predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable, string); - if (predefHashPtr == NULL) { - /* - * The following platform specific call allows the user to define - * bitmaps that may only exist during run time. If it returns None - * nothing was found and we return the error. - */ - - bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string, - &width, &height); - - if (bitmap == None) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bitmap \"%s\" not defined", string)); - Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BITMAP", string, - NULL); - } - goto error; - } - } else { - predefPtr = Tcl_GetHashValue(predefHashPtr); - width = predefPtr->width; - height = predefPtr->height; - if (predefPtr->native) { - bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin), - predefPtr->source); - if (bitmap == None) { - Tcl_Panic("native bitmap creation failed"); - } - } else { - bitmap = XCreateBitmapFromData(Tk_Display(tkwin), - RootWindowOfScreen(Tk_Screen(tkwin)), - predefPtr->source, (unsigned)width, (unsigned)height); - } - } - } - - /* - * Add information about this bitmap to our database. - */ - - bitmapPtr = ckalloc(sizeof(TkBitmap)); - bitmapPtr->bitmap = bitmap; - bitmapPtr->width = width; - bitmapPtr->height = height; - bitmapPtr->display = Tk_Display(tkwin); - bitmapPtr->screenNum = Tk_ScreenNumber(tkwin); - bitmapPtr->resourceRefCount = 1; - bitmapPtr->objRefCount = 0; - bitmapPtr->nameHashPtr = nameHashPtr; - bitmapPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapIdTable, - (char *) bitmap, &isNew); - if (!isNew) { - Tcl_Panic("bitmap already registered in Tk_GetBitmap"); - } - bitmapPtr->nextPtr = existingBitmapPtr; - Tcl_SetHashValue(nameHashPtr, bitmapPtr); - Tcl_SetHashValue(bitmapPtr->idHashPtr, bitmapPtr); - return bitmapPtr; - - error: - if (isNew) { - Tcl_DeleteHashEntry(nameHashPtr); - } - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_DefineBitmap -- - * - * This function associates a textual name with a binary bitmap - * description, so that the name may be used to refer to the bitmap in - * future calls to Tk_GetBitmap. - * - * Results: - * A standard Tcl result. If an error occurs then TCL_ERROR is returned - * and a message is left in the interp's result. - * - * Side effects: - * "Name" is entered into the bitmap table and may be used from here on - * to refer to the given bitmap. - * - *---------------------------------------------------------------------- - */ - -int -Tk_DefineBitmap( - Tcl_Interp *interp, /* Interpreter to use for error reporting. */ - const char *name, /* Name to use for bitmap. Must not already be - * defined as a bitmap. */ - const void *source, /* Address of bits for bitmap. */ - int width, /* Width of bitmap. */ - int height) /* Height of bitmap. */ -{ - int isNew; - Tcl_HashEntry *predefHashPtr; - TkPredefBitmap *predefPtr; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * Initialize the Bitmap module if not initialized already for this - * thread. Since the current TkDisplay structure cannot be introspected - * from here, pass a NULL pointer to BitmapInit, which will know to - * initialize only the data in the ThreadSpecificData structure for the - * current thread. - */ - - if (!tsdPtr->initialized) { - BitmapInit(NULL); - } - - predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable, - name, &isNew); - if (!isNew) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bitmap \"%s\" is already defined", name)); - Tcl_SetErrorCode(interp, "TK", "BITMAP", "EXISTS", NULL); - return TCL_ERROR; - } - predefPtr = ckalloc(sizeof(TkPredefBitmap)); - predefPtr->source = source; - predefPtr->width = width; - predefPtr->height = height; - predefPtr->native = 0; - Tcl_SetHashValue(predefHashPtr, predefPtr); - return TCL_OK; -} - -/* - *-------------------------------------------------------------- - * - * Tk_NameOfBitmap -- - * - * Given a bitmap, return a textual string identifying the bitmap. - * - * Results: - * The return value is the string name associated with bitmap. - * - * Side effects: - * None. - * - *-------------------------------------------------------------- - */ - -const char * -Tk_NameOfBitmap( - Display *display, /* Display for which bitmap was allocated. */ - Pixmap bitmap) /* Bitmap whose name is wanted. */ -{ - Tcl_HashEntry *idHashPtr; - TkBitmap *bitmapPtr; - TkDisplay *dispPtr = TkGetDisplay(display); - - if (dispPtr == NULL || !dispPtr->bitmapInit) { - unknown: - Tcl_Panic("Tk_NameOfBitmap received unknown bitmap argument"); - } - - idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap); - if (idHashPtr == NULL) { - goto unknown; - } - bitmapPtr = Tcl_GetHashValue(idHashPtr); - return bitmapPtr->nameHashPtr->key.string; -} - -/* - *-------------------------------------------------------------- - * - * Tk_SizeOfBitmap -- - * - * Given a bitmap managed by this module, returns the width and height of - * the bitmap. - * - * Results: - * The words at *widthPtr and *heightPtr are filled in with the - * dimenstions of bitmap. - * - * Side effects: - * If bitmap isn't managed by this module then the function panics.. - * - *-------------------------------------------------------------- - */ - -void -Tk_SizeOfBitmap( - Display *display, /* Display for which bitmap was allocated. */ - Pixmap bitmap, /* Bitmap whose size is wanted. */ - int *widthPtr, /* Store bitmap width here. */ - int *heightPtr) /* Store bitmap height here. */ -{ - Tcl_HashEntry *idHashPtr; - TkBitmap *bitmapPtr; - TkDisplay *dispPtr = TkGetDisplay(display); - - if (!dispPtr->bitmapInit) { - unknownBitmap: - Tcl_Panic("Tk_SizeOfBitmap received unknown bitmap argument"); - } - - idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap); - if (idHashPtr == NULL) { - goto unknownBitmap; - } - bitmapPtr = Tcl_GetHashValue(idHashPtr); - *widthPtr = bitmapPtr->width; - *heightPtr = bitmapPtr->height; -} - -/* - *---------------------------------------------------------------------- - * - * FreeBitmap -- - * - * This function does all the work of releasing a bitmap allocated by - * Tk_GetBitmap or TkGetBitmapFromData. It is invoked by both - * Tk_FreeBitmap and Tk_FreeBitmapFromObj - * - * Results: - * None. - * - * Side effects: - * The reference count associated with bitmap is decremented, and it is - * officially deallocated if no-one is using it anymore. - * - *---------------------------------------------------------------------- - */ - -static void -FreeBitmap( - TkBitmap *bitmapPtr) /* Bitmap to be released. */ -{ - TkBitmap *prevPtr; - - bitmapPtr->resourceRefCount--; - if (bitmapPtr->resourceRefCount > 0) { - return; - } - - Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap); - Tcl_DeleteHashEntry(bitmapPtr->idHashPtr); - prevPtr = Tcl_GetHashValue(bitmapPtr->nameHashPtr); - if (prevPtr == bitmapPtr) { - if (bitmapPtr->nextPtr == NULL) { - Tcl_DeleteHashEntry(bitmapPtr->nameHashPtr); - } else { - Tcl_SetHashValue(bitmapPtr->nameHashPtr, bitmapPtr->nextPtr); - } - } else { - while (prevPtr->nextPtr != bitmapPtr) { - prevPtr = prevPtr->nextPtr; - } - prevPtr->nextPtr = bitmapPtr->nextPtr; - } - if (bitmapPtr->objRefCount == 0) { - ckfree(bitmapPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_FreeBitmap -- - * - * This function is called to release a bitmap allocated by Tk_GetBitmap - * or TkGetBitmapFromData. - * - * Results: - * None. - * - * Side effects: - * The reference count associated with bitmap is decremented, and it is - * officially deallocated if no-one is using it anymore. - * - *---------------------------------------------------------------------- - */ - -void -Tk_FreeBitmap( - Display *display, /* Display for which bitmap was allocated. */ - Pixmap bitmap) /* Bitmap to be released. */ -{ - Tcl_HashEntry *idHashPtr; - TkDisplay *dispPtr = TkGetDisplay(display); - - if (!dispPtr->bitmapInit) { - Tcl_Panic("Tk_FreeBitmap called before Tk_GetBitmap"); - } - - idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap); - if (idHashPtr == NULL) { - Tcl_Panic("Tk_FreeBitmap received unknown bitmap argument"); - } - FreeBitmap(Tcl_GetHashValue(idHashPtr)); -} - -/* - *---------------------------------------------------------------------- - * - * Tk_FreeBitmapFromObj -- - * - * This function is called to release a bitmap allocated by - * Tk_AllocBitmapFromObj. It does not throw away the Tcl_Obj *; it only - * gets rid of the hash table entry for this bitmap and clears the cached - * value that is normally stored in the object. - * - * Results: - * None. - * - * Side effects: - * The reference count associated with the bitmap represented by objPtr - * is decremented, and the bitmap is released to X if there are no - * remaining uses for it. - * - *---------------------------------------------------------------------- - */ - -void -Tk_FreeBitmapFromObj( - Tk_Window tkwin, /* The window this bitmap lives in. Needed for - * the display value. */ - Tcl_Obj *objPtr) /* The Tcl_Obj * to be freed. */ -{ - FreeBitmap(GetBitmapFromObj(tkwin, objPtr)); -} - -/* - *--------------------------------------------------------------------------- - * - * FreeBitmapObjProc, FreeBitmapObj -- - * - * This proc is called to release an object reference to a bitmap. - * Called when the object's internal rep is released or when the cached - * bitmapPtr needs to be changed. - * - * Results: - * None. - * - * Side effects: - * The object reference count is decremented. When both it and the hash - * ref count go to zero, the color's resources are released. - * - *--------------------------------------------------------------------------- - */ - -static void -FreeBitmapObjProc( - Tcl_Obj *objPtr) /* The object we are releasing. */ -{ - FreeBitmapObj(objPtr); - objPtr->typePtr = NULL; -} - -static void -FreeBitmapObj( - Tcl_Obj *objPtr) /* The object we are releasing. */ -{ - TkBitmap *bitmapPtr = objPtr->internalRep.twoPtrValue.ptr1; - - if (bitmapPtr != NULL) { - bitmapPtr->objRefCount--; - if ((bitmapPtr->objRefCount == 0) - && (bitmapPtr->resourceRefCount == 0)) { - ckfree(bitmapPtr); - } - objPtr->internalRep.twoPtrValue.ptr1 = NULL; - } -} - -/* - *--------------------------------------------------------------------------- - * - * DupBitmapObjProc -- - * - * When a cached bitmap object is duplicated, this is called to update - * the internal reps. - * - * Results: - * None. - * - * Side effects: - * The color's objRefCount is incremented and the internal rep of the - * copy is set to point to it. - * - *--------------------------------------------------------------------------- - */ - -static void -DupBitmapObjProc( - Tcl_Obj *srcObjPtr, /* The object we are copying from. */ - Tcl_Obj *dupObjPtr) /* The object we are copying to. */ -{ - TkBitmap *bitmapPtr = srcObjPtr->internalRep.twoPtrValue.ptr1; - - dupObjPtr->typePtr = srcObjPtr->typePtr; - dupObjPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr; - - if (bitmapPtr != NULL) { - bitmapPtr->objRefCount++; - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetBitmapFromData -- - * - * Given a description of the bits for a bitmap, make a bitmap that has - * the given properties. *** NOTE: this function is obsolete and really - * shouldn't be used anymore. *** - * - * Results: - * The return value is the X identifer for the desired bitmap (a - * one-plane Pixmap), unless it couldn't be created properly. In this - * case, None is returned and an error message is left in the interp's - * result. The caller should never modify the bitmap that is returned, - * and should eventually call Tk_FreeBitmap when the bitmap is no longer - * needed. - * - * Side effects: - * The bitmap is added to an internal database with a reference count. - * For each call to this function, there should eventually be a call to - * Tk_FreeBitmap, so that the database can be cleaned up when bitmaps - * aren't needed anymore. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -Pixmap -Tk_GetBitmapFromData( - Tcl_Interp *interp, /* Interpreter to use for error reporting. */ - Tk_Window tkwin, /* Window in which bitmap will be used. */ - const void *source, /* Bitmap data for bitmap shape. */ - int width, int height) /* Dimensions of bitmap. */ -{ - DataKey nameKey; - Tcl_HashEntry *dataHashPtr; - int isNew; - char string[16 + TCL_INTEGER_SPACE]; - char *name; - TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (!tsdPtr->initialized) { - BitmapInit(dispPtr); - } - - nameKey.source = source; - nameKey.width = width; - nameKey.height = height; - dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable, - (char *) &nameKey, &isNew); - if (!isNew) { - name = Tcl_GetHashValue(dataHashPtr); - } else { - dispPtr->bitmapAutoNumber++; - sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber); - name = string; - Tcl_SetHashValue(dataHashPtr, name); - if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) { - Tcl_DeleteHashEntry(dataHashPtr); - return TCL_ERROR; - } - } - return Tk_GetBitmap(interp, tkwin, name); -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetBitmapFromObj -- - * - * Returns the bitmap referred to by a Tcl object. The bitmap must - * already have been allocated via a call to Tk_AllocBitmapFromObj or - * Tk_GetBitmap. - * - * Results: - * Returns the Pixmap that matches the tkwin and the string rep of - * objPtr. - * - * Side effects: - * If the object is not already a bitmap, the conversion will free any - * old internal representation. - * - *---------------------------------------------------------------------- - */ - -Pixmap -Tk_GetBitmapFromObj( - Tk_Window tkwin, - Tcl_Obj *objPtr) /* The object from which to get pixels. */ -{ - TkBitmap *bitmapPtr = GetBitmapFromObj(tkwin, objPtr); - - return bitmapPtr->bitmap; -} - -/* - *---------------------------------------------------------------------- - * - * GetBitmapFromObj -- - * - * Returns the bitmap referred to by a Tcl object. The bitmap must - * already have been allocated via a call to Tk_AllocBitmapFromObj or - * Tk_GetBitmap. - * - * Results: - * Returns the TkBitmap * that matches the tkwin and the string rep of - * objPtr. - * - * Side effects: - * If the object is not already a bitmap, the conversion will free any - * old internal representation. - * - *---------------------------------------------------------------------- - */ - -static TkBitmap * -GetBitmapFromObj( - Tk_Window tkwin, /* Window in which the bitmap will be used. */ - Tcl_Obj *objPtr) /* The object that describes the desired - * bitmap. */ -{ - TkBitmap *bitmapPtr; - Tcl_HashEntry *hashPtr; - TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - - if (objPtr->typePtr != &tkBitmapObjType) { - InitBitmapObj(objPtr); - } - - bitmapPtr = objPtr->internalRep.twoPtrValue.ptr1; - if (bitmapPtr != NULL) { - if ((bitmapPtr->resourceRefCount > 0) - && (Tk_Display(tkwin) == bitmapPtr->display)) { - return bitmapPtr; - } - hashPtr = bitmapPtr->nameHashPtr; - FreeBitmapObj(objPtr); - } else { - hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, - Tcl_GetString(objPtr)); - if (hashPtr == NULL) { - goto error; - } - } - - /* - * At this point we've got a hash table entry, off of which hang one or - * more TkBitmap structures. See if any of them will work. - */ - - for (bitmapPtr = Tcl_GetHashValue(hashPtr); bitmapPtr != NULL; - bitmapPtr = bitmapPtr->nextPtr) { - if (Tk_Display(tkwin) == bitmapPtr->display) { - objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr; - bitmapPtr->objRefCount++; - return bitmapPtr; - } - } - - error: - Tcl_Panic("GetBitmapFromObj called with non-existent bitmap!"); - /* - * The following code isn't reached; it's just there to please compilers. - */ - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * InitBitmapObj -- - * - * Bookeeping function to change an objPtr to a bitmap type. - * - * Results: - * None. - * - * Side effects: - * The old internal rep of the object is freed. The internal rep is - * cleared. The final form of the object is set by either - * Tk_AllocBitmapFromObj or GetBitmapFromObj. - * - *---------------------------------------------------------------------- - */ - -static void -InitBitmapObj( - Tcl_Obj *objPtr) /* The object to convert. */ -{ - const Tcl_ObjType *typePtr; - - /* - * Free the old internalRep before setting the new one. - */ - - Tcl_GetString(objPtr); - typePtr = objPtr->typePtr; - if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - typePtr->freeIntRepProc(objPtr); - } - objPtr->typePtr = &tkBitmapObjType; - objPtr->internalRep.twoPtrValue.ptr1 = NULL; -} - -/* - *---------------------------------------------------------------------- - * - * BitmapInit -- - * - * Initializes hash tables used by this module. Initializes tables stored - * in TkDisplay structure if a TkDisplay pointer is passed in. Also - * initializes the thread-local data in the current thread's - * ThreadSpecificData structure. - * - * Results: - * None. - * - * Side effects: - * Read the code. - * - *---------------------------------------------------------------------- - */ - -static void -BitmapInit( - TkDisplay *dispPtr) /* TkDisplay structure encapsulating - * thread-specific data used by this module, - * or NULL if unavailable. */ -{ - Tcl_Interp *dummy; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * First initialize the data in the ThreadSpecificData strucuture, if - * needed. - */ - - if (!tsdPtr->initialized) { - tsdPtr->initialized = 1; - dummy = Tcl_CreateInterp(); - Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS); - - Tk_DefineBitmap(dummy, "error", error_bits, - error_width, error_height); - Tk_DefineBitmap(dummy, "gray75", gray75_bits, - gray75_width, gray75_height); - Tk_DefineBitmap(dummy, "gray50", gray50_bits, - gray50_width, gray50_height); - Tk_DefineBitmap(dummy, "gray25", gray25_bits, - gray25_width, gray25_height); - Tk_DefineBitmap(dummy, "gray12", gray12_bits, - gray12_width, gray12_height); - Tk_DefineBitmap(dummy, "hourglass", hourglass_bits, - hourglass_width, hourglass_height); - Tk_DefineBitmap(dummy, "info", info_bits, - info_width, info_height); - Tk_DefineBitmap(dummy, "questhead", questhead_bits, - questhead_width, questhead_height); - Tk_DefineBitmap(dummy, "question", question_bits, - question_width, question_height); - Tk_DefineBitmap(dummy, "warning", warning_bits, - warning_width, warning_height); - - TkpDefineNativeBitmaps(); - Tcl_DeleteInterp(dummy); - } - - /* - * Was a valid TkDisplay pointer passed? If so, initialize the Bitmap - * module tables in that structure. - */ - - if (dispPtr != NULL) { - dispPtr->bitmapInit = 1; - Tcl_InitHashTable(&dispPtr->bitmapNameTable, TCL_STRING_KEYS); - Tcl_InitHashTable(&dispPtr->bitmapDataTable, - sizeof(DataKey) / sizeof(int)); - - /* - * The call below is tricky: can't use sizeof(IdKey) because it gets - * padded with extra unpredictable bytes on some 64-bit machines. - */ - - /* - * The comment above doesn't make sense... - */ - - Tcl_InitHashTable(&dispPtr->bitmapIdTable, TCL_ONE_WORD_KEYS); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkReadBitmapFile -- - * - * Loads a bitmap image in X bitmap format into the specified drawable. - * This is equivelent to the XReadBitmapFile in X. - * - * Results: - * Sets the size, hotspot, and bitmap on success. - * - * Side effects: - * Creates a new bitmap from the file data. - * - *---------------------------------------------------------------------- - */ - -int -TkReadBitmapFile( - Display *display, - Drawable d, - const char *filename, - unsigned int *width_return, - unsigned int *height_return, - Pixmap *bitmap_return, - int *x_hot_return, - int *y_hot_return) -{ - char *data; - - data = TkGetBitmapData(NULL, NULL, filename, - (int *) width_return, (int *) height_return, x_hot_return, - y_hot_return); - if (data == NULL) { - return BitmapFileInvalid; - } - - *bitmap_return = XCreateBitmapFromData(display, d, data, *width_return, - *height_return); - ckfree(data); - return BitmapSuccess; -} - -/* - *---------------------------------------------------------------------- - * - * TkDebugBitmap -- - * - * This function returns debugging information about a bitmap. - * - * Results: - * The return value is a list with one sublist for each TkBitmap - * corresponding to "name". Each sublist has two elements that contain - * the resourceRefCount and objRefCount fields from the TkBitmap - * structure. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -TkDebugBitmap( - Tk_Window tkwin, /* The window in which the bitmap will be used - * (not currently used). */ - const char *name) /* Name of the desired color. */ -{ - TkBitmap *bitmapPtr; - Tcl_HashEntry *hashPtr; - Tcl_Obj *resultPtr, *objPtr; - TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - - resultPtr = Tcl_NewObj(); - hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, name); - if (hashPtr != NULL) { - bitmapPtr = Tcl_GetHashValue(hashPtr); - if (bitmapPtr == NULL) { - Tcl_Panic("TkDebugBitmap found empty hash table entry"); - } - for ( ; (bitmapPtr != NULL); bitmapPtr = bitmapPtr->nextPtr) { - objPtr = Tcl_NewObj(); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(bitmapPtr->resourceRefCount)); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(bitmapPtr->objRefCount)); - Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); - } - } - return resultPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TkGetBitmapPredefTable -- - * - * This function is used by tkMacBitmap.c to access the thread-specific - * predefBitmap table that maps from the names of the predefined bitmaps - * to data associated with those bitmaps. It is required because the - * table is allocated in thread-local storage and is not visible outside - * this file. - - * Results: - * Returns a pointer to the predefined bitmap hash table for the current - * thread. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_HashTable * -TkGetBitmapPredefTable(void) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - return &tsdPtr->predefBitmapTable; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ |