XKBCompat.c revision 1ab64890
1/* $Xorg: XKBCompat.c,v 1.3 2000/08/17 19:45:00 cpqbld Exp $ */ 2/************************************************************ 3Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 4 5Permission to use, copy, modify, and distribute this 6software and its documentation for any purpose and without 7fee is hereby granted, provided that the above copyright 8notice appear in all copies and that both that copyright 9notice and this permission notice appear in supporting 10documentation, and that the name of Silicon Graphics not be 11used in advertising or publicity pertaining to distribution 12of the software without specific prior written permission. 13Silicon Graphics makes no representation about the suitability 14of this software for any purpose. It is provided "as is" 15without any express or implied warranty. 16 17SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 26********************************************************/ 27/* $XFree86$ */ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <stdio.h> 33#define NEED_REPLIES 34#define NEED_EVENTS 35#define NEED_MAP_READERS 36#include "Xlibint.h" 37#include <X11/extensions/XKBproto.h> 38#include "XKBlibint.h" 39 40Status 41_XkbReadGetCompatMapReply( Display * dpy, 42 xkbGetCompatMapReply * rep, 43 XkbDescPtr xkb, 44 int * nread_rtrn) 45{ 46register int i; 47XkbReadBufferRec buf; 48 49 if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) 50 return BadAlloc; 51 52 if (nread_rtrn) 53 *nread_rtrn= (int)rep->length*4; 54 55 i= rep->firstSI+rep->nSI; 56 if ((!xkb->compat)&& 57 (XkbAllocCompatMap(xkb,XkbAllCompatMask,i)!=Success)) 58 return BadAlloc; 59 60 if (rep->nSI!=0) { 61 XkbSymInterpretRec *syms; 62 xkbSymInterpretWireDesc *wire; 63 64 wire= (xkbSymInterpretWireDesc *)_XkbGetReadBufferPtr(&buf, 65 rep->nSI*SIZEOF(xkbSymInterpretWireDesc)); 66 if (wire==NULL) 67 goto BAILOUT; 68 syms= &xkb->compat->sym_interpret[rep->firstSI]; 69 70 for (i=0;i<rep->nSI;i++,syms++,wire++) { 71 syms->sym= wire->sym; 72 syms->mods= wire->mods; 73 syms->match= wire->match; 74 syms->virtual_mod= wire->virtualMod; 75 syms->flags= wire->flags; 76 syms->act= *((XkbAnyAction *)&wire->act); 77 } 78 xkb->compat->num_si+= rep->nSI; 79 } 80 81 if (rep->groups&XkbAllGroupsMask) { 82 register unsigned bit,nGroups; 83 xkbModsWireDesc * wire; 84 for (i=0,nGroups=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 85 if (rep->groups&bit) 86 nGroups++; 87 } 88 wire= (xkbModsWireDesc *)_XkbGetReadBufferPtr(&buf, 89 nGroups*SIZEOF(xkbModsWireDesc)); 90 if (wire==NULL) 91 goto BAILOUT; 92 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 93 if ((rep->groups&bit)==0) 94 continue; 95 xkb->compat->groups[i].mask= wire->mask; 96 xkb->compat->groups[i].real_mods= wire->realMods; 97 xkb->compat->groups[i].vmods= wire->virtualMods; 98 wire++; 99 } 100 } 101 i= _XkbFreeReadBuffer(&buf); 102 if (i) 103 fprintf(stderr,"CompatMapReply! Bad length (%d extra bytes)\n",i); 104 if (i || buf.error) 105 return BadLength; 106 return Success; 107BAILOUT: 108 _XkbFreeReadBuffer(&buf); 109 return BadLength; 110} 111 112Status 113XkbGetCompatMap(Display *dpy,unsigned which,XkbDescPtr xkb) 114{ 115 register xkbGetCompatMapReq *req; 116 xkbGetCompatMapReply rep; 117 Status status; 118 XkbInfoPtr xkbi; 119 120 if ( (!dpy) || (!xkb) || (dpy->flags & XlibDisplayNoXkb) || 121 ((xkb->dpy!=NULL)&&(xkb->dpy!=dpy)) || 122 (!dpy->xkb_info && (!XkbUseExtension(dpy,NULL,NULL)))) 123 return BadAccess; 124 LockDisplay(dpy); 125 xkbi = dpy->xkb_info; 126 GetReq(kbGetCompatMap, req); 127 req->reqType = xkbi->codes->major_opcode; 128 req->xkbReqType = X_kbGetCompatMap; 129 req->deviceSpec = xkb->device_spec; 130 if (which&XkbSymInterpMask) 131 req->getAllSI= True; 132 else req->getAllSI= False; 133 req->firstSI= req->nSI= 0; 134 135 if (which&XkbGroupCompatMask) 136 req->groups= XkbAllGroupsMask; 137 else req->groups= 0; 138 139 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 140 UnlockDisplay(dpy); 141 SyncHandle(); 142 return BadLength; 143 } 144 if (xkb->dpy==NULL) 145 xkb->dpy= dpy; 146 if (xkb->device_spec==XkbUseCoreKbd) 147 xkb->device_spec= rep.deviceID; 148 149 status = _XkbReadGetCompatMapReply(dpy,&rep,xkb,NULL); 150 UnlockDisplay(dpy); 151 SyncHandle(); 152 return status; 153} 154 155static Bool 156_XkbWriteSetCompatMap(Display *dpy,xkbSetCompatMapReq *req,XkbDescPtr xkb) 157{ 158CARD16 firstSI; 159CARD16 nSI; 160int size; 161register int i,nGroups; 162register unsigned bit; 163unsigned groups; 164char * buf; 165 166 firstSI = req->firstSI; 167 nSI = req->nSI; 168 size= nSI*SIZEOF(xkbSymInterpretWireDesc); 169 nGroups= 0; 170 groups= req->groups; 171 if (groups&XkbAllGroupsMask) { 172 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 173 if (groups&bit) 174 nGroups++; 175 } 176 size+= SIZEOF(xkbModsWireDesc)*nGroups; 177 } 178 req->length+= size/4; 179 BufAlloc(char *,buf,size); 180 if (!buf) 181 return False; 182 183 if (nSI) { 184 XkbSymInterpretPtr sym= &xkb->compat->sym_interpret[firstSI]; 185 xkbSymInterpretWireDesc *wire= (xkbSymInterpretWireDesc *)buf; 186 for (i=0;i<nSI;i++,wire++,sym++) { 187 wire->sym= (CARD32)sym->sym; 188 wire->mods= sym->mods; 189 wire->match= sym->match; 190 wire->flags= sym->flags; 191 wire->virtualMod= sym->virtual_mod; 192 memcpy(&wire->act,&sym->act,sz_xkbActionWireDesc); 193 } 194 buf+= nSI*SIZEOF(xkbSymInterpretWireDesc); 195 } 196 if (groups&XkbAllGroupsMask) { 197 xkbModsWireDesc * out; 198 199 out= (xkbModsWireDesc *)buf; 200 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 201 if ((groups&bit)!=0) { 202 out->mask= xkb->compat->groups[i].mask; 203 out->realMods= xkb->compat->groups[i].real_mods; 204 out->virtualMods= xkb->compat->groups[i].vmods; 205 out++; 206 } 207 } 208 buf+= nGroups*SIZEOF(xkbModsWireDesc); 209 } 210 return True; 211} 212 213Bool 214XkbSetCompatMap(Display *dpy,unsigned which,XkbDescPtr xkb,Bool updateActions) 215{ 216 register xkbSetCompatMapReq *req; 217 Status ok; 218 XkbInfoPtr xkbi; 219 220 if ((dpy->flags & XlibDisplayNoXkb) || (dpy!=xkb->dpy) || 221 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 222 return False; 223 if ((!xkb->compat) || 224 ((which&XkbSymInterpMask)&&(!xkb->compat->sym_interpret))) 225 return False; 226 LockDisplay(dpy); 227 xkbi = dpy->xkb_info; 228 GetReq(kbSetCompatMap, req); 229 req->reqType = xkbi->codes->major_opcode; 230 req->xkbReqType = X_kbSetCompatMap; 231 req->deviceSpec = xkb->device_spec; 232 req->recomputeActions = updateActions; 233 if (which&XkbSymInterpMask) { 234 req->truncateSI = True; 235 req->firstSI= 0; 236 req->nSI= xkb->compat->num_si; 237 } 238 else { 239 req->truncateSI = False; 240 req->firstSI= 0; 241 req->nSI= 0; 242 } 243 if (which&XkbGroupCompatMask) 244 req->groups= XkbAllGroupsMask; 245 else req->groups= 0; 246 ok= _XkbWriteSetCompatMap(dpy,req,xkb); 247 UnlockDisplay(dpy); 248 SyncHandle(); 249 return ok; 250} 251 252