1/************************************************************ 2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4Permission to use, copy, modify, and distribute this 5software and its documentation for any purpose and without 6fee is hereby granted, provided that the above copyright 7notice appear in all copies and that both that copyright 8notice and this permission notice appear in supporting 9documentation, and that the name of Silicon Graphics not be 10used in advertising or publicity pertaining to distribution 11of the software without specific prior written permission. 12Silicon Graphics makes no representation about the suitability 13of this software for any purpose. It is provided "as is" 14without any express or implied warranty. 15 16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23THE 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 37XkbDescPtr 38XkbGetKeyboardByName(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 222XkbDescPtr 223XkbGetKeyboard(Display *dpy, unsigned which, unsigned deviceSpec) 224{ 225 return XkbGetKeyboardByName(dpy, deviceSpec, NULL, which, which, False); 226} 227