GetAtomNm.c revision b4ee4795
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#define NEED_REPLIES
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "Xlibint.h"
32#include "Xintatom.h"
33
34static
35char *_XGetAtomName(
36    Display *dpy,
37    Atom atom)
38{
39    xResourceReq *req;
40    char *name;
41    register Entry *table;
42    register int idx;
43    register Entry e;
44
45    if (dpy->atoms) {
46	table = dpy->atoms->table;
47	for (idx = TABLESIZE; --idx >= 0; ) {
48	    if ((e = *table++) && (e->atom == atom)) {
49		idx = strlen(EntryName(e)) + 1;
50		if ((name = (char *)Xmalloc(idx)))
51		    strcpy(name, EntryName(e));
52		return name;
53	    }
54	}
55    }
56    GetResReq(GetAtomName, atom, req);
57    return (char *)NULL;
58}
59
60char *XGetAtomName(
61    register Display *dpy,
62    Atom atom)
63{
64    xGetAtomNameReply rep;
65    char *name;
66
67    LockDisplay(dpy);
68    if ((name = _XGetAtomName(dpy, atom))) {
69	UnlockDisplay(dpy);
70	return name;
71    }
72    if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
73	UnlockDisplay(dpy);
74	SyncHandle();
75	return(NULL);
76    }
77    if ((name = (char *) Xmalloc(rep.nameLength+1))) {
78	_XReadPad(dpy, name, (long)rep.nameLength);
79	name[rep.nameLength] = '\0';
80	_XUpdateAtomCache(dpy, name, atom, 0, -1, 0);
81    } else {
82	_XEatData(dpy, (unsigned long) (rep.nameLength + 3) & ~3);
83	name = (char *) NULL;
84    }
85    UnlockDisplay(dpy);
86    SyncHandle();
87    return(name);
88}
89
90typedef struct {
91    unsigned long start_seq;
92    unsigned long stop_seq;
93    Atom *atoms;
94    char **names;
95    int idx;
96    int count;
97    Status status;
98} _XGetAtomNameState;
99
100static
101Bool _XGetAtomNameHandler(
102    register Display *dpy,
103    register xReply *rep,
104    char *buf,
105    int len,
106    XPointer data)
107{
108    register _XGetAtomNameState *state;
109    xGetAtomNameReply replbuf;
110    register xGetAtomNameReply *repl;
111
112    state = (_XGetAtomNameState *)data;
113    if (dpy->last_request_read < state->start_seq ||
114	dpy->last_request_read > state->stop_seq)
115	return False;
116    while (state->idx < state->count && state->names[state->idx])
117	state->idx++;
118    if (state->idx >= state->count)
119	return False;
120    if (rep->generic.type == X_Error) {
121	state->status = 0;
122	return False;
123    }
124    repl = (xGetAtomNameReply *)
125	_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
126			(SIZEOF(xGetAtomNameReply) - SIZEOF(xReply)) >> 2,
127			False);
128    state->names[state->idx] = (char *) Xmalloc(repl->nameLength+1);
129    _XGetAsyncData(dpy, state->names[state->idx], buf, len,
130		   SIZEOF(xGetAtomNameReply), repl->nameLength,
131		   repl->length << 2);
132    if (state->names[state->idx]) {
133	state->names[state->idx][repl->nameLength] = '\0';
134	_XUpdateAtomCache(dpy, state->names[state->idx],
135			  state->atoms[state->idx], 0, -1, 0);
136    } else {
137	state->status = 0;
138    }
139    return True;
140}
141
142Status
143XGetAtomNames (
144    Display *dpy,
145    Atom *atoms,
146    int count,
147    char **names_return)
148{
149    _XAsyncHandler async;
150    _XGetAtomNameState async_state;
151    xGetAtomNameReply rep;
152    int i;
153    int missed = -1;
154
155    LockDisplay(dpy);
156    async_state.start_seq = dpy->request + 1;
157    async_state.atoms = atoms;
158    async_state.names = names_return;
159    async_state.idx = 0;
160    async_state.count = count - 1;
161    async_state.status = 1;
162    async.next = dpy->async_handlers;
163    async.handler = _XGetAtomNameHandler;
164    async.data = (XPointer)&async_state;
165    dpy->async_handlers = &async;
166    for (i = 0; i < count; i++) {
167	if (!(names_return[i] = _XGetAtomName(dpy, atoms[i]))) {
168	    missed = i;
169	    async_state.stop_seq = dpy->request;
170	}
171    }
172    if (missed >= 0) {
173	if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
174	    if ((names_return[missed] = (char *) Xmalloc(rep.nameLength+1))) {
175		_XReadPad(dpy, names_return[missed], (long)rep.nameLength);
176		names_return[missed][rep.nameLength] = '\0';
177		_XUpdateAtomCache(dpy, names_return[missed], atoms[missed],
178				  0, -1, 0);
179	    } else {
180		_XEatData(dpy, (unsigned long) (rep.nameLength + 3) & ~3);
181		async_state.status = 0;
182	    }
183	}
184    }
185    DeqAsyncHandler(dpy, &async);
186    UnlockDisplay(dpy);
187    if (missed >= 0)
188	SyncHandle();
189    return async_state.status;
190}
191