First import
[xorg_rtime.git] / xorg-server-1.4 / xkb / xkbUtils.c
blobc7f9a2681663ec684257e9844b13e4ee1a22055a
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 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
31 #include "os.h"
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <math.h>
35 #define NEED_EVENTS 1
36 #include <X11/X.h>
37 #include <X11/Xproto.h>
38 #define XK_CYRILLIC
39 #include <X11/keysym.h>
40 #include "misc.h"
41 #include "inputstr.h"
43 #define XKBSRV_NEED_FILE_FUNCS
44 #include <xkbsrv.h>
45 #include <X11/extensions/XKBgeom.h>
46 #include "xkb.h"
48 int XkbDisableLockActions = 0;
50 /***====================================================================***/
52 DeviceIntPtr
53 _XkbLookupAnyDevice(int id,int *why_rtrn)
55 DeviceIntPtr dev = NULL;
57 dev= (DeviceIntPtr)LookupKeyboardDevice();
58 if ((id==XkbUseCoreKbd)||(dev->id==id))
59 return dev;
61 dev= (DeviceIntPtr)LookupPointerDevice();
62 if ((id==XkbUseCorePtr)||(dev->id==id))
63 return dev;
65 if (id&(~0xff))
66 dev = NULL;
68 dev= (DeviceIntPtr)LookupDevice(id);
69 if (dev!=NULL)
70 return dev;
71 if ((!dev)&&(why_rtrn))
72 *why_rtrn= XkbErr_BadDevice;
73 return dev;
76 DeviceIntPtr
77 _XkbLookupKeyboard(int id,int *why_rtrn)
79 DeviceIntPtr dev = NULL;
81 if (id == XkbDfltXIId)
82 id = XkbUseCoreKbd;
83 if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
84 return NULL;
85 else if ((!dev->key)||(!dev->key->xkbInfo)) {
86 if (why_rtrn)
87 *why_rtrn= XkbErr_BadClass;
88 return NULL;
90 return dev;
93 DeviceIntPtr
94 _XkbLookupBellDevice(int id,int *why_rtrn)
96 DeviceIntPtr dev = NULL;
98 if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
99 return NULL;
100 else if ((!dev->kbdfeed)&&(!dev->bell)) {
101 if (why_rtrn)
102 *why_rtrn= XkbErr_BadClass;
103 return NULL;
105 return dev;
108 DeviceIntPtr
109 _XkbLookupLedDevice(int id,int *why_rtrn)
111 DeviceIntPtr dev = NULL;
113 if (id == XkbDfltXIId)
114 id = XkbUseCorePtr;
115 if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
116 return NULL;
117 else if ((!dev->kbdfeed)&&(!dev->leds)) {
118 if (why_rtrn)
119 *why_rtrn= XkbErr_BadClass;
120 return NULL;
122 return dev;
125 DeviceIntPtr
126 _XkbLookupButtonDevice(int id,int *why_rtrn)
128 DeviceIntPtr dev = NULL;
130 if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
131 return NULL;
132 else if (!dev->button) {
133 if (why_rtrn)
134 *why_rtrn= XkbErr_BadClass;
135 return NULL;
137 return dev;
140 void
141 XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
143 register unsigned tmp;
145 switch (act->type) {
146 case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
147 if (act->mods.flags&XkbSA_UseModMapMods)
148 act->mods.real_mods= act->mods.mask= mods;
149 if ((tmp= XkbModActionVMods(&act->mods))!=0)
150 act->mods.mask|= XkbMaskForVMask(xkb,tmp);
151 break;
152 case XkbSA_ISOLock:
153 if (act->iso.flags&XkbSA_UseModMapMods)
154 act->iso.real_mods= act->iso.mask= mods;
155 if ((tmp= XkbModActionVMods(&act->iso))!=0)
156 act->iso.mask|= XkbMaskForVMask(xkb,tmp);
157 break;
159 return;
162 unsigned
163 XkbMaskForVMask(XkbDescPtr xkb,unsigned vmask)
165 register int i,bit;
166 register unsigned mask;
168 for (mask=i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
169 if (vmask&bit)
170 mask|= xkb->server->vmods[i];
172 return mask;
175 /***====================================================================***/
177 void
178 XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev,
179 KeyCode first,
180 CARD8 num,
181 XkbChangesPtr changes)
183 XkbDescPtr xkb;
184 unsigned key,nG,explicit;
185 KeySymsPtr pCore;
186 int types[XkbNumKbdGroups];
187 KeySym tsyms[XkbMaxSymsPerKey],*syms;
188 XkbMapChangesPtr mc;
190 xkb= pXDev->key->xkbInfo->desc;
191 #ifdef NOTYET
192 if (first<xkb->min_key_code) {
193 if (first>=XkbMinLegalKeyCode) {
194 xkb->min_key_code= first;
195 /* 1/12/95 (ef) -- XXX! should zero out the new maps */
196 changes->map.changed|= XkbKeycodesMask;
197 /* generate a NewKeyboard notify here? */
200 #endif
201 if (first+num-1>xkb->max_key_code) {
202 /* 1/12/95 (ef) -- XXX! should allow XKB structures to grow */
203 num= xkb->max_key_code-first+1;
206 mc= (changes?(&changes->map):NULL);
208 pCore= &pXDev->key->curKeySyms;
209 syms= &pCore->map[(first-xkb->min_key_code)*pCore->mapWidth];
210 for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) {
211 explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
212 types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
213 types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
214 types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
215 types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
216 nG= XkbKeyTypesForCoreSymbols(xkb,pCore->mapWidth,syms,explicit,types,
217 tsyms);
218 XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
219 memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
220 XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
222 if (changes->map.changed&XkbKeySymsMask) {
223 CARD8 oldLast,newLast;
224 oldLast = changes->map.first_key_sym+changes->map.num_key_syms-1;
225 newLast = first+num-1;
227 if (first<changes->map.first_key_sym)
228 changes->map.first_key_sym = first;
229 if (oldLast>newLast)
230 newLast= oldLast;
231 changes->map.num_key_syms = newLast-changes->map.first_key_sym+1;
233 else {
234 changes->map.changed|= XkbKeySymsMask;
235 changes->map.first_key_sym = first;
236 changes->map.num_key_syms = num;
238 return;
241 void
242 XkbUpdateDescActions( XkbDescPtr xkb,
243 KeyCode first,
244 CARD8 num,
245 XkbChangesPtr changes)
247 register unsigned key;
249 for (key=first;key<(first+num);key++) {
250 XkbApplyCompatMapToKey(xkb,key,changes);
253 if (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask)) {
254 unsigned char newVMods[XkbNumVirtualMods];
255 register unsigned bit,i;
256 unsigned present;
258 bzero(newVMods,XkbNumVirtualMods);
259 present= 0;
260 for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
261 if (xkb->server->vmodmap[key]==0)
262 continue;
263 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
264 if (bit&xkb->server->vmodmap[key]) {
265 present|= bit;
266 newVMods[i]|= xkb->map->modmap[key];
270 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
271 if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
272 changes->map.changed|= XkbVirtualModsMask;
273 changes->map.vmods|= bit;
274 xkb->server->vmods[i]= newVMods[i];
278 if (changes->map.changed&XkbVirtualModsMask)
279 XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
281 if (changes->map.changed&XkbKeyActionsMask) {
282 CARD8 oldLast,newLast;
283 oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
284 newLast = first+num-1;
286 if (first<changes->map.first_key_act)
287 changes->map.first_key_act = first;
288 if (newLast>oldLast)
289 newLast= oldLast;
290 changes->map.num_key_acts= newLast-changes->map.first_key_act+1;
292 else {
293 changes->map.changed|= XkbKeyActionsMask;
294 changes->map.first_key_act = first;
295 changes->map.num_key_acts = num;
297 return;
300 void
301 XkbUpdateActions( DeviceIntPtr pXDev,
302 KeyCode first,
303 CARD8 num,
304 XkbChangesPtr changes,
305 unsigned * needChecksRtrn,
306 XkbEventCausePtr cause)
308 XkbSrvInfoPtr xkbi;
309 XkbDescPtr xkb;
310 CARD8 * repeat;
312 if (needChecksRtrn)
313 *needChecksRtrn= 0;
314 xkbi= pXDev->key->xkbInfo;
315 xkb= xkbi->desc;
316 repeat= xkb->ctrls->per_key_repeat;
318 if (pXDev->kbdfeed)
319 memcpy(repeat,pXDev->kbdfeed->ctrl.autoRepeats,32);
321 XkbUpdateDescActions(xkb,first,num,changes);
323 if ((pXDev->kbdfeed)&&
324 (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) {
325 memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, 32);
326 (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl);
328 return;
331 void
332 XkbUpdateCoreDescription(DeviceIntPtr keybd,Bool resize)
334 register int key,tmp;
335 int maxSymsPerKey,maxKeysPerMod;
336 int first,last,firstCommon,lastCommon;
337 XkbDescPtr xkb;
338 KeyClassPtr keyc;
339 CARD8 keysPerMod[XkbNumModifiers];
341 if (!keybd || !keybd->key || !keybd->key->xkbInfo)
342 return;
343 xkb= keybd->key->xkbInfo->desc;
344 keyc= keybd->key;
345 maxSymsPerKey= maxKeysPerMod= 0;
346 bzero(keysPerMod,sizeof(keysPerMod));
347 memcpy(keyc->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
348 if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&&
349 (xkb->max_key_code==keyc->curKeySyms.maxKeyCode)) {
350 first= firstCommon= xkb->min_key_code;
351 last= lastCommon= xkb->max_key_code;
353 else if (resize) {
354 keyc->curKeySyms.minKeyCode= xkb->min_key_code;
355 keyc->curKeySyms.maxKeyCode= xkb->max_key_code;
356 tmp= keyc->curKeySyms.mapWidth*_XkbCoreNumKeys(keyc);
357 keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym);
358 if (!keyc->curKeySyms.map)
359 FatalError("Couldn't allocate keysyms\n");
360 first= firstCommon= xkb->min_key_code;
361 last= lastCommon= xkb->max_key_code;
363 else {
364 if (xkb->min_key_code<keyc->curKeySyms.minKeyCode) {
365 first= xkb->min_key_code;
366 firstCommon= keyc->curKeySyms.minKeyCode;
368 else {
369 firstCommon= xkb->min_key_code;
370 first= keyc->curKeySyms.minKeyCode;
372 if (xkb->max_key_code>keyc->curKeySyms.maxKeyCode) {
373 lastCommon= keyc->curKeySyms.maxKeyCode;
374 last= xkb->max_key_code;
376 else {
377 lastCommon= xkb->max_key_code;
378 last= keyc->curKeySyms.maxKeyCode;
382 /* determine sizes */
383 for (key=first;key<=last;key++) {
384 if (XkbKeycodeInRange(xkb,key)) {
385 int nGroups;
386 int w;
387 nGroups= XkbKeyNumGroups(xkb,key);
388 tmp= 0;
389 if (nGroups>0) {
390 if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<=2)
391 tmp+= 2;
392 else tmp+= w + 2;
394 if (nGroups>1) {
395 if (tmp <= 2) {
396 if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))<2)
397 tmp+= 2;
398 else tmp+= w;
399 } else {
400 if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))>2)
401 tmp+= w - 2;
404 if (nGroups>2)
405 tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup3Index);
406 if (nGroups>3)
407 tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index);
408 if (tmp>maxSymsPerKey)
409 maxSymsPerKey= tmp;
411 if (_XkbCoreKeycodeInRange(keyc,key)) {
412 if (keyc->modifierMap[key]!=0) {
413 register unsigned bit,i,mask;
414 mask= keyc->modifierMap[key];
415 for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
416 if (mask&bit) {
417 keysPerMod[i]++;
418 if (keysPerMod[i]>maxKeysPerMod)
419 maxKeysPerMod= keysPerMod[i];
426 if (maxKeysPerMod>0) {
427 tmp= maxKeysPerMod*XkbNumModifiers;
428 if (keyc->modifierKeyMap==NULL)
429 keyc->modifierKeyMap= (KeyCode *)_XkbCalloc(1, tmp);
430 else if (keyc->maxKeysPerModifier<maxKeysPerMod)
431 keyc->modifierKeyMap= (KeyCode *)_XkbRealloc(keyc->modifierKeyMap,tmp);
432 if (keyc->modifierKeyMap==NULL)
433 FatalError("Couldn't allocate modifierKeyMap in UpdateCore\n");
434 bzero(keyc->modifierKeyMap,tmp);
436 else if ((keyc->maxKeysPerModifier>0)&&(keyc->modifierKeyMap!=NULL)) {
437 _XkbFree(keyc->modifierKeyMap);
438 keyc->modifierKeyMap= NULL;
440 keyc->maxKeysPerModifier= maxKeysPerMod;
442 if (maxSymsPerKey>0) {
443 tmp= maxSymsPerKey*_XkbCoreNumKeys(keyc);
444 keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym);
445 if (keyc->curKeySyms.map==NULL)
446 FatalError("Couldn't allocate symbols map in UpdateCore\n");
448 else if ((keyc->curKeySyms.mapWidth>0)&&(keyc->curKeySyms.map!=NULL)) {
449 _XkbFree(keyc->curKeySyms.map);
450 keyc->curKeySyms.map= NULL;
452 keyc->curKeySyms.mapWidth= maxSymsPerKey;
454 bzero(keysPerMod,sizeof(keysPerMod));
455 for (key=firstCommon;key<=lastCommon;key++) {
456 if (keyc->curKeySyms.map!=NULL) {
457 KeySym *pCore,*pXKB;
458 unsigned nGroups,groupWidth,n,nOut;
460 nGroups= XkbKeyNumGroups(xkb,key);
461 n= (key-keyc->curKeySyms.minKeyCode)*maxSymsPerKey;
462 pCore= &keyc->curKeySyms.map[n];
463 bzero(pCore,maxSymsPerKey*sizeof(KeySym));
464 pXKB= XkbKeySymsPtr(xkb,key);
465 nOut= 2;
466 if (nGroups>0) {
467 groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index);
468 if (groupWidth>0) pCore[0]= pXKB[0];
469 if (groupWidth>1) pCore[1]= pXKB[1];
470 for (n=2;n<groupWidth;n++) {
471 pCore[2+n]= pXKB[n];
473 if (groupWidth>2)
474 nOut= groupWidth;
476 pXKB+= XkbKeyGroupsWidth(xkb,key);
477 nOut+= 2;
478 if (nGroups>1) {
479 groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index);
480 if (groupWidth>0) pCore[2]= pXKB[0];
481 if (groupWidth>1) pCore[3]= pXKB[1];
482 for (n=2;n<groupWidth;n++) {
483 pCore[nOut+(n-2)]= pXKB[n];
485 if (groupWidth>2)
486 nOut+= (groupWidth-2);
488 pXKB+= XkbKeyGroupsWidth(xkb,key);
489 for (n=XkbGroup3Index;n<nGroups;n++) {
490 register int s;
491 groupWidth= XkbKeyGroupWidth(xkb,key,n);
492 for (s=0;s<groupWidth;s++) {
493 pCore[nOut++]= pXKB[s];
495 pXKB+= XkbKeyGroupsWidth(xkb,key);
497 if (!pCore[2] && !pCore[3] && maxSymsPerKey >= 6 &&
498 (pCore[4] || pCore[5])) {
499 pCore[2] = pCore[4];
500 pCore[3] = pCore[5];
503 if (keyc->modifierMap[key]!=0) {
504 register unsigned bit,i,mask;
505 mask= keyc->modifierMap[key];
506 for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
507 if (mask&bit) {
508 tmp= i*maxKeysPerMod+keysPerMod[i];
509 keyc->modifierKeyMap[tmp]= key;
510 keysPerMod[i]++;
515 return;
518 void
519 XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff)
521 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
522 xkbControlsNotify cn;
523 XkbControlsPtr ctrls = pXDev->key->xkbInfo->desc->ctrls;
524 XkbControlsRec old;
525 old = *ctrls;
527 if (key== -1) { /* global autorepeat setting changed */
528 if (onoff) ctrls->enabled_ctrls |= XkbRepeatKeysMask;
529 else ctrls->enabled_ctrls &= ~XkbRepeatKeysMask;
531 else if (pXDev->kbdfeed) {
532 ctrls->per_key_repeat[key/8] =
533 pXDev->kbdfeed->ctrl.autoRepeats[key/8];
536 if (XkbComputeControlsNotify(pXDev,&old,ctrls,&cn,True))
537 XkbSendControlsNotify(pXDev,&cn);
539 return;
542 void
543 XkbApplyMappingChange( DeviceIntPtr kbd,
544 CARD8 request,
545 KeyCode firstKey,
546 CARD8 num,
547 ClientPtr client)
549 XkbEventCauseRec cause;
550 XkbChangesRec changes;
551 unsigned check;
553 if (kbd->key->xkbInfo==NULL)
554 XkbInitDevice(kbd);
555 bzero(&changes,sizeof(XkbChangesRec));
556 check= 0;
557 if (request==MappingKeyboard) {
558 XkbSetCauseCoreReq(&cause,X_ChangeKeyboardMapping,client);
559 XkbUpdateKeyTypesFromCore(kbd,firstKey,num,&changes);
560 XkbUpdateActions(kbd,firstKey,num,&changes,&check,&cause);
561 if (check)
562 XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause);
564 else if (request==MappingModifier) {
565 XkbDescPtr xkb= kbd->key->xkbInfo->desc;
567 XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client);
569 num = xkb->max_key_code-xkb->min_key_code+1;
570 memcpy(xkb->map->modmap,kbd->key->modifierMap,xkb->max_key_code+1);
572 changes.map.changed|= XkbModifierMapMask;
573 changes.map.first_modmap_key= xkb->min_key_code;
574 changes.map.num_modmap_keys= num;
575 XkbUpdateActions(kbd,xkb->min_key_code,num,&changes,&check,&cause);
576 if (check)
577 XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause);
579 /* 3/26/94 (ef) -- XXX! Doesn't deal with input extension requests */
580 XkbSendNotification(kbd,&changes,&cause);
581 return;
584 void
585 XkbDisableComputedAutoRepeats(DeviceIntPtr dev,unsigned key)
587 XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
588 xkbMapNotify mn;
590 xkbi->desc->server->explicit[key]|= XkbExplicitAutoRepeatMask;
591 bzero(&mn,sizeof(mn));
592 mn.changed= XkbExplicitComponentsMask;
593 mn.firstKeyExplicit= key;
594 mn.nKeyExplicit= 1;
595 XkbSendMapNotify(dev,&mn);
596 return;
599 unsigned
600 XkbStateChangedFlags(XkbStatePtr old,XkbStatePtr new)
602 int changed;
604 changed=(old->group!=new->group?XkbGroupStateMask:0);
605 changed|=(old->base_group!=new->base_group?XkbGroupBaseMask:0);
606 changed|=(old->latched_group!=new->latched_group?XkbGroupLatchMask:0);
607 changed|=(old->locked_group!=new->locked_group?XkbGroupLockMask:0);
608 changed|=(old->mods!=new->mods?XkbModifierStateMask:0);
609 changed|=(old->base_mods!=new->base_mods?XkbModifierBaseMask:0);
610 changed|=(old->latched_mods!=new->latched_mods?XkbModifierLatchMask:0);
611 changed|=(old->locked_mods!=new->locked_mods?XkbModifierLockMask:0);
612 changed|=(old->compat_state!=new->compat_state?XkbCompatStateMask:0);
613 changed|=(old->grab_mods!=new->grab_mods?XkbGrabModsMask:0);
614 if (old->compat_grab_mods!=new->compat_grab_mods)
615 changed|= XkbCompatGrabModsMask;
616 changed|=(old->lookup_mods!=new->lookup_mods?XkbLookupModsMask:0);
617 if (old->compat_lookup_mods!=new->compat_lookup_mods)
618 changed|= XkbCompatLookupModsMask;
619 changed|=(old->ptr_buttons!=new->ptr_buttons?XkbPointerButtonMask:0);
620 return changed;
623 static void
624 XkbComputeCompatState(XkbSrvInfoPtr xkbi)
626 CARD16 grp_mask;
627 XkbStatePtr state= &xkbi->state;
628 XkbCompatMapPtr map;
630 if (!state || !xkbi->desc || !xkbi->desc->ctrls || !xkbi->desc->compat)
631 return;
633 map= xkbi->desc->compat;
634 grp_mask= map->groups[state->group].mask;
635 state->compat_state = state->mods|grp_mask;
636 state->compat_lookup_mods= state->lookup_mods|grp_mask;
638 if (xkbi->desc->ctrls->enabled_ctrls&XkbIgnoreGroupLockMask)
639 grp_mask= map->groups[state->base_group].mask;
640 state->compat_grab_mods= state->grab_mods|grp_mask;
641 return;
644 unsigned
645 XkbAdjustGroup(int group,XkbControlsPtr ctrls)
647 unsigned act;
649 act= XkbOutOfRangeGroupAction(ctrls->groups_wrap);
650 if (group<0) {
651 while ( group < 0 ) {
652 if (act==XkbClampIntoRange) {
653 group= XkbGroup1Index;
655 else if (act==XkbRedirectIntoRange) {
656 int newGroup;
657 newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
658 if (newGroup>=ctrls->num_groups)
659 group= XkbGroup1Index;
660 else group= newGroup;
662 else {
663 group+= ctrls->num_groups;
667 else if (group>=ctrls->num_groups) {
668 if (act==XkbClampIntoRange) {
669 group= ctrls->num_groups-1;
671 else if (act==XkbRedirectIntoRange) {
672 int newGroup;
673 newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
674 if (newGroup>=ctrls->num_groups)
675 group= XkbGroup1Index;
676 else group= newGroup;
678 else {
679 group%= ctrls->num_groups;
682 return group;
685 void
686 XkbComputeDerivedState(XkbSrvInfoPtr xkbi)
688 XkbStatePtr state= &xkbi->state;
689 XkbControlsPtr ctrls= xkbi->desc->ctrls;
690 unsigned char grp;
692 if (!state || !ctrls)
693 return;
695 state->mods= (state->base_mods|state->latched_mods);
696 state->mods|= state->locked_mods;
697 state->lookup_mods= state->mods&(~ctrls->internal.mask);
698 state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask);
699 state->grab_mods|=
700 ((state->base_mods|state->latched_mods)&ctrls->ignore_lock.mask);
703 grp= state->locked_group;
704 if (grp>=ctrls->num_groups)
705 state->locked_group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
707 grp= state->locked_group+state->base_group+state->latched_group;
708 if (grp>=ctrls->num_groups)
709 state->group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
710 else state->group= grp;
711 XkbComputeCompatState(xkbi);
712 return;
715 /***====================================================================***/
717 void
718 XkbCheckSecondaryEffects( XkbSrvInfoPtr xkbi,
719 unsigned which,
720 XkbChangesPtr changes,
721 XkbEventCausePtr cause)
723 if (which&XkbStateNotifyMask) {
724 XkbStateRec old;
725 old= xkbi->state;
726 changes->state_changes|= XkbStateChangedFlags(&old,&xkbi->state);
727 XkbComputeDerivedState(xkbi);
729 if (which&XkbIndicatorStateNotifyMask)
730 XkbUpdateIndicators(xkbi->device,XkbAllIndicatorsMask,True,changes,
731 cause);
732 return;
735 /***====================================================================***/
737 Bool
738 XkbEnableDisableControls( XkbSrvInfoPtr xkbi,
739 unsigned long change,
740 unsigned long newValues,
741 XkbChangesPtr changes,
742 XkbEventCausePtr cause)
744 XkbControlsPtr ctrls;
745 unsigned old;
746 XkbSrvLedInfoPtr sli;
748 ctrls= xkbi->desc->ctrls;
749 old= ctrls->enabled_ctrls;
750 ctrls->enabled_ctrls&= ~change;
751 ctrls->enabled_ctrls|= (change&newValues);
752 if (old==ctrls->enabled_ctrls)
753 return False;
754 if (cause!=NULL) {
755 xkbControlsNotify cn;
756 cn.numGroups= ctrls->num_groups;
757 cn.changedControls|= XkbControlsEnabledMask;
758 cn.enabledControls= ctrls->enabled_ctrls;
759 cn.enabledControlChanges= (ctrls->enabled_ctrls^old);
760 cn.keycode= cause->kc;
761 cn.eventType= cause->event;
762 cn.requestMajor= cause->mjr;
763 cn.requestMinor= cause->mnr;
764 XkbSendControlsNotify(xkbi->device,&cn);
766 else {
767 /* Yes, this really should be an XOR. If ctrls->enabled_ctrls_changes*/
768 /* is non-zero, the controls in question changed already in "this" */
769 /* request and this change merely undoes the previous one. By the */
770 /* same token, we have to figure out whether or not ControlsEnabled */
771 /* should be set or not in the changes structure */
772 changes->ctrls.enabled_ctrls_changes^= (ctrls->enabled_ctrls^old);
773 if (changes->ctrls.enabled_ctrls_changes)
774 changes->ctrls.changed_ctrls|= XkbControlsEnabledMask;
775 else changes->ctrls.changed_ctrls&= ~XkbControlsEnabledMask;
777 sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
778 XkbUpdateIndicators(xkbi->device,sli->usesControls,True,changes,cause);
779 return True;
782 /***====================================================================***/
784 #define MAX_TOC 16
786 XkbGeometryPtr
787 XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree)
789 XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
790 XkbDescPtr xkb= xkbi->desc;
792 *shouldFree= 0;
793 if (name==None) {
794 if (xkb->geom!=NULL)
795 return xkb->geom;
796 name= xkb->names->geometry;
798 if ((xkb->geom!=NULL)&&(xkb->geom->name==name))
799 return xkb->geom;
800 *shouldFree= 1;
801 return NULL;
804 void
805 XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper)
807 *lower = sym;
808 *upper = sym;
809 switch(sym >> 8) {
810 case 0: /* Latin 1 */
811 if ((sym >= XK_A) && (sym <= XK_Z))
812 *lower += (XK_a - XK_A);
813 else if ((sym >= XK_a) && (sym <= XK_z))
814 *upper -= (XK_a - XK_A);
815 else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
816 *lower += (XK_agrave - XK_Agrave);
817 else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
818 *upper -= (XK_agrave - XK_Agrave);
819 else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
820 *lower += (XK_oslash - XK_Ooblique);
821 else if ((sym >= XK_oslash) && (sym <= XK_thorn))
822 *upper -= (XK_oslash - XK_Ooblique);
823 break;
824 case 1: /* Latin 2 */
825 /* Assume the KeySym is a legal value (ignore discontinuities) */
826 if (sym == XK_Aogonek)
827 *lower = XK_aogonek;
828 else if (sym >= XK_Lstroke && sym <= XK_Sacute)
829 *lower += (XK_lstroke - XK_Lstroke);
830 else if (sym >= XK_Scaron && sym <= XK_Zacute)
831 *lower += (XK_scaron - XK_Scaron);
832 else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
833 *lower += (XK_zcaron - XK_Zcaron);
834 else if (sym == XK_aogonek)
835 *upper = XK_Aogonek;
836 else if (sym >= XK_lstroke && sym <= XK_sacute)
837 *upper -= (XK_lstroke - XK_Lstroke);
838 else if (sym >= XK_scaron && sym <= XK_zacute)
839 *upper -= (XK_scaron - XK_Scaron);
840 else if (sym >= XK_zcaron && sym <= XK_zabovedot)
841 *upper -= (XK_zcaron - XK_Zcaron);
842 else if (sym >= XK_Racute && sym <= XK_Tcedilla)
843 *lower += (XK_racute - XK_Racute);
844 else if (sym >= XK_racute && sym <= XK_tcedilla)
845 *upper -= (XK_racute - XK_Racute);
846 break;
847 case 2: /* Latin 3 */
848 /* Assume the KeySym is a legal value (ignore discontinuities) */
849 if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
850 *lower += (XK_hstroke - XK_Hstroke);
851 else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
852 *lower += (XK_gbreve - XK_Gbreve);
853 else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
854 *upper -= (XK_hstroke - XK_Hstroke);
855 else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
856 *upper -= (XK_gbreve - XK_Gbreve);
857 else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
858 *lower += (XK_cabovedot - XK_Cabovedot);
859 else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
860 *upper -= (XK_cabovedot - XK_Cabovedot);
861 break;
862 case 3: /* Latin 4 */
863 /* Assume the KeySym is a legal value (ignore discontinuities) */
864 if (sym >= XK_Rcedilla && sym <= XK_Tslash)
865 *lower += (XK_rcedilla - XK_Rcedilla);
866 else if (sym >= XK_rcedilla && sym <= XK_tslash)
867 *upper -= (XK_rcedilla - XK_Rcedilla);
868 else if (sym == XK_ENG)
869 *lower = XK_eng;
870 else if (sym == XK_eng)
871 *upper = XK_ENG;
872 else if (sym >= XK_Amacron && sym <= XK_Umacron)
873 *lower += (XK_amacron - XK_Amacron);
874 else if (sym >= XK_amacron && sym <= XK_umacron)
875 *upper -= (XK_amacron - XK_Amacron);
876 break;
877 case 6: /* Cyrillic */
878 /* Assume the KeySym is a legal value (ignore discontinuities) */
879 if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
880 *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
881 else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
882 *upper += (XK_Serbian_DJE - XK_Serbian_dje);
883 else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
884 *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
885 else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
886 *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
887 break;
888 case 7: /* Greek */
889 /* Assume the KeySym is a legal value (ignore discontinuities) */
890 if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
891 *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
892 else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
893 sym != XK_Greek_iotaaccentdieresis &&
894 sym != XK_Greek_upsilonaccentdieresis)
895 *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
896 else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
897 *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
898 else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
899 sym != XK_Greek_finalsmallsigma)
900 *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
901 break;
907 * Copy an XKB map from src to dst, reallocating when necessary: if some
908 * map components are present in one, but not in the other, the destination
909 * components will be allocated or freed as necessary.
911 * Basic map consistency is assumed on both sides, so maps with random
912 * uninitialised data (e.g. names->radio_grous == NULL, names->num_rg == 19)
913 * _will_ cause failures. You've been warned.
915 * Returns TRUE on success, or FALSE on failure. If this function fails,
916 * dst may be in an inconsistent state: all its pointers are guaranteed
917 * to remain valid, but part of the map may be from src and part from dst.
919 * FIXME: This function wants to be broken up into multiple functions.
921 Bool
922 XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
924 int i = 0, j = 0, k = 0;
925 void *tmp = NULL;
926 XkbColorPtr scolor = NULL, dcolor = NULL;
927 XkbDoodadPtr sdoodad = NULL, ddoodad = NULL;
928 XkbKeyTypePtr stype = NULL, dtype = NULL;
929 XkbOutlinePtr soutline = NULL, doutline = NULL;
930 XkbPropertyPtr sprop = NULL, dprop = NULL;
931 XkbRowPtr srow = NULL, drow = NULL;
932 XkbSectionPtr ssection = NULL, dsection = NULL;
933 XkbShapePtr sshape = NULL, dshape = NULL;
934 DeviceIntPtr pDev = NULL, tmpDev = NULL;
935 xkbMapNotify mn;
936 xkbNewKeyboardNotify nkn;
938 if (!src || !dst || src == dst)
939 return FALSE;
941 /* client map */
942 if (src->map) {
943 if (!dst->map) {
944 tmp = xcalloc(1, sizeof(XkbClientMapRec));
945 if (!tmp)
946 return FALSE;
947 dst->map = tmp;
950 if (src->map->syms) {
951 if (src->map->size_syms != dst->map->size_syms) {
952 if (dst->map->syms)
953 tmp = xrealloc(dst->map->syms,
954 src->map->size_syms * sizeof(KeySym));
955 else
956 tmp = xalloc(src->map->size_syms * sizeof(KeySym));
957 if (!tmp)
958 return FALSE;
959 dst->map->syms = tmp;
962 memcpy(dst->map->syms, src->map->syms,
963 src->map->size_syms * sizeof(KeySym));
965 else {
966 if (dst->map->syms) {
967 xfree(dst->map->syms);
968 dst->map->syms = NULL;
971 dst->map->num_syms = src->map->num_syms;
972 dst->map->size_syms = src->map->size_syms;
974 if (src->map->key_sym_map) {
975 if (src->max_key_code != dst->max_key_code) {
976 if (dst->map->key_sym_map)
977 tmp = xrealloc(dst->map->key_sym_map,
978 (src->max_key_code + 1) *
979 sizeof(XkbSymMapRec));
980 else
981 tmp = xalloc((src->max_key_code + 1) *
982 sizeof(XkbSymMapRec));
983 if (!tmp)
984 return FALSE;
985 dst->map->key_sym_map = tmp;
987 memcpy(dst->map->key_sym_map, src->map->key_sym_map,
988 (src->max_key_code + 1) * sizeof(XkbSymMapRec));
990 else {
991 if (dst->map->key_sym_map) {
992 xfree(dst->map->key_sym_map);
993 dst->map->key_sym_map = NULL;
997 if (src->map->types && src->map->num_types) {
998 if (src->map->num_types > dst->map->size_types ||
999 !dst->map->types || !dst->map->size_types) {
1000 if (dst->map->types && dst->map->size_types) {
1001 tmp = xrealloc(dst->map->types,
1002 src->map->num_types * sizeof(XkbKeyTypeRec));
1003 if (!tmp)
1004 return FALSE;
1005 dst->map->types = tmp;
1006 bzero(dst->map->types + dst->map->num_types,
1007 (src->map->num_types - dst->map->num_types) *
1008 sizeof(XkbKeyTypeRec));
1010 else {
1011 tmp = xcalloc(src->map->num_types, sizeof(XkbKeyTypeRec));
1012 if (!tmp)
1013 return FALSE;
1014 dst->map->types = tmp;
1017 else if (src->map->num_types < dst->map->num_types &&
1018 dst->map->types) {
1019 for (i = src->map->num_types, dtype = (dst->map->types + i);
1020 i < dst->map->num_types; i++, dtype++) {
1021 if (dtype->level_names)
1022 xfree(dtype->level_names);
1023 dtype->level_names = NULL;
1024 dtype->num_levels = 0;
1025 if (dtype->map_count) {
1026 if (dtype->map)
1027 xfree(dtype->map);
1028 if (dtype->preserve)
1029 xfree(dtype->preserve);
1034 stype = src->map->types;
1035 dtype = dst->map->types;
1036 for (i = 0; i < src->map->num_types; i++, dtype++, stype++) {
1037 if (stype->num_levels && stype->level_names) {
1038 if (stype->num_levels != dtype->num_levels &&
1039 dtype->num_levels && dtype->level_names &&
1040 i < dst->map->num_types) {
1041 tmp = xrealloc(dtype->level_names,
1042 stype->num_levels * sizeof(Atom));
1043 if (!tmp)
1044 continue;
1045 dtype->level_names = tmp;
1047 else if (!dtype->num_levels || !dtype->level_names ||
1048 i >= dst->map->num_types) {
1049 tmp = xalloc(stype->num_levels * sizeof(Atom));
1050 if (!tmp)
1051 continue;
1052 dtype->level_names = tmp;
1054 dtype->num_levels = stype->num_levels;
1055 memcpy(dtype->level_names, stype->level_names,
1056 stype->num_levels * sizeof(Atom));
1058 else {
1059 if (dtype->num_levels && dtype->level_names &&
1060 i < dst->map->num_types)
1061 xfree(dtype->level_names);
1062 dtype->num_levels = 0;
1063 dtype->level_names = NULL;
1066 dtype->name = stype->name;
1067 memcpy(&dtype->mods, &stype->mods, sizeof(XkbModsRec));
1069 if (stype->map_count) {
1070 if (stype->map) {
1071 if (stype->map_count != dtype->map_count &&
1072 dtype->map_count && dtype->map &&
1073 i < dst->map->num_types) {
1074 tmp = xrealloc(dtype->map,
1075 stype->map_count *
1076 sizeof(XkbKTMapEntryRec));
1077 if (!tmp)
1078 return FALSE;
1079 dtype->map = tmp;
1081 else if (!dtype->map_count || !dtype->map ||
1082 i >= dst->map->num_types) {
1083 tmp = xalloc(stype->map_count *
1084 sizeof(XkbKTMapEntryRec));
1085 if (!tmp)
1086 return FALSE;
1087 dtype->map = tmp;
1090 memcpy(dtype->map, stype->map,
1091 stype->map_count * sizeof(XkbKTMapEntryRec));
1093 else {
1094 if (dtype->map && i < dst->map->num_types)
1095 xfree(dtype->map);
1096 dtype->map = NULL;
1099 if (stype->preserve) {
1100 if (stype->map_count != dtype->map_count &&
1101 dtype->map_count && dtype->preserve &&
1102 i < dst->map->num_types) {
1103 tmp = xrealloc(dtype->preserve,
1104 stype->map_count *
1105 sizeof(XkbModsRec));
1106 if (!tmp)
1107 return FALSE;
1108 dtype->preserve = tmp;
1110 else if (!dtype->preserve || !dtype->map_count ||
1111 i >= dst->map->num_types) {
1112 tmp = xalloc(stype->map_count *
1113 sizeof(XkbModsRec));
1114 if (!tmp)
1115 return FALSE;
1116 dtype->preserve = tmp;
1119 memcpy(dtype->preserve, stype->preserve,
1120 stype->map_count * sizeof(XkbModsRec));
1122 else {
1123 if (dtype->preserve && i < dst->map->num_types)
1124 xfree(dtype->preserve);
1125 dtype->preserve = NULL;
1128 dtype->map_count = stype->map_count;
1130 else {
1131 if (dtype->map_count && i < dst->map->num_types) {
1132 if (dtype->map)
1133 xfree(dtype->map);
1134 if (dtype->preserve)
1135 xfree(dtype->preserve);
1137 dtype->map_count = 0;
1138 dtype->map = NULL;
1139 dtype->preserve = NULL;
1143 dst->map->size_types = src->map->num_types;
1144 dst->map->num_types = src->map->num_types;
1146 else {
1147 if (dst->map->types) {
1148 for (i = 0, dtype = dst->map->types; i < dst->map->num_types;
1149 i++, dtype++) {
1150 if (dtype->level_names)
1151 xfree(dtype->level_names);
1152 if (dtype->map && dtype->map_count)
1153 xfree(dtype->map);
1154 if (dtype->preserve && dtype->map_count)
1155 xfree(dtype->preserve);
1157 xfree(dst->map->types);
1158 dst->map->types = NULL;
1160 dst->map->num_types = 0;
1161 dst->map->size_types = 0;
1164 if (src->map->modmap) {
1165 if (src->max_key_code != dst->max_key_code) {
1166 if (dst->map->modmap)
1167 tmp = xrealloc(dst->map->modmap, src->max_key_code + 1);
1168 else
1169 tmp = xalloc(src->max_key_code + 1);
1170 if (!tmp)
1171 return FALSE;
1172 dst->map->modmap = tmp;
1174 memcpy(dst->map->modmap, src->map->modmap, src->max_key_code + 1);
1176 else {
1177 if (dst->map->modmap) {
1178 xfree(dst->map->modmap);
1179 dst->map->modmap = NULL;
1183 else {
1184 if (dst->map)
1185 XkbFreeClientMap(dst, XkbAllClientInfoMask, True);
1188 /* server map */
1189 if (src->server) {
1190 if (!dst->server) {
1191 tmp = xcalloc(1, sizeof(XkbServerMapRec));
1192 if (!tmp)
1193 return FALSE;
1194 dst->server = tmp;
1197 if (src->server->explicit) {
1198 if (src->max_key_code != dst->max_key_code) {
1199 if (dst->server->explicit)
1200 tmp = xrealloc(dst->server->explicit, src->max_key_code + 1);
1201 else
1202 tmp = xalloc(src->max_key_code + 1);
1203 if (!tmp)
1204 return FALSE;
1205 dst->server->explicit = tmp;
1207 memcpy(dst->server->explicit, src->server->explicit,
1208 src->max_key_code + 1);
1210 else {
1211 if (dst->server->explicit) {
1212 xfree(dst->server->explicit);
1213 dst->server->explicit = NULL;
1217 if (src->server->acts) {
1218 if (src->server->size_acts != dst->server->size_acts) {
1219 if (dst->server->acts)
1220 tmp = xrealloc(dst->server->acts,
1221 src->server->size_acts * sizeof(XkbAction));
1222 else
1223 tmp = xalloc(src->server->size_acts * sizeof(XkbAction));
1224 if (!tmp)
1225 return FALSE;
1226 dst->server->acts = tmp;
1228 memcpy(dst->server->acts, src->server->acts,
1229 src->server->size_acts * sizeof(XkbAction));
1231 else {
1232 if (dst->server->acts) {
1233 xfree(dst->server->acts);
1234 dst->server->acts = NULL;
1237 dst->server->size_acts = src->server->size_acts;
1238 dst->server->num_acts = src->server->num_acts;
1240 if (src->server->key_acts) {
1241 if (src->max_key_code != dst->max_key_code) {
1242 if (dst->server->key_acts)
1243 tmp = xrealloc(dst->server->key_acts,
1244 (src->max_key_code + 1) *
1245 sizeof(unsigned short));
1246 else
1247 tmp = xalloc((src->max_key_code + 1) *
1248 sizeof(unsigned short));
1249 if (!tmp)
1250 return FALSE;
1251 dst->server->key_acts = tmp;
1253 memcpy(dst->server->key_acts, src->server->key_acts,
1254 (src->max_key_code + 1) * sizeof(unsigned short));
1256 else {
1257 if (dst->server->key_acts) {
1258 xfree(dst->server->key_acts);
1259 dst->server->key_acts = NULL;
1263 if (src->server->behaviors) {
1264 if (src->max_key_code != dst->max_key_code) {
1265 if (dst->server->behaviors)
1266 tmp = xrealloc(dst->server->behaviors,
1267 (src->max_key_code + 1) *
1268 sizeof(XkbBehavior));
1269 else
1270 tmp = xalloc((src->max_key_code + 1) *
1271 sizeof(XkbBehavior));
1272 if (!tmp)
1273 return FALSE;
1274 dst->server->behaviors = tmp;
1276 memcpy(dst->server->behaviors, src->server->behaviors,
1277 (src->max_key_code + 1) * sizeof(XkbBehavior));
1279 else {
1280 if (dst->server->behaviors) {
1281 xfree(dst->server->behaviors);
1282 dst->server->behaviors = NULL;
1286 memcpy(dst->server->vmods, src->server->vmods, XkbNumVirtualMods);
1288 if (src->server->vmodmap) {
1289 if (src->max_key_code != dst->max_key_code) {
1290 if (dst->server->vmodmap)
1291 tmp = xrealloc(dst->server->vmodmap,
1292 (src->max_key_code + 1) *
1293 sizeof(unsigned short));
1294 else
1295 tmp = xalloc((src->max_key_code + 1) *
1296 sizeof(unsigned short));
1297 if (!tmp)
1298 return FALSE;
1299 dst->server->vmodmap = tmp;
1301 memcpy(dst->server->vmodmap, src->server->vmodmap,
1302 (src->max_key_code + 1) * sizeof(unsigned short));
1304 else {
1305 if (dst->server->vmodmap) {
1306 xfree(dst->server->vmodmap);
1307 dst->server->vmodmap = NULL;
1311 else {
1312 if (dst->server)
1313 XkbFreeServerMap(dst, XkbAllServerInfoMask, True);
1316 /* indicators */
1317 if (src->indicators) {
1318 if (!dst->indicators) {
1319 dst->indicators = xalloc(sizeof(XkbIndicatorRec));
1320 if (!dst->indicators)
1321 return FALSE;
1323 memcpy(dst->indicators, src->indicators, sizeof(XkbIndicatorRec));
1325 else {
1326 if (dst->indicators) {
1327 xfree(dst->indicators);
1328 dst->indicators = NULL;
1332 /* controls */
1333 if (src->ctrls) {
1334 if (!dst->ctrls) {
1335 dst->ctrls = xalloc(sizeof(XkbControlsRec));
1336 if (!dst->ctrls)
1337 return FALSE;
1339 memcpy(dst->ctrls, src->ctrls, sizeof(XkbControlsRec));
1341 else {
1342 if (dst->ctrls) {
1343 xfree(dst->ctrls);
1344 dst->ctrls = NULL;
1348 /* names */
1349 if (src->names) {
1350 if (!dst->names) {
1351 dst->names = xcalloc(1, sizeof(XkbNamesRec));
1352 if (!dst->names)
1353 return FALSE;
1356 if (src->names->keys) {
1357 if (src->max_key_code != dst->max_key_code) {
1358 if (dst->names->keys)
1359 tmp = xrealloc(dst->names->keys, (src->max_key_code + 1) *
1360 sizeof(XkbKeyNameRec));
1361 else
1362 tmp = xalloc((src->max_key_code + 1) *
1363 sizeof(XkbKeyNameRec));
1364 if (!tmp)
1365 return FALSE;
1366 dst->names->keys = tmp;
1368 memcpy(dst->names->keys, src->names->keys,
1369 (src->max_key_code + 1) * sizeof(XkbKeyNameRec));
1371 else {
1372 if (dst->names->keys) {
1373 xfree(dst->names->keys);
1374 dst->names->keys = NULL;
1378 if (src->names->num_key_aliases) {
1379 if (src->names->num_key_aliases != dst->names->num_key_aliases) {
1380 if (dst->names->key_aliases)
1381 tmp = xrealloc(dst->names->key_aliases,
1382 src->names->num_key_aliases *
1383 sizeof(XkbKeyAliasRec));
1384 else
1385 tmp = xalloc(src->names->num_key_aliases *
1386 sizeof(XkbKeyAliasRec));
1387 if (!tmp)
1388 return FALSE;
1389 dst->names->key_aliases = tmp;
1391 memcpy(dst->names->key_aliases, src->names->key_aliases,
1392 src->names->num_key_aliases * sizeof(XkbKeyAliasRec));
1394 else {
1395 if (dst->names->key_aliases) {
1396 xfree(dst->names->key_aliases);
1397 dst->names->key_aliases = NULL;
1400 dst->names->num_key_aliases = src->names->num_key_aliases;
1402 if (src->names->num_rg) {
1403 if (src->names->num_rg != dst->names->num_rg) {
1404 if (dst->names->radio_groups)
1405 tmp = xrealloc(dst->names->radio_groups,
1406 src->names->num_rg * sizeof(Atom));
1407 else
1408 tmp = xalloc(src->names->num_rg * sizeof(Atom));
1409 if (!tmp)
1410 return FALSE;
1411 dst->names->radio_groups = tmp;
1413 memcpy(dst->names->radio_groups, src->names->radio_groups,
1414 src->names->num_rg * sizeof(Atom));
1416 else {
1417 if (dst->names->radio_groups)
1418 xfree(dst->names->radio_groups);
1420 dst->names->num_rg = src->names->num_rg;
1422 dst->names->keycodes = src->names->keycodes;
1423 dst->names->geometry = src->names->geometry;
1424 dst->names->symbols = src->names->symbols;
1425 dst->names->types = src->names->types;
1426 dst->names->compat = src->names->compat;
1427 dst->names->phys_symbols = src->names->phys_symbols;
1429 memcpy(dst->names->vmods, src->names->vmods,
1430 XkbNumVirtualMods * sizeof(Atom));
1431 memcpy(dst->names->indicators, src->names->indicators,
1432 XkbNumIndicators * sizeof(Atom));
1433 memcpy(dst->names->groups, src->names->groups,
1434 XkbNumKbdGroups * sizeof(Atom));
1436 else {
1437 if (dst->names)
1438 XkbFreeNames(dst, XkbAllNamesMask, True);
1441 /* compat */
1442 if (src->compat) {
1443 if (!dst->compat) {
1444 dst->compat = xcalloc(1, sizeof(XkbCompatMapRec));
1445 if (!dst->compat)
1446 return FALSE;
1449 if (src->compat->sym_interpret && src->compat->num_si) {
1450 if (src->compat->num_si != dst->compat->size_si) {
1451 if (dst->compat->sym_interpret)
1452 tmp = xrealloc(dst->compat->sym_interpret,
1453 src->compat->num_si *
1454 sizeof(XkbSymInterpretRec));
1455 else
1456 tmp = xalloc(src->compat->num_si *
1457 sizeof(XkbSymInterpretRec));
1458 if (!tmp)
1459 return FALSE;
1460 dst->compat->sym_interpret = tmp;
1462 memcpy(dst->compat->sym_interpret, src->compat->sym_interpret,
1463 src->compat->num_si * sizeof(XkbSymInterpretRec));
1465 dst->compat->num_si = src->compat->num_si;
1466 dst->compat->size_si = src->compat->num_si;
1468 else {
1469 if (dst->compat->sym_interpret && dst->compat->size_si)
1470 xfree(dst->compat->sym_interpret);
1472 dst->compat->sym_interpret = NULL;
1473 dst->compat->num_si = 0;
1474 dst->compat->size_si = 0;
1477 memcpy(dst->compat->groups, src->compat->groups,
1478 XkbNumKbdGroups * sizeof(XkbModsRec));
1480 else {
1481 if (dst->compat)
1482 XkbFreeCompatMap(dst, XkbAllCompatMask, True);
1485 /* geometry */
1486 if (src->geom) {
1487 if (!dst->geom) {
1488 dst->geom = xcalloc(sizeof(XkbGeometryRec), 1);
1489 if (!dst->geom)
1490 return FALSE;
1493 /* properties */
1494 if (src->geom->num_properties) {
1495 if (src->geom->num_properties != dst->geom->sz_properties) {
1496 if (src->geom->num_properties < dst->geom->sz_properties) {
1497 for (i = src->geom->num_properties,
1498 dprop = dst->geom->properties +
1499 src->geom->num_properties;
1500 i < dst->geom->num_properties;
1501 i++, dprop++) {
1502 xfree(dprop->name);
1503 xfree(dprop->value);
1507 if (dst->geom->sz_properties)
1508 tmp = xrealloc(dst->geom->properties,
1509 src->geom->num_properties *
1510 sizeof(XkbPropertyRec));
1511 else
1512 tmp = xalloc(src->geom->num_properties *
1513 sizeof(XkbPropertyRec));
1514 if (!tmp)
1515 return FALSE;
1516 dst->geom->properties = tmp;
1519 dst->geom->sz_properties = src->geom->num_properties;
1521 if (dst->geom->sz_properties > dst->geom->num_properties) {
1522 bzero(dst->geom->properties + dst->geom->num_properties,
1523 (dst->geom->sz_properties - dst->geom->num_properties) *
1524 sizeof(XkbPropertyRec));
1527 for (i = 0,
1528 sprop = src->geom->properties,
1529 dprop = dst->geom->properties;
1530 i < src->geom->num_properties;
1531 i++, sprop++, dprop++) {
1532 if (i < dst->geom->num_properties) {
1533 if (strlen(sprop->name) != strlen(dprop->name)) {
1534 tmp = xrealloc(dprop->name, strlen(sprop->name) + 1);
1535 if (!tmp)
1536 return FALSE;
1537 dprop->name = tmp;
1539 if (strlen(sprop->value) != strlen(dprop->value)) {
1540 tmp = xrealloc(dprop->value, strlen(sprop->value) + 1);
1541 if (!tmp)
1542 return FALSE;
1543 dprop->value = tmp;
1545 strcpy(dprop->name, sprop->name);
1546 strcpy(dprop->value, sprop->value);
1548 else {
1549 dprop->name = xstrdup(sprop->name);
1550 dprop->value = xstrdup(sprop->value);
1554 dst->geom->num_properties = dst->geom->sz_properties;
1556 else {
1557 if (dst->geom->sz_properties) {
1558 for (i = 0, dprop = dst->geom->properties;
1559 i < dst->geom->num_properties;
1560 i++, dprop++) {
1561 xfree(dprop->name);
1562 xfree(dprop->value);
1564 xfree(dst->geom->properties);
1565 dst->geom->properties = NULL;
1568 dst->geom->num_properties = 0;
1569 dst->geom->sz_properties = 0;
1572 /* colors */
1573 if (src->geom->num_colors) {
1574 if (src->geom->num_colors != dst->geom->sz_colors) {
1575 if (src->geom->num_colors < dst->geom->sz_colors) {
1576 for (i = src->geom->num_colors,
1577 dcolor = dst->geom->colors +
1578 src->geom->num_colors;
1579 i < dst->geom->num_colors;
1580 i++, dcolor++) {
1581 xfree(dcolor->spec);
1585 if (dst->geom->sz_colors)
1586 tmp = xrealloc(dst->geom->colors,
1587 src->geom->num_colors *
1588 sizeof(XkbColorRec));
1589 else
1590 tmp = xalloc(src->geom->num_colors *
1591 sizeof(XkbColorRec));
1592 if (!tmp)
1593 return FALSE;
1594 dst->geom->colors = tmp;
1597 dst->geom->sz_colors = src->geom->num_colors;
1599 if (dst->geom->sz_colors > dst->geom->num_colors) {
1600 bzero(dst->geom->colors + dst->geom->num_colors,
1601 (dst->geom->sz_colors - dst->geom->num_colors) *
1602 sizeof(XkbColorRec));
1605 for (i = 0,
1606 scolor = src->geom->colors,
1607 dcolor = dst->geom->colors;
1608 i < src->geom->num_colors;
1609 i++, scolor++, dcolor++) {
1610 if (i < dst->geom->num_colors) {
1611 if (strlen(scolor->spec) != strlen(dcolor->spec)) {
1612 tmp = xrealloc(dcolor->spec, strlen(scolor->spec) + 1);
1613 if (!tmp)
1614 return FALSE;
1615 dcolor->spec = tmp;
1617 strcpy(dcolor->spec, scolor->spec);
1619 else {
1620 dcolor->spec = xstrdup(scolor->spec);
1624 dst->geom->num_colors = dst->geom->sz_colors;
1626 else {
1627 if (dst->geom->sz_colors) {
1628 for (i = 0, dcolor = dst->geom->colors;
1629 i < dst->geom->num_colors;
1630 i++, dcolor++) {
1631 xfree(dcolor->spec);
1633 xfree(dst->geom->colors);
1634 dst->geom->colors = NULL;
1637 dst->geom->num_colors = 0;
1638 dst->geom->sz_colors = 0;
1641 /* shapes */
1642 /* shapes break down into outlines, which break down into points. */
1643 if (dst->geom->num_shapes) {
1644 for (i = 0, dshape = dst->geom->shapes;
1645 i < dst->geom->num_shapes;
1646 i++, dshape++) {
1647 for (j = 0, doutline = dshape->outlines;
1648 j < dshape->num_outlines;
1649 j++, doutline++) {
1650 if (doutline->sz_points)
1651 xfree(doutline->points);
1654 if (dshape->sz_outlines) {
1655 xfree(dshape->outlines);
1656 dshape->outlines = NULL;
1659 dshape->num_outlines = 0;
1660 dshape->sz_outlines = 0;
1664 if (src->geom->num_shapes) {
1665 tmp = xcalloc(src->geom->num_shapes, sizeof(XkbShapeRec));
1666 if (!tmp)
1667 return FALSE;
1668 dst->geom->shapes = tmp;
1670 for (i = 0, sshape = src->geom->shapes, dshape = dst->geom->shapes;
1671 i < src->geom->num_shapes;
1672 i++, sshape++, dshape++) {
1673 if (sshape->num_outlines) {
1674 tmp = xcalloc(sshape->num_outlines, sizeof(XkbOutlineRec));
1675 if (!tmp)
1676 return FALSE;
1677 dshape->outlines = tmp;
1679 for (j = 0,
1680 soutline = sshape->outlines,
1681 doutline = dshape->outlines;
1682 j < sshape->num_outlines;
1683 j++, soutline++, doutline++) {
1684 if (soutline->num_points) {
1685 tmp = xalloc(soutline->num_points *
1686 sizeof(XkbPointRec));
1687 if (!tmp)
1688 return FALSE;
1689 doutline->points = tmp;
1691 memcpy(doutline->points, soutline->points,
1692 soutline->num_points * sizeof(XkbPointRec));
1695 doutline->num_points = soutline->num_points;
1696 doutline->sz_points = soutline->sz_points;
1700 dshape->num_outlines = sshape->num_outlines;
1701 dshape->sz_outlines = sshape->num_outlines;
1704 dst->geom->num_shapes = src->geom->num_shapes;
1705 dst->geom->sz_shapes = src->geom->num_shapes;
1707 else {
1708 if (dst->geom->sz_shapes) {
1709 xfree(dst->geom->shapes);
1710 dst->geom->shapes = NULL;
1713 dst->geom->num_shapes = 0;
1714 dst->geom->sz_shapes = 0;
1717 /* sections */
1718 /* sections break down into doodads, and also into rows, which break
1719 * down into keys. */
1720 if (dst->geom->num_sections) {
1721 for (i = 0, dsection = dst->geom->sections;
1722 i < dst->geom->num_sections;
1723 i++, dsection++) {
1724 for (j = 0, drow = dsection->rows;
1725 j < dsection->num_rows;
1726 j++, drow++) {
1727 if (drow->num_keys)
1728 xfree(drow->keys);
1731 if (dsection->num_rows)
1732 xfree(dsection->rows);
1734 /* cut and waste from geom/doodad below. */
1735 for (j = 0, ddoodad = dsection->doodads;
1736 j < dsection->num_doodads;
1737 j++, ddoodad++) {
1738 if (ddoodad->any.type == XkbTextDoodad) {
1739 if (ddoodad->text.text) {
1740 xfree(ddoodad->text.text);
1741 ddoodad->text.text = NULL;
1743 if (ddoodad->text.font) {
1744 xfree(ddoodad->text.font);
1745 ddoodad->text.font = NULL;
1748 else if (ddoodad->any.type == XkbLogoDoodad) {
1749 if (ddoodad->logo.logo_name) {
1750 xfree(ddoodad->logo.logo_name);
1751 ddoodad->logo.logo_name = NULL;
1756 if (dsection->num_doodads)
1757 xfree(dsection->doodads);
1760 dst->geom->num_sections = 0;
1763 if (src->geom->num_sections) {
1764 if (dst->geom->sz_sections)
1765 tmp = xrealloc(dst->geom->sections,
1766 src->geom->num_sections *
1767 sizeof(XkbSectionRec));
1768 else
1769 tmp = xalloc(src->geom->num_sections * sizeof(XkbSectionRec));
1770 if (!tmp)
1771 return FALSE;
1772 dst->geom->sections = tmp;
1774 for (i = 0,
1775 ssection = src->geom->sections,
1776 dsection = dst->geom->sections;
1777 i < src->geom->num_sections;
1778 i++, ssection++, dsection++) {
1779 if (ssection->num_rows) {
1780 tmp = xcalloc(ssection->num_rows, sizeof(XkbRowRec));
1781 if (!tmp)
1782 return FALSE;
1783 dsection->rows = tmp;
1785 for (j = 0, srow = ssection->rows, drow = dsection->rows;
1786 j < ssection->num_rows;
1787 j++, srow++, drow++) {
1788 if (srow->num_keys) {
1789 tmp = xalloc(srow->num_keys * sizeof(XkbKeyRec));
1790 if (!tmp)
1791 return FALSE;
1792 drow->keys = tmp;
1793 memcpy(drow->keys, srow->keys,
1794 srow->num_keys * sizeof(XkbKeyRec));
1796 drow->num_keys = srow->num_keys;
1797 drow->sz_keys = srow->num_keys;
1800 if (ssection->num_doodads) {
1801 tmp = xcalloc(ssection->num_doodads, sizeof(XkbDoodadRec));
1802 if (!tmp)
1803 return FALSE;
1804 dsection->doodads = tmp;
1806 for (k = 0,
1807 sdoodad = ssection->doodads,
1808 ddoodad = dsection->doodads;
1809 k < ssection->num_doodads;
1810 k++, sdoodad++, ddoodad++) {
1811 if (sdoodad->any.type == XkbTextDoodad) {
1812 if (sdoodad->text.text)
1813 ddoodad->text.text =
1814 xstrdup(sdoodad->text.text);
1815 if (sdoodad->text.font)
1816 ddoodad->text.font =
1817 xstrdup(sdoodad->text.font);
1819 else if (sdoodad->any.type == XkbLogoDoodad) {
1820 if (sdoodad->logo.logo_name)
1821 ddoodad->logo.logo_name =
1822 xstrdup(sdoodad->logo.logo_name);
1824 ddoodad->any.type = sdoodad->any.type;
1826 dsection->num_doodads = ssection->num_doodads;
1827 dsection->sz_doodads = ssection->num_doodads;
1830 else {
1831 if (dst->geom->sz_sections) {
1832 xfree(dst->geom->sections);
1833 dst->geom->sections = NULL;
1836 dst->geom->num_sections = 0;
1837 dst->geom->sz_sections = 0;
1840 /* doodads */
1841 if (dst->geom->num_doodads) {
1842 for (i = src->geom->num_doodads,
1843 ddoodad = dst->geom->doodads +
1844 src->geom->num_doodads;
1845 i < dst->geom->num_doodads;
1846 i++, ddoodad++) {
1847 if (ddoodad->any.type == XkbTextDoodad) {
1848 if (ddoodad->text.text) {
1849 xfree(ddoodad->text.text);
1850 ddoodad->text.text = NULL;
1852 if (ddoodad->text.font) {
1853 xfree(ddoodad->text.font);
1854 ddoodad->text.font = NULL;
1857 else if (ddoodad->any.type == XkbLogoDoodad) {
1858 if (ddoodad->logo.logo_name) {
1859 xfree(ddoodad->logo.logo_name);
1860 ddoodad->logo.logo_name = NULL;
1866 if (src->geom->num_doodads) {
1867 if (dst->geom->sz_doodads)
1868 tmp = xrealloc(dst->geom->doodads,
1869 src->geom->num_doodads *
1870 sizeof(XkbDoodadRec));
1871 else
1872 tmp = xalloc(src->geom->num_doodads *
1873 sizeof(XkbDoodadRec));
1874 if (!tmp)
1875 return FALSE;
1876 bzero(tmp, src->geom->num_doodads * sizeof(XkbDoodadRec));
1877 dst->geom->doodads = tmp;
1879 dst->geom->sz_doodads = src->geom->num_doodads;
1881 for (i = 0,
1882 sdoodad = src->geom->doodads,
1883 ddoodad = dst->geom->doodads;
1884 i < src->geom->num_doodads;
1885 i++, sdoodad++, ddoodad++) {
1886 ddoodad->any.type = sdoodad->any.type;
1887 if (sdoodad->any.type == XkbTextDoodad) {
1888 if (sdoodad->text.text)
1889 ddoodad->text.text = xstrdup(sdoodad->text.text);
1890 if (sdoodad->text.font)
1891 ddoodad->text.font = xstrdup(sdoodad->text.font);
1893 else if (sdoodad->any.type == XkbLogoDoodad) {
1894 if (sdoodad->logo.logo_name)
1895 ddoodad->logo.logo_name =
1896 xstrdup(sdoodad->logo.logo_name);
1900 dst->geom->num_doodads = dst->geom->sz_doodads;
1902 else {
1903 if (dst->geom->sz_doodads) {
1904 xfree(dst->geom->doodads);
1905 dst->geom->doodads = NULL;
1908 dst->geom->num_doodads = 0;
1909 dst->geom->sz_doodads = 0;
1912 /* key aliases */
1913 if (src->geom->num_key_aliases) {
1914 if (src->geom->num_key_aliases != dst->geom->sz_key_aliases) {
1915 if (dst->geom->sz_key_aliases)
1916 tmp = xrealloc(dst->geom->key_aliases,
1917 src->geom->num_key_aliases *
1918 2 * XkbKeyNameLength);
1919 else
1920 tmp = xalloc(src->geom->num_key_aliases *
1921 2 * XkbKeyNameLength);
1922 if (!tmp)
1923 return FALSE;
1924 dst->geom->key_aliases = tmp;
1926 dst->geom->sz_key_aliases = src->geom->num_key_aliases;
1929 memcpy(dst->geom->key_aliases, src->geom->key_aliases,
1930 src->geom->num_key_aliases * 2 * XkbKeyNameLength);
1932 dst->geom->num_key_aliases = dst->geom->sz_key_aliases;
1934 else {
1935 if (dst->geom->sz_key_aliases && dst->geom->key_aliases) {
1936 xfree(dst->geom->key_aliases);
1937 dst->geom->key_aliases = NULL;
1939 dst->geom->num_key_aliases = 0;
1940 dst->geom->sz_key_aliases = 0;
1943 /* font */
1944 if (src->geom->label_font) {
1945 if (!dst->geom->label_font) {
1946 tmp = xalloc(strlen(src->geom->label_font));
1947 if (!tmp)
1948 return FALSE;
1949 dst->geom->label_font = tmp;
1951 else if (strlen(src->geom->label_font) !=
1952 strlen(dst->geom->label_font)) {
1953 tmp = xrealloc(dst->geom->label_font,
1954 strlen(src->geom->label_font));
1955 if (!tmp)
1956 return FALSE;
1957 dst->geom->label_font = tmp;
1960 strcpy(dst->geom->label_font, src->geom->label_font);
1961 i = XkbGeomColorIndex(src->geom, src->geom->label_color);
1962 dst->geom->label_color = &(src->geom->colors[i]);
1963 i = XkbGeomColorIndex(src->geom, src->geom->base_color);
1964 dst->geom->base_color = &(src->geom->colors[i]);
1966 else {
1967 if (dst->geom->label_font) {
1968 xfree(dst->geom->label_font);
1969 dst->geom->label_font = NULL;
1971 dst->geom->label_color = NULL;
1972 dst->geom->base_color = NULL;
1975 dst->geom->name = src->geom->name;
1976 dst->geom->width_mm = src->geom->width_mm;
1977 dst->geom->height_mm = src->geom->height_mm;
1979 else
1981 if (dst->geom) {
1982 /* I LOVE THE DIFFERENT CALL SIGNATURE. REALLY, I DO. */
1983 XkbFreeGeometry(dst->geom, XkbGeomAllMask, True);
1984 dst->geom = NULL;
1988 if (inputInfo.keyboard->key->xkbInfo &&
1989 inputInfo.keyboard->key->xkbInfo->desc == dst) {
1990 pDev = inputInfo.keyboard;
1992 else {
1993 for (tmpDev = inputInfo.devices; tmpDev && !pDev;
1994 tmpDev = tmpDev->next) {
1995 if (tmpDev->key && tmpDev->key->xkbInfo &&
1996 tmpDev->key->xkbInfo->desc == dst) {
1997 pDev = tmpDev;
1998 break;
2001 for (tmpDev = inputInfo.off_devices; tmpDev && !pDev;
2002 tmpDev = tmpDev->next) {
2003 if (tmpDev->key && tmpDev->key->xkbInfo &&
2004 tmpDev->key->xkbInfo->desc == dst) {
2005 pDev = tmpDev;
2006 break;
2011 if (sendNotifies) {
2012 if (!pDev) {
2013 ErrorF("XkbCopyKeymap: asked for notifies, but can't find device!\n");
2015 else {
2016 /* send NewKeyboardNotify if the keycode range changed, else
2017 * just MapNotify. we also need to send NKN if the geometry
2018 * changed (obviously ...). */
2019 if ((src->min_key_code != dst->min_key_code ||
2020 src->max_key_code != dst->max_key_code) && sendNotifies) {
2021 nkn.oldMinKeyCode = dst->min_key_code;
2022 nkn.oldMaxKeyCode = dst->max_key_code;
2023 nkn.deviceID = nkn.oldDeviceID = pDev->id;
2024 nkn.minKeyCode = src->min_key_code;
2025 nkn.maxKeyCode = src->max_key_code;
2026 nkn.requestMajor = XkbReqCode;
2027 nkn.requestMinor = X_kbSetMap; /* XXX bare-faced lie */
2028 nkn.changed = XkbAllNewKeyboardEventsMask;
2029 XkbSendNewKeyboardNotify(pDev, &nkn);
2031 else if (sendNotifies) {
2032 mn.deviceID = pDev->id;
2033 mn.minKeyCode = src->min_key_code;
2034 mn.maxKeyCode = src->max_key_code;
2035 mn.firstType = 0;
2036 mn.nTypes = src->map->num_types;
2037 mn.firstKeySym = src->min_key_code;
2038 mn.nKeySyms = XkbNumKeys(src);
2039 mn.firstKeyAct = src->min_key_code;
2040 mn.nKeyActs = XkbNumKeys(src);
2041 /* Cargo-culted from ProcXkbGetMap. */
2042 mn.firstKeyBehavior = src->min_key_code;
2043 mn.nKeyBehaviors = XkbNumKeys(src);
2044 mn.firstKeyExplicit = src->min_key_code;
2045 mn.nKeyExplicit = XkbNumKeys(src);
2046 mn.firstModMapKey = src->min_key_code;
2047 mn.nModMapKeys = XkbNumKeys(src);
2048 mn.firstVModMapKey = src->min_key_code;
2049 mn.nVModMapKeys = XkbNumKeys(src);
2050 mn.virtualMods = ~0; /* ??? */
2051 mn.changed = XkbAllMapComponentsMask;
2052 XkbSendMapNotify(pDev, &mn);
2057 dst->min_key_code = src->min_key_code;
2058 dst->max_key_code = src->max_key_code;
2060 return TRUE;