GetAtomNm.c revision eb411b4b
1/*
2
3Copyright 1986, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include "Xlibint.h"
31#include "Xintatom.h"
32
33static
34char *_XGetAtomName(
35    Display *dpy,
36    Atom atom)
37{
38    xResourceReq *req;
39    char *name;
40    register Entry *table;
41    register int idx;
42    register Entry e;
43
44    if (dpy->atoms) {
45	table = dpy->atoms->table;
46	for (idx = TABLESIZE; --idx >= 0; ) {
47	    if ((e = *table++) && (e->atom == atom)) {
48		idx = strlen(EntryName(e)) + 1;
49		if ((name = Xmalloc(idx)))
50		    strcpy(name, EntryName(e));
51		return name;
52	    }
53	}
54    }
55    GetResReq(GetAtomName, atom, req);
56    return (char *)NULL;
57}
58
59char *XGetAtomName(
60    register Display *dpy,
61    Atom atom)
62{
63    xGetAtomNameReply rep;
64    char *name;
65
66    LockDisplay(dpy);
67    if ((name = _XGetAtomName(dpy, atom))) {
68	UnlockDisplay(dpy);
69	return name;
70    }
71    if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
72	UnlockDisplay(dpy);
73	SyncHandle();
74	return(NULL);
75    }
76    if ((name = Xmalloc(rep.nameLength + 1))) {
77	_XReadPad(dpy, name, (long)rep.nameLength);
78	name[rep.nameLength] = '\0';
79	_XUpdateAtomCache(dpy, name, atom, 0, -1, 0);
80    } else {
81	_XEatDataWords(dpy, rep.length);
82	name = (char *) NULL;
83    }
84    UnlockDisplay(dpy);
85    SyncHandle();
86    return(name);
87}
88
89typedef struct {
90    unsigned long start_seq;
91    unsigned long stop_seq;
92    Atom *atoms;
93    char **names;
94    int idx;
95    int count;
96    Status status;
97} _XGetAtomNameState;
98
99static
100Bool _XGetAtomNameHandler(
101    register Display *dpy,
102    register xReply *rep,
103    char *buf,
104    int len,
105    XPointer data)
106{
107    register _XGetAtomNameState *state;
108    xGetAtomNameReply replbuf;
109    register xGetAtomNameReply *repl;
110
111    state = (_XGetAtomNameState *)data;
112    if (dpy->last_request_read < state->start_seq ||
113	dpy->last_request_read > state->stop_seq)
114	return False;
115    while (state->idx < state->count && state->names[state->idx])
116	state->idx++;
117    if (state->idx >= state->count)
118	return False;
119    if (rep->generic.type == X_Error) {
120	state->status = 0;
121	return False;
122    }
123    repl = (xGetAtomNameReply *)
124	_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
125			(SIZEOF(xGetAtomNameReply) - SIZEOF(xReply)) >> 2,
126			False);
127    state->names[state->idx] = Xmalloc(repl->nameLength + 1);
128    _XGetAsyncData(dpy, state->names[state->idx], buf, len,
129		   SIZEOF(xGetAtomNameReply), repl->nameLength,
130		   repl->length << 2);
131    if (state->names[state->idx]) {
132	state->names[state->idx][repl->nameLength] = '\0';
133	_XUpdateAtomCache(dpy, state->names[state->idx],
134			  state->atoms[state->idx], 0, -1, 0);
135    } else {
136	state->status = 0;
137    }
138    return True;
139}
140
141Status
142XGetAtomNames (
143    Display *dpy,
144    Atom *atoms,
145    int count,
146    char **names_return)
147{
148    _XAsyncHandler async;
149    _XGetAtomNameState async_state;
150    xGetAtomNameReply rep;
151    int i;
152    int missed = -1;
153
154    LockDisplay(dpy);
155    async_state.start_seq = dpy->request + 1;
156    async_state.atoms = atoms;
157    async_state.names = names_return;
158    async_state.idx = 0;
159    async_state.count = count - 1;
160    async_state.status = 1;
161    async.next = dpy->async_handlers;
162    async.handler = _XGetAtomNameHandler;
163    async.data = (XPointer)&async_state;
164    dpy->async_handlers = &async;
165    for (i = 0; i < count; i++) {
166	if (!(names_return[i] = _XGetAtomName(dpy, atoms[i]))) {
167	    missed = i;
168	    async_state.stop_seq = dpy->request;
169	}
170    }
171    if (missed >= 0) {
172	if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
173	    if ((names_return[missed] = Xmalloc(rep.nameLength + 1))) {
174		_XReadPad(dpy, names_return[missed], (long)rep.nameLength);
175		names_return[missed][rep.nameLength] = '\0';
176		_XUpdateAtomCache(dpy, names_return[missed], atoms[missed],
177				  0, -1, 0);
178	    } else {
179		_XEatDataWords(dpy, rep.length);
180		async_state.status = 0;
181	    }
182	}
183    }
184    DeqAsyncHandler(dpy, &async);
185    UnlockDisplay(dpy);
186    if (missed >= 0)
187	SyncHandle();
188    return async_state.status;
189}
190