XKBCompat.c revision e9fcaa8a
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#ifdef HAVE_CONFIG_H 28#include <config.h> 29#endif 30#include <stdio.h> 31#define NEED_MAP_READERS 32#include "Xlibint.h" 33#include <X11/extensions/XKBproto.h> 34#include "XKBlibint.h" 35 36Status 37_XkbReadGetCompatMapReply( Display * dpy, 38 xkbGetCompatMapReply * rep, 39 XkbDescPtr xkb, 40 int * nread_rtrn) 41{ 42register int i; 43XkbReadBufferRec buf; 44 45 if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) 46 return BadAlloc; 47 48 if (nread_rtrn) 49 *nread_rtrn= (int)rep->length*4; 50 51 i= rep->firstSI+rep->nSI; 52 if ((!xkb->compat)&& 53 (XkbAllocCompatMap(xkb,XkbAllCompatMask,i)!=Success)) 54 return BadAlloc; 55 56 if (rep->nSI!=0) { 57 XkbSymInterpretRec *syms; 58 xkbSymInterpretWireDesc *wire; 59 60 wire= (xkbSymInterpretWireDesc *)_XkbGetReadBufferPtr(&buf, 61 rep->nSI*SIZEOF(xkbSymInterpretWireDesc)); 62 if (wire==NULL) 63 goto BAILOUT; 64 syms= &xkb->compat->sym_interpret[rep->firstSI]; 65 66 for (i=0;i<rep->nSI;i++,syms++,wire++) { 67 syms->sym= wire->sym; 68 syms->mods= wire->mods; 69 syms->match= wire->match; 70 syms->virtual_mod= wire->virtualMod; 71 syms->flags= wire->flags; 72 syms->act= *((XkbAnyAction *)&wire->act); 73 } 74 xkb->compat->num_si+= rep->nSI; 75 } 76 77 if (rep->groups&XkbAllGroupsMask) { 78 register unsigned bit,nGroups; 79 xkbModsWireDesc * wire; 80 for (i=0,nGroups=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 81 if (rep->groups&bit) 82 nGroups++; 83 } 84 wire= (xkbModsWireDesc *)_XkbGetReadBufferPtr(&buf, 85 nGroups*SIZEOF(xkbModsWireDesc)); 86 if (wire==NULL) 87 goto BAILOUT; 88 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 89 if ((rep->groups&bit)==0) 90 continue; 91 xkb->compat->groups[i].mask= wire->mask; 92 xkb->compat->groups[i].real_mods= wire->realMods; 93 xkb->compat->groups[i].vmods= wire->virtualMods; 94 wire++; 95 } 96 } 97 i= _XkbFreeReadBuffer(&buf); 98 if (i) 99 fprintf(stderr,"CompatMapReply! Bad length (%d extra bytes)\n",i); 100 if (i || buf.error) 101 return BadLength; 102 return Success; 103BAILOUT: 104 _XkbFreeReadBuffer(&buf); 105 return BadLength; 106} 107 108Status 109XkbGetCompatMap(Display *dpy,unsigned which,XkbDescPtr xkb) 110{ 111 register xkbGetCompatMapReq *req; 112 xkbGetCompatMapReply rep; 113 Status status; 114 XkbInfoPtr xkbi; 115 116 if ( (!dpy) || (!xkb) || (dpy->flags & XlibDisplayNoXkb) || 117 ((xkb->dpy!=NULL)&&(xkb->dpy!=dpy)) || 118 (!dpy->xkb_info && (!XkbUseExtension(dpy,NULL,NULL)))) 119 return BadAccess; 120 LockDisplay(dpy); 121 xkbi = dpy->xkb_info; 122 GetReq(kbGetCompatMap, req); 123 req->reqType = xkbi->codes->major_opcode; 124 req->xkbReqType = X_kbGetCompatMap; 125 req->deviceSpec = xkb->device_spec; 126 if (which&XkbSymInterpMask) 127 req->getAllSI= True; 128 else req->getAllSI= False; 129 req->firstSI= req->nSI= 0; 130 131 if (which&XkbGroupCompatMask) 132 req->groups= XkbAllGroupsMask; 133 else req->groups= 0; 134 135 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 136 UnlockDisplay(dpy); 137 SyncHandle(); 138 return BadLength; 139 } 140 if (xkb->dpy==NULL) 141 xkb->dpy= dpy; 142 if (xkb->device_spec==XkbUseCoreKbd) 143 xkb->device_spec= rep.deviceID; 144 145 status = _XkbReadGetCompatMapReply(dpy,&rep,xkb,NULL); 146 UnlockDisplay(dpy); 147 SyncHandle(); 148 return status; 149} 150 151static Bool 152_XkbWriteSetCompatMap(Display *dpy,xkbSetCompatMapReq *req,XkbDescPtr xkb) 153{ 154CARD16 firstSI; 155CARD16 nSI; 156int size; 157register int i,nGroups; 158register unsigned bit; 159unsigned groups; 160char * buf; 161 162 firstSI = req->firstSI; 163 nSI = req->nSI; 164 size= nSI*SIZEOF(xkbSymInterpretWireDesc); 165 nGroups= 0; 166 groups= req->groups; 167 if (groups&XkbAllGroupsMask) { 168 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 169 if (groups&bit) 170 nGroups++; 171 } 172 size+= SIZEOF(xkbModsWireDesc)*nGroups; 173 } 174 req->length+= size/4; 175 BufAlloc(char *,buf,size); 176 if (!buf) 177 return False; 178 179 if (nSI) { 180 XkbSymInterpretPtr sym= &xkb->compat->sym_interpret[firstSI]; 181 xkbSymInterpretWireDesc *wire= (xkbSymInterpretWireDesc *)buf; 182 for (i=0;i<nSI;i++,wire++,sym++) { 183 wire->sym= (CARD32)sym->sym; 184 wire->mods= sym->mods; 185 wire->match= sym->match; 186 wire->flags= sym->flags; 187 wire->virtualMod= sym->virtual_mod; 188 memcpy(&wire->act,&sym->act,sz_xkbActionWireDesc); 189 } 190 buf+= nSI*SIZEOF(xkbSymInterpretWireDesc); 191 } 192 if (groups&XkbAllGroupsMask) { 193 xkbModsWireDesc * out; 194 195 out= (xkbModsWireDesc *)buf; 196 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 197 if ((groups&bit)!=0) { 198 out->mask= xkb->compat->groups[i].mask; 199 out->realMods= xkb->compat->groups[i].real_mods; 200 out->virtualMods= xkb->compat->groups[i].vmods; 201 out++; 202 } 203 } 204 buf+= nGroups*SIZEOF(xkbModsWireDesc); 205 } 206 return True; 207} 208 209Bool 210XkbSetCompatMap(Display *dpy,unsigned which,XkbDescPtr xkb,Bool updateActions) 211{ 212 register xkbSetCompatMapReq *req; 213 Status ok; 214 XkbInfoPtr xkbi; 215 216 if ((dpy->flags & XlibDisplayNoXkb) || (dpy!=xkb->dpy) || 217 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 218 return False; 219 if ((!xkb->compat) || 220 ((which&XkbSymInterpMask)&&(!xkb->compat->sym_interpret))) 221 return False; 222 LockDisplay(dpy); 223 xkbi = dpy->xkb_info; 224 GetReq(kbSetCompatMap, req); 225 req->reqType = xkbi->codes->major_opcode; 226 req->xkbReqType = X_kbSetCompatMap; 227 req->deviceSpec = xkb->device_spec; 228 req->recomputeActions = updateActions; 229 if (which&XkbSymInterpMask) { 230 req->truncateSI = True; 231 req->firstSI= 0; 232 req->nSI= xkb->compat->num_si; 233 } 234 else { 235 req->truncateSI = False; 236 req->firstSI= 0; 237 req->nSI= 0; 238 } 239 if (which&XkbGroupCompatMask) 240 req->groups= XkbAllGroupsMask; 241 else req->groups= 0; 242 ok= _XkbWriteSetCompatMap(dpy,req,xkb); 243 UnlockDisplay(dpy); 244 SyncHandle(); 245 return ok; 246} 247 248