1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
32 #include <X11/extensions/XKBproto.h>
33 #include "XKBlibint.h"
36 _XkbSizeKeyTypes(XkbDescPtr xkb,xkbSetMapReq *req)
41 if (((req->present&XkbKeyTypesMask)==0)||(req->nTypes==0)) {
42 req->present&= ~XkbKeyTypesMask;
43 req->firstType= req->nTypes= 0;
47 map= &xkb->map->types[req->firstType];
48 for (i=0;i<req->nTypes;i++,map++){
49 len+= SIZEOF(xkbKeyTypeWireDesc);
50 len+= map->map_count*SIZEOF(xkbKTSetMapEntryWireDesc);
52 len+= map->map_count*SIZEOF(xkbModsWireDesc);
58 _XkbWriteKeyTypes(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
63 xkbKeyTypeWireDesc *desc;
65 if ((req->present&XkbKeyTypesMask)==0)
67 type= &xkb->map->types[req->firstType];
68 for (i=0;i<req->nTypes;i++,type++) {
69 sz= SIZEOF(xkbKeyTypeWireDesc);
70 sz+= type->map_count*SIZEOF(xkbKTSetMapEntryWireDesc);
72 sz+= type->map_count*SIZEOF(xkbModsWireDesc);
73 BufAlloc(xkbKeyTypeWireDesc *,desc,sz);
74 desc->mask = type->mods.mask;
75 desc->realMods = type->mods.real_mods;
76 desc->virtualMods = type->mods.vmods;
77 desc->numLevels = type->num_levels;
78 desc->nMapEntries = type->map_count;
79 desc->preserve = (type->preserve!=NULL);
80 buf= (char *)&desc[1];
81 if (desc->nMapEntries>0) {
82 xkbKTSetMapEntryWireDesc *wire;
83 wire= (xkbKTSetMapEntryWireDesc *)buf;
84 for (n=0;n<type->map_count;n++,wire++) {
85 wire->level= type->map[n].level;
86 wire->realMods= type->map[n].mods.real_mods;
87 wire->virtualMods= type->map[n].mods.vmods;
91 xkbModsWireDesc *pwire;
92 pwire= (xkbModsWireDesc *)buf;
93 for (n=0;n<type->map_count;n++,pwire++) {
94 pwire->realMods= type->preserve[n].real_mods;
95 pwire->virtualMods= type->preserve[n].vmods;
104 _XkbSizeKeySyms(XkbDescPtr xkb,xkbSetMapReq *req)
109 if (((req->present&XkbKeySymsMask)==0)||(req->nKeySyms==0)) {
110 req->present&= ~XkbKeySymsMask;
111 req->firstKeySym= req->nKeySyms= 0;
115 len= (int)(req->nKeySyms*sizeof(XkbSymMapRec));
116 for (i=nSyms=0;i<req->nKeySyms;i++) {
117 nSyms+= XkbKeyNumSyms(xkb,i+req->firstKeySym);
119 len+= nSyms*sizeof(CARD32);
120 req->totalSyms= nSyms;
125 _XkbWriteKeySyms(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
127 register KeySym * pSym;
130 xkbSymMapWireDesc *desc;
133 if ((req->present&XkbKeySymsMask)==0)
135 symMap = &xkb->map->key_sym_map[req->firstKeySym];
136 for (i=0;i<req->nKeySyms;i++,symMap++) {
137 BufAlloc(xkbSymMapWireDesc *,desc,
138 SIZEOF(xkbSymMapWireDesc)+
139 (XkbKeyNumSyms(xkb,i+req->firstKeySym)*sizeof(CARD32)));
140 desc->ktIndex[0] = symMap->kt_index[0];
141 desc->ktIndex[1] = symMap->kt_index[1];
142 desc->ktIndex[2] = symMap->kt_index[2];
143 desc->ktIndex[3] = symMap->kt_index[3];
144 desc->groupInfo = symMap->group_info;
145 desc->width = symMap->width;
146 desc->nSyms = XkbKeyNumSyms(xkb,i+req->firstKeySym);
147 outSym = (CARD32 *)&desc[1];
149 pSym = XkbKeySymsPtr(xkb,i+req->firstKeySym);
150 _XkbWriteCopyKeySyms(pSym,outSym,desc->nSyms);
157 _XkbSizeKeyActions(XkbDescPtr xkb,xkbSetMapReq *req)
161 if (((req->present&XkbKeyActionsMask)==0)||(req->nKeyActs==0)) {
162 req->present&= ~XkbKeyActionsMask;
163 req->firstKeyAct= req->nKeyActs= 0;
167 for (nActs=i=0;i<req->nKeyActs;i++) {
168 if (xkb->server->key_acts[i+req->firstKeyAct]!=0)
169 nActs+= XkbKeyNumActions(xkb,i+req->firstKeyAct);
171 len= XkbPaddedSize(req->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
172 req->totalActs= nActs;
177 _XkbWriteKeyActions(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
184 if ((req->present&XkbKeyActionsMask)==0)
186 n = XkbPaddedSize(req->nKeyActs);
187 n+= (req->totalActs*SIZEOF(xkbActionWireDesc));
189 BufAlloc(CARD8 *,numDesc,n);
190 for (i=0;i<req->nKeyActs;i++) {
191 if (xkb->server->key_acts[i+req->firstKeyAct]==0)
193 else numDesc[i] = XkbKeyNumActions(xkb,(i+req->firstKeyAct));
195 actDesc = (XkbAction *)&numDesc[XkbPaddedSize(req->nKeyActs)];
196 for (i=0;i<req->nKeyActs;i++) {
197 if (xkb->server->key_acts[i+req->firstKeyAct]!=0) {
198 n = XkbKeyNumActions(xkb,(i+req->firstKeyAct));
199 memcpy(actDesc,XkbKeyActionsPtr(xkb,(i+req->firstKeyAct)),
200 n*SIZEOF(xkbActionWireDesc));
208 _XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbSetMapReq *req)
210 register int i,first,last,nFound;
212 if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) {
213 req->present&= ~XkbKeyBehaviorsMask;
214 req->firstKeyBehavior= req->nKeyBehaviors= 0;
215 req->totalKeyBehaviors= 0;
218 first= req->firstKeyBehavior;
219 last= first+req->nKeyBehaviors-1;
220 for (i=first,nFound=0;i<=last;i++) {
221 if (xkb->server->behaviors[i].type!=XkbKB_Default)
224 req->totalKeyBehaviors= nFound;
225 return (nFound*SIZEOF(xkbBehaviorWireDesc));
229 _XkbWriteKeyBehaviors(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
231 register int i,first,last;
232 xkbBehaviorWireDesc * wire;
235 if ((req->present&XkbKeyBehaviorsMask)==0)
237 first= req->firstKeyBehavior;
238 last= first+req->nKeyBehaviors-1;
240 i= req->totalKeyBehaviors*SIZEOF(xkbBehaviorWireDesc);
241 BufAlloc(char *,buf,i);
242 wire= (xkbBehaviorWireDesc *)buf;
243 for (i=first;i<=last;i++) {
244 if (xkb->server->behaviors[i].type!=XkbKB_Default) {
246 wire->type= xkb->server->behaviors[i].type;
247 wire->data= xkb->server->behaviors[i].data;
248 buf+= SIZEOF(xkbBehaviorWireDesc);
249 wire= (xkbBehaviorWireDesc *)buf;
256 _XkbSizeVirtualMods(xkbSetMapReq *req)
258 register int i,bit,nMods;
260 if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) {
261 req->present&= ~XkbVirtualModsMask;
265 for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
266 if (req->virtualMods&bit)
269 return XkbPaddedSize(nMods);
273 _XkbWriteVirtualMods( Display * dpy,
281 /* This was req->present&XkbVirtualModsMask==0, and '==' beats '&' */
282 if (((req->present & XkbVirtualModsMask) == 0) || (size < 1))
284 BufAlloc(CARD8 *,vmods,size);
285 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
286 if (req->virtualMods&bit)
287 *vmods++= xkb->server->vmods[i];
293 _XkbSizeKeyExplicit(XkbDescPtr xkb,xkbSetMapReq *req)
295 register int i,first,last,nFound;
297 if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit==0)) {
298 req->present&= ~XkbExplicitComponentsMask;
299 req->firstKeyExplicit= req->nKeyExplicit= 0;
300 req->totalKeyExplicit= 0;
303 first= req->firstKeyExplicit;
304 last= first+req->nKeyExplicit-1;
306 for (i=first,nFound=0;i<=last;i++) {
307 if (xkb->server->explicit[i]!=0)
310 req->totalKeyExplicit= nFound;
311 return XkbPaddedSize((nFound*2));
315 _XkbWriteKeyExplicit(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
317 register int i,first,last;
320 if ((req->present&XkbExplicitComponentsMask)==0)
322 first= req->firstKeyExplicit;
323 last= first+req->nKeyExplicit - 1;
324 i= XkbPaddedSize((req->totalKeyExplicit*2));
325 BufAlloc(CARD8 *,wire,i);
326 for (i=first;i<=last;i++) {
327 if (xkb->server->explicit[i]!=0) {
329 wire[1]= xkb->server->explicit[i];
337 _XkbSizeModifierMap(XkbDescPtr xkb,xkbSetMapReq *req)
339 register int i,first,last,nFound;
341 if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys==0)) {
342 req->present&= ~XkbModifierMapMask;
343 req->firstModMapKey= req->nModMapKeys= 0;
344 req->totalModMapKeys= 0;
347 first= req->firstModMapKey;
348 last= first+req->nModMapKeys-1;
350 for (i=first,nFound=0;i<=last;i++) {
351 if (xkb->map->modmap[i]!=0)
354 req->totalModMapKeys= nFound;
355 return XkbPaddedSize((nFound*2));
359 _XkbWriteModifierMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
361 register int i,first,last;
364 if ((req->present&XkbModifierMapMask)==0)
366 first= req->firstModMapKey;
367 last= first+req->nModMapKeys-1;
368 if (req->totalModMapKeys>0) {
369 i= XkbPaddedSize((req->totalModMapKeys*2));
370 BufAlloc(CARD8 *,wire,i);
371 for (i=first;i<=last;i++) {
372 if (xkb->map->modmap[i]!=0) {
374 wire[1]= xkb->map->modmap[i];
383 _XkbSizeVirtualModMap(XkbDescPtr xkb,xkbSetMapReq *req)
385 register int i,first,last,nFound;
387 if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys==0)) {
388 req->present&= ~XkbVirtualModMapMask;
389 req->firstVModMapKey= req->nVModMapKeys= 0;
390 req->totalVModMapKeys= 0;
393 first= req->firstVModMapKey;
394 last= first+req->nVModMapKeys-1;
396 for (i=first,nFound=0;i<=last;i++) {
397 if (xkb->server->vmodmap[i]!=0)
400 req->totalVModMapKeys= nFound;
401 return nFound*SIZEOF(xkbVModMapWireDesc);
405 _XkbWriteVirtualModMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
407 register int i,first,last;
408 xkbVModMapWireDesc * wire;
410 if ((req->present&XkbVirtualModMapMask)==0)
412 first= req->firstVModMapKey;
413 last= first+req->nVModMapKeys-1;
414 if (req->totalVModMapKeys>0) {
415 i= req->totalVModMapKeys*SIZEOF(xkbVModMapWireDesc);
416 BufAlloc(xkbVModMapWireDesc *,wire,i);
417 for (i=first;i<=last;i++) {
418 if (xkb->server->vmodmap[i]!=0) {
420 wire->vmods= xkb->server->vmodmap[i];
429 SendSetMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
434 req->length+= _XkbSizeKeyTypes(xkb,req)/4;
435 req->length+= _XkbSizeKeySyms(xkb,req)/4;
436 req->length+= _XkbSizeKeyActions(xkb,req)/4;
437 req->length+= _XkbSizeKeyBehaviors(xkb,req)/4;
438 szMods= _XkbSizeVirtualMods(req);
439 req->length+= szMods/4;
440 req->length+= _XkbSizeKeyExplicit(xkb,req)/4;
441 req->length+= _XkbSizeModifierMap(xkb,req)/4;
442 req->length+= _XkbSizeVirtualModMap(xkb,req)/4;
446 _XkbWriteKeyTypes(dpy,xkb,&tmp);
447 if ( tmp.nKeySyms>0 )
448 _XkbWriteKeySyms(dpy,xkb,&tmp);
450 _XkbWriteKeyActions(dpy,xkb,&tmp);
451 if ( tmp.totalKeyBehaviors>0 )
452 _XkbWriteKeyBehaviors(dpy,xkb,&tmp);
453 if ( tmp.virtualMods )
454 _XkbWriteVirtualMods(dpy,xkb,&tmp,szMods);
455 if ( tmp.totalKeyExplicit>0)
456 _XkbWriteKeyExplicit(dpy,xkb,&tmp);
457 if ( tmp.totalModMapKeys>0)
458 _XkbWriteModifierMap(dpy,xkb,&tmp);
459 if ( tmp.totalVModMapKeys>0)
460 _XkbWriteVirtualModMap(dpy,xkb,&tmp);
465 XkbSetMap(Display *dpy,unsigned which,XkbDescPtr xkb)
467 register xkbSetMapReq * req;
472 if ((dpy->flags & XlibDisplayNoXkb) ||
473 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))||
479 if (((which&XkbKeyTypesMask)&&((!map)||(!map->types)))||
480 ((which&XkbKeySymsMask)&&((!map)||(!map->syms)||(!map->key_sym_map)))||
481 ((which&XkbKeyActionsMask)&&((!srv)||(!srv->key_acts)))||
482 ((which&XkbKeyBehaviorsMask)&&((!srv)||(!srv->behaviors)))||
483 ((which&XkbVirtualModsMask)&&(!srv))||
484 ((which&XkbExplicitComponentsMask)&&((!srv)||(!srv->explicit)))||
485 ((which&XkbModifierMapMask)&&((!map)||(!map->modmap)))||
486 ((which&XkbVirtualModMapMask)&&((!srv)||(!srv->vmodmap))))
490 xkbi = dpy->xkb_info;
491 GetReq(kbSetMap, req);
492 req->reqType = xkbi->codes->major_opcode;
493 req->xkbReqType = X_kbSetMap;
494 req->deviceSpec = xkb->device_spec;
495 req->present = which;
496 req->flags = XkbSetMapAllFlags;
497 req->minKeyCode= xkb->min_key_code;
498 req->maxKeyCode= xkb->max_key_code;
500 if (which&XkbKeyTypesMask) req->nTypes = map->num_types;
501 else req->nTypes = 0;
502 if (which&XkbKeySymsMask) {
503 req->firstKeySym = xkb->min_key_code;
504 req->nKeySyms = XkbNumKeys(xkb);
506 if (which&XkbKeyActionsMask) {
507 req->firstKeyAct = xkb->min_key_code;
508 req->nKeyActs = XkbNumKeys(xkb);
510 if (which&XkbKeyBehaviorsMask) {
511 req->firstKeyBehavior = xkb->min_key_code;
512 req->nKeyBehaviors = XkbNumKeys(xkb);
514 if (which&XkbVirtualModsMask)
515 req->virtualMods= ~0;
516 if (which&XkbExplicitComponentsMask) {
517 req->firstKeyExplicit= xkb->min_key_code;
518 req->nKeyExplicit = XkbNumKeys(xkb);
520 if (which&XkbModifierMapMask) {
521 req->firstModMapKey= xkb->min_key_code;
522 req->nModMapKeys = XkbNumKeys(xkb);
524 if (which&XkbVirtualModMapMask) {
525 req->firstVModMapKey= xkb->min_key_code;
526 req->nVModMapKeys = XkbNumKeys(xkb);
528 SendSetMap(dpy,xkb,req);
535 XkbChangeMap(Display *dpy,XkbDescPtr xkb,XkbMapChangesPtr changes)
537 register xkbSetMapReq * req;
542 if ((dpy->flags & XlibDisplayNoXkb) ||
543 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))||
549 if (((changes->changed&XkbKeyTypesMask)&&((!map)||(!map->types)))||
550 ((changes->changed&XkbKeySymsMask)&&((!map)||(!map->syms)||
551 (!map->key_sym_map)))||
552 ((changes->changed&XkbKeyActionsMask)&&((!srv)||(!srv->key_acts)))||
553 ((changes->changed&XkbKeyBehaviorsMask)&&((!srv)||(!srv->behaviors)))||
554 ((changes->changed&XkbVirtualModsMask)&&(!srv))||
555 ((changes->changed&XkbExplicitComponentsMask)&&
556 ((!srv)||(!srv->explicit)))||
557 ((changes->changed&XkbModifierMapMask)&&((!map)||(!map->modmap)))||
558 ((changes->changed&XkbVirtualModMapMask)&&((!srv)||(!srv->vmodmap))))
562 xkbi = dpy->xkb_info;
563 GetReq(kbSetMap, req);
564 req->reqType = xkbi->codes->major_opcode;
565 req->xkbReqType = X_kbSetMap;
566 req->deviceSpec = xkb->device_spec;
567 req->present = changes->changed;
568 req->flags = XkbSetMapRecomputeActions;
569 req->minKeyCode= xkb->min_key_code;
570 req->maxKeyCode= xkb->max_key_code;
571 req->firstType = changes->first_type;
572 req->nTypes = changes->num_types;
573 req->firstKeySym = changes->first_key_sym;
574 req->nKeySyms = changes->num_key_syms;
575 req->firstKeyAct = changes->first_key_act;
576 req->nKeyActs = changes->num_key_acts;
577 req->firstKeyBehavior = changes->first_key_behavior;
578 req->nKeyBehaviors = changes->num_key_behaviors;
579 req->virtualMods = changes->vmods;
580 req->firstKeyExplicit = changes->first_key_explicit;
581 req->nKeyExplicit = changes->num_key_explicit;
582 req->firstModMapKey = changes->first_modmap_key;
583 req->nModMapKeys = changes->num_modmap_keys;
584 req->firstVModMapKey = changes->first_vmodmap_key;
585 req->nVModMapKeys = changes->num_vmodmap_keys;
586 SendSetMap(dpy,xkb,req);