|
|
1.1 ! root 1: /* ! 2: * tkPixmap.c -- ! 3: * ! 4: * This file maintains a database of read-only pixmaps for the Tk ! 5: * toolkit. This allows pixmaps to be shared between widgets and ! 6: * also avoids interactions with the X server. ! 7: * ! 8: * Copyright 1992 by Sven Delmas ! 9: * ! 10: * This source is based upon the file tkBitmap.c from: ! 11: * ! 12: * Copyright 1990-1992 Regents of the University of California ! 13: * Permission to use, copy, modify, and distribute this ! 14: * software and its documentation for any purpose and without ! 15: * fee is hereby granted, provided that the above copyright ! 16: * notice appear in all copies. The University of California ! 17: * makes no representations about the suitability of this ! 18: * software for any purpose. It is provided "as is" without ! 19: * express or implied warranty. ! 20: * file: /user6/ouster/wish/RCS/tkBitmap.c,v 1.16 ! 21: * 92/08/24 09:45:43 ouster Exp $ SPRITE (Berkeley); ! 22: */ ! 23: ! 24: #if defined(USE_XPM3) ! 25: ! 26: #ifndef lint ! 27: static char *AtFSid = "$Header: tkPixmap.c[1.1] Mon Sep 28 14:12:35 1992 [email protected] frozen $"; ! 28: #endif /* not lint */ ! 29: ! 30: #include "tkconfig.h" ! 31: #include "tk.h" ! 32: ! 33: /* ! 34: * The includes below are for pre-defined bitmaps. ! 35: */ ! 36: ! 37: #include "bitmaps/gray50" ! 38: #include "bitmaps/gray25" ! 39: ! 40: /* ! 41: * Include the xpm 3 defines for color pixmaps ! 42: */ ! 43: //#include "xpmtk.h" ! 44: #include <xpm.h> ! 45: ! 46: /* ! 47: * One of the following data structures exists for each bitmap that is ! 48: * currently in use. Each structure is indexed with both "idTable" and ! 49: * "nameTable". ! 50: */ ! 51: ! 52: typedef struct { ! 53: Pixmap bitmap; /* X identifier for bitmap. None means this ! 54: * bitmap was created by Tk_DefinePixmap ! 55: * and it isn't currently in use. */ ! 56: unsigned int width, height; /* Dimensions of bitmap. */ ! 57: Display *display; /* Display for which bitmap is valid. */ ! 58: int refCount; /* Number of active uses of bitmap. */ ! 59: Tcl_HashEntry *hashPtr; /* Entry in nameTable for this structure ! 60: * (needed when deleting). */ ! 61: } TkBitmap; ! 62: ! 63: /* ! 64: * Hash table to map from a textual description of a bitmap to the ! 65: * TkBitmap record for the bitmap, and key structure used in that ! 66: * hash table: ! 67: */ ! 68: ! 69: static Tcl_HashTable nameTable; ! 70: typedef struct { ! 71: Tk_Uid name; /* Textual name for desired bitmap. */ ! 72: Screen *screen; /* Screen for which bitmap will be used. */ ! 73: } NameKey; ! 74: ! 75: /* ! 76: * Hash table that maps from bitmap identifiers to the TkBitmap structure ! 77: * for the pixmap. This table is indexed by Bitmap ids, and is used by ! 78: * Tk_FreePixmap. ! 79: */ ! 80: ! 81: static Tcl_HashTable idTable; ! 82: ! 83: /* ! 84: * For each call to Tk_DefinePixmap one of the following structures is ! 85: * created to hold information about the pixmap. ! 86: */ ! 87: ! 88: typedef struct { ! 89: char *source; /* Bits for bitmap. */ ! 90: Pixmap pixmap; /* Pre-defined pixmap */ ! 91: unsigned int width, height; /* Dimensions of bitmap. */ ! 92: } PredefBitmap; ! 93: ! 94: /* ! 95: * Hash table create by Tk_DefinePixmap to map from a name to a ! 96: * collection of in-core data about a bitmap. The table is ! 97: * indexed by the address of the data for the bitmap, and the entries ! 98: * contain pointers to PredefBitmap structures. ! 99: */ ! 100: ! 101: static Tcl_HashTable predefTable; ! 102: ! 103: /* ! 104: * Hash table used by Tk_GetPixmapFromData to map from a collection ! 105: * of in-core data about a bitmap to a Tk_Uid giving an automatically- ! 106: * generated name for the bitmap: ! 107: */ ! 108: ! 109: static Tcl_HashTable dataTable; ! 110: typedef struct { ! 111: char *source; /* Bitmap bits. */ ! 112: unsigned int width, height; /* Dimensions of bitmap. */ ! 113: } DataKey; ! 114: ! 115: static int initialized = 0; /* 0 means static structures haven't been ! 116: * initialized yet. */ ! 117: ! 118: /* ! 119: * Forward declarations for procedures defined in this file: ! 120: */ ! 121: ! 122: static void PixmapInit _ANSI_ARGS_((Tk_Window tkwin)); ! 123: ! 124: /* ! 125: *---------------------------------------------------------------------- ! 126: * ! 127: * Tk_GetPixmap -- ! 128: * ! 129: * Given a string describing a bitmap or pixmap, locate (or create ! 130: * if necessary) a pixmap that fits the description. ! 131: * ! 132: * Results: ! 133: * The return value is the X identifer for the desired pixmap, ! 134: * unless string couldn't be parsed correctly. In this case, ! 135: * None is returned and an error message is left in ! 136: * interp->result. The caller should never modify the pixmap ! 137: * that is returned, and should eventually call Tk_FreePixmap ! 138: * when the pixmap is no longer needed. ! 139: * ! 140: * Side effects: ! 141: * The pixmap is added to an internal database with a reference count. ! 142: * For each call to this procedure, there should eventually be a call ! 143: * to Tk_FreePixmap, so that the database can be cleaned up when pixmaps ! 144: * aren't needed anymore. ! 145: * ! 146: *---------------------------------------------------------------------- ! 147: */ ! 148: Pixmap ! 149: Tk_GetPixmap(interp, tkwin, string) ! 150: Tcl_Interp *interp; /* Interpreter to use for error reporting. */ ! 151: Tk_Window tkwin; /* Window in which pixmap will be used. */ ! 152: Tk_Uid string; /* Description of pixmap. See manual entry ! 153: * for details on legal syntax. */ ! 154: { ! 155: NameKey key; ! 156: Tcl_HashEntry *nameHashPtr, *idHashPtr, *predefHashPtr; ! 157: register TkBitmap *bitmapPtr; ! 158: PredefBitmap *predefPtr; ! 159: int new; ! 160: Pixmap bitmap; ! 161: Pixmap bitmap_shape; ! 162: unsigned int width, height; ! 163: int dummy2; ! 164: XpmAttributes xpm_attributes; ! 165: Display *dpy = Tk_Display(tkwin); ! 166: ! 167: if (!initialized) { ! 168: PixmapInit(tkwin); ! 169: } ! 170: ! 171: key.name = string; ! 172: key.screen = Tk_Screen(tkwin); ! 173: nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &key, &new); ! 174: if (!new) { ! 175: bitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr); ! 176: bitmapPtr->refCount++; ! 177: return bitmapPtr->bitmap; ! 178: } ! 179: ! 180: /* ! 181: * No suitable bitmap exists. Create a new bitmap from the ! 182: * information contained in the string. If the string starts ! 183: * with "@" then the rest of the string is a file name containing ! 184: * the bitmap. Otherwise the string must refer to a bitmap ! 185: * defined by a call to Tk_DefinePixmap. ! 186: */ ! 187: ! 188: if (*string == '@') { ! 189: string = Tcl_TildeSubst(interp, string + 1); ! 190: if (string == NULL) { ! 191: goto error; ! 192: } ! 193: ! 194: if (XReadBitmapFile(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), ! 195: string, &width, &height, &bitmap_shape, &dummy2, &dummy2) ! 196: != BitmapSuccess) ! 197: { ! 198: xpm_attributes.visual = Tk_DefaultVisual(Tk_Screen(tkwin)); ! 199: xpm_attributes.colormap = Tk_DefaultColormap(Tk_Screen(tkwin)); ! 200: xpm_attributes.depth = Tk_DefaultDepth(Tk_Screen(tkwin)); ! 201: xpm_attributes.valuemask = XpmVisual | XpmColormap | XpmDepth; ! 202: ! 203: if (XpmReadFileToPixmap(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), ! 204: string, &bitmap, &bitmap_shape, ! 205: &xpm_attributes) != BitmapSuccess) { ! 206: Tcl_AppendResult(interp, "error reading bitmap file \"", ! 207: string, "\"", (char *) NULL); ! 208: goto error; ! 209: } { ! 210: width = xpm_attributes.width; ! 211: height = xpm_attributes.height; ! 212: XpmFreeAttributes(&xpm_attributes); ! 213: } ! 214: } else { ! 215: bitmap = XCreatePixmap(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), ! 216: width, height, ! 217: Tk_DefaultDepth(Tk_Screen(tkwin))); ! 218: XCopyPlane(dpy, bitmap_shape, bitmap, ! 219: Tk_DefaultGC(Tk_Screen(tkwin)), ! 220: 0, 0, width, height, 0, 0, 1); ! 221: } ! 222: } else { ! 223: /* first try for a display-specific version */ ! 224: predefHashPtr = Tcl_FindHashEntry(&predefTable, (char *) &key); ! 225: if (predefHashPtr == NULL) { ! 226: /* try for a non-display specific version */ ! 227: key.screen = (Screen*) NULL; ! 228: predefHashPtr = Tcl_FindHashEntry(&predefTable, (char *) &key); ! 229: if (predefHashPtr == NULL) { ! 230: /* give up */ ! 231: Tcl_AppendResult(interp, "pixmap \"", string, ! 232: "\" not defined", (char *) NULL); ! 233: goto error; ! 234: } ! 235: } ! 236: predefPtr = (PredefBitmap *) Tcl_GetHashValue(predefHashPtr); ! 237: width = predefPtr->width; ! 238: height = predefPtr->height; ! 239: if (predefPtr->source != NULL) { ! 240: bitmap_shape = ! 241: XCreateBitmapFromData(dpy, Tk_DefaultRootWindow(dpy), ! 242: predefPtr->source, width, height); ! 243: bitmap = XCreatePixmap(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), ! 244: width, height, ! 245: Tk_DefaultDepth(Tk_Screen(tkwin))); ! 246: XCopyPlane(dpy, bitmap_shape, bitmap, ! 247: Tk_DefaultGC(Tk_Screen(tkwin)), ! 248: 0, 0, width, height, 0, 0, 1); ! 249: } else { ! 250: if (predefPtr->pixmap != None) { ! 251: bitmap = predefPtr->pixmap; ! 252: } else { ! 253: bitmap = ! 254: XCreatePixmap(dpy, RootWindowOfScreen(Tk_Screen(tkwin)), ! 255: width, height, ! 256: Tk_DefaultDepth(Tk_Screen(tkwin))); ! 257: } ! 258: } ! 259: } ! 260: ! 261: /* ! 262: * Add information about this bitmap to our database. ! 263: */ ! 264: ! 265: bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap)); ! 266: bitmapPtr->bitmap = bitmap; ! 267: bitmapPtr->width = width; ! 268: bitmapPtr->height = height; ! 269: bitmapPtr->display = dpy; ! 270: bitmapPtr->refCount = 1; ! 271: bitmapPtr->hashPtr = nameHashPtr; ! 272: idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) bitmapPtr->bitmap, ! 273: &new); ! 274: if (!new) { ! 275: /* deh patched to support multiple displays */ ! 276: /* panic("pixmap already registered in Tk_GetPixmap"); */ ! 277: bitmapPtr->refCount = 1000; ! 278: } ! 279: Tcl_SetHashValue(nameHashPtr, bitmapPtr); ! 280: Tcl_SetHashValue(idHashPtr, bitmapPtr); ! 281: return bitmapPtr->bitmap; ! 282: ! 283: error: ! 284: Tcl_DeleteHashEntry(nameHashPtr); ! 285: return None; ! 286: } ! 287: ! 288: /* ! 289: *---------------------------------------------------------------------- ! 290: * ! 291: * Tk_DefinePixmap -- ! 292: * ! 293: * This procedure associates a textual name with a binary pixmap ! 294: * description, so that the name may be used to refer to the ! 295: * pixmap in future calls to Tk_GetPixmap. The pixmap can ! 296: * be pre-created by the user, or can be created later ! 297: * by Tk_GetPixmap(). Since pixmaps are display-specific, ! 298: * a user supplied pixmap will be associated with tkwin's display. ! 299: * If pixmap is given as None, then a new pixmap will be created ! 300: * by Tk_GetPixmap for each unique display. ! 301: * ! 302: * Results: ! 303: * A standard Tcl result. If an error occurs then TCL_ERROR is ! 304: * returned and a message is left in interp->result. ! 305: * ! 306: * Side effects: ! 307: * "Name" is entered into the pixmap table and may be used from ! 308: * here on to refer to the given pixmap. ! 309: * ! 310: *---------------------------------------------------------------------- ! 311: */ ! 312: ! 313: int ! 314: Tk_DefinePixmap(interp, name, tkwin, pixmap, source, width, height) ! 315: Tcl_Interp *interp; /* Interpreter to use for error reporting. */ ! 316: Tk_Uid name; /* Name to use for bitmap. Must not already ! 317: * be defined as a bitmap. */ ! 318: Tk_Window tkwin; /* any window on screen where pixmap lives */ ! 319: Pixmap pixmap; /* pixmap to associate with name, ! 320: * or None to create a new pixmap */ ! 321: char *source; /* Address of bits for bitmap. */ ! 322: unsigned int width; /* Width of bitmap. */ ! 323: unsigned int height; /* Height of bitmap. */ ! 324: { ! 325: int new; ! 326: Tcl_HashEntry *predefHashPtr; ! 327: PredefBitmap *predefPtr; ! 328: NameKey key; ! 329: ! 330: if (!initialized) { ! 331: PixmapInit(tkwin); ! 332: } ! 333: ! 334: key.name = name; ! 335: key.screen = (pixmap != None) ? Tk_Screen(tkwin) : (Screen *)NULL; ! 336: predefHashPtr = Tcl_CreateHashEntry(&predefTable, (char *) &key, &new); ! 337: if (!new) { ! 338: Tcl_AppendResult(interp, "bitmap \"", name, ! 339: "\" is already defined", (char *) NULL); ! 340: return TCL_ERROR; ! 341: } ! 342: predefPtr = (PredefBitmap *) malloc(sizeof(PredefBitmap)); ! 343: predefPtr->source = source; ! 344: predefPtr->pixmap = pixmap; ! 345: predefPtr->width = width; ! 346: predefPtr->height = height; ! 347: Tcl_SetHashValue(predefHashPtr, predefPtr); ! 348: return TCL_OK; ! 349: } ! 350: ! 351: /* ! 352: *-------------------------------------------------------------- ! 353: * ! 354: * Tk_NameOfPixmap -- ! 355: * ! 356: * Given a pixmap, return a textual string identifying the ! 357: * pixmap. ! 358: * ! 359: * Results: ! 360: * The return value is the string name associated with pixmap. ! 361: * ! 362: * Side effects: ! 363: * None. ! 364: * ! 365: *-------------------------------------------------------------- ! 366: */ ! 367: ! 368: Tk_Uid ! 369: Tk_NameOfPixmap(bitmap) ! 370: Pixmap bitmap; /* Bitmap whose name is wanted. */ ! 371: { ! 372: Tcl_HashEntry *idHashPtr; ! 373: TkBitmap *bitmapPtr; ! 374: ! 375: if (!initialized) { ! 376: unknown: ! 377: panic("Tk_NameOfPixmap received unknown pixmap argument"); ! 378: } ! 379: ! 380: idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap); ! 381: if (idHashPtr == NULL) { ! 382: goto unknown; ! 383: } ! 384: bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); ! 385: if (bitmapPtr->hashPtr == NULL) { ! 386: /* the bitmap has been un-defined */ ! 387: return Tk_GetUid("UndefinedBitmap"); ! 388: } ! 389: return ((NameKey *) bitmapPtr->hashPtr->key.words)->name; ! 390: } ! 391: ! 392: /* ! 393: *-------------------------------------------------------------- ! 394: * ! 395: * Tk_SizeOfPixmap -- ! 396: * ! 397: * Given a pixmap managed by this module, returns the width ! 398: * and height of the pixmap.. ! 399: * ! 400: * Results: ! 401: * The words at *widthPtr and *heightPtr are filled in with ! 402: * the dimenstions of pixmap. ! 403: * ! 404: * Side effects: ! 405: * If pixmap isn't managed by this module then the procedure ! 406: * panics.. ! 407: * ! 408: *-------------------------------------------------------------- ! 409: */ ! 410: ! 411: void ! 412: Tk_SizeOfPixmap(bitmap, widthPtr, heightPtr) ! 413: Pixmap bitmap; /* Bitmap whose size is wanted. */ ! 414: unsigned int *widthPtr; /* Store bitmap width here. */ ! 415: unsigned int *heightPtr; /* Store bitmap height here. */ ! 416: { ! 417: Tcl_HashEntry *idHashPtr; ! 418: TkBitmap *bitmapPtr; ! 419: ! 420: if (!initialized) { ! 421: unknownBitmap: ! 422: panic("Tk_SizeOfPixmap received unknown pixmap argument"); ! 423: } ! 424: ! 425: idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap); ! 426: if (idHashPtr == NULL) { ! 427: goto unknownBitmap; ! 428: } ! 429: bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); ! 430: *widthPtr = bitmapPtr->width; ! 431: *heightPtr = bitmapPtr->height; ! 432: } ! 433: ! 434: /* ! 435: *---------------------------------------------------------------------- ! 436: * ! 437: * Tk_FreePixmap -- ! 438: * ! 439: * This procedure is called to release a pixmap allocated by ! 440: * Tk_GetPixmap. ! 441: * ! 442: * Results: ! 443: * None. ! 444: * ! 445: * Side effects: ! 446: * The reference count associated with bitmap is decremented, and ! 447: * it is officially deallocated if no-one is using it anymore. ! 448: * ! 449: *---------------------------------------------------------------------- ! 450: */ ! 451: ! 452: void ! 453: Tk_FreePixmap(bitmap) ! 454: Pixmap bitmap; /* Bitmap to be released. */ ! 455: { ! 456: Tcl_HashEntry *idHashPtr; ! 457: register TkBitmap *bitmapPtr; ! 458: ! 459: if (!initialized) { ! 460: panic("Tk_FreePixmap called before Tk_GetPixmap"); ! 461: } ! 462: ! 463: idHashPtr = Tcl_FindHashEntry(&idTable, (char *) bitmap); ! 464: if (idHashPtr == NULL) { ! 465: panic("Tk_FreePixmap received unknown pixmap argument"); ! 466: } ! 467: bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); ! 468: bitmapPtr->refCount--; ! 469: if (bitmapPtr->refCount == 0) { ! 470: XFreePixmap(bitmapPtr->display, bitmapPtr->bitmap); ! 471: Tcl_DeleteHashEntry(idHashPtr); ! 472: if (bitmapPtr->hashPtr != NULL) { ! 473: /* If hashPtr is NULL, the bitmap has been undefined, ! 474: * and already removed from the name table */ ! 475: Tcl_DeleteHashEntry(bitmapPtr->hashPtr); ! 476: } ! 477: ckfree((char *) bitmapPtr); ! 478: } ! 479: } ! 480: ! 481: /* ! 482: *---------------------------------------------------------------------- ! 483: * ! 484: * Tk_GetPixmapFromData -- ! 485: * ! 486: * Given a description of the bits for a pixmap, make a pixmap that ! 487: * has the given properties. ! 488: * ! 489: * Results: ! 490: * The return value is the X identifer for the desired pixmap, ! 491: * unless it couldn't be created properly. In this case, None is ! 492: * returned and an error message is left in interp->result. The ! 493: * caller should never modify the bitmap that is returned, and ! 494: * should eventually call Tk_FreePixmap when the pixmap is no ! 495: * longer needed. ! 496: * ! 497: * Side effects: ! 498: * The pixmap is added to an internal database with a reference count. ! 499: * For each call to this procedure, there should eventually be a call ! 500: * to Tk_FreePixmap, so that the database can be cleaned up when pixmaps ! 501: * aren't needed anymore. ! 502: * ! 503: *---------------------------------------------------------------------- ! 504: */ ! 505: ! 506: /* ARGSUSED */ ! 507: Pixmap ! 508: Tk_GetPixmapFromData(interp, tkwin, source, width, height) ! 509: Tcl_Interp *interp; /* Interpreter to use for error reporting. */ ! 510: Tk_Window tkwin; /* Window in which bitmap will be used. */ ! 511: char *source; /* Bitmap data for bitmap shape. */ ! 512: unsigned int width, height; /* Dimensions of bitmap. */ ! 513: { ! 514: DataKey key; ! 515: Tcl_HashEntry *dataHashPtr; ! 516: Tk_Uid name = NULL; /* Initialization need only to prevent ! 517: * compiler warning. */ ! 518: int new; ! 519: static autoNumber = 0; ! 520: char string[20]; ! 521: ! 522: if (!initialized) { ! 523: PixmapInit(tkwin); ! 524: } ! 525: ! 526: key.source = source; ! 527: key.width = width; ! 528: key.height = height; ! 529: dataHashPtr = Tcl_CreateHashEntry(&dataTable, (char *) &key, &new); ! 530: if (!new) { ! 531: name = (Tk_Uid) Tcl_GetHashValue(dataHashPtr); ! 532: } else { ! 533: autoNumber++; ! 534: sprintf(string, "_tk%d", autoNumber); ! 535: name = Tk_GetUid(string); ! 536: Tcl_SetHashValue(dataHashPtr, name); ! 537: if (Tk_DefinePixmap(interp, name, tkwin, None, source, width, ! 538: height) != TCL_OK) { ! 539: Tcl_DeleteHashEntry(dataHashPtr); ! 540: return TCL_ERROR; ! 541: } ! 542: } ! 543: return Tk_GetPixmap(interp, tkwin, name); ! 544: } ! 545: ! 546: /* ! 547: *---------------------------------------------------------------------- ! 548: * ! 549: * PixmapInit -- ! 550: * ! 551: * Initialize the structures used for pixmap management. ! 552: * ! 553: * Results: ! 554: * None. ! 555: * ! 556: * Side effects: ! 557: * Read the code. ! 558: * ! 559: *---------------------------------------------------------------------- ! 560: */ ! 561: ! 562: static void ! 563: PixmapInit(tkwin) ! 564: Tk_Window tkwin; /* any window on screen where pixmap lives */ ! 565: { ! 566: Tcl_Interp *dummy; ! 567: ! 568: dummy = Tcl_CreateInterp(); ! 569: initialized = 1; ! 570: Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int)); ! 571: Tcl_InitHashTable(&dataTable, sizeof(DataKey)/sizeof(int)); ! 572: Tcl_InitHashTable(&predefTable, sizeof(NameKey)/sizeof(int)); ! 573: Tcl_InitHashTable(&idTable, TCL_ONE_WORD_KEYS); ! 574: ! 575: Tk_DefinePixmap(dummy, Tk_GetUid("gray50"), tkwin, None, ! 576: (char *)gray50_bits, gray50_width, gray50_height); ! 577: Tk_DefinePixmap(dummy, Tk_GetUid("gray25"), tkwin, None, ! 578: (char *)gray25_bits, gray25_width, gray25_height); ! 579: Tcl_DeleteInterp(dummy); ! 580: } ! 581: ! 582: /* ! 583: *---------------------------------------------------------------------- ! 584: * ! 585: * Tk_UndefinePixmap -- ! 586: * ! 587: * This procedure removes any association "name" with ! 588: * a bitmap or pixmap. This can be used to undefine ! 589: * names defined by either Tk_DefinePixmap or Tk_DefinePixmap. ! 590: * If tkwin is NULL, only display-independent pixmaps will ! 591: * be removed, otherwise both display-independent and ! 592: * the pixmap associated with tkwin will be undefined. ! 593: * ! 594: * Results: ! 595: * A standard Tcl result. If an error occurs then TCL_ERROR is ! 596: * returned and a message is left in interp->result. ! 597: * ! 598: * Side effects: ! 599: * "Name" is removed from the predef table. ! 600: * ! 601: *---------------------------------------------------------------------- ! 602: */ ! 603: ! 604: int ! 605: Tk_UndefinePixmap(interp, name, tkwin) ! 606: Tcl_Interp *interp; /* Interpreter to use for error reporting. */ ! 607: Tk_Uid name; /* Name of bitmap/pixmap to undefine */ ! 608: Tk_Window tkwin; /* any window on screen where pixmap lives */ ! 609: { ! 610: NameKey key; ! 611: Tcl_HashEntry *predefHashPtr, *nameHashPtr; ! 612: TkBitmap *bitmapPtr; ! 613: int cnt = 0; ! 614: ! 615: if (!initialized) { ! 616: PixmapInit(tkwin); ! 617: } ! 618: ! 619: key.name = name; ! 620: key.screen = (Screen *) NULL; ! 621: predefHashPtr = Tcl_FindHashEntry(&predefTable, (char*)&key); ! 622: if (predefHashPtr != NULL) { ! 623: ++cnt; ! 624: Tcl_DeleteHashEntry(predefHashPtr); ! 625: } ! 626: ! 627: key.screen = Tk_Screen(tkwin); ! 628: predefHashPtr = Tcl_FindHashEntry(&predefTable, (char*)&key); ! 629: if (predefHashPtr != NULL) { ! 630: ++cnt; ! 631: Tcl_DeleteHashEntry(predefHashPtr); ! 632: } ! 633: if (cnt == 0) { ! 634: Tcl_AppendResult(interp, "pixmap \"", name, ! 635: "\" doesn't exist", (char *) NULL); ! 636: return TCL_ERROR; ! 637: } ! 638: ! 639: /* ! 640: * Remove it from the name table if it is there (it might not ! 641: * have been created yet, it which case we wont find it). We ! 642: * delete it from the name table and mark the hashPtr as NULL ! 643: * so that we know it has been deleted. The pixmap still exists, ! 644: * and well later be freed and removed from idTable by Tk_FreeBitmap(). ! 645: */ ! 646: nameHashPtr = Tcl_FindHashEntry(&nameTable, (char *) &key); ! 647: if (nameHashPtr != NULL) { ! 648: bitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr); ! 649: /* assert(nameHashPtr == bitmapPtr->hashPtr); */ ! 650: /* assert(bitmapPtr->refCount > 0); */ ! 651: bitmapPtr->hashPtr = (Tcl_HashEntry*) NULL; ! 652: Tcl_DeleteHashEntry(nameHashPtr); ! 653: } ! 654: return TCL_OK; ! 655: } ! 656: ! 657: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.