Use correct swap{l,s} (or none at all for CARD8)
[gstreamer-omap:xserver.git] / xkb / xkb.c
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
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.
15
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.
24
25 ********************************************************/
26
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <X11/X.h>
33 #include <X11/Xproto.h>
34 #include "misc.h"
35 #include "inputstr.h"
36 #define XKBSRV_NEED_FILE_FUNCS
37 #include <xkbsrv.h>
38 #include "extnsionst.h"
39 #include "xace.h"
40 #include "xkb.h"
41 #include "protocol-versions.h"
42
43 #include <X11/extensions/XI.h>
44 #include <X11/extensions/XKMformat.h>
45
46 int             XkbEventBase;
47 static  int     XkbErrorBase;
48 int             XkbReqCode;
49 int             XkbKeyboardErrorCode;
50 CARD32          xkbDebugFlags = 0;
51 static CARD32   xkbDebugCtrls = 0;
52
53 static RESTYPE  RT_XKBCLIENT;
54
55 /***====================================================================***/
56
57 #define CHK_DEVICE(dev, id, client, access_mode, lf) {\
58     int why;\
59     int rc = lf(&(dev), id, client, access_mode, &why);\
60     if (rc != Success) {\
61         client->errorValue = _XkbErrCode2(why, id);\
62         return rc;\
63     }\
64 }
65
66 #define CHK_KBD_DEVICE(dev, id, client, mode) \
67     CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard)
68 #define CHK_LED_DEVICE(dev, id, client, mode) \
69     CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice)
70 #define CHK_BELL_DEVICE(dev, id, client, mode) \
71     CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice)
72 #define CHK_ANY_DEVICE(dev, id, client, mode) \
73     CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice)
74
75 #define CHK_ATOM_ONLY2(a,ev,er) {\
76         if (((a)==None)||(!ValidAtom((a)))) {\
77             (ev)= (XID)(a);\
78             return er;\
79         }\
80 }
81 #define CHK_ATOM_ONLY(a) \
82         CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
83
84 #define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
85         if (((a)!=None)&&(!ValidAtom((a)))) {\
86             (ev)= (XID)(a);\
87             (er)= BadAtom;\
88             return ret;\
89         }\
90 }
91 #define CHK_ATOM_OR_NONE2(a,ev,er) {\
92         if (((a)!=None)&&(!ValidAtom((a)))) {\
93             (ev)= (XID)(a);\
94             return er;\
95         }\
96 }
97 #define CHK_ATOM_OR_NONE(a) \
98         CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
99
100 #define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret)       {\
101         if ((mask)&(~(legal))) { \
102             (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
103             (er)= BadValue;\
104             return ret;\
105         }\
106 }
107 #define CHK_MASK_LEGAL2(err,mask,legal,ev,er)   {\
108         if ((mask)&(~(legal))) { \
109             (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
110             return er;\
111         }\
112 }
113 #define CHK_MASK_LEGAL(err,mask,legal) \
114         CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
115
116 #define CHK_MASK_MATCH(err,affect,value) {\
117         if ((value)&(~(affect))) { \
118             client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
119             return BadMatch;\
120         }\
121 }
122 #define CHK_MASK_OVERLAP(err,m1,m2) {\
123         if ((m1)&(m2)) { \
124             client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
125             return BadMatch;\
126         }\
127 }
128 #define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
129         if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
130             (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
131             return er;\
132         }\
133         else if ( (first)<(x)->min_key_code ) {\
134             (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
135             return er;\
136         }\
137 }
138 #define CHK_KEY_RANGE(err,first,num,x)  \
139         CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
140
141 #define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
142         if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
143             (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
144             return er;\
145         }\
146         else if ( (first)<(r)->minKeyCode ) {\
147             (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
148             return er;\
149         }\
150 }
151 #define CHK_REQ_KEY_RANGE(err,first,num,r)  \
152         CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
153
154 /***====================================================================***/
155
156 int
157 ProcXkbUseExtension(ClientPtr client)
158 {
159     REQUEST(xkbUseExtensionReq);
160     xkbUseExtensionReply        rep;
161     int supported;
162
163     REQUEST_SIZE_MATCH(xkbUseExtensionReq);
164     if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) {
165         /* pre-release version 0.65 is compatible with 1.00 */
166         supported= ((SERVER_XKB_MAJOR_VERSION==1)&&
167                     (stuff->wantedMajor==0)&&(stuff->wantedMinor==65));
168     }
169     else supported = 1;
170
171     if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) {
172         client->xkbClientFlags= _XkbClientInitialized;
173         client->vMajor= stuff->wantedMajor;
174         client->vMinor= stuff->wantedMinor;
175     }
176     else if (xkbDebugFlags&0x1) {
177         ErrorF("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n",
178                                         client->index,
179                                         (long)client->clientAsMask,
180                                         stuff->wantedMajor,stuff->wantedMinor,
181                                         SERVER_XKB_MAJOR_VERSION,SERVER_XKB_MINOR_VERSION);
182     }
183     memset(&rep, 0, sizeof(xkbUseExtensionReply));
184     rep.type = X_Reply;
185     rep.supported = supported;
186     rep.length = 0;
187     rep.sequenceNumber = client->sequence;
188     rep.serverMajor = SERVER_XKB_MAJOR_VERSION;
189     rep.serverMinor = SERVER_XKB_MINOR_VERSION;
190     if ( client->swapped ) {
191         swaps(&rep.sequenceNumber);
192         swaps(&rep.serverMajor);
193         swaps(&rep.serverMinor);
194     }
195     WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep);
196     return Success;
197 }
198
199 /***====================================================================***/
200
201 int
202 ProcXkbSelectEvents(ClientPtr client)
203 {
204     unsigned            legal;
205     DeviceIntPtr        dev;
206     XkbInterestPtr      masks;
207     REQUEST(xkbSelectEventsReq);
208
209     REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
210
211     if (!(client->xkbClientFlags&_XkbClientInitialized))
212         return BadAccess;
213
214     CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess);
215
216     if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) {
217         client->mapNotifyMask&= ~stuff->affectMap;
218         client->mapNotifyMask|= (stuff->affectMap&stuff->map);
219     }
220     if ((stuff->affectWhich&(~XkbMapNotifyMask))==0) 
221         return Success;
222
223     masks = XkbFindClientResource((DevicePtr)dev,client);
224     if (!masks){
225         XID id = FakeClientID(client->index);
226         if (!AddResource(id,RT_XKBCLIENT,dev))
227             return BadAlloc;
228         masks= XkbAddClientResource((DevicePtr)dev,client,id);
229     }
230     if (masks) {
231         union {
232             CARD8       *c8;
233             CARD16      *c16;
234             CARD32      *c32;
235         } from,to;
236         register unsigned bit,ndx,maskLeft,dataLeft,size;
237
238         from.c8= (CARD8 *)&stuff[1];
239         dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
240         maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
241         for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
242             if ((bit&maskLeft)==0)
243                 continue;
244             maskLeft&= ~bit;
245             switch (ndx) {
246                 case XkbNewKeyboardNotify:
247                     to.c16= &client->newKeyboardNotifyMask;
248                     legal= XkbAllNewKeyboardEventsMask;
249                     size= 2;
250                     break;
251                 case XkbStateNotify:
252                     to.c16= &masks->stateNotifyMask;
253                     legal= XkbAllStateEventsMask;
254                     size= 2;
255                     break;
256                 case XkbControlsNotify:
257                     to.c32= &masks->ctrlsNotifyMask;
258                     legal= XkbAllControlEventsMask;
259                     size= 4;
260                     break;
261                 case XkbIndicatorStateNotify:
262                     to.c32= &masks->iStateNotifyMask;
263                     legal= XkbAllIndicatorEventsMask;
264                     size= 4;
265                     break;
266                 case XkbIndicatorMapNotify:
267                     to.c32= &masks->iMapNotifyMask;
268                     legal= XkbAllIndicatorEventsMask;
269                     size= 4;
270                     break;
271                 case XkbNamesNotify:
272                     to.c16= &masks->namesNotifyMask;
273                     legal= XkbAllNameEventsMask;
274                     size= 2;
275                     break;
276                 case XkbCompatMapNotify:
277                     to.c8= &masks->compatNotifyMask;
278                     legal= XkbAllCompatMapEventsMask;
279                     size= 1;
280                     break;
281                 case XkbBellNotify:
282                     to.c8= &masks->bellNotifyMask;
283                     legal= XkbAllBellEventsMask;
284                     size= 1;
285                     break;
286                 case XkbActionMessage:
287                     to.c8= &masks->actionMessageMask;
288                     legal= XkbAllActionMessagesMask;
289                     size= 1;
290                     break;
291                 case XkbAccessXNotify:
292                     to.c16= &masks->accessXNotifyMask;
293                     legal= XkbAllAccessXEventsMask;
294                     size= 2;
295                     break;
296                 case XkbExtensionDeviceNotify:
297                     to.c16= &masks->extDevNotifyMask;
298                     legal= XkbAllExtensionDeviceEventsMask;
299                     size= 2;
300                     break;
301                 default:
302                     client->errorValue = _XkbErrCode2(33,bit);
303                     return BadValue;
304             }
305
306             if (stuff->clear&bit) {
307                 if (size==2)            to.c16[0]= 0;
308                 else if (size==4)       to.c32[0]= 0;
309                 else                    to.c8[0]=  0;
310             }
311             else if (stuff->selectAll&bit) {
312                 if (size==2)            to.c16[0]= ~0;
313                 else if (size==4)       to.c32[0]= ~0;
314                 else                    to.c8[0]=  ~0;
315             }
316             else {
317                 if (dataLeft<(size*2))
318                     return BadLength;
319                 if (size==2) {
320                     CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]);
321                     CHK_MASK_LEGAL(ndx,from.c16[0],legal);
322                     to.c16[0]&= ~from.c16[0];
323                     to.c16[0]|= (from.c16[0]&from.c16[1]);
324                 }
325                 else if (size==4) {
326                     CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]);
327                     CHK_MASK_LEGAL(ndx,from.c32[0],legal);
328                     to.c32[0]&= ~from.c32[0];
329                     to.c32[0]|= (from.c32[0]&from.c32[1]);
330                 }
331                 else  {
332                     CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]);
333                     CHK_MASK_LEGAL(ndx,from.c8[0],legal);
334                     to.c8[0]&= ~from.c8[0];
335                     to.c8[0]|= (from.c8[0]&from.c8[1]);
336                     size= 2;
337                 }
338                 from.c8+= (size*2);
339                 dataLeft-= (size*2);
340             }
341         }
342         if (dataLeft>2) {
343             ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",dataLeft);
344             return BadLength;
345         }
346         return Success;
347     }
348     return BadAlloc;
349 }
350
351 /***====================================================================***/
352 /**
353  * Ring a bell on the given device for the given client.
354  */
355 static int
356 _XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
357          int bellClass, int bellID, int pitch, int duration,
358          int percent, int forceSound, int eventOnly, Atom name)
359 {
360     int         base;
361     pointer     ctrl;
362     int         oldPitch, oldDuration;
363     int         newPercent;
364
365     if (bellClass == KbdFeedbackClass) {
366         KbdFeedbackPtr  k;
367         if (bellID==XkbDfltXIId)
368             k= dev->kbdfeed;
369         else {
370             for (k=dev->kbdfeed; k; k=k->next) {
371                 if (k->ctrl.id == bellID)
372                     break;
373             }
374         }
375         if (!k) {
376             client->errorValue = _XkbErrCode2(0x5,bellID);
377             return BadValue;
378         }
379         base = k->ctrl.bell;
380         ctrl = (pointer) &(k->ctrl);
381         oldPitch= k->ctrl.bell_pitch;
382         oldDuration= k->ctrl.bell_duration;
383         if (pitch!=0) {
384             if (pitch==-1)
385                 k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch;
386             else k->ctrl.bell_pitch= pitch;
387         }
388         if (duration!=0) {
389             if (duration==-1)
390                 k->ctrl.bell_duration= defaultKeyboardControl.bell_duration;
391             else k->ctrl.bell_duration= duration;
392         }
393     }
394     else if (bellClass == BellFeedbackClass) {
395         BellFeedbackPtr b;
396         if (bellID==XkbDfltXIId)
397             b= dev->bell;
398         else {
399             for (b=dev->bell; b; b=b->next) {
400                 if (b->ctrl.id == bellID)
401                     break;
402             }
403         }
404         if (!b) {
405             client->errorValue = _XkbErrCode2(0x6,bellID);
406             return BadValue;
407         }
408         base = b->ctrl.percent;
409         ctrl = (pointer) &(b->ctrl);
410         oldPitch= b->ctrl.pitch;
411         oldDuration= b->ctrl.duration;
412         if (pitch!=0) {
413             if (pitch==-1)
414                 b->ctrl.pitch= defaultKeyboardControl.bell_pitch;
415             else b->ctrl.pitch= pitch;
416         }
417         if (duration!=0) {
418             if (duration==-1)
419                 b->ctrl.duration= defaultKeyboardControl.bell_duration;
420             else b->ctrl.duration= duration;
421         }
422     }
423     else {
424         client->errorValue = _XkbErrCode2(0x7, bellClass);
425         return BadValue;
426     }
427
428     newPercent = (base * percent)/100;
429     if (percent < 0)
430          newPercent = base + newPercent;
431     else newPercent = base - newPercent + percent;
432
433     XkbHandleBell(forceSound, eventOnly,
434                   dev, newPercent, ctrl, bellClass,
435                   name, pWin, client);
436     if ((pitch!=0)||(duration!=0)) {
437         if (bellClass == KbdFeedbackClass) {
438             KbdFeedbackPtr      k;
439             k= (KbdFeedbackPtr)ctrl;
440             if (pitch!=0)
441                 k->ctrl.bell_pitch= oldPitch;
442             if (duration!=0)
443                 k->ctrl.bell_duration= oldDuration;
444         }
445         else {
446             BellFeedbackPtr     b;
447             b= (BellFeedbackPtr)ctrl;
448             if (pitch!=0)
449                 b->ctrl.pitch= oldPitch;
450             if (duration!=0)
451                 b->ctrl.duration= oldDuration;
452         }
453     }
454
455     return Success;
456 }
457
458 int
459 ProcXkbBell(ClientPtr client)
460 {
461     REQUEST(xkbBellReq);
462     DeviceIntPtr dev;
463     WindowPtr    pWin;
464     int rc;
465
466     REQUEST_SIZE_MATCH(xkbBellReq);
467
468     if (!(client->xkbClientFlags&_XkbClientInitialized))
469         return BadAccess;
470
471     CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess);
472     CHK_ATOM_OR_NONE(stuff->name);
473
474     /* device-independent checks request for sane values */
475     if ((stuff->forceSound)&&(stuff->eventOnly)) {
476         client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly);
477         return BadMatch;
478     }
479     if (stuff->percent < -100 || stuff->percent > 100) {
480         client->errorValue = _XkbErrCode2(0x2,stuff->percent);
481         return BadValue;
482     }
483     if (stuff->duration<-1) {
484         client->errorValue = _XkbErrCode2(0x3,stuff->duration);
485         return BadValue;
486     }
487     if (stuff->pitch<-1) {
488         client->errorValue = _XkbErrCode2(0x4,stuff->pitch);
489         return BadValue;
490     }
491
492     if (stuff->bellClass == XkbDfltXIClass) {
493         if (dev->kbdfeed!=NULL)
494              stuff->bellClass= KbdFeedbackClass;
495         else stuff->bellClass= BellFeedbackClass;
496     }
497
498     if (stuff->window!=None) {
499         rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
500         if (rc != Success) {
501             client->errorValue= stuff->window;
502             return rc;
503         }
504     }
505     else pWin= NULL;
506
507     /* Client wants to ring a bell on the core keyboard?
508        Ring the bell on the core keyboard (which does nothing, but if that
509        fails the client is screwed anyway), and then on all extension devices.
510        Fail if the core keyboard fails but not the extension devices.  this
511        may cause some keyboards to ding and others to stay silent. Fix
512        your client to use explicit keyboards to avoid this.
513
514        dev is the device the client requested.
515      */
516     rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID,
517                   stuff->pitch, stuff->duration, stuff->percent,
518                   stuff->forceSound, stuff->eventOnly, stuff->name);
519
520     if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) ||
521                             (stuff->deviceSpec == XkbUseCorePtr)))
522     {
523         DeviceIntPtr other;
524         for (other = inputInfo.devices; other; other = other->next)
525         {
526             if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev)
527             {
528                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess);
529                 if (rc == Success)
530                     _XkbBell(client, other, pWin, stuff->bellClass,
531                              stuff->bellID, stuff->pitch, stuff->duration,
532                              stuff->percent, stuff->forceSound,
533                              stuff->eventOnly, stuff->name);
534             }
535         }
536         rc = Success; /* reset to success, that's what we got for the VCK */
537     }
538
539     return rc;
540 }
541
542 /***====================================================================***/
543
544 int
545 ProcXkbGetState(ClientPtr client)
546 {
547     REQUEST(xkbGetStateReq);
548     DeviceIntPtr        dev;
549     xkbGetStateReply     rep;
550     XkbStateRec         *xkb;
551
552     REQUEST_SIZE_MATCH(xkbGetStateReq);
553
554     if (!(client->xkbClientFlags&_XkbClientInitialized))
555         return BadAccess;
556
557     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
558
559     xkb= &dev->key->xkbInfo->state;
560     memset(&rep, 0, sizeof(xkbGetStateReply));
561     rep.type= X_Reply;
562     rep.sequenceNumber= client->sequence;
563     rep.length = 0;
564     rep.deviceID = dev->id;
565     rep.mods = XkbStateFieldFromRec(xkb) & 0xff;
566     rep.baseMods = xkb->base_mods;
567     rep.lockedMods = xkb->locked_mods;
568     rep.latchedMods = xkb->latched_mods;
569     rep.group = xkb->group;
570     rep.baseGroup = xkb->base_group;
571     rep.latchedGroup = xkb->latched_group;
572     rep.lockedGroup = xkb->locked_group;
573     rep.compatState = xkb->compat_state;
574     rep.ptrBtnState = xkb->ptr_buttons;
575     if (client->swapped) {
576         swaps(&rep.sequenceNumber);
577         swaps(&rep.ptrBtnState);
578     }
579     WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep);
580     return Success;
581 }
582
583 /***====================================================================***/
584
585 int
586 ProcXkbLatchLockState(ClientPtr client)
587 {
588     int status;
589     DeviceIntPtr dev, tmpd;
590     XkbStateRec oldState,*newState;
591     CARD16 changed;
592     xkbStateNotify sn;
593     XkbEventCauseRec cause;
594
595     REQUEST(xkbLatchLockStateReq);
596     REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
597
598     if (!(client->xkbClientFlags & _XkbClientInitialized))
599         return BadAccess;
600
601     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
602     CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks);
603     CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches);
604
605     status = Success;
606
607     for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
608         if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) {
609             if (!tmpd->key || !tmpd->key->xkbInfo)
610                 continue;
611
612             oldState = tmpd->key->xkbInfo->state;
613             newState = &tmpd->key->xkbInfo->state;
614             if (stuff->affectModLocks) {
615                 newState->locked_mods &= ~stuff->affectModLocks;
616                 newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks);
617             }
618             if (status == Success && stuff->lockGroup)
619                 newState->locked_group = stuff->groupLock;
620             if (status == Success && stuff->affectModLatches)
621                 status = XkbLatchModifiers(tmpd, stuff->affectModLatches,
622                                            stuff->modLatches);
623             if (status == Success && stuff->latchGroup)
624                 status = XkbLatchGroup(tmpd, stuff->groupLatch);
625
626             if (status != Success)
627                 return status;
628
629             XkbComputeDerivedState(tmpd->key->xkbInfo);
630
631             changed = XkbStateChangedFlags(&oldState, newState);
632             if (changed) {
633                 sn.keycode = 0;
634                 sn.eventType = 0;
635                 sn.requestMajor = XkbReqCode;
636                 sn.requestMinor = X_kbLatchLockState;
637                 sn.changed = changed;
638                 XkbSendStateNotify(tmpd, &sn);
639                 changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE);
640                 if (changed) {
641                     XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client);
642                     XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause);
643                 }
644             }
645         }
646     }
647
648     return Success;
649 }
650
651 /***====================================================================***/
652
653 int
654 ProcXkbGetControls(ClientPtr client)
655 {
656     xkbGetControlsReply rep;
657     XkbControlsPtr      xkb;
658     DeviceIntPtr        dev;
659
660     REQUEST(xkbGetControlsReq);
661     REQUEST_SIZE_MATCH(xkbGetControlsReq);
662
663     if (!(client->xkbClientFlags&_XkbClientInitialized))
664         return BadAccess;
665
666     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
667     
668     xkb = dev->key->xkbInfo->desc->ctrls;
669     rep.type = X_Reply;
670     rep.length = bytes_to_int32(SIZEOF(xkbGetControlsReply)-
671                   SIZEOF(xGenericReply));
672     rep.sequenceNumber = client->sequence;
673     rep.deviceID = ((DeviceIntPtr)dev)->id;
674     rep.numGroups = xkb->num_groups;
675     rep.groupsWrap = xkb->groups_wrap;
676     rep.internalMods = xkb->internal.mask;
677     rep.ignoreLockMods = xkb->ignore_lock.mask;
678     rep.internalRealMods = xkb->internal.real_mods;
679     rep.ignoreLockRealMods = xkb->ignore_lock.real_mods;
680     rep.internalVMods = xkb->internal.vmods;
681     rep.ignoreLockVMods = xkb->ignore_lock.vmods;
682     rep.enabledCtrls = xkb->enabled_ctrls;
683     rep.repeatDelay = xkb->repeat_delay;
684     rep.repeatInterval = xkb->repeat_interval;
685     rep.slowKeysDelay = xkb->slow_keys_delay;
686     rep.debounceDelay = xkb->debounce_delay;
687     rep.mkDelay = xkb->mk_delay;
688     rep.mkInterval = xkb->mk_interval;
689     rep.mkTimeToMax = xkb->mk_time_to_max;
690     rep.mkMaxSpeed = xkb->mk_max_speed;
691     rep.mkCurve = xkb->mk_curve;
692     rep.mkDfltBtn = xkb->mk_dflt_btn;
693     rep.axTimeout = xkb->ax_timeout;
694     rep.axtCtrlsMask = xkb->axt_ctrls_mask;
695     rep.axtCtrlsValues = xkb->axt_ctrls_values;
696     rep.axtOptsMask = xkb->axt_opts_mask;
697     rep.axtOptsValues = xkb->axt_opts_values;
698     rep.axOptions = xkb->ax_options;
699     memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize);
700     if (client->swapped) {
701         swaps(&rep.sequenceNumber);
702         swapl(&rep.length);
703         swaps(&rep.internalVMods);
704         swaps(&rep.ignoreLockVMods);
705         swapl(&rep.enabledCtrls);
706         swaps(&rep.repeatDelay);
707         swaps(&rep.repeatInterval);
708         swaps(&rep.slowKeysDelay);
709         swaps(&rep.debounceDelay);
710         swaps(&rep.mkDelay);
711         swaps(&rep.mkInterval);
712         swaps(&rep.mkTimeToMax);
713         swaps(&rep.mkMaxSpeed);
714         swaps(&rep.mkCurve);
715         swaps(&rep.axTimeout);
716         swapl(&rep.axtCtrlsMask);
717         swapl(&rep.axtCtrlsValues);
718         swaps(&rep.axtOptsMask);
719         swaps(&rep.axtOptsValues);
720         swaps(&rep.axOptions);
721     }
722     WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep);
723     return Success;
724 }
725
726 int
727 ProcXkbSetControls(ClientPtr client)
728 {
729     DeviceIntPtr        dev, tmpd;
730     XkbSrvInfoPtr       xkbi;
731     XkbControlsPtr      ctrl;
732     XkbControlsRec      new,old;
733     xkbControlsNotify   cn;
734     XkbEventCauseRec    cause;
735     XkbSrvLedInfoPtr    sli;
736
737     REQUEST(xkbSetControlsReq);
738     REQUEST_SIZE_MATCH(xkbSetControlsReq);
739
740     if (!(client->xkbClientFlags & _XkbClientInitialized))
741         return BadAccess;
742
743     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
744     CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask);
745
746     for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
747         if (!tmpd->key || !tmpd->key->xkbInfo)
748             continue;
749         if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) {
750             xkbi = tmpd->key->xkbInfo;
751             ctrl = xkbi->desc->ctrls;
752             new = *ctrl;
753             XkbSetCauseXkbReq(&cause, X_kbSetControls, client);
754
755             if (stuff->changeCtrls & XkbInternalModsMask) {
756                 CHK_MASK_MATCH(0x02, stuff->affectInternalMods,
757                                stuff->internalMods);
758                 CHK_MASK_MATCH(0x03, stuff->affectInternalVMods,
759                                stuff->internalVMods);
760
761                 new.internal.real_mods &= ~(stuff->affectInternalMods);
762                 new.internal.real_mods |= (stuff->affectInternalMods &
763                                            stuff->internalMods);
764                 new.internal.vmods &= ~(stuff->affectInternalVMods);
765                 new.internal.vmods |= (stuff->affectInternalVMods &
766                                        stuff->internalVMods);
767                 new.internal.mask = new.internal.real_mods |
768                                     XkbMaskForVMask(xkbi->desc,
769                                                     new.internal.vmods);
770             }
771
772             if (stuff->changeCtrls & XkbIgnoreLockModsMask) {
773                 CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods,
774                                stuff->ignoreLockMods);
775                 CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods,
776                                stuff->ignoreLockVMods);
777
778                 new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods);
779                 new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods &
780                                               stuff->ignoreLockMods);
781                 new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods);
782                 new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods &
783                                           stuff->ignoreLockVMods);
784                 new.ignore_lock.mask = new.ignore_lock.real_mods |
785                                        XkbMaskForVMask(xkbi->desc,
786                                                        new.ignore_lock.vmods);
787             }
788
789             CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls,
790                            stuff->enabledCtrls);
791             if (stuff->affectEnabledCtrls) {
792                 CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls,
793                                XkbAllBooleanCtrlsMask);
794
795                 new.enabled_ctrls &= ~(stuff->affectEnabledCtrls);
796                 new.enabled_ctrls |= (stuff->affectEnabledCtrls &
797                                       stuff->enabledCtrls);
798             }
799
800             if (stuff->changeCtrls & XkbRepeatKeysMask) {
801                 if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) {
802                     client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay,
803                                                       stuff->repeatInterval);
804                     return BadValue;
805                 }
806
807                 new.repeat_delay = stuff->repeatDelay;
808                 new.repeat_interval = stuff->repeatInterval;
809             }
810
811             if (stuff->changeCtrls & XkbSlowKeysMask) {
812                 if (stuff->slowKeysDelay < 1) {
813                     client->errorValue = _XkbErrCode2(0x09,
814                                                       stuff->slowKeysDelay);
815                     return BadValue;
816                 }
817
818                 new.slow_keys_delay = stuff->slowKeysDelay;
819             }
820
821             if (stuff->changeCtrls & XkbBounceKeysMask) {
822                 if (stuff->debounceDelay < 1) {
823                     client->errorValue = _XkbErrCode2(0x0A,
824                                                       stuff->debounceDelay);
825                     return BadValue;
826                 }
827
828                 new.debounce_delay = stuff->debounceDelay;
829             }
830
831             if (stuff->changeCtrls & XkbMouseKeysMask) {
832                 if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) {
833                     client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn);
834                     return BadValue;
835                 }
836
837                 new.mk_dflt_btn = stuff->mkDfltBtn;
838             }
839
840             if (stuff->changeCtrls & XkbMouseKeysAccelMask) {
841                 if (stuff->mkDelay < 1 || stuff->mkInterval < 1 ||
842                     stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 ||
843                     stuff->mkCurve < -1000) {
844                     client->errorValue = _XkbErrCode2(0x0C,0);
845                     return BadValue;
846                 }
847
848                 new.mk_delay = stuff->mkDelay;
849                 new.mk_interval = stuff->mkInterval;
850                 new.mk_time_to_max = stuff->mkTimeToMax;
851                 new.mk_max_speed = stuff->mkMaxSpeed;
852                 new.mk_curve = stuff->mkCurve;
853                 AccessXComputeCurveFactor(xkbi, &new);
854             }
855
856             if (stuff->changeCtrls & XkbGroupsWrapMask) {
857                 unsigned act, num;
858
859                 act = XkbOutOfRangeGroupAction(stuff->groupsWrap);
860                 switch (act) {
861                 case XkbRedirectIntoRange:
862                     num = XkbOutOfRangeGroupNumber(stuff->groupsWrap);
863                     if (num >= new.num_groups) {
864                         client->errorValue = _XkbErrCode3(0x0D, new.num_groups,
865                                                           num);
866                         return BadValue;
867                     }
868                 case XkbWrapIntoRange:
869                 case XkbClampIntoRange:
870                     break;
871                 default:
872                     client->errorValue = _XkbErrCode2(0x0E, act);
873                     return BadValue;
874                 }
875
876                 new.groups_wrap= stuff->groupsWrap;
877             }
878
879             CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask);
880             if (stuff->changeCtrls & XkbAccessXKeysMask) {
881                 new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask;
882             }
883             else {
884                 if (stuff->changeCtrls & XkbStickyKeysMask) {
885                     new.ax_options &= ~(XkbAX_SKOptionsMask);
886                     new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask);
887                 }
888             
889                 if (stuff->changeCtrls & XkbAccessXFeedbackMask) {
890                     new.ax_options &= ~(XkbAX_FBOptionsMask);
891                     new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask);
892                 }
893             }
894
895             if (stuff->changeCtrls & XkbAccessXTimeoutMask) {
896                 if (stuff->axTimeout < 1) {
897                     client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout);
898                     return BadValue;
899                 }
900                 CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask,
901                                stuff->axtCtrlsValues);
902                 CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask,
903                                XkbAllBooleanCtrlsMask);
904                 CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues);
905                 CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask);
906                 new.ax_timeout = stuff->axTimeout;
907                 new.axt_ctrls_mask = stuff->axtCtrlsMask;
908                 new.axt_ctrls_values = (stuff->axtCtrlsValues &
909                                         stuff->axtCtrlsMask);
910                 new.axt_opts_mask = stuff->axtOptsMask;
911                 new.axt_opts_values = (stuff->axtOptsValues &
912                                        stuff->axtOptsMask);
913             }
914
915             if (stuff->changeCtrls & XkbPerKeyRepeatMask) {
916                 memcpy(new.per_key_repeat, stuff->perKeyRepeat,
917                        XkbPerKeyBitArraySize);
918                 if (xkbi->repeatKey &&
919                     !BitIsOn(new.per_key_repeat, xkbi->repeatKey)) {
920                     AccessXCancelRepeatKey(xkbi, xkbi->repeatKey);
921                 }
922             }
923
924             old= *ctrl;
925             *ctrl= new;
926             XkbDDXChangeControls(tmpd, &old, ctrl);
927
928             if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) {
929                 cn.keycode = 0;
930                 cn.eventType = 0;
931                 cn.requestMajor = XkbReqCode;
932                 cn.requestMinor = X_kbSetControls;
933                 XkbSendControlsNotify(tmpd, &cn);
934             }
935
936             sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0);
937             if (sli)
938                 XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL,
939                                     &cause);
940
941             /* If sticky keys were disabled, clear all locks and latches */
942             if ((old.enabled_ctrls & XkbStickyKeysMask) &&
943                 !(ctrl->enabled_ctrls & XkbStickyKeysMask))
944                 XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause);
945         }
946     }
947
948     return Success;
949 }
950
951 /***====================================================================***/
952
953 static int
954 XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep)
955 {
956     XkbKeyTypeRec       *type;
957     unsigned            i,len;
958
959     len= 0;
960     if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)||
961         (!xkb)||(!xkb->map)||(!xkb->map->types)) {
962         rep->present&= ~XkbKeyTypesMask;
963         rep->firstType= rep->nTypes= 0;
964         return 0;
965     }
966     type= &xkb->map->types[rep->firstType];
967     for (i=0;i<rep->nTypes;i++,type++){
968         len+= SIZEOF(xkbKeyTypeWireDesc);
969         if (type->map_count>0) {
970             len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc));
971             if (type->preserve)
972                 len+= (type->map_count*SIZEOF(xkbModsWireDesc));
973         }
974     }
975     return len;
976 }
977
978 static char *
979 XkbWriteKeyTypes(       XkbDescPtr              xkb,
980                         xkbGetMapReply *        rep,
981                         char *                  buf,
982                         ClientPtr               client)
983 {
984     XkbKeyTypePtr       type;
985     unsigned            i;
986     xkbKeyTypeWireDesc *wire;
987
988     type= &xkb->map->types[rep->firstType];
989     for (i=0;i<rep->nTypes;i++,type++) {
990         register unsigned n;
991         wire= (xkbKeyTypeWireDesc *)buf;
992         wire->mask = type->mods.mask;
993         wire->realMods = type->mods.real_mods;
994         wire->virtualMods = type->mods.vmods;
995         wire->numLevels = type->num_levels;
996         wire->nMapEntries = type->map_count;
997         wire->preserve = (type->preserve!=NULL);
998         if (client->swapped) {
999             swaps(&wire->virtualMods);
1000         }       
1001
1002         buf= (char *)&wire[1];
1003         if (wire->nMapEntries>0) {
1004             xkbKTMapEntryWireDesc *     wire;
1005             XkbKTMapEntryPtr            entry;
1006             wire= (xkbKTMapEntryWireDesc *)buf;
1007             entry= type->map;
1008             for (n=0;n<type->map_count;n++,wire++,entry++) {
1009                 wire->active= entry->active;
1010                 wire->mask= entry->mods.mask;
1011                 wire->level= entry->level;
1012                 wire->realMods= entry->mods.real_mods;
1013                 wire->virtualMods= entry->mods.vmods;
1014                 if (client->swapped) {
1015                     swaps(&wire->virtualMods);
1016                 }
1017             }
1018             buf= (char *)wire;
1019             if (type->preserve!=NULL) {
1020                 xkbModsWireDesc *       pwire;
1021                 XkbModsPtr              preserve;
1022                 pwire= (xkbModsWireDesc *)buf;
1023                 preserve= type->preserve;
1024                 for (n=0;n<type->map_count;n++,pwire++,preserve++) {
1025                     pwire->mask= preserve->mask;
1026                     pwire->realMods= preserve->real_mods;
1027                     pwire->virtualMods= preserve->vmods;
1028                     if (client->swapped) {
1029                         swaps(&pwire->virtualMods);
1030                     }
1031                 }
1032                 buf= (char *)pwire;
1033             }
1034         }
1035     }
1036     return buf;
1037 }
1038
1039 static int
1040 XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep)
1041 {
1042     XkbSymMapPtr        symMap;
1043     unsigned            i,len;
1044     unsigned            nSyms,nSymsThisKey;
1045
1046     if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)||
1047         (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) {
1048         rep->present&= ~XkbKeySymsMask;
1049         rep->firstKeySym= rep->nKeySyms= 0;
1050         rep->totalSyms= 0;
1051         return 0;
1052     }
1053     len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc);
1054     symMap = &xkb->map->key_sym_map[rep->firstKeySym];
1055     for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) {
1056         if (symMap->offset!=0) {
1057             nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width;
1058             nSyms+= nSymsThisKey;
1059         }
1060     }
1061     len+= nSyms*4;
1062     rep->totalSyms= nSyms;
1063     return len;
1064 }
1065
1066 static int
1067 XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep)
1068 {
1069 register unsigned i,nMods,bit;
1070
1071     if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)||
1072         (!xkb)||(!xkb->server)) {
1073         rep->present&= ~XkbVirtualModsMask;
1074         rep->virtualMods= 0;
1075         return 0;
1076     }
1077     for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
1078         if (rep->virtualMods&bit)
1079             nMods++;
1080     }
1081     return XkbPaddedSize(nMods);
1082 }
1083
1084 static char *
1085 XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
1086 {
1087 register KeySym *       pSym;
1088 XkbSymMapPtr            symMap;
1089 xkbSymMapWireDesc *     outMap;
1090 register unsigned       i;
1091
1092     symMap = &xkb->map->key_sym_map[rep->firstKeySym];
1093     for (i=0;i<rep->nKeySyms;i++,symMap++) {
1094         outMap = (xkbSymMapWireDesc *)buf;
1095         outMap->ktIndex[0] = symMap->kt_index[0];
1096         outMap->ktIndex[1] = symMap->kt_index[1];
1097         outMap->ktIndex[2] = symMap->kt_index[2];
1098         outMap->ktIndex[3] = symMap->kt_index[3];
1099         outMap->groupInfo = symMap->group_info;
1100         outMap->width= symMap->width;
1101         outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info);
1102         buf= (char *)&outMap[1];
1103         if (outMap->nSyms==0)
1104             continue;
1105
1106         pSym = &xkb->map->syms[symMap->offset];
1107         memcpy((char *)buf,(char *)pSym,outMap->nSyms*4);
1108         if (client->swapped) {
1109             register int nSyms= outMap->nSyms;
1110             swaps(&outMap->nSyms);
1111             while (nSyms-->0) {
1112                 swapl(buf);
1113                 buf+= 4;
1114             }
1115         }
1116         else buf+= outMap->nSyms*4;
1117     }
1118     return buf;
1119 }
1120
1121 static int
1122 XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep)
1123 {
1124     unsigned            i,len,nActs;
1125     register KeyCode    firstKey;
1126
1127     if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)||
1128         (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) {
1129         rep->present&= ~XkbKeyActionsMask;
1130         rep->firstKeyAct= rep->nKeyActs= 0;
1131         rep->totalActs= 0;
1132         return 0;
1133     }
1134     firstKey= rep->firstKeyAct;
1135     for (nActs=i=0;i<rep->nKeyActs;i++) {
1136         if (xkb->server->key_acts[i+firstKey]!=0)
1137             nActs+= XkbKeyNumActions(xkb,i+firstKey);
1138     }
1139     len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
1140     rep->totalActs= nActs;
1141     return len;
1142 }
1143
1144 static char *
1145 XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
1146                                                         ClientPtr client)
1147 {
1148     unsigned            i;
1149     CARD8 *             numDesc;
1150     XkbAnyAction *      actDesc;
1151
1152     numDesc = (CARD8 *)buf;
1153     for (i=0;i<rep->nKeyActs;i++) {
1154         if (xkb->server->key_acts[i+rep->firstKeyAct]==0)
1155              numDesc[i] = 0;
1156         else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
1157     }
1158     buf+= XkbPaddedSize(rep->nKeyActs);
1159
1160     actDesc = (XkbAnyAction *)buf;
1161     for (i=0;i<rep->nKeyActs;i++) {
1162         if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) {
1163             unsigned int num;
1164             num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
1165             memcpy((char *)actDesc,
1166                    (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)),
1167                    num*SIZEOF(xkbActionWireDesc));
1168             actDesc+= num;
1169         }
1170     }
1171     buf = (char *)actDesc;
1172     return buf;
1173 }
1174
1175 static int
1176 XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep)
1177 {
1178     unsigned            i,len,nBhvr;
1179     XkbBehavior *       bhv;
1180
1181     if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)||
1182         (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) {
1183         rep->present&= ~XkbKeyBehaviorsMask;
1184         rep->firstKeyBehavior= rep->nKeyBehaviors= 0;
1185         rep->totalKeyBehaviors= 0;
1186         return 0;
1187     }
1188     bhv= &xkb->server->behaviors[rep->firstKeyBehavior];
1189     for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) {
1190         if (bhv->type!=XkbKB_Default)
1191             nBhvr++;
1192     }
1193     len= nBhvr*SIZEOF(xkbBehaviorWireDesc);
1194     rep->totalKeyBehaviors= nBhvr;
1195     return len;
1196 }
1197
1198 static char *
1199 XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
1200                                                         ClientPtr client)
1201 {
1202     unsigned            i;
1203     xkbBehaviorWireDesc *wire;
1204     XkbBehavior         *pBhvr;
1205
1206     wire = (xkbBehaviorWireDesc *)buf;
1207     pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior];
1208     for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) {
1209         if (pBhvr->type!=XkbKB_Default) {
1210             wire->key=  i+rep->firstKeyBehavior;
1211             wire->type= pBhvr->type;
1212             wire->data= pBhvr->data;
1213             wire++;
1214         }
1215     }
1216     buf = (char *)wire;
1217     return buf;
1218 }
1219
1220 static int
1221 XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep)
1222 {
1223     unsigned    i,len,nRtrn;
1224
1225     if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)||
1226         (!xkb)||(!xkb->server)||(!xkb->server->explicit)) {
1227         rep->present&= ~XkbExplicitComponentsMask;
1228         rep->firstKeyExplicit= rep->nKeyExplicit= 0;
1229         rep->totalKeyExplicit= 0;
1230         return 0;
1231     }
1232     for (nRtrn=i=0;i<rep->nKeyExplicit;i++) {
1233         if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0)
1234             nRtrn++;
1235     }
1236     rep->totalKeyExplicit= nRtrn;
1237     len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */
1238     return len;
1239 }
1240
1241 static char *
1242 XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
1243 {
1244 unsigned        i;
1245 char *          start;
1246 unsigned char * pExp;
1247
1248     start= buf;
1249     pExp= &xkb->server->explicit[rep->firstKeyExplicit];
1250     for (i=0;i<rep->nKeyExplicit;i++,pExp++) {
1251         if (*pExp!=0) {
1252             *buf++= i+rep->firstKeyExplicit;
1253             *buf++= *pExp;
1254         }
1255     }
1256     i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
1257     return buf+i;
1258 }
1259
1260 static int
1261 XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep)
1262 {
1263     unsigned    i,len,nRtrn;
1264
1265     if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)||
1266         (!xkb)||(!xkb->map)||(!xkb->map->modmap)) {
1267         rep->present&= ~XkbModifierMapMask;
1268         rep->firstModMapKey= rep->nModMapKeys= 0;
1269         rep->totalModMapKeys= 0;
1270         return 0;
1271     }
1272     for (nRtrn=i=0;i<rep->nModMapKeys;i++) {
1273         if (xkb->map->modmap[i+rep->firstModMapKey]!=0)
1274             nRtrn++;
1275     }
1276     rep->totalModMapKeys= nRtrn;
1277     len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */
1278     return len;
1279 }
1280
1281 static char *
1282 XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
1283                                                         ClientPtr client)
1284 {
1285 unsigned        i;
1286 char *          start;
1287 unsigned char * pMap;
1288
1289     start= buf;
1290     pMap= &xkb->map->modmap[rep->firstModMapKey];
1291     for (i=0;i<rep->nModMapKeys;i++,pMap++) {
1292         if (*pMap!=0) {
1293             *buf++= i+rep->firstModMapKey;
1294             *buf++= *pMap;
1295         }
1296     }
1297     i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
1298     return buf+i;
1299 }
1300
1301 static int
1302 XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep)
1303 {
1304     unsigned    i,len,nRtrn;
1305
1306     if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)||
1307         (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) {
1308         rep->present&= ~XkbVirtualModMapMask;
1309         rep->firstVModMapKey= rep->nVModMapKeys= 0;
1310         rep->totalVModMapKeys= 0;
1311         return 0;
1312     }
1313     for (nRtrn=i=0;i<rep->nVModMapKeys;i++) {
1314         if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0)
1315             nRtrn++;
1316     }
1317     rep->totalVModMapKeys= nRtrn;
1318     len= nRtrn*SIZEOF(xkbVModMapWireDesc);
1319     return len;
1320 }
1321
1322 static char *
1323 XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
1324                                                         ClientPtr client)
1325 {
1326 unsigned                i;
1327 xkbVModMapWireDesc *    wire;
1328 unsigned short *        pMap;
1329
1330     wire= (xkbVModMapWireDesc *)buf;
1331     pMap= &xkb->server->vmodmap[rep->firstVModMapKey];
1332     for (i=0;i<rep->nVModMapKeys;i++,pMap++) {
1333         if (*pMap!=0) {
1334             wire->key= i+rep->firstVModMapKey;
1335             wire->vmods= *pMap;
1336             wire++;
1337         }
1338     }
1339     return (char *)wire;
1340 }
1341
1342 static Status
1343 XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep)
1344 {
1345 int     len;
1346
1347     rep->minKeyCode= xkb->min_key_code;
1348     rep->maxKeyCode= xkb->max_key_code;
1349     len= XkbSizeKeyTypes(xkb,rep);
1350     len+= XkbSizeKeySyms(xkb,rep);
1351     len+= XkbSizeKeyActions(xkb,rep);
1352     len+= XkbSizeKeyBehaviors(xkb,rep);
1353     len+= XkbSizeVirtualMods(xkb,rep);
1354     len+= XkbSizeExplicit(xkb,rep);
1355     len+= XkbSizeModifierMap(xkb,rep);
1356     len+= XkbSizeVirtualModMap(xkb,rep);
1357     rep->length+= (len/4);
1358     return Success;
1359 }
1360
1361 static int
1362 XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep)
1363 {
1364 unsigned        i,len;
1365 char            *desc,*start;
1366
1367     len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
1368     start= desc= calloc(1, len);
1369     if (!start)
1370         return BadAlloc;
1371     if ( rep->nTypes>0 )
1372         desc = XkbWriteKeyTypes(xkb,rep,desc,client);
1373     if ( rep->nKeySyms>0 )
1374         desc = XkbWriteKeySyms(xkb,rep,desc,client);
1375     if ( rep->nKeyActs>0 )
1376         desc = XkbWriteKeyActions(xkb,rep,desc,client);
1377     if ( rep->totalKeyBehaviors>0 )
1378         desc = XkbWriteKeyBehaviors(xkb,rep,desc,client);
1379     if ( rep->virtualMods ) {
1380         register int sz,bit;
1381         for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
1382             if (rep->virtualMods&bit) {
1383                 desc[sz++]= xkb->server->vmods[i];
1384             }
1385         }
1386         desc+= XkbPaddedSize(sz);
1387     }
1388     if ( rep->totalKeyExplicit>0 )
1389         desc= XkbWriteExplicit(xkb,rep,desc,client);
1390     if ( rep->totalModMapKeys>0 )
1391         desc= XkbWriteModifierMap(xkb,rep,desc,client);
1392     if ( rep->totalVModMapKeys>0 )
1393         desc= XkbWriteVirtualModMap(xkb,rep,desc,client);
1394     if ((desc-start)!=(len)) {
1395         ErrorF("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n",
1396                                         len, (unsigned long)(desc-start));
1397     }
1398     if (client->swapped) {
1399         swaps(&rep->sequenceNumber);
1400         swapl(&rep->length);
1401         swaps(&rep->present);
1402         swaps(&rep->totalSyms);
1403         swaps(&rep->totalActs);
1404     }
1405     WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep);
1406     WriteToClient(client, len, start);
1407     free((char *)start);
1408     return Success;
1409 }
1410
1411 int
1412 ProcXkbGetMap(ClientPtr client)
1413 {
1414     DeviceIntPtr         dev;
1415     xkbGetMapReply       rep;
1416     XkbDescRec          *xkb;
1417     int                  n,status;
1418
1419     REQUEST(xkbGetMapReq);
1420     REQUEST_SIZE_MATCH(xkbGetMapReq);
1421     
1422     if (!(client->xkbClientFlags&_XkbClientInitialized))
1423         return BadAccess;
1424
1425     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
1426     CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial);
1427     CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask);
1428     CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask);
1429
1430     xkb= dev->key->xkbInfo->desc;
1431     memset(&rep, 0, sizeof(xkbGetMapReply));
1432     rep.type= X_Reply;
1433     rep.sequenceNumber= client->sequence;
1434     rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2;
1435     rep.deviceID = dev->id;
1436     rep.present = stuff->partial|stuff->full;
1437     rep.minKeyCode = xkb->min_key_code;
1438     rep.maxKeyCode = xkb->max_key_code;
1439     if ( stuff->full&XkbKeyTypesMask ) {
1440         rep.firstType = 0;
1441         rep.nTypes = xkb->map->num_types;
1442     }
1443     else if (stuff->partial&XkbKeyTypesMask) {
1444         if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) {
1445             client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types,
1446                                         stuff->firstType,stuff->nTypes);
1447             return BadValue;
1448         }
1449         rep.firstType = stuff->firstType;
1450         rep.nTypes = stuff->nTypes;
1451     }
1452     else rep.nTypes = 0;
1453     rep.totalTypes = xkb->map->num_types;
1454
1455     n= XkbNumKeys(xkb);
1456     if ( stuff->full&XkbKeySymsMask ) {
1457         rep.firstKeySym = xkb->min_key_code;
1458         rep.nKeySyms = n;
1459     }
1460     else if (stuff->partial&XkbKeySymsMask) {
1461         CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb);
1462         rep.firstKeySym = stuff->firstKeySym;
1463         rep.nKeySyms = stuff->nKeySyms;
1464     }
1465     else rep.nKeySyms = 0;
1466     rep.totalSyms= 0;
1467
1468     if ( stuff->full&XkbKeyActionsMask ) {
1469         rep.firstKeyAct= xkb->min_key_code;
1470         rep.nKeyActs= n;
1471     }
1472     else if (stuff->partial&XkbKeyActionsMask) {
1473         CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb);
1474         rep.firstKeyAct= stuff->firstKeyAct;
1475         rep.nKeyActs= stuff->nKeyActs;
1476     }
1477     else rep.nKeyActs= 0;
1478     rep.totalActs= 0;
1479
1480     if ( stuff->full&XkbKeyBehaviorsMask ) {
1481         rep.firstKeyBehavior = xkb->min_key_code;
1482         rep.nKeyBehaviors = n;
1483     }
1484     else if (stuff->partial&XkbKeyBehaviorsMask) {
1485         CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb);
1486         rep.firstKeyBehavior= stuff->firstKeyBehavior;
1487         rep.nKeyBehaviors= stuff->nKeyBehaviors;
1488     }
1489     else rep.nKeyBehaviors = 0;
1490     rep.totalKeyBehaviors= 0;
1491
1492     if (stuff->full&XkbVirtualModsMask)
1493         rep.virtualMods= ~0;
1494     else if (stuff->partial&XkbVirtualModsMask)
1495         rep.virtualMods= stuff->virtualMods;
1496     
1497     if (stuff->full&XkbExplicitComponentsMask) {
1498         rep.firstKeyExplicit= xkb->min_key_code;
1499         rep.nKeyExplicit= n;
1500     }
1501     else if (stuff->partial&XkbExplicitComponentsMask) {
1502         CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb);
1503         rep.firstKeyExplicit= stuff->firstKeyExplicit;
1504         rep.nKeyExplicit= stuff->nKeyExplicit;
1505     }
1506     else rep.nKeyExplicit = 0;
1507     rep.totalKeyExplicit=  0;
1508
1509     if (stuff->full&XkbModifierMapMask) {
1510         rep.firstModMapKey= xkb->min_key_code;
1511         rep.nModMapKeys= n;
1512     }
1513     else if (stuff->partial&XkbModifierMapMask) {
1514         CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb);
1515         rep.firstModMapKey= stuff->firstModMapKey;
1516         rep.nModMapKeys= stuff->nModMapKeys;
1517     }
1518     else rep.nModMapKeys = 0;
1519     rep.totalModMapKeys= 0;
1520
1521     if (stuff->full&XkbVirtualModMapMask) {
1522         rep.firstVModMapKey= xkb->min_key_code;
1523         rep.nVModMapKeys= n;
1524     }
1525     else if (stuff->partial&XkbVirtualModMapMask) {
1526         CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb);
1527         rep.firstVModMapKey= stuff->firstVModMapKey;
1528         rep.nVModMapKeys= stuff->nVModMapKeys;
1529     }
1530     else rep.nVModMapKeys = 0;
1531     rep.totalVModMapKeys= 0;
1532
1533     if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success)
1534         return status;
1535     return XkbSendMap(client,xkb,&rep);
1536 }
1537
1538 /***====================================================================***/
1539
1540 static int
1541 CheckKeyTypes(  ClientPtr       client,
1542                 XkbDescPtr      xkb,
1543                 xkbSetMapReq *  req,
1544                 xkbKeyTypeWireDesc **wireRtrn,
1545                 int      *      nMapsRtrn,
1546                 CARD8 *         mapWidthRtrn)
1547 {
1548 unsigned                nMaps;
1549 register unsigned       i,n;
1550 register CARD8 *        map;
1551 register xkbKeyTypeWireDesc     *wire = *wireRtrn;
1552
1553     if (req->firstType>((unsigned)xkb->map->num_types)) {
1554         *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types);
1555         return 0;
1556     }
1557     if (req->flags&XkbSetMapResizeTypes) {
1558         nMaps = req->firstType+req->nTypes;
1559         if (nMaps<XkbNumRequiredTypes) {  /* canonical types must be there */
1560             *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4);
1561             return 0;
1562         }
1563     }
1564     else if (req->present&XkbKeyTypesMask) {
1565         nMaps = xkb->map->num_types;
1566         if ((req->firstType+req->nTypes)>nMaps) {
1567             *nMapsRtrn = req->firstType+req->nTypes;
1568             return 0;
1569         }
1570     }
1571     else {
1572         *nMapsRtrn = xkb->map->num_types;
1573         for (i=0;i<xkb->map->num_types;i++) {
1574             mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1575         }
1576         return 1;
1577     }
1578
1579     for (i=0;i<req->firstType;i++) {
1580         mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1581     }
1582     for (i=0;i<req->nTypes;i++) {
1583         unsigned        width;
1584         if (client->swapped) {
1585             swaps(&wire->virtualMods);
1586         }
1587         n= i+req->firstType;
1588         width= wire->numLevels;
1589         if (width<1) {
1590             *nMapsRtrn= _XkbErrCode3(0x04,n,width);
1591             return 0;
1592         }
1593         else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */
1594             *nMapsRtrn= _XkbErrCode3(0x05,n,width);
1595             return 0;
1596         }
1597         else if ((width!=2)&&
1598                  ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)||
1599                   (n==XkbAlphabeticIndex))) {
1600             /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
1601             *nMapsRtrn= _XkbErrCode3(0x05,n,width);
1602             return 0;
1603         }
1604         if (wire->nMapEntries>0) {
1605             xkbKTSetMapEntryWireDesc *  mapWire;
1606             xkbModsWireDesc *           preWire;
1607             mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1];
1608             preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
1609             for (n=0;n<wire->nMapEntries;n++) {
1610                 if (client->swapped) {
1611                     swaps(&mapWire[n].virtualMods);
1612                 }
1613                 if (mapWire[n].realMods&(~wire->realMods)) {
1614                     *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods,
1615                                                  wire->realMods);
1616                     return 0;
1617                 }
1618                 if (mapWire[n].virtualMods&(~wire->virtualMods)) {
1619                     *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods);
1620                     return 0;
1621                 }
1622                 if (mapWire[n].level>=wire->numLevels) {
1623                     *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels,
1624                                                  mapWire[n].level);
1625                     return 0;
1626                 }
1627                 if (wire->preserve) {
1628                     if (client->swapped) {
1629                         swaps(&preWire[n].virtualMods);
1630                     }
1631                     if (preWire[n].realMods&(~mapWire[n].realMods)) {
1632                         *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods,
1633                                                         mapWire[n].realMods);
1634                         return 0;
1635                     }
1636                     if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) {
1637                         *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods);
1638                         return 0;
1639                     }
1640                 }
1641             }
1642             if (wire->preserve)
1643                  map= (CARD8 *)&preWire[wire->nMapEntries];
1644             else map= (CARD8 *)&mapWire[wire->nMapEntries];
1645         }
1646         else map= (CARD8 *)&wire[1];
1647         mapWidthRtrn[i+req->firstType] = wire->numLevels;
1648         wire= (xkbKeyTypeWireDesc *)map;
1649     }
1650     for (i=req->firstType+req->nTypes;i<nMaps;i++) {
1651         mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1652     }
1653     *nMapsRtrn = nMaps;
1654     *wireRtrn = wire;
1655     return 1;
1656 }
1657
1658 static int
1659 CheckKeySyms(   ClientPtr               client,
1660                 XkbDescPtr              xkb,
1661                 xkbSetMapReq *          req,
1662                 int                     nTypes,
1663                 CARD8 *                 mapWidths,
1664                 CARD16 *                symsPerKey,
1665                 xkbSymMapWireDesc **    wireRtrn,
1666                 int *                   errorRtrn)
1667 {
1668 register unsigned       i;
1669 XkbSymMapPtr            map;
1670 xkbSymMapWireDesc*      wire = *wireRtrn;
1671
1672     if (!(XkbKeySymsMask&req->present))
1673         return 1;
1674     CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0);
1675     for (i=0;i<req->nKeySyms;i++) {
1676         KeySym *pSyms;
1677         register unsigned nG;
1678         if (client->swapped) {
1679             swaps(&wire->nSyms);
1680         }
1681         nG = XkbNumGroups(wire->groupInfo);
1682         if (nG>XkbNumKbdGroups) {
1683             *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG);
1684             return 0;
1685         }
1686         if (nG>0) {
1687             register int g,w;
1688             for (g=w=0;g<nG;g++) {
1689                 if (wire->ktIndex[g]>=(unsigned)nTypes) {
1690                     *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g,
1691                                                            wire->ktIndex[g]);
1692                     return 0;
1693                 }
1694                 if (mapWidths[wire->ktIndex[g]]>w)
1695                     w= mapWidths[wire->ktIndex[g]];
1696             }
1697             if (wire->width!=w) {
1698                 *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width);
1699                 return 0;
1700             }
1701             w*= nG;
1702             symsPerKey[i+req->firstKeySym] = w;
1703             if (w!=wire->nSyms) {
1704                 *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w);
1705                 return 0;
1706             }
1707         }
1708         else if (wire->nSyms!=0) {
1709             *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms);
1710             return 0;
1711         }
1712         pSyms = (KeySym *)&wire[1];
1713         wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
1714     }
1715
1716     map = &xkb->map->key_sym_map[i];
1717     for (;i<=(unsigned)xkb->max_key_code;i++,map++) {
1718         register int g,nG,w;
1719         nG= XkbKeyNumGroups(xkb,i);
1720         for (w=g=0;g<nG;g++)  {
1721             if (map->kt_index[g]>=(unsigned)nTypes) {
1722                 *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]);
1723                 return 0;
1724             }
1725             if (mapWidths[map->kt_index[g]]>w)
1726                     w= mapWidths[map->kt_index[g]];
1727         }
1728         symsPerKey[i] = w*nG;
1729     }
1730     *wireRtrn = wire;
1731     return 1;
1732 }
1733
1734 static int
1735 CheckKeyActions(        XkbDescPtr      xkb,
1736                         xkbSetMapReq *  req,
1737                         int             nTypes,
1738                         CARD8 *         mapWidths,
1739                         CARD16 *        symsPerKey,
1740                         CARD8 **        wireRtrn,
1741                         int *           nActsRtrn)
1742 {
1743 int                      nActs;
1744 CARD8 *                  wire = *wireRtrn;
1745 register unsigned        i;
1746
1747     if (!(XkbKeyActionsMask&req->present))
1748         return 1;
1749     CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0);
1750     for (nActs=i=0;i<req->nKeyActs;i++) {
1751         if (wire[0]!=0) {
1752             if (wire[0]==symsPerKey[i+req->firstKeyAct])
1753                 nActs+= wire[0];
1754             else {
1755                 *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]);
1756                 return 0;
1757             }
1758         }
1759         wire++;
1760     }
1761     if (req->nKeyActs%4)
1762         wire+= 4-(req->nKeyActs%4);
1763     *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs);
1764     *nActsRtrn = nActs;
1765     return 1;
1766 }
1767
1768 static int
1769 CheckKeyBehaviors(      XkbDescPtr              xkb,
1770                         xkbSetMapReq *          req,
1771                         xkbBehaviorWireDesc **  wireRtrn,
1772                         int *                   errorRtrn)
1773 {
1774 register xkbBehaviorWireDesc *  wire = *wireRtrn;
1775 register XkbServerMapPtr        server = xkb->server;
1776 register unsigned               i;
1777 unsigned                        first,last;
1778
1779     if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) {
1780         req->present&= ~XkbKeyBehaviorsMask;
1781         req->nKeyBehaviors= 0;
1782         return 1;
1783     }
1784     first= req->firstKeyBehavior;
1785     last=  req->firstKeyBehavior+req->nKeyBehaviors-1;
1786     if (first<req->minKeyCode) {
1787         *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode);
1788         return 0;
1789     }
1790     if (last>req->maxKeyCode) {
1791         *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode);
1792         return 0;
1793     }
1794         
1795     for (i=0;i<req->totalKeyBehaviors;i++,wire++) {
1796         if ((wire->key<first)||(wire->key>last)) {
1797             *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key);
1798             return 0;
1799         }
1800         if ((wire->type&XkbKB_Permanent)&&
1801             ((server->behaviors[wire->key].type!=wire->type)||
1802              (server->behaviors[wire->key].data!=wire->data))) {
1803             *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type);
1804             return 0;
1805         }
1806         if ((wire->type==XkbKB_RadioGroup)&&
1807                 ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) {
1808             *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data,
1809                                                         XkbMaxRadioGroups);
1810             return 0;
1811         }
1812         if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) {
1813             CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0);
1814         }
1815     }
1816     *wireRtrn = wire;
1817     return 1;
1818 }
1819
1820 static int
1821 CheckVirtualMods(       XkbDescRec *    xkb,
1822                         xkbSetMapReq *  req,
1823                         CARD8 **        wireRtrn,
1824                         int *           errorRtrn)
1825 {
1826 register CARD8          *wire = *wireRtrn;
1827 register unsigned        i,nMods,bit;
1828
1829     if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
1830         return 1;
1831     for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
1832         if (req->virtualMods&bit)
1833             nMods++;
1834     }
1835     *wireRtrn= (wire+XkbPaddedSize(nMods));
1836     return 1;
1837 }
1838
1839 static int
1840 CheckKeyExplicit(       XkbDescPtr      xkb,
1841                         xkbSetMapReq *  req,
1842                         CARD8 **        wireRtrn,
1843                         int     *       errorRtrn)
1844 {
1845 register CARD8 *        wire = *wireRtrn;
1846 CARD8   *               start;
1847 register unsigned       i;
1848 int                     first,last;
1849
1850     if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) {
1851         req->present&= ~XkbExplicitComponentsMask;
1852         req->nKeyExplicit= 0;
1853         return 1;
1854     }
1855     first= req->firstKeyExplicit;
1856     last=  first+req->nKeyExplicit-1;
1857     if (first<req->minKeyCode) {
1858         *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode);
1859         return 0;
1860     }
1861     if (last>req->maxKeyCode) {
1862         *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode);
1863         return 0;
1864     }
1865     start= wire; 
1866     for (i=0;i<req->totalKeyExplicit;i++,wire+=2) {
1867         if ((wire[0]<first)||(wire[0]>last)) {
1868             *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]);
1869             return 0;
1870         }
1871         if (wire[1]&(~XkbAllExplicitMask)) {
1872              *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]);
1873              return 0;
1874         }
1875     }
1876     wire+= XkbPaddedSize(wire-start)-(wire-start);
1877     *wireRtrn= wire;
1878     return 1;
1879 }
1880
1881 static int
1882 CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn)
1883 {
1884 register CARD8 *        wire = *wireRtrn;
1885 CARD8   *               start;
1886 register unsigned       i;
1887 int                     first,last;
1888
1889     if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) {
1890         req->present&= ~XkbModifierMapMask;
1891         req->nModMapKeys= 0;
1892         return 1;
1893     }
1894     first= req->firstModMapKey;
1895     last=  first+req->nModMapKeys-1;
1896     if (first<req->minKeyCode) {
1897         *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode);
1898         return 0;
1899     }
1900     if (last>req->maxKeyCode) {
1901         *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode);
1902         return 0;
1903     }
1904     start= wire; 
1905     for (i=0;i<req->totalModMapKeys;i++,wire+=2) {
1906         if ((wire[0]<first)||(wire[0]>last)) {
1907             *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]);
1908             return 0;
1909         }
1910     }
1911     wire+= XkbPaddedSize(wire-start)-(wire-start);
1912     *wireRtrn= wire;
1913     return 1;
1914 }
1915
1916 static int
1917 CheckVirtualModMap(     XkbDescPtr xkb,
1918                         xkbSetMapReq *req,
1919                         xkbVModMapWireDesc **wireRtrn,
1920                         int *errRtrn)
1921 {
1922 register xkbVModMapWireDesc *   wire = *wireRtrn;
1923 register unsigned               i;
1924 int                             first,last;
1925
1926     if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) {
1927         req->present&= ~XkbVirtualModMapMask;
1928         req->nVModMapKeys= 0;
1929         return 1;
1930     }
1931     first= req->firstVModMapKey;
1932     last=  first+req->nVModMapKeys-1;
1933     if (first<req->minKeyCode) {
1934         *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode);
1935         return 0;
1936     }
1937     if (last>req->maxKeyCode) {
1938         *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode);
1939         return 0;
1940     }
1941     for (i=0;i<req->totalVModMapKeys;i++,wire++) {
1942         if ((wire->key<first)||(wire->key>last)) {
1943             *errRtrn = _XkbErrCode4(0x73,first,last,wire->key);
1944             return 0;
1945         }
1946     }
1947     *wireRtrn= wire;
1948     return 1;
1949 }
1950
1951 static char *
1952 SetKeyTypes(    XkbDescPtr              xkb,
1953                 xkbSetMapReq *          req,
1954                 xkbKeyTypeWireDesc *    wire,
1955                 XkbChangesPtr           changes)
1956 {
1957 register unsigned       i;
1958 unsigned                first,last;
1959 CARD8                   *map;
1960
1961     if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) {
1962         i= req->firstType+req->nTypes;
1963         if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) {
1964             return NULL;
1965         }
1966     }
1967     if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types)
1968         xkb->map->num_types= req->firstType+req->nTypes;
1969
1970     for (i=0;i<req->nTypes;i++) {
1971         XkbKeyTypePtr           pOld;
1972         register unsigned       n;
1973
1974         if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries,
1975                                 wire->preserve,wire->numLevels)!=Success) {
1976             return NULL;
1977         }
1978         pOld = &xkb->map->types[i+req->firstType];
1979         map = (CARD8 *)&wire[1];
1980
1981         pOld->mods.real_mods = wire->realMods;
1982         pOld->mods.vmods= wire->virtualMods;
1983         pOld->num_levels = wire->numLevels;
1984         pOld->map_count= wire->nMapEntries;
1985
1986         pOld->mods.mask= pOld->mods.real_mods|
1987                                         XkbMaskForVMask(xkb,pOld->mods.vmods);
1988
1989         if (wire->nMapEntries) {
1990             xkbKTSetMapEntryWireDesc *mapWire;
1991             xkbModsWireDesc *preWire;
1992             unsigned tmp;
1993             mapWire= (xkbKTSetMapEntryWireDesc *)map;
1994             preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
1995             for (n=0;n<wire->nMapEntries;n++) {
1996                 pOld->map[n].active= 1;
1997                 pOld->map[n].mods.mask= mapWire[n].realMods;
1998                 pOld->map[n].mods.real_mods= mapWire[n].realMods;
1999                 pOld->map[n].mods.vmods= mapWire[n].virtualMods;
2000                 pOld->map[n].level= mapWire[n].level;
2001                 if (mapWire[n].virtualMods!=0) {
2002                     tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods);
2003                     pOld->map[n].active= (tmp!=0);
2004                     pOld->map[n].mods.mask|= tmp;
2005                 }
2006                 if (wire->preserve) {
2007                     pOld->preserve[n].real_mods= preWire[n].realMods;
2008                     pOld->preserve[n].vmods= preWire[n].virtualMods;
2009                     tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods);
2010                     pOld->preserve[n].mask= preWire[n].realMods|tmp;
2011                 }
2012             }
2013             if (wire->preserve)
2014                  map= (CARD8 *)&preWire[wire->nMapEntries];
2015             else map= (CARD8 *)&mapWire[wire->nMapEntries];
2016         }
2017         else map= (CARD8 *)&wire[1];
2018         wire = (xkbKeyTypeWireDesc *)map;
2019     }
2020     first= req->firstType;
2021     last= first+req->nTypes-1; /* last changed type */
2022     if (changes->map.changed&XkbKeyTypesMask) {
2023         int oldLast;
2024         oldLast= changes->map.first_type+changes->map.num_types-1;
2025         if (changes->map.first_type<first)
2026             first= changes->map.first_type;
2027         if (oldLast>last)
2028             last= oldLast;
2029     }
2030     changes->map.changed|= XkbKeyTypesMask;
2031     changes->map.first_type = first;
2032     changes->map.num_types = (last-first)+1;
2033     return (char *)wire;
2034 }
2035
2036 static char *
2037 SetKeySyms(     ClientPtr               client,
2038                 XkbDescPtr              xkb,
2039                 xkbSetMapReq *          req,
2040                 xkbSymMapWireDesc *     wire,
2041                 XkbChangesPtr           changes,
2042                 DeviceIntPtr            dev)
2043 {
2044 register unsigned       i,s;
2045 XkbSymMapPtr            oldMap;
2046 KeySym *                newSyms;
2047 KeySym *                pSyms;
2048 unsigned                first,last;
2049
2050     oldMap = &xkb->map->key_sym_map[req->firstKeySym];
2051     for (i=0;i<req->nKeySyms;i++,oldMap++) {
2052         pSyms = (KeySym *)&wire[1];
2053         if (wire->nSyms>0) {
2054             newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms);
2055             for (s=0;s<wire->nSyms;s++) {
2056                 newSyms[s]= pSyms[s];
2057             }
2058             if (client->swapped) {
2059                 for (s=0;s<wire->nSyms;s++) {
2060                     swapl(&newSyms[s]);
2061                 }
2062             }
2063         }
2064         oldMap->kt_index[0] = wire->ktIndex[0];
2065         oldMap->kt_index[1] = wire->ktIndex[1];
2066         oldMap->kt_index[2] = wire->ktIndex[2];
2067         oldMap->kt_index[3] = wire->ktIndex[3];
2068         oldMap->group_info = wire->groupInfo;
2069         oldMap->width = wire->width;
2070         wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
2071     }
2072     first= req->firstKeySym;
2073     last= first+req->nKeySyms-1;
2074     if (changes->map.changed&XkbKeySymsMask) {
2075         int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1);
2076         if (changes->map.first_key_sym<first)
2077             first= changes->map.first_key_sym;
2078         if (oldLast>last)
2079             last= oldLast;
2080     }
2081     changes->map.changed|= XkbKeySymsMask;
2082     changes->map.first_key_sym = first;
2083     changes->map.num_key_syms = (last-first+1);
2084
2085     s= 0;
2086     for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
2087         if (XkbKeyNumGroups(xkb,i)>s)
2088             s= XkbKeyNumGroups(xkb,i);
2089     }
2090     if (s!=xkb->ctrls->num_groups) {
2091         xkbControlsNotify       cn;
2092         XkbControlsRec          old;
2093         cn.keycode= 0;
2094         cn.eventType= 0;
2095         cn.requestMajor= XkbReqCode;
2096         cn.requestMinor= X_kbSetMap;
2097         old= *xkb->ctrls;
2098         xkb->ctrls->num_groups= s;
2099         if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,FALSE))
2100             XkbSendControlsNotify(dev,&cn);
2101     }
2102     return (char *)wire;
2103 }
2104
2105 static char *
2106 SetKeyActions(  XkbDescPtr      xkb,
2107                 xkbSetMapReq *  req,
2108                 CARD8 *         wire,
2109                 XkbChangesPtr   changes)
2110 {
2111 register unsigned       i,first,last;
2112 CARD8 *                 nActs = wire;
2113 XkbAction *             newActs;
2114     
2115     wire+= XkbPaddedSize(req->nKeyActs);
2116     for (i=0;i<req->nKeyActs;i++) {
2117         if (nActs[i]==0)
2118             xkb->server->key_acts[i+req->firstKeyAct]= 0;
2119         else {
2120             newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]);
2121             memcpy((char *)newActs,(char *)wire,
2122                                         nActs[i]*SIZEOF(xkbActionWireDesc));
2123             wire+= nActs[i]*SIZEOF(xkbActionWireDesc);
2124         }
2125     }
2126     first= req->firstKeyAct;
2127     last= (first+req->nKeyActs-1);
2128     if (changes->map.changed&XkbKeyActionsMask) {
2129         int oldLast;
2130         oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
2131         if (changes->map.first_key_act<first)
2132             first= changes->map.first_key_act;
2133         if (oldLast>last)
2134             last= oldLast;
2135     }
2136     changes->map.changed|= XkbKeyActionsMask;
2137     changes->map.first_key_act= first;
2138     changes->map.num_key_acts= (last-first+1);
2139     return (char *)wire;
2140 }
2141
2142 static char *
2143 SetKeyBehaviors(        XkbSrvInfoPtr    xkbi,
2144                         xkbSetMapReq    *req,
2145                         xkbBehaviorWireDesc     *wire,
2146                         XkbChangesPtr    changes)
2147 {
2148 register unsigned i;
2149 int maxRG = -1;
2150 XkbDescPtr       xkb = xkbi->desc;
2151 XkbServerMapPtr  server = xkb->server;
2152 unsigned         first,last;
2153
2154     first= req->firstKeyBehavior;
2155     last= req->firstKeyBehavior+req->nKeyBehaviors-1;
2156     memset(&server->behaviors[first], 0, req->nKeyBehaviors*sizeof(XkbBehavior));
2157     for (i=0;i<req->totalKeyBehaviors;i++) {
2158         if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) {
2159             server->behaviors[wire->key].type= wire->type;
2160             server->behaviors[wire->key].data= wire->data;
2161             if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG))
2162                 maxRG= wire->data + 1;
2163         }
2164         wire++;
2165     }
2166
2167     if (maxRG>(int)xkbi->nRadioGroups) {
2168         int sz = maxRG*sizeof(XkbRadioGroupRec);
2169         if (xkbi->radioGroups)
2170              xkbi->radioGroups= realloc(xkbi->radioGroups,sz);
2171         else xkbi->radioGroups= calloc(1, sz);
2172         if (xkbi->radioGroups) {
2173              if (xkbi->nRadioGroups)
2174                  memset(&xkbi->radioGroups[xkbi->nRadioGroups], 0,
2175                         (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec));
2176              xkbi->nRadioGroups= maxRG;
2177         }
2178         else xkbi->nRadioGroups= 0;
2179         /* should compute members here */
2180     }
2181     if (changes->map.changed&XkbKeyBehaviorsMask) {
2182         unsigned oldLast;
2183         oldLast= changes->map.first_key_behavior+
2184                                         changes->map.num_key_behaviors-1;
2185         if (changes->map.first_key_behavior<req->firstKeyBehavior)
2186              first= changes->map.first_key_behavior;
2187         if (oldLast>last)
2188             last= oldLast;
2189     }
2190     changes->map.changed|= XkbKeyBehaviorsMask;
2191     changes->map.first_key_behavior = first;
2192     changes->map.num_key_behaviors = (last-first+1);
2193     return (char *)wire;
2194 }
2195
2196 static char *
2197 SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
2198                                                 XkbChangesPtr changes)
2199 {
2200 register int            i,bit,nMods;
2201 XkbServerMapPtr         srv = xkbi->desc->server;
2202
2203     if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
2204         return (char *)wire;
2205     for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
2206         if (req->virtualMods&bit) {
2207             if (srv->vmods[i]!=wire[nMods]) {
2208                 changes->map.changed|= XkbVirtualModsMask;
2209                 changes->map.vmods|= bit;
2210                 srv->vmods[i]= wire[nMods];
2211             }
2212             nMods++;
2213         }
2214     }
2215     return (char *)(wire+XkbPaddedSize(nMods));
2216 }
2217
2218 static char *
2219 SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
2220                                                         XkbChangesPtr changes)
2221 {
2222 register unsigned       i,first,last;
2223 XkbServerMapPtr         xkb = xkbi->desc->server;
2224 CARD8 *                 start;
2225
2226     start= wire;
2227     first= req->firstKeyExplicit;
2228     last=  req->firstKeyExplicit+req->nKeyExplicit-1;
2229     memset(&xkb->explicit[first], 0, req->nKeyExplicit);
2230     for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) {
2231         xkb->explicit[wire[0]]= wire[1];
2232     }
2233     if (first>0) {
2234         if (changes->map.changed&XkbExplicitComponentsMask) {
2235             int oldLast;
2236             oldLast= changes->map.first_key_explicit+
2237                                         changes->map.num_key_explicit-1;
2238             if (changes->map.first_key_explicit<first)
2239                 first= changes->map.first_key_explicit;
2240             if (oldLast>last)
2241                 last= oldLast;
2242         }
2243         changes->map.first_key_explicit= first;
2244         changes->map.num_key_explicit= (last-first)+1;
2245     }
2246     wire+= XkbPaddedSize(wire-start)-(wire-start);
2247     return (char *)wire;
2248 }
2249
2250 static char *
2251 SetModifierMap( XkbSrvInfoPtr   xkbi,
2252                 xkbSetMapReq *  req,
2253                 CARD8 *         wire,
2254                 XkbChangesPtr   changes)
2255 {
2256 register unsigned       i,first,last;
2257 XkbClientMapPtr         xkb = xkbi->desc->map;
2258 CARD8 *                 start;
2259
2260     start= wire;
2261     first= req->firstModMapKey;
2262     last=  req->firstModMapKey+req->nModMapKeys-1;
2263     memset(&xkb->modmap[first], 0, req->nModMapKeys);
2264     for (i=0;i<req->totalModMapKeys;i++,wire+= 2) {
2265         xkb->modmap[wire[0]]= wire[1];
2266     }
2267     if (first>0) {
2268         if (changes->map.changed&XkbModifierMapMask) {
2269             int oldLast;
2270             oldLast= changes->map.first_modmap_key+
2271                                                 changes->map.num_modmap_keys-1;
2272             if (changes->map.first_modmap_key<first)
2273                 first= changes->map.first_modmap_key;
2274             if (oldLast>last)
2275                 last= oldLast;
2276         }
2277         changes->map.first_modmap_key= first;
2278         changes->map.num_modmap_keys= (last-first)+1;
2279     }
2280     wire+= XkbPaddedSize(wire-start)-(wire-start);
2281     return (char *)wire;
2282 }
2283
2284 static char *
2285 SetVirtualModMap(       XkbSrvInfoPtr           xkbi,
2286                         xkbSetMapReq *          req,
2287                         xkbVModMapWireDesc *    wire,
2288                         XkbChangesPtr           changes)
2289 {
2290 register unsigned       i,first,last;
2291 XkbServerMapPtr         srv = xkbi->desc->server;
2292
2293     first= req->firstVModMapKey;
2294     last=  req->firstVModMapKey+req->nVModMapKeys-1;
2295     memset(&srv->vmodmap[first], 0, req->nVModMapKeys*sizeof(unsigned short));
2296     for (i=0;i<req->totalVModMapKeys;i++,wire++) {
2297         srv->vmodmap[wire->key]= wire->vmods;
2298     }
2299     if (first>0) {
2300         if (changes->map.changed&XkbVirtualModMapMask) {
2301             int oldLast;
2302             oldLast= changes->map.first_vmodmap_key+
2303                                         changes->map.num_vmodmap_keys-1;
2304             if (changes->map.first_vmodmap_key<first)
2305                 first= changes->map.first_vmodmap_key;
2306             if (oldLast>last)
2307                 last= oldLast;
2308         }
2309         changes->map.first_vmodmap_key= first;
2310         changes->map.num_vmodmap_keys= (last-first)+1;
2311     }
2312     return (char *)wire;
2313 }
2314
2315 /**
2316  * Check if the given request can be applied to the given device but don't
2317  * actually do anything..
2318  */
2319 static int
2320 _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* values)
2321 {
2322     XkbSrvInfoPtr       xkbi;
2323     XkbDescPtr          xkb;
2324     int                 error;
2325     int                 nTypes = 0, nActions;
2326     CARD8               mapWidths[XkbMaxLegalKeyCode + 1] = {0};
2327     CARD16              symsPerKey[XkbMaxLegalKeyCode + 1] = {0};
2328     XkbSymMapPtr        map;
2329     int                 i;
2330
2331     xkbi= dev->key->xkbInfo;
2332     xkb = xkbi->desc;
2333
2334     if ((xkb->min_key_code != req->minKeyCode)||
2335         (xkb->max_key_code != req->maxKeyCode)) {
2336         if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */
2337             req->minKeyCode= xkb->min_key_code;
2338             req->maxKeyCode= xkb->max_key_code;
2339         }
2340         else {
2341             if (!XkbIsLegalKeycode(req->minKeyCode)) {
2342                 client->errorValue = _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode);
2343                 return BadValue;
2344             }
2345             if (req->minKeyCode > req->maxKeyCode) {
2346                 client->errorValue = _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode);
2347                 return BadMatch;
2348             }
2349         }
2350     }
2351
2352     if ((req->present & XkbKeyTypesMask) &&
2353         (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values,
2354                                                 &nTypes,mapWidths))) {
2355         client->errorValue = nTypes;
2356         return BadValue;
2357     }
2358
2359     /* symsPerKey/mapWidths must be filled regardless of client-side flags */
2360     map = &xkb->map->key_sym_map[xkb->min_key_code];
2361     for (i=xkb->min_key_code;i<xkb->max_key_code;i++,map++) {
2362         register int g,ng,w;
2363         ng= XkbNumGroups(map->group_info);
2364         for (w=g=0;g<ng;g++) {
2365             if (map->kt_index[g]>=(unsigned)nTypes) {
2366                 client->errorValue = _XkbErrCode4(0x13,i,g,map->kt_index[g]);
2367                 return 0;
2368             }
2369             if (mapWidths[map->kt_index[g]]>w)
2370                 w= mapWidths[map->kt_index[g]];
2371         }
2372         symsPerKey[i] = w*ng;
2373     }
2374
2375     if ((req->present & XkbKeySymsMask) &&
2376         (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey,
2377                                         (xkbSymMapWireDesc **)&values,&error))) {
2378         client->errorValue = error;
2379         return BadValue;
2380     }
2381
2382     if ((req->present & XkbKeyActionsMask) &&
2383         (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey,
2384                                                 (CARD8 **)&values,&nActions))) {
2385         client->errorValue = nActions;
2386         return BadValue;
2387     }
2388
2389     if ((req->present & XkbKeyBehaviorsMask) &&
2390         (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) {
2391         client->errorValue = error;
2392         return BadValue;
2393     }
2394
2395     if ((req->present & XkbVirtualModsMask) &&
2396         (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) {
2397         client->errorValue= error;
2398         return BadValue;
2399     }
2400     if ((req->present&XkbExplicitComponentsMask) &&
2401         (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) {
2402         client->errorValue= error;
2403         return BadValue;
2404     }
2405     if ((req->present&XkbModifierMapMask) &&
2406         (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) {
2407         client->errorValue= error;
2408         return BadValue;
2409     }
2410     if ((req->present&XkbVirtualModMapMask) &&
2411         (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) {
2412         client->errorValue= error;
2413         return BadValue;
2414     }
2415
2416     if (((values-((char *)req))/4)!= req->length) {
2417         ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n");
2418         client->errorValue = values-((char *)&req[1]);
2419         return BadLength;
2420     }
2421
2422     return Success;
2423 }
2424
2425 /**
2426  * Apply the given request on the given device.
2427  */
2428 static int
2429 _XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char *values)
2430 {
2431     XkbEventCauseRec    cause;
2432     XkbChangesRec       change;
2433     Bool                sentNKN;
2434     XkbSrvInfoPtr       xkbi;
2435     XkbDescPtr          xkb;
2436
2437     xkbi= dev->key->xkbInfo;
2438     xkb = xkbi->desc;
2439
2440     XkbSetCauseXkbReq(&cause,X_kbSetMap,client);
2441     memset(&change, 0, sizeof(change));
2442     sentNKN = FALSE;
2443     if ((xkb->min_key_code!=req->minKeyCode)||
2444         (xkb->max_key_code!=req->maxKeyCode)) {
2445         Status                  status;
2446         xkbNewKeyboardNotify    nkn;
2447         nkn.deviceID = nkn.oldDeviceID = dev->id;
2448         nkn.oldMinKeyCode = xkb->min_key_code;
2449         nkn.oldMaxKeyCode = xkb->max_key_code;
2450         status= XkbChangeKeycodeRange(xkb, req->minKeyCode,
2451                                       req->maxKeyCode, &change);
2452         if (status != Success)
2453             return status; /* oh-oh. what about the other keyboards? */
2454         nkn.minKeyCode = xkb->min_key_code;
2455         nkn.maxKeyCode = xkb->max_key_code;
2456         nkn.requestMajor = XkbReqCode;
2457         nkn.requestMinor = X_kbSetMap;
2458         nkn.changed = XkbNKN_KeycodesMask;
2459         XkbSendNewKeyboardNotify(dev,&nkn);
2460         sentNKN = TRUE;
2461     }
2462
2463     if (req->present&XkbKeyTypesMask) {
2464         values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change);
2465         if (!values)    goto allocFailure;
2466     }
2467     if (req->present&XkbKeySymsMask) {
2468         values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc *)values,&change,dev);
2469         if (!values)    goto allocFailure;
2470     }
2471     if (req->present&XkbKeyActionsMask) {
2472         values = SetKeyActions(xkb,req,(CARD8 *)values,&change);
2473         if (!values)    goto allocFailure;
2474     }
2475     if (req->present&XkbKeyBehaviorsMask) {
2476         values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change);
2477         if (!values)    goto allocFailure;
2478     }
2479     if (req->present&XkbVirtualModsMask)
2480         values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change);
2481     if (req->present&XkbExplicitComponentsMask)
2482         values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change);
2483     if (req->present&XkbModifierMapMask)
2484         values= SetModifierMap(xkbi,req,(CARD8 *)values,&change);
2485     if (req->present&XkbVirtualModMapMask)
2486         values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change);
2487     if (((values-((char *)req))/4)!=req->length) {
2488         ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n");
2489         client->errorValue = values-((char *)&req[1]);
2490         return BadLength;
2491     }
2492     if (req->flags&XkbSetMapRecomputeActions) {
2493         KeyCode         first,last,firstMM,lastMM;
2494         if (change.map.num_key_syms>0) {
2495             first= change.map.first_key_sym;
2496             last= first+change.map.num_key_syms-1;
2497         }
2498         else first= last= 0;
2499         if (change.map.num_modmap_keys>0) {
2500             firstMM= change.map.first_modmap_key;
2501             lastMM= first+change.map.num_modmap_keys-1;
2502         }
2503         else firstMM= lastMM= 0;
2504         if ((last>0) && (lastMM>0)) {
2505             if (firstMM<first)
2506                 first= firstMM;
2507             if (lastMM>last)
2508                 last= lastMM;
2509         }
2510         else if (lastMM>0) {
2511             first= firstMM;
2512             last= lastMM;
2513         }
2514         if (last>0) {
2515             unsigned check= 0;
2516             XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause);
2517             if (check)
2518                 XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
2519         }
2520     }
2521     if (!sentNKN)
2522         XkbSendNotification(dev,&change,&cause);
2523
2524     return Success;
2525 allocFailure:
2526     return BadAlloc;
2527 }
2528
2529
2530 int
2531 ProcXkbSetMap(ClientPtr client)
2532 {
2533     DeviceIntPtr        dev;
2534     char *              tmp;
2535     int                 rc;
2536
2537     REQUEST(xkbSetMapReq);
2538     REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
2539
2540     if (!(client->xkbClientFlags&_XkbClientInitialized))
2541         return BadAccess;
2542
2543     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
2544     CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
2545
2546     tmp = (char *)&stuff[1];
2547
2548     /* Check if we can to the SetMap on the requested device. If this
2549        succeeds, do the same thing for all extension devices (if needed).
2550        If any of them fails, fail.  */
2551     rc = _XkbSetMapChecks(client, dev, stuff, tmp);
2552
2553     if (rc != Success)
2554         return rc;
2555
2556     if (stuff->deviceSpec == XkbUseCoreKbd)
2557     {
2558         DeviceIntPtr other;
2559         for (other = inputInfo.devices; other; other = other->next)
2560         {
2561             if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev)
2562             {
2563                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
2564                 if (rc == Success)
2565                 {
2566                     rc = _XkbSetMapChecks(client, other, stuff, tmp);
2567                     if (rc != Success)
2568                         return rc;
2569                 }
2570             }
2571         }
2572     }
2573
2574     /* We know now that we will succed with the SetMap. In theory anyway. */
2575     rc = _XkbSetMap(client, dev, stuff, tmp);
2576     if (rc != Success)
2577         return rc;
2578
2579     if (stuff->deviceSpec == XkbUseCoreKbd)
2580     {
2581         DeviceIntPtr other;
2582         for (other = inputInfo.devices; other; other = other->next)
2583         {
2584             if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev)
2585             {
2586                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
2587                 if (rc == Success)
2588                     _XkbSetMap(client, other, stuff, tmp);
2589                 /* ignore rc. if the SetMap failed although the check above
2590                    reported true there isn't much we can do. we still need to
2591                    set all other devices, hoping that at least they stay in
2592                    sync. */
2593             }
2594         }
2595     }
2596
2597     return Success;
2598 }
2599
2600 /***====================================================================***/
2601
2602 static Status
2603 XkbComputeGetCompatMapReplySize(        XkbCompatMapPtr         compat,
2604                                         xkbGetCompatMapReply *  rep)
2605 {
2606 unsigned         size,nGroups;
2607
2608     nGroups= 0;
2609     if (rep->groups!=0) {
2610         register int i,bit;
2611         for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
2612             if (rep->groups&bit)
2613                 nGroups++;
2614         }
2615     }
2616     size= nGroups*SIZEOF(xkbModsWireDesc);
2617     size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc));
2618     rep->length= size/4;
2619     return Success;
2620 }
2621
2622 static int
2623 XkbSendCompatMap(       ClientPtr               client,
2624                         XkbCompatMapPtr         compat,
2625                         xkbGetCompatMapReply *  rep)
2626 {
2627 char    *       data;
2628 int             size;
2629
2630     size= rep->length*4;
2631     if (size>0) {
2632         data = malloc(size);
2633         if (data) {
2634             register unsigned i,bit;
2635             xkbModsWireDesc *   grp;
2636             XkbSymInterpretPtr  sym= &compat->sym_interpret[rep->firstSI];
2637             xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
2638             for (i=0;i<rep->nSI;i++,sym++,wire++) {
2639                 wire->sym= sym->sym;
2640                 wire->mods= sym->mods;
2641                 wire->match= sym->match;
2642                 wire->virtualMod= sym->virtual_mod;
2643                 wire->flags= sym->flags;
2644                 memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc);
2645                 if (client->swapped) {
2646                     swapl(&wire->sym);
2647                 }
2648             }
2649             if (rep->groups) {
2650                 grp = (xkbModsWireDesc *)wire;
2651                 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
2652                     if (rep->groups&bit) {
2653                         grp->mask= compat->groups[i].mask;
2654                         grp->realMods= compat->groups[i].real_mods;
2655                         grp->virtualMods= compat->groups[i].vmods;
2656                         if (client->swapped) {
2657                             swaps(&grp->virtualMods);
2658                         }
2659                         grp++;
2660                     }
2661                 }
2662                 wire= (xkbSymInterpretWireDesc*)grp;
2663             }
2664         }
2665         else return BadAlloc;
2666     }
2667     else data= NULL;
2668
2669     if (client->swapped) {
2670         swaps(&rep->sequenceNumber);
2671         swapl(&rep->length);
2672         swaps(&rep->firstSI);
2673         swaps(&rep->nSI);
2674         swaps(&rep->nTotalSI);
2675     }
2676
2677     WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep);
2678     if (data) {
2679         WriteToClient(client, size, data);
2680         free((char *)data);
2681     }
2682     return Success;
2683 }
2684
2685 int
2686 ProcXkbGetCompatMap(ClientPtr client)
2687 {
2688     xkbGetCompatMapReply        rep;
2689     DeviceIntPtr                dev;
2690     XkbDescPtr                  xkb;
2691     XkbCompatMapPtr             compat;
2692
2693     REQUEST(xkbGetCompatMapReq);
2694     REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
2695
2696     if (!(client->xkbClientFlags&_XkbClientInitialized))
2697         return BadAccess;
2698
2699     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
2700
2701     xkb = dev->key->xkbInfo->desc;
2702     compat= xkb->compat;
2703
2704     rep.type = X_Reply;
2705     rep.deviceID = dev->id;
2706     rep.sequenceNumber = client->sequence;
2707     rep.length = 0;
2708     rep.firstSI = stuff->firstSI;
2709     rep.nSI = stuff->nSI;
2710     if (stuff->getAllSI) {
2711         rep.firstSI = 0;
2712         rep.nSI = compat->num_si;
2713     }
2714     else if ((((unsigned)stuff->nSI)>0)&&
2715                 ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) {
2716         client->errorValue = _XkbErrCode2(0x05,compat->num_si);
2717         return BadValue;
2718     }
2719     rep.nTotalSI = compat->num_si;
2720     rep.groups= stuff->groups;
2721     XkbComputeGetCompatMapReplySize(compat,&rep);
2722     return XkbSendCompatMap(client,compat,&rep);
2723 }
2724
2725 /**
2726  * Apply the given request on the given device.
2727  * If dryRun is TRUE, then value checks are performed, but the device isn't
2728  * modified.
2729  */
2730 static int
2731 _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
2732                  xkbSetCompatMapReq *req, char* data, BOOL dryRun)
2733 {
2734     XkbSrvInfoPtr       xkbi;
2735     XkbDescPtr          xkb;
2736     XkbCompatMapPtr     compat;
2737     int                 nGroups;
2738     unsigned            i,bit;
2739
2740     xkbi = dev->key->xkbInfo;
2741     xkb = xkbi->desc;
2742     compat = xkb->compat;
2743
2744     if ((req->nSI>0)||(req->truncateSI)) {
2745         xkbSymInterpretWireDesc *wire;
2746         if (req->firstSI>compat->num_si) {
2747             client->errorValue = _XkbErrCode2(0x02,compat->num_si);
2748             return BadValue;
2749         }
2750         wire= (xkbSymInterpretWireDesc *)data;
2751         wire+= req->nSI;
2752         data = (char *)wire;
2753     }
2754
2755     nGroups= 0;
2756     if (req->groups!=0) {
2757         for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
2758             if ( req->groups&bit )
2759                 nGroups++;
2760         }
2761     }
2762     data+= nGroups*SIZEOF(xkbModsWireDesc);
2763     if (((data-((char *)req))/4)!=req->length) {
2764         return BadLength;
2765     }
2766
2767     /* Done all the checks we can do */
2768     if (dryRun)
2769         return Success;
2770
2771     data = (char *)&req[1];
2772     if (req->nSI>0) {
2773         xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
2774         XkbSymInterpretPtr      sym;
2775         unsigned int            skipped = 0;
2776         if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) {
2777             compat->num_si= req->firstSI+req->nSI;
2778             compat->sym_interpret= realloc(compat->sym_interpret,
2779                                             compat->num_si * sizeof(XkbSymInterpretRec));
2780             if (!compat->sym_interpret) {
2781                 compat->num_si= 0;
2782                 return BadAlloc;
2783             }
2784         }
2785         else if (req->truncateSI) {
2786             compat->num_si = req->firstSI+req->nSI;
2787         }
2788         sym = &compat->sym_interpret[req->firstSI];
2789         for (i=0;i<req->nSI;i++,wire++) {
2790             if (client->swapped) {
2791                 swapl(&wire->sym);
2792             }
2793             if (wire->sym == NoSymbol && wire->match == XkbSI_AnyOfOrNone &&
2794                 (wire->mods & 0xff) == 0xff &&
2795                 wire->act.type == XkbSA_XFree86Private) {
2796                 ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private "
2797                        "action from client\n");
2798                 skipped++;
2799                 continue;
2800             }
2801             sym->sym= wire->sym;
2802             sym->mods= wire->mods;
2803             sym->match= wire->match;
2804             sym->flags= wire->flags;
2805             sym->virtual_mod= wire->virtualMod;
2806             memcpy((char *)&sym->act,(char *)&wire->act,
2807                    SIZEOF(xkbActionWireDesc));
2808             sym++;
2809         }
2810         if (skipped) {
2811             if (req->firstSI + req->nSI < compat->num_si)
2812                 memmove(sym, sym + skipped,
2813                         (compat->num_si - req->firstSI - req->nSI) *
2814                          sizeof(*sym));
2815             compat->num_si -= skipped;
2816         }
2817         data = (char *)wire;
2818     }
2819     else if (req->truncateSI) {
2820         compat->num_si = req->firstSI;
2821     }
2822
2823     if (req->groups!=0) {
2824         unsigned i, bit;
2825         xkbModsWireDesc *wire = (xkbModsWireDesc *)data;
2826         for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
2827             if (req->groups & bit) {
2828                 if (client->swapped) {
2829                     swaps(&wire->virtualMods);
2830                 }
2831                 compat->groups[i].mask= wire->realMods;
2832                 compat->groups[i].real_mods= wire->realMods;
2833                 compat->groups[i].vmods= wire->virtualMods;