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