11ab64890Smrg/************************************************************ 21ab64890SmrgCopyright (c) 1995 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 371ab64890Smrgstatic void 38818534a1Smrg_FreeComponentNames(int num, XkbComponentNamePtr names) 391ab64890Smrg{ 40818534a1Smrg int i; 41818534a1Smrg XkbComponentNamePtr tmp; 42818534a1Smrg 43818534a1Smrg if ((num < 1) || (names == NULL)) 44818534a1Smrg return; 45818534a1Smrg for (i = 0, tmp = names; i < num; i++, tmp++) { 46818534a1Smrg if (tmp->name) { 47818534a1Smrg _XkbFree(tmp->name); 48818534a1Smrg tmp->name = NULL; 49818534a1Smrg } 501ab64890Smrg } 511ab64890Smrg _XkbFree(names); 521ab64890Smrg return; 531ab64890Smrg} 541ab64890Smrg 551ab64890Smrg/***====================================================================***/ 561ab64890Smrg 571ab64890Smrgstatic XkbComponentNamePtr 58818534a1Smrg_ReadListing(XkbReadBufferPtr buf, int count, Status * status_rtrn) 591ab64890Smrg{ 60818534a1Smrg XkbComponentNamePtr first, this; 61818534a1Smrg register int i; 62818534a1Smrg CARD16 *flags; 63818534a1Smrg int slen, wlen; 64818534a1Smrg char *str; 65818534a1Smrg 66818534a1Smrg if (count < 1) 67818534a1Smrg return NULL; 68818534a1Smrg first = _XkbTypedCalloc(count, XkbComponentNameRec); 691ab64890Smrg if (!first) 70818534a1Smrg return NULL; 71818534a1Smrg for (this = first, i = 0; i < count; i++, this++) { 72818534a1Smrg flags = (CARD16 *) _XkbGetReadBufferPtr(buf, 2 * sizeof(CARD16)); 73818534a1Smrg if (!flags) 74818534a1Smrg goto BAILOUT; 75818534a1Smrg this->flags = flags[0]; 76818534a1Smrg slen = flags[1]; 77818534a1Smrg wlen = ((slen + 1) / 2) * 2; /* pad to 2 byte boundary */ 78818534a1Smrg this->name = _XkbTypedCalloc(slen + 1, char); 79818534a1Smrg 80818534a1Smrg if (!this->name) 81818534a1Smrg goto BAILOUT; 82818534a1Smrg str = (char *) _XkbGetReadBufferPtr(buf, wlen); 83818534a1Smrg if (!str) 84818534a1Smrg goto BAILOUT; 859c019ec5Smaya memcpy(this->name, str, (size_t) slen); 861ab64890Smrg } 871ab64890Smrg return first; 88818534a1Smrg BAILOUT: 89818534a1Smrg *status_rtrn = BadAlloc; 90818534a1Smrg _FreeComponentNames(i, first); 911ab64890Smrg return NULL; 921ab64890Smrg} 931ab64890Smrg 941ab64890Smrg/***====================================================================***/ 951ab64890Smrg 961ab64890SmrgXkbComponentListPtr 97818534a1SmrgXkbListComponents(Display *dpy, 98818534a1Smrg unsigned deviceSpec, 99818534a1Smrg XkbComponentNamesPtr ptrns, 100818534a1Smrg int *max_inout) 1011ab64890Smrg{ 102818534a1Smrg register xkbListComponentsReq *req; 103818534a1Smrg xkbListComponentsReply rep; 104818534a1Smrg XkbInfoPtr xkbi; 105818534a1Smrg XkbComponentListPtr list; 106818534a1Smrg XkbReadBufferRec buf; 107818534a1Smrg int left; 108818534a1Smrg char *str; 109818534a1Smrg int extraLen, len, mapLen, codesLen, typesLen, compatLen, symsLen, geomLen; 110818534a1Smrg 111818534a1Smrg if ((dpy == NULL) || (dpy->flags & XlibDisplayNoXkb) || 112818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || 113818534a1Smrg (ptrns == NULL) || (max_inout == NULL)) 114818534a1Smrg return NULL; 115818534a1Smrg 116818534a1Smrg xkbi = dpy->xkb_info; 1171ab64890Smrg LockDisplay(dpy); 1181ab64890Smrg GetReq(kbListComponents, req); 119818534a1Smrg req->reqType = xkbi->codes->major_opcode; 120818534a1Smrg req->xkbReqType = X_kbListComponents; 121818534a1Smrg req->deviceSpec = deviceSpec; 122818534a1Smrg req->maxNames = *max_inout; 1231ab64890Smrg 124818534a1Smrg mapLen = codesLen = typesLen = compatLen = symsLen = geomLen = 0; 1251ab64890Smrg if (ptrns->keymap) 126818534a1Smrg mapLen = (int) strlen(ptrns->keymap); 1271ab64890Smrg if (ptrns->keycodes) 128818534a1Smrg codesLen = (int) strlen(ptrns->keycodes); 1291ab64890Smrg if (ptrns->types) 130818534a1Smrg typesLen = (int) strlen(ptrns->types); 1311ab64890Smrg if (ptrns->compat) 132818534a1Smrg compatLen = (int) strlen(ptrns->compat); 1331ab64890Smrg if (ptrns->symbols) 134818534a1Smrg symsLen = (int) strlen(ptrns->symbols); 1351ab64890Smrg if (ptrns->geometry) 136818534a1Smrg geomLen = (int) strlen(ptrns->geometry); 137818534a1Smrg if (mapLen > 255) 138818534a1Smrg mapLen = 255; 139818534a1Smrg if (codesLen > 255) 140818534a1Smrg codesLen = 255; 141818534a1Smrg if (typesLen > 255) 142818534a1Smrg typesLen = 255; 143818534a1Smrg if (compatLen > 255) 144818534a1Smrg compatLen = 255; 145818534a1Smrg if (symsLen > 255) 146818534a1Smrg symsLen = 255; 147818534a1Smrg if (geomLen > 255) 148818534a1Smrg geomLen = 255; 149818534a1Smrg 150818534a1Smrg len = mapLen + codesLen + typesLen + compatLen + symsLen + geomLen + 6; 151818534a1Smrg len = XkbPaddedSize(len); 152818534a1Smrg req->length += len / 4; 153818534a1Smrg BufAlloc(char *, str, len); 154818534a1Smrg 155818534a1Smrg *str++ = mapLen; 156818534a1Smrg if (mapLen > 0) { 1579c019ec5Smaya memcpy(str, ptrns->keymap, (size_t) mapLen); 158818534a1Smrg str += mapLen; 1591ab64890Smrg } 160818534a1Smrg *str++ = codesLen; 161818534a1Smrg if (codesLen > 0) { 1629c019ec5Smaya memcpy(str, ptrns->keycodes, (size_t) codesLen); 163818534a1Smrg str += codesLen; 1641ab64890Smrg } 165818534a1Smrg *str++ = typesLen; 166818534a1Smrg if (typesLen > 0) { 1679c019ec5Smaya memcpy(str, ptrns->types, (size_t) typesLen); 168818534a1Smrg str += typesLen; 1691ab64890Smrg } 170818534a1Smrg *str++ = compatLen; 171818534a1Smrg if (compatLen > 0) { 1729c019ec5Smaya memcpy(str, ptrns->compat, (size_t) compatLen); 173818534a1Smrg str += compatLen; 1741ab64890Smrg } 175818534a1Smrg *str++ = symsLen; 176818534a1Smrg if (symsLen > 0) { 1779c019ec5Smaya memcpy(str, ptrns->symbols, (size_t) symsLen); 178818534a1Smrg str += symsLen; 1791ab64890Smrg } 180818534a1Smrg *str++ = geomLen; 181818534a1Smrg if (geomLen > 0) { 1829c019ec5Smaya memcpy(str, ptrns->geometry, (size_t) geomLen); 183818534a1Smrg str += geomLen; 1841ab64890Smrg } 185818534a1Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) 186818534a1Smrg goto BAILOUT; 187818534a1Smrg extraLen = (int) rep.length * 4; 188818534a1Smrg *max_inout = rep.extra; 189818534a1Smrg if (extraLen == 0) { /* no matches, but we don't want to report a failure */ 190818534a1Smrg list = _XkbTypedCalloc(1, XkbComponentListRec); 191818534a1Smrg UnlockDisplay(dpy); 192818534a1Smrg SyncHandle(); 193818534a1Smrg return list; 1941ab64890Smrg } 195818534a1Smrg if (_XkbInitReadBuffer(dpy, &buf, extraLen)) { 196818534a1Smrg Status status = Success; 197818534a1Smrg 198818534a1Smrg list = _XkbTypedCalloc(1, XkbComponentListRec); 199818534a1Smrg if (!list) { 200818534a1Smrg _XkbFreeReadBuffer(&buf); 201818534a1Smrg goto BAILOUT; 202818534a1Smrg } 203818534a1Smrg list->num_keymaps = rep.nKeymaps; 204818534a1Smrg list->num_keycodes = rep.nKeycodes; 205818534a1Smrg list->num_types = rep.nTypes; 206818534a1Smrg list->num_compat = rep.nCompatMaps; 207818534a1Smrg list->num_symbols = rep.nSymbols; 208818534a1Smrg list->num_geometry = rep.nGeometries; 209818534a1Smrg if ((status == Success) && (list->num_keymaps > 0)) 210818534a1Smrg list->keymaps = _ReadListing(&buf, list->num_keymaps, &status); 211818534a1Smrg if ((status == Success) && (list->num_keycodes > 0)) 212818534a1Smrg list->keycodes = _ReadListing(&buf, list->num_keycodes, &status); 213818534a1Smrg if ((status == Success) && (list->num_types > 0)) 214818534a1Smrg list->types = _ReadListing(&buf, list->num_types, &status); 215818534a1Smrg if ((status == Success) && (list->num_compat > 0)) 216818534a1Smrg list->compat = _ReadListing(&buf, list->num_compat, &status); 217818534a1Smrg if ((status == Success) && (list->num_symbols > 0)) 218818534a1Smrg list->symbols = _ReadListing(&buf, list->num_symbols, &status); 219818534a1Smrg if ((status == Success) && (list->num_geometry > 0)) 220818534a1Smrg list->geometry = _ReadListing(&buf, list->num_geometry, &status); 221818534a1Smrg left = _XkbFreeReadBuffer(&buf); 222818534a1Smrg if ((status != Success) || (buf.error) || (left > 2)) { 223818534a1Smrg XkbFreeComponentList(list); 224818534a1Smrg goto BAILOUT; 225818534a1Smrg } 226818534a1Smrg UnlockDisplay(dpy); 227818534a1Smrg SyncHandle(); 228818534a1Smrg return list; 2291ab64890Smrg } 230818534a1Smrg BAILOUT: 2311ab64890Smrg UnlockDisplay(dpy); 2321ab64890Smrg SyncHandle(); 2331ab64890Smrg return NULL; 2341ab64890Smrg} 2351ab64890Smrg 2361ab64890Smrgvoid 2371ab64890SmrgXkbFreeComponentList(XkbComponentListPtr list) 2381ab64890Smrg{ 2391ab64890Smrg if (list) { 240818534a1Smrg if (list->keymaps) 241818534a1Smrg _FreeComponentNames(list->num_keymaps, list->keymaps); 242818534a1Smrg if (list->keycodes) 243818534a1Smrg _FreeComponentNames(list->num_keycodes, list->keycodes); 244818534a1Smrg if (list->types) 245818534a1Smrg _FreeComponentNames(list->num_types, list->types); 246818534a1Smrg if (list->compat) 247818534a1Smrg _FreeComponentNames(list->num_compat, list->compat); 248818534a1Smrg if (list->symbols) 249818534a1Smrg _FreeComponentNames(list->num_symbols, list->symbols); 250818534a1Smrg if (list->geometry) 251818534a1Smrg _FreeComponentNames(list->num_geometry, list->geometry); 252818534a1Smrg bzero((char *) list, sizeof(XkbComponentListRec)); 253818534a1Smrg _XkbFree(list); 2541ab64890Smrg } 2551ab64890Smrg return; 2561ab64890Smrg} 257