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#ifdef HAVE_CONFIG_H 281ab64890Smrg#include <config.h> 291ab64890Smrg#endif 301ab64890Smrg#include <stdio.h> 311ab64890Smrg#define NEED_MAP_READERS 321ab64890Smrg#include "Xlibint.h" 331ab64890Smrg#include <X11/extensions/XKBproto.h> 341ab64890Smrg#include "XKBlibint.h" 351ab64890Smrg 361ab64890SmrgStatus 37818534a1Smrg_XkbReadGetCompatMapReply(Display *dpy, 38818534a1Smrg xkbGetCompatMapReply *rep, 39818534a1Smrg XkbDescPtr xkb, 40818534a1Smrg int *nread_rtrn) 411ab64890Smrg{ 42818534a1Smrg register int i; 43818534a1Smrg XkbReadBufferRec buf; 441ab64890Smrg 45818534a1Smrg if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) 46818534a1Smrg return BadAlloc; 471ab64890Smrg 481ab64890Smrg if (nread_rtrn) 49818534a1Smrg *nread_rtrn = (int) rep->length * 4; 50818534a1Smrg 51818534a1Smrg i = rep->firstSI + rep->nSI; 52818534a1Smrg if ((!xkb->compat) && 53818534a1Smrg (XkbAllocCompatMap(xkb, XkbAllCompatMask, i) != Success)) 54818534a1Smrg return BadAlloc; 55818534a1Smrg 56818534a1Smrg if (rep->nSI != 0) { 57818534a1Smrg XkbSymInterpretRec *syms; 58818534a1Smrg xkbSymInterpretWireDesc *wire; 59818534a1Smrg 60818534a1Smrg wire = (xkbSymInterpretWireDesc *) _XkbGetReadBufferPtr(&buf, 61818534a1Smrg rep->nSI * SIZEOF (xkbSymInterpretWireDesc)); 62818534a1Smrg if (wire == NULL) 63818534a1Smrg goto BAILOUT; 64818534a1Smrg syms = &xkb->compat->sym_interpret[rep->firstSI]; 65818534a1Smrg 66818534a1Smrg for (i = 0; i < rep->nSI; i++, syms++, wire++) { 67818534a1Smrg syms->sym = wire->sym; 68818534a1Smrg syms->mods = wire->mods; 69818534a1Smrg syms->match = wire->match; 70818534a1Smrg syms->virtual_mod = wire->virtualMod; 71818534a1Smrg syms->flags = wire->flags; 72818534a1Smrg syms->act = *((XkbAnyAction *) &wire->act); 73818534a1Smrg } 74818534a1Smrg xkb->compat->num_si += rep->nSI; 751ab64890Smrg } 761ab64890Smrg 77818534a1Smrg if (rep->groups & XkbAllGroupsMask) { 78818534a1Smrg register unsigned bit, nGroups; 79818534a1Smrg xkbModsWireDesc *wire; 80818534a1Smrg 81818534a1Smrg for (i = 0, nGroups = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 82818534a1Smrg if (rep->groups & bit) 83818534a1Smrg nGroups++; 84818534a1Smrg } 85818534a1Smrg wire = (xkbModsWireDesc *) 86818534a1Smrg _XkbGetReadBufferPtr(&buf, nGroups * SIZEOF(xkbModsWireDesc)); 87818534a1Smrg if (wire == NULL) 88818534a1Smrg goto BAILOUT; 89818534a1Smrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 90818534a1Smrg if ((rep->groups & bit) == 0) 91818534a1Smrg continue; 92818534a1Smrg xkb->compat->groups[i].mask = wire->mask; 93818534a1Smrg xkb->compat->groups[i].real_mods = wire->realMods; 94818534a1Smrg xkb->compat->groups[i].vmods = wire->virtualMods; 95818534a1Smrg wire++; 96818534a1Smrg } 971ab64890Smrg } 98818534a1Smrg i = _XkbFreeReadBuffer(&buf); 9961b2299dSmrg if (i) 100818534a1Smrg fprintf(stderr, "CompatMapReply! Bad length (%d extra bytes)\n", i); 1011ab64890Smrg if (i || buf.error) 102818534a1Smrg return BadLength; 1031ab64890Smrg return Success; 104818534a1Smrg BAILOUT: 1051ab64890Smrg _XkbFreeReadBuffer(&buf); 1061ab64890Smrg return BadLength; 1071ab64890Smrg} 1081ab64890Smrg 1091ab64890SmrgStatus 110818534a1SmrgXkbGetCompatMap(Display *dpy, unsigned which, XkbDescPtr xkb) 1111ab64890Smrg{ 1121ab64890Smrg register xkbGetCompatMapReq *req; 113818534a1Smrg xkbGetCompatMapReply rep; 114818534a1Smrg Status status; 1151ab64890Smrg XkbInfoPtr xkbi; 1161ab64890Smrg 117818534a1Smrg if ((!dpy) || (!xkb) || (dpy->flags & XlibDisplayNoXkb) || 118818534a1Smrg ((xkb->dpy != NULL) && (xkb->dpy != dpy)) || 119818534a1Smrg (!dpy->xkb_info && (!XkbUseExtension(dpy, NULL, NULL)))) 120818534a1Smrg return BadAccess; 1211ab64890Smrg LockDisplay(dpy); 1221ab64890Smrg xkbi = dpy->xkb_info; 1231ab64890Smrg GetReq(kbGetCompatMap, req); 1241ab64890Smrg req->reqType = xkbi->codes->major_opcode; 1251ab64890Smrg req->xkbReqType = X_kbGetCompatMap; 1261ab64890Smrg req->deviceSpec = xkb->device_spec; 127818534a1Smrg if (which & XkbSymInterpMask) 128818534a1Smrg req->getAllSI = True; 129818534a1Smrg else 130818534a1Smrg req->getAllSI = False; 131818534a1Smrg req->firstSI = req->nSI = 0; 132818534a1Smrg 133818534a1Smrg if (which & XkbGroupCompatMask) 134818534a1Smrg req->groups = XkbAllGroupsMask; 135818534a1Smrg else 136818534a1Smrg req->groups = 0; 137818534a1Smrg 138818534a1Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 139818534a1Smrg UnlockDisplay(dpy); 140818534a1Smrg SyncHandle(); 141818534a1Smrg return BadLength; 1421ab64890Smrg } 143818534a1Smrg if (xkb->dpy == NULL) 144818534a1Smrg xkb->dpy = dpy; 145818534a1Smrg if (xkb->device_spec == XkbUseCoreKbd) 146818534a1Smrg xkb->device_spec = rep.deviceID; 1471ab64890Smrg 148818534a1Smrg status = _XkbReadGetCompatMapReply(dpy, &rep, xkb, NULL); 1491ab64890Smrg UnlockDisplay(dpy); 1501ab64890Smrg SyncHandle(); 1511ab64890Smrg return status; 1521ab64890Smrg} 1531ab64890Smrg 1541ab64890Smrgstatic Bool 155818534a1Smrg_XkbWriteSetCompatMap(Display *dpy, xkbSetCompatMapReq *req, XkbDescPtr xkb) 1561ab64890Smrg{ 157818534a1Smrg CARD16 firstSI; 158818534a1Smrg CARD16 nSI; 159818534a1Smrg int size; 160818534a1Smrg register int i, nGroups; 161818534a1Smrg register unsigned bit; 162818534a1Smrg unsigned groups; 163818534a1Smrg char *buf; 1641ab64890Smrg 1651ab64890Smrg firstSI = req->firstSI; 1661ab64890Smrg nSI = req->nSI; 167818534a1Smrg size = nSI * SIZEOF(xkbSymInterpretWireDesc); 168818534a1Smrg nGroups = 0; 169818534a1Smrg groups = req->groups; 170818534a1Smrg if (groups & XkbAllGroupsMask) { 171818534a1Smrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 172818534a1Smrg if (groups & bit) 173818534a1Smrg nGroups++; 174818534a1Smrg } 175818534a1Smrg size += SIZEOF(xkbModsWireDesc) * nGroups; 1761ab64890Smrg } 177818534a1Smrg req->length += size / 4; 178818534a1Smrg BufAlloc(char *, buf, size); 179818534a1Smrg 1801ab64890Smrg if (!buf) 181818534a1Smrg return False; 1821ab64890Smrg 1831ab64890Smrg if (nSI) { 184818534a1Smrg XkbSymInterpretPtr sym = &xkb->compat->sym_interpret[firstSI]; 185818534a1Smrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) buf; 186818534a1Smrg 187818534a1Smrg for (i = 0; i < nSI; i++, wire++, sym++) { 188818534a1Smrg wire->sym = (CARD32) sym->sym; 189818534a1Smrg wire->mods = sym->mods; 190818534a1Smrg wire->match = sym->match; 191818534a1Smrg wire->flags = sym->flags; 192818534a1Smrg wire->virtualMod = sym->virtual_mod; 193818534a1Smrg memcpy(&wire->act, &sym->act, sz_xkbActionWireDesc); 194818534a1Smrg } 195818534a1Smrg buf += nSI * SIZEOF(xkbSymInterpretWireDesc); 1961ab64890Smrg } 197818534a1Smrg if (groups & XkbAllGroupsMask) { 198818534a1Smrg xkbModsWireDesc *out = (xkbModsWireDesc *) buf; 199818534a1Smrg 200818534a1Smrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 201818534a1Smrg if ((groups & bit) != 0) { 202818534a1Smrg out->mask = xkb->compat->groups[i].mask; 203818534a1Smrg out->realMods = xkb->compat->groups[i].real_mods; 204818534a1Smrg out->virtualMods = xkb->compat->groups[i].vmods; 205818534a1Smrg out++; 206818534a1Smrg } 207818534a1Smrg } 208818534a1Smrg buf += nGroups * SIZEOF(xkbModsWireDesc); 2091ab64890Smrg } 2101ab64890Smrg return True; 2111ab64890Smrg} 2121ab64890Smrg 2131ab64890SmrgBool 214818534a1SmrgXkbSetCompatMap(Display *dpy, unsigned which, XkbDescPtr xkb, 215818534a1Smrg Bool updateActions) 2161ab64890Smrg{ 2171ab64890Smrg register xkbSetCompatMapReq *req; 218818534a1Smrg Status ok; 2191ab64890Smrg XkbInfoPtr xkbi; 2201ab64890Smrg 221818534a1Smrg if ((dpy->flags & XlibDisplayNoXkb) || (dpy != xkb->dpy) || 222818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 223818534a1Smrg return False; 2241ab64890Smrg if ((!xkb->compat) || 225818534a1Smrg ((which & XkbSymInterpMask) && (!xkb->compat->sym_interpret))) 226818534a1Smrg return False; 2271ab64890Smrg LockDisplay(dpy); 2281ab64890Smrg xkbi = dpy->xkb_info; 2291ab64890Smrg GetReq(kbSetCompatMap, req); 2301ab64890Smrg req->reqType = xkbi->codes->major_opcode; 2311ab64890Smrg req->xkbReqType = X_kbSetCompatMap; 2321ab64890Smrg req->deviceSpec = xkb->device_spec; 2331ab64890Smrg req->recomputeActions = updateActions; 234818534a1Smrg if (which & XkbSymInterpMask) { 235818534a1Smrg req->truncateSI = True; 236818534a1Smrg req->firstSI = 0; 237818534a1Smrg req->nSI = xkb->compat->num_si; 2381ab64890Smrg } 2391ab64890Smrg else { 240818534a1Smrg req->truncateSI = False; 241818534a1Smrg req->firstSI = 0; 242818534a1Smrg req->nSI = 0; 2431ab64890Smrg } 244818534a1Smrg if (which & XkbGroupCompatMask) 245818534a1Smrg req->groups = XkbAllGroupsMask; 246818534a1Smrg else 247818534a1Smrg req->groups = 0; 248818534a1Smrg ok = _XkbWriteSetCompatMap(dpy, req, xkb); 2491ab64890Smrg UnlockDisplay(dpy); 2501ab64890Smrg SyncHandle(); 2511ab64890Smrg return ok; 2521ab64890Smrg} 253