1/* 2 * tkAtom.c -- 3 * 4 * This file manages a cache of X Atoms in order to avoid interactions 5 * with the X server. It's much like the Xmu routines, except it has a 6 * cleaner interface (caller doesn't have to provide permanent storage 7 * for atom names, for example). 8 * 9 * Copyright (c) 1990-1994 The Regents of the University of California. 10 * Copyright (c) 1994 Sun Microsystems, Inc. 11 * 12 * See the file "license.terms" for information on usage and redistribution of 13 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 14 * 15 * RCS: @(#) $Id$ 16 */ 17 18#include "tkInt.h" 19 20/* 21 * The following are a list of the predefined atom strings. They should match 22 * those found in xatom.h 23 */ 24 25static char * atomNameArray[] = { 26 "PRIMARY", "SECONDARY", "ARC", 27 "ATOM", "BITMAP", "CARDINAL", 28 "COLORMAP", "CURSOR", "CUT_BUFFER0", 29 "CUT_BUFFER1", "CUT_BUFFER2", "CUT_BUFFER3", 30 "CUT_BUFFER4", "CUT_BUFFER5", "CUT_BUFFER6", 31 "CUT_BUFFER7", "DRAWABLE", "FONT", 32 "INTEGER", "PIXMAP", "POINT", 33 "RECTANGLE", "RESOURCE_MANAGER", "RGB_COLOR_MAP", 34 "RGB_BEST_MAP", "RGB_BLUE_MAP", "RGB_DEFAULT_MAP", 35 "RGB_GRAY_MAP", "RGB_GREEN_MAP", "RGB_RED_MAP", 36 "STRING", "VISUALID", "WINDOW", 37 "WM_COMMAND", "WM_HINTS", "WM_CLIENT_MACHINE", 38 "WM_ICON_NAME", "WM_ICON_SIZE", "WM_NAME", 39 "WM_NORMAL_HINTS", "WM_SIZE_HINTS", "WM_ZOOM_HINTS", 40 "MIN_SPACE", "NORM_SPACE", "MAX_SPACE", 41 "END_SPACE", "SUPERSCRIPT_X", "SUPERSCRIPT_Y", 42 "SUBSCRIPT_X", "SUBSCRIPT_Y", "UNDERLINE_POSITION", 43 "UNDERLINE_THICKNESS", "STRIKEOUT_ASCENT", "STRIKEOUT_DESCENT", 44 "ITALIC_ANGLE", "X_HEIGHT", "QUAD_WIDTH", 45 "WEIGHT", "POINT_SIZE", "RESOLUTION", 46 "COPYRIGHT", "NOTICE", "FONT_NAME", 47 "FAMILY_NAME", "FULL_NAME", "CAP_HEIGHT", 48 "WM_CLASS", "WM_TRANSIENT_FOR", 49 NULL 50}; 51 52/* 53 * Forward references to functions defined in this file: 54 */ 55 56static void AtomInit(TkDisplay *dispPtr); 57 58/* 59 *-------------------------------------------------------------- 60 * 61 * Tk_InternAtom -- 62 * 63 * Given a string, produce the equivalent X atom. This function is 64 * equivalent to XInternAtom, except that it keeps a local cache of 65 * atoms. Once a name is known, the server need not be contacted again 66 * for that name. 67 * 68 * Results: 69 * The return value is the Atom corresponding to name. 70 * 71 * Side effects: 72 * A new entry may be added to the local atom cache. 73 * 74 *-------------------------------------------------------------- 75 */ 76 77Atom 78Tk_InternAtom( 79 Tk_Window tkwin, /* Window token; map name to atom for this 80 * window's display. */ 81 CONST char *name) /* Name to turn into atom. */ 82{ 83 register TkDisplay *dispPtr; 84 register Tcl_HashEntry *hPtr; 85 int isNew; 86 87 dispPtr = ((TkWindow *) tkwin)->dispPtr; 88 if (!dispPtr->atomInit) { 89 AtomInit(dispPtr); 90 } 91 92 hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew); 93 if (isNew) { 94 Tcl_HashEntry *hPtr2; 95 Atom atom; 96 97 atom = XInternAtom(dispPtr->display, name, False); 98 Tcl_SetHashValue(hPtr, atom); 99 hPtr2 = Tcl_CreateHashEntry(&dispPtr->atomTable, (char*) atom, &isNew); 100 Tcl_SetHashValue(hPtr2, Tcl_GetHashKey(&dispPtr->nameTable, hPtr)); 101 } 102 return (Atom) Tcl_GetHashValue(hPtr); 103} 104 105/* 106 *-------------------------------------------------------------- 107 * 108 * Tk_GetAtomName -- 109 * 110 * This function is equivalent to XGetAtomName except that it uses the 111 * local atom cache to avoid contacting the server. 112 * 113 * Results: 114 * The return value is a character string corresponding to the atom given 115 * by "atom". This string's storage space is static: it need not be freed 116 * by the caller, and should not be modified by the caller. If "atom" 117 * doesn't exist on tkwin's display, then the string "?bad atom?" is 118 * returned. 119 * 120 * Side effects: 121 * None. 122 * 123 *-------------------------------------------------------------- 124 */ 125 126CONST char * 127Tk_GetAtomName( 128 Tk_Window tkwin, /* Window token; map atom to name relative to 129 * this window's display. */ 130 Atom atom) /* Atom whose name is wanted. */ 131{ 132 register TkDisplay *dispPtr; 133 register Tcl_HashEntry *hPtr; 134 135 dispPtr = ((TkWindow *) tkwin)->dispPtr; 136 if (!dispPtr->atomInit) { 137 AtomInit(dispPtr); 138 } 139 140 hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, (char *) atom); 141 if (hPtr == NULL) { 142 char *name; 143 Tk_ErrorHandler handler; 144 int isNew, mustFree; 145 146 handler = Tk_CreateErrorHandler(dispPtr->display, BadAtom, -1, -1, 147 NULL, (ClientData) NULL); 148 name = XGetAtomName(dispPtr->display, atom); 149 mustFree = 1; 150 if (name == NULL) { 151 name = "?bad atom?"; 152 mustFree = 0; 153 } 154 Tk_DeleteErrorHandler(handler); 155 hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew); 156 Tcl_SetHashValue(hPtr, atom); 157 if (mustFree) { 158 XFree(name); 159 } 160 name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr); 161 hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom, &isNew); 162 Tcl_SetHashValue(hPtr, name); 163 } 164 return Tcl_GetHashValue(hPtr); 165} 166 167/* 168 *-------------------------------------------------------------- 169 * 170 * AtomInit -- 171 * 172 * Initialize atom-related information for a display. 173 * 174 * Results: 175 * None. 176 * 177 * Side effects: 178 * Tables get initialized, etc. etc.. 179 * 180 *-------------------------------------------------------------- 181 */ 182 183static void 184AtomInit( 185 register TkDisplay *dispPtr)/* Display to initialize. */ 186{ 187 Tcl_HashEntry *hPtr; 188 Atom atom; 189 190 dispPtr->atomInit = 1; 191 Tcl_InitHashTable(&dispPtr->nameTable, TCL_STRING_KEYS); 192 Tcl_InitHashTable(&dispPtr->atomTable, TCL_ONE_WORD_KEYS); 193 194 for (atom = 1; atom <= XA_LAST_PREDEFINED; atom++) { 195 char *name; 196 int isNew; 197 198 hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, (char *) atom); 199 if (hPtr != NULL) { 200 continue; 201 } 202 203 name = atomNameArray[atom - 1]; 204 hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew); 205 Tcl_SetHashValue(hPtr, atom); 206 name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr); 207 hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom, &isNew); 208 Tcl_SetHashValue(hPtr, name); 209 } 210} 211 212/* 213 * Local Variables: 214 * mode: c 215 * c-basic-offset: 4 216 * fill-column: 78 217 * End: 218 */ 219