GetAtomNm.c revision 2d67cb4f
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    uint64_t start_seq;
91    uint64_t 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    uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
111
112    state = (_XGetAtomNameState *)data;
113    if (last_request_read < state->start_seq ||
114	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] = 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 = X_DPY_GET_REQUEST(dpy) + 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 = X_DPY_GET_REQUEST(dpy);
170	}
171    }
172    if (missed >= 0) {
173	if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
174	    if ((names_return[missed] = 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		_XEatDataWords(dpy, rep.length);
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