11ab64890Smrg/************************************************************ 21ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 31ab64890Smrg 41ab64890SmrgPermission to use, copy, modify, and distribute this 51ab64890Smrgsoftware and its documentation for any purpose and without 61ab64890Smrgfee is hereby granted, provided that the above copyright 71ab64890Smrgnotice appear in all copies and that both that copyright 81ab64890Smrgnotice and this permission notice appear in supporting 961b2299dSmrgdocumentation, and that the name of Silicon Graphics not be 1061b2299dSmrgused in advertising or publicity pertaining to distribution 111ab64890Smrgof the software without specific prior written permission. 1261b2299dSmrgSilicon Graphics makes no representation about the suitability 131ab64890Smrgof this software for any purpose. It is provided "as is" 141ab64890Smrgwithout any express or implied warranty. 151ab64890Smrg 1661b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1761b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 181ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1961b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2061b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2161b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 221ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 231ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 241ab64890Smrg 251ab64890Smrg********************************************************/ 261ab64890Smrg 271ab64890Smrg#define NEED_MAP_READERS 281ab64890Smrg#ifdef HAVE_CONFIG_H 291ab64890Smrg#include <config.h> 301ab64890Smrg#endif 311ab64890Smrg#include "Xlibint.h" 321ab64890Smrg#include <X11/extensions/XKBproto.h> 331ab64890Smrg#include "XKBlibint.h" 341ab64890Smrg 351ab64890Smrg/***====================================================================***/ 361ab64890Smrg 371ab64890SmrgXkbDescPtr 38818534a1SmrgXkbGetKeyboardByName(Display *dpy, 39818534a1Smrg unsigned deviceSpec, 40818534a1Smrg XkbComponentNamesPtr names, 41818534a1Smrg unsigned want, 42818534a1Smrg unsigned need, 43818534a1Smrg Bool load) 441ab64890Smrg{ 45818534a1Smrg register xkbGetKbdByNameReq *req; 46818534a1Smrg xkbGetKbdByNameReply rep; 472d67cb4fSmrg int len, extraLen = 0; 48818534a1Smrg char *str; 49818534a1Smrg XkbDescPtr xkb; 50818534a1Smrg int mapLen, codesLen, typesLen, compatLen; 51818534a1Smrg int symsLen, geomLen; 52818534a1Smrg XkbInfoPtr xkbi; 53818534a1Smrg 54818534a1Smrg if ((dpy == NULL) || (dpy->flags & XlibDisplayNoXkb) || 55818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 56818534a1Smrg return NULL; 57818534a1Smrg 58818534a1Smrg xkbi = dpy->xkb_info; 59818534a1Smrg xkb = (XkbDescRec *) _XkbCalloc(1, sizeof(XkbDescRec)); 601ab64890Smrg if (!xkb) 61818534a1Smrg return NULL; 621ab64890Smrg xkb->device_spec = deviceSpec; 63818534a1Smrg xkb->map = (XkbClientMapRec *) _XkbCalloc(1, sizeof(XkbClientMapRec)); 641ab64890Smrg xkb->dpy = dpy; 651ab64890Smrg 661ab64890Smrg LockDisplay(dpy); 671ab64890Smrg GetReq(kbGetKbdByName, req); 681ab64890Smrg req->reqType = xkbi->codes->major_opcode; 691ab64890Smrg req->xkbReqType = X_kbGetKbdByName; 701ab64890Smrg req->deviceSpec = xkb->device_spec; 71818534a1Smrg req->want = want; 72818534a1Smrg req->need = need; 73818534a1Smrg req->load = load; 741ab64890Smrg 75818534a1Smrg mapLen = codesLen = typesLen = compatLen = symsLen = geomLen = 0; 761ab64890Smrg if (names) { 77818534a1Smrg if (names->keymap) 78818534a1Smrg mapLen = (int) strlen(names->keymap); 79818534a1Smrg if (names->keycodes) 80818534a1Smrg codesLen = (int) strlen(names->keycodes); 81818534a1Smrg if (names->types) 82818534a1Smrg typesLen = (int) strlen(names->types); 83818534a1Smrg if (names->compat) 84818534a1Smrg compatLen = (int) strlen(names->compat); 85818534a1Smrg if (names->symbols) 86818534a1Smrg symsLen = (int) strlen(names->symbols); 87818534a1Smrg if (names->geometry) 88818534a1Smrg geomLen = (int) strlen(names->geometry); 89818534a1Smrg if (mapLen > 255) 90818534a1Smrg mapLen = 255; 91818534a1Smrg if (codesLen > 255) 92818534a1Smrg codesLen = 255; 93818534a1Smrg if (typesLen > 255) 94818534a1Smrg typesLen = 255; 95818534a1Smrg if (compatLen > 255) 96818534a1Smrg compatLen = 255; 97818534a1Smrg if (symsLen > 255) 98818534a1Smrg symsLen = 255; 99818534a1Smrg if (geomLen > 255) 100818534a1Smrg geomLen = 255; 1011ab64890Smrg } 102818534a1Smrg else 103818534a1Smrg mapLen = codesLen = typesLen = compatLen = symsLen = geomLen = 0; 104818534a1Smrg 105818534a1Smrg len = mapLen + codesLen + typesLen + compatLen + symsLen + geomLen + 6; 106818534a1Smrg len = XkbPaddedSize(len); 107818534a1Smrg req->length += len / 4; 108818534a1Smrg BufAlloc(char *, str, len); 109818534a1Smrg 110818534a1Smrg *str++ = mapLen; 111818534a1Smrg if (mapLen > 0) { 1129c019ec5Smaya memcpy(str, names->keymap, (size_t) mapLen); 113818534a1Smrg str += mapLen; 1141ab64890Smrg } 115818534a1Smrg *str++ = codesLen; 116818534a1Smrg if (codesLen > 0) { 1179c019ec5Smaya memcpy(str, names->keycodes, (size_t) codesLen); 118818534a1Smrg str += codesLen; 1191ab64890Smrg } 120818534a1Smrg *str++ = typesLen; 121818534a1Smrg if (typesLen > 0) { 1229c019ec5Smaya memcpy(str, names->types, (size_t) typesLen); 123818534a1Smrg str += typesLen; 1241ab64890Smrg } 125818534a1Smrg *str++ = compatLen; 126818534a1Smrg if (compatLen > 0) { 1279c019ec5Smaya memcpy(str, names->compat, (size_t) compatLen); 128818534a1Smrg str += compatLen; 1291ab64890Smrg } 130818534a1Smrg *str++ = symsLen; 131818534a1Smrg if (symsLen > 0) { 1329c019ec5Smaya memcpy(str, names->symbols, (size_t) symsLen); 133818534a1Smrg str += symsLen; 1341ab64890Smrg } 135818534a1Smrg *str++ = geomLen; 136818534a1Smrg if (geomLen > 0) { 1379c019ec5Smaya memcpy(str, names->geometry, (size_t) geomLen); 138818534a1Smrg str += geomLen; 1391ab64890Smrg } 140818534a1Smrg if ((!_XReply(dpy, (xReply *) &rep, 0, xFalse)) || (!rep.reported)) 141818534a1Smrg goto BAILOUT; 142818534a1Smrg extraLen = (int) rep.length * 4; 1431ab64890Smrg 144818534a1Smrg xkb->device_spec = rep.deviceID; 1451ab64890Smrg xkb->min_key_code = rep.minKeyCode; 1461ab64890Smrg xkb->max_key_code = rep.maxKeyCode; 147818534a1Smrg if (rep.reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) { 148818534a1Smrg xkbGetMapReply mrep; 149818534a1Smrg Status status; 150818534a1Smrg int nread = 0; 151818534a1Smrg 152818534a1Smrg _XRead(dpy, (char *) &mrep, SIZEOF(xkbGetMapReply)); 153818534a1Smrg extraLen -= SIZEOF(xkbGetMapReply); 154818534a1Smrg status = _XkbReadGetMapReply(dpy, &mrep, xkb, &nread); 155818534a1Smrg extraLen -= nread; 156818534a1Smrg if (status != Success) 157818534a1Smrg goto BAILOUT; 1581ab64890Smrg } 159818534a1Smrg if (rep.reported & XkbGBN_CompatMapMask) { 160818534a1Smrg xkbGetCompatMapReply crep; 161818534a1Smrg Status status; 162818534a1Smrg int nread = 0; 163818534a1Smrg 164818534a1Smrg _XRead(dpy, (char *) &crep, SIZEOF(xkbGetCompatMapReply)); 165818534a1Smrg extraLen -= SIZEOF(xkbGetCompatMapReply); 166818534a1Smrg status = _XkbReadGetCompatMapReply(dpy, &crep, xkb, &nread); 167818534a1Smrg extraLen -= nread; 168818534a1Smrg if (status != Success) 169818534a1Smrg goto BAILOUT; 1701ab64890Smrg } 171818534a1Smrg if (rep.reported & XkbGBN_IndicatorMapMask) { 172818534a1Smrg xkbGetIndicatorMapReply irep; 173818534a1Smrg Status status; 174818534a1Smrg int nread = 0; 175818534a1Smrg 176818534a1Smrg _XRead(dpy, (char *) &irep, SIZEOF(xkbGetIndicatorMapReply)); 177818534a1Smrg extraLen -= SIZEOF(xkbGetIndicatorMapReply); 178818534a1Smrg status = _XkbReadGetIndicatorMapReply(dpy, &irep, xkb, &nread); 179818534a1Smrg extraLen -= nread; 180818534a1Smrg if (status != Success) 181818534a1Smrg goto BAILOUT; 1821ab64890Smrg } 183818534a1Smrg if (rep.reported & (XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask)) { 184818534a1Smrg xkbGetNamesReply nrep; 185818534a1Smrg Status status; 186818534a1Smrg int nread = 0; 187818534a1Smrg 188818534a1Smrg _XRead(dpy, (char *) &nrep, SIZEOF(xkbGetNamesReply)); 189818534a1Smrg extraLen -= SIZEOF(xkbGetNamesReply); 190818534a1Smrg status = _XkbReadGetNamesReply(dpy, &nrep, xkb, &nread); 191818534a1Smrg extraLen -= nread; 192818534a1Smrg if (status != Success) 193818534a1Smrg goto BAILOUT; 1941ab64890Smrg } 195818534a1Smrg if (rep.reported & XkbGBN_GeometryMask) { 196818534a1Smrg xkbGetGeometryReply grep; 197818534a1Smrg Status status; 198818534a1Smrg int nread = 0; 199818534a1Smrg 200818534a1Smrg _XRead(dpy, (char *) &grep, SIZEOF(xkbGetGeometryReply)); 201818534a1Smrg extraLen -= SIZEOF(xkbGetGeometryReply); 202818534a1Smrg status = _XkbReadGetGeometryReply(dpy, &grep, xkb, &nread); 203818534a1Smrg extraLen -= nread; 204818534a1Smrg if (status != Success) 205818534a1Smrg goto BAILOUT; 2061ab64890Smrg } 2072d67cb4fSmrg if (extraLen > 0) 2082d67cb4fSmrg goto BAILOUT; 2091ab64890Smrg UnlockDisplay(dpy); 2101ab64890Smrg SyncHandle(); 2111ab64890Smrg return xkb; 212818534a1Smrg BAILOUT: 213818534a1Smrg if (xkb != NULL) 214818534a1Smrg XkbFreeKeyboard(xkb, XkbAllComponentsMask, xTrue); 2152d67cb4fSmrg if (extraLen > 0) 2162d67cb4fSmrg _XEatData(dpy, extraLen); 2171ab64890Smrg UnlockDisplay(dpy); 2181ab64890Smrg SyncHandle(); 2191ab64890Smrg return NULL; 2201ab64890Smrg} 2211ab64890Smrg 2221ab64890SmrgXkbDescPtr 223818534a1SmrgXkbGetKeyboard(Display *dpy, unsigned which, unsigned deviceSpec) 2241ab64890Smrg{ 225818534a1Smrg return XkbGetKeyboardByName(dpy, deviceSpec, NULL, which, which, False); 2261ab64890Smrg} 227