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