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