1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/*
* tkAtom.c --
*
* This file manages a cache of X Atoms in order to avoid
* interactions with the X server. It's much like the Xmu
* routines, except it has a cleaner interface (caller
* doesn't have to provide permanent storage for atom names,
* for example).
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
static char sccsid[] = "@(#) tkAtom.c 1.11 95/02/23 11:03:53";
#include "tkPort.h"
#include "tkInt.h"
/*
* Forward references to procedures defined in this file:
*/
static void AtomInit _ANSI_ARGS_((TkDisplay *dispPtr));
/*
*--------------------------------------------------------------
*
* Tk_InternAtom --
*
* Given a string, produce the equivalent X atom. This
* procedure is equivalent to XInternAtom, except that it
* keeps a local cache of atoms. Once a name is known,
* the server need not be contacted again for that name.
*
* Results:
* The return value is the Atom corresponding to name.
*
* Side effects:
* A new entry may be added to the local atom cache.
*
*--------------------------------------------------------------
*/
Atom
Tk_InternAtom(tkwin, name)
Tk_Window tkwin; /* Window token; map name to atom
* for this window's display. */
char *name; /* Name to turn into atom. */
{
register TkDisplay *dispPtr;
register Tcl_HashEntry *hPtr;
int new;
dispPtr = ((TkWindow *) tkwin)->dispPtr;
if (!dispPtr->atomInit) {
AtomInit(dispPtr);
}
hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &new);
if (new) {
Tcl_HashEntry *hPtr2;
Atom atom;
atom = XInternAtom(dispPtr->display, name, False);
Tcl_SetHashValue(hPtr, atom);
hPtr2 = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom,
&new);
Tcl_SetHashValue(hPtr2, Tcl_GetHashKey(&dispPtr->nameTable, hPtr));
}
return (Atom) Tcl_GetHashValue(hPtr);
}
/*
*--------------------------------------------------------------
*
* Tk_GetAtomName --
*
* This procedure is equivalent to XGetAtomName except that
* it uses the local atom cache to avoid contacting the
* server.
*
* Results:
* The return value is a character string corresponding to
* the atom given by "atom". This string's storage space
* is static: it need not be freed by the caller, and should
* not be modified by the caller. If "atom" doesn't exist
* on tkwin's display, then the string "?bad atom?" is returned.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
char *
Tk_GetAtomName(tkwin, atom)
Tk_Window tkwin; /* Window token; map atom to name
* relative to this window's
* display. */
Atom atom; /* Atom whose name is wanted. */
{
register TkDisplay *dispPtr;
register Tcl_HashEntry *hPtr;
dispPtr = ((TkWindow *) tkwin)->dispPtr;
if (!dispPtr->atomInit) {
AtomInit(dispPtr);
}
hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, (char *) atom);
if (hPtr == NULL) {
char *name;
Tk_ErrorHandler handler;
int new, mustFree;
handler= Tk_CreateErrorHandler(dispPtr->display, BadAtom,
-1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL);
name = XGetAtomName(dispPtr->display, atom);
mustFree = 1;
if (name == NULL) {
name = "?bad atom?";
mustFree = 0;
}
Tk_DeleteErrorHandler(handler);
hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, (char *) name,
&new);
Tcl_SetHashValue(hPtr, atom);
if (mustFree) {
XFree(name);
}
name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom,
&new);
Tcl_SetHashValue(hPtr, name);
}
return (char *) Tcl_GetHashValue(hPtr);
}
/*
*--------------------------------------------------------------
*
* AtomInit --
*
* Initialize atom-related information for a display.
*
* Results:
* None.
*
* Side effects:
* Tables get initialized, etc. etc..
*
*--------------------------------------------------------------
*/
static void
AtomInit(dispPtr)
register TkDisplay *dispPtr; /* Display to initialize. */
{
dispPtr->atomInit = 1;
Tcl_InitHashTable(&dispPtr->nameTable, TCL_STRING_KEYS);
Tcl_InitHashTable(&dispPtr->atomTable, TCL_ONE_WORD_KEYS);
}
|