1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27 #define NEED_MAP_READERS
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include "Xlibint.h"
32 #include <X11/extensions/XKBproto.h>
33 #include "XKBlibint.h"
34
35 /***====================================================================***/
36
37 XkbDescPtr
XkbGetKeyboardByName(Display * dpy,unsigned deviceSpec,XkbComponentNamesPtr names,unsigned want,unsigned need,Bool load)38 XkbGetKeyboardByName(Display *dpy,
39 unsigned deviceSpec,
40 XkbComponentNamesPtr names,
41 unsigned want,
42 unsigned need,
43 Bool load)
44 {
45 register xkbGetKbdByNameReq *req;
46 xkbGetKbdByNameReply rep;
47 int len, extraLen = 0;
48 char *str;
49 XkbDescPtr xkb;
50 int mapLen, codesLen, typesLen, compatLen;
51 int symsLen, geomLen;
52 XkbInfoPtr xkbi;
53
54 if ((dpy == NULL) || (dpy->flags & XlibDisplayNoXkb) ||
55 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
56 return NULL;
57
58 xkbi = dpy->xkb_info;
59 xkb = (XkbDescRec *) _XkbCalloc(1, sizeof(XkbDescRec));
60 if (!xkb)
61 return NULL;
62 xkb->device_spec = deviceSpec;
63 xkb->map = (XkbClientMapRec *) _XkbCalloc(1, sizeof(XkbClientMapRec));
64 xkb->dpy = dpy;
65
66 LockDisplay(dpy);
67 GetReq(kbGetKbdByName, req);
68 req->reqType = xkbi->codes->major_opcode;
69 req->xkbReqType = X_kbGetKbdByName;
70 req->deviceSpec = xkb->device_spec;
71 req->want = want;
72 req->need = need;
73 req->load = load;
74
75 mapLen = codesLen = typesLen = compatLen = symsLen = geomLen = 0;
76 if (names) {
77 if (names->keymap)
78 mapLen = (int) strlen(names->keymap);
79 if (names->keycodes)
80 codesLen = (int) strlen(names->keycodes);
81 if (names->types)
82 typesLen = (int) strlen(names->types);
83 if (names->compat)
84 compatLen = (int) strlen(names->compat);
85 if (names->symbols)
86 symsLen = (int) strlen(names->symbols);
87 if (names->geometry)
88 geomLen = (int) strlen(names->geometry);
89 if (mapLen > 255)
90 mapLen = 255;
91 if (codesLen > 255)
92 codesLen = 255;
93 if (typesLen > 255)
94 typesLen = 255;
95 if (compatLen > 255)
96 compatLen = 255;
97 if (symsLen > 255)
98 symsLen = 255;
99 if (geomLen > 255)
100 geomLen = 255;
101 }
102 else
103 mapLen = codesLen = typesLen = compatLen = symsLen = geomLen = 0;
104
105 len = mapLen + codesLen + typesLen + compatLen + symsLen + geomLen + 6;
106 len = XkbPaddedSize(len);
107 req->length += len / 4;
108 BufAlloc(char *, str, len);
109
110 *str++ = mapLen;
111 if (mapLen > 0) {
112 memcpy(str, names->keymap, (size_t) mapLen);
113 str += mapLen;
114 }
115 *str++ = codesLen;
116 if (codesLen > 0) {
117 memcpy(str, names->keycodes, (size_t) codesLen);
118 str += codesLen;
119 }
120 *str++ = typesLen;
121 if (typesLen > 0) {
122 memcpy(str, names->types, (size_t) typesLen);
123 str += typesLen;
124 }
125 *str++ = compatLen;
126 if (compatLen > 0) {
127 memcpy(str, names->compat, (size_t) compatLen);
128 str += compatLen;
129 }
130 *str++ = symsLen;
131 if (symsLen > 0) {
132 memcpy(str, names->symbols, (size_t) symsLen);
133 str += symsLen;
134 }
135 *str++ = geomLen;
136 if (geomLen > 0) {
137 memcpy(str, names->geometry, (size_t) geomLen);
138 str += geomLen;
139 }
140 if ((!_XReply(dpy, (xReply *) &rep, 0, xFalse)) || (!rep.reported))
141 goto BAILOUT;
142 extraLen = (int) rep.length * 4;
143
144 xkb->device_spec = rep.deviceID;
145 xkb->min_key_code = rep.minKeyCode;
146 xkb->max_key_code = rep.maxKeyCode;
147 if (rep.reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) {
148 xkbGetMapReply mrep;
149 Status status;
150 int nread = 0;
151
152 _XRead(dpy, (char *) &mrep, SIZEOF(xkbGetMapReply));
153 extraLen -= SIZEOF(xkbGetMapReply);
154 status = _XkbReadGetMapReply(dpy, &mrep, xkb, &nread);
155 extraLen -= nread;
156 if (status != Success)
157 goto BAILOUT;
158 }
159 if (rep.reported & XkbGBN_CompatMapMask) {
160 xkbGetCompatMapReply crep;
161 Status status;
162 int nread = 0;
163
164 _XRead(dpy, (char *) &crep, SIZEOF(xkbGetCompatMapReply));
165 extraLen -= SIZEOF(xkbGetCompatMapReply);
166 status = _XkbReadGetCompatMapReply(dpy, &crep, xkb, &nread);
167 extraLen -= nread;
168 if (status != Success)
169 goto BAILOUT;
170 }
171 if (rep.reported & XkbGBN_IndicatorMapMask) {
172 xkbGetIndicatorMapReply irep;
173 Status status;
174 int nread = 0;
175
176 _XRead(dpy, (char *) &irep, SIZEOF(xkbGetIndicatorMapReply));
177 extraLen -= SIZEOF(xkbGetIndicatorMapReply);
178 status = _XkbReadGetIndicatorMapReply(dpy, &irep, xkb, &nread);
179 extraLen -= nread;
180 if (status != Success)
181 goto BAILOUT;
182 }
183 if (rep.reported & (XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask)) {
184 xkbGetNamesReply nrep;
185 Status status;
186 int nread = 0;
187
188 _XRead(dpy, (char *) &nrep, SIZEOF(xkbGetNamesReply));
189 extraLen -= SIZEOF(xkbGetNamesReply);
190 status = _XkbReadGetNamesReply(dpy, &nrep, xkb, &nread);
191 extraLen -= nread;
192 if (status != Success)
193 goto BAILOUT;
194 }
195 if (rep.reported & XkbGBN_GeometryMask) {
196 xkbGetGeometryReply grep;
197 Status status;
198 int nread = 0;
199
200 _XRead(dpy, (char *) &grep, SIZEOF(xkbGetGeometryReply));
201 extraLen -= SIZEOF(xkbGetGeometryReply);
202 status = _XkbReadGetGeometryReply(dpy, &grep, xkb, &nread);
203 extraLen -= nread;
204 if (status != Success)
205 goto BAILOUT;
206 }
207 if (extraLen > 0)
208 goto BAILOUT;
209 UnlockDisplay(dpy);
210 SyncHandle();
211 return xkb;
212 BAILOUT:
213 if (xkb != NULL)
214 XkbFreeKeyboard(xkb, XkbAllComponentsMask, xTrue);
215 if (extraLen > 0)
216 _XEatData(dpy, extraLen);
217 UnlockDisplay(dpy);
218 SyncHandle();
219 return NULL;
220 }
221
222 XkbDescPtr
XkbGetKeyboard(Display * dpy,unsigned which,unsigned deviceSpec)223 XkbGetKeyboard(Display *dpy, unsigned which, unsigned deviceSpec)
224 {
225 return XkbGetKeyboardByName(dpy, deviceSpec, NULL, which, which, False);
226 }
227