OSDN Git Service

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