First import
[xorg_rtime.git] / xorg-server-1.4 / xkb / xkb.c
blobcf4243070b1a15e6711eef3afdf2e8cfe56f77f6
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
31 #include <stdio.h>
32 #include <X11/X.h>
33 #define NEED_EVENTS
34 #define NEED_REPLIES
35 #include <X11/Xproto.h>
36 #include "misc.h"
37 #include "inputstr.h"
38 #define XKBSRV_NEED_FILE_FUNCS
39 #include <xkbsrv.h>
40 #include "extnsionst.h"
41 #include "xkb.h"
43 #include <X11/extensions/XI.h>
45 int XkbEventBase;
46 static int XkbErrorBase;
47 int XkbReqCode;
48 static int XkbKeyboardErrorCode;
49 CARD32 xkbDebugFlags = 0;
50 static CARD32 xkbDebugCtrls = 0;
52 static RESTYPE RT_XKBCLIENT;
54 /***====================================================================***/
56 #define CHK_DEVICE(d,sp,lf) {\
57 int why;\
58 d = (DeviceIntPtr)lf((sp),&why);\
59 if (!dev) {\
60 client->errorValue = _XkbErrCode2(why,(sp));\
61 return XkbKeyboardErrorCode;\
65 #define CHK_KBD_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupKeyboard)
66 #define CHK_LED_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupLedDevice)
67 #define CHK_BELL_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupBellDevice)
68 #define CHK_ANY_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupAnyDevice)
70 #define CHK_ATOM_ONLY2(a,ev,er) {\
71 if (((a)==None)||(!ValidAtom((a)))) {\
72 (ev)= (XID)(a);\
73 return er;\
76 #define CHK_ATOM_ONLY(a) \
77 CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
79 #define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
80 if (((a)!=None)&&(!ValidAtom((a)))) {\
81 (ev)= (XID)(a);\
82 (er)= BadAtom;\
83 return ret;\
86 #define CHK_ATOM_OR_NONE2(a,ev,er) {\
87 if (((a)!=None)&&(!ValidAtom((a)))) {\
88 (ev)= (XID)(a);\
89 return er;\
92 #define CHK_ATOM_OR_NONE(a) \
93 CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
95 #define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\
96 if ((mask)&(~(legal))) { \
97 (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
98 (er)= BadValue;\
99 return ret;\
102 #define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\
103 if ((mask)&(~(legal))) { \
104 (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
105 return er;\
108 #define CHK_MASK_LEGAL(err,mask,legal) \
109 CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
111 #define CHK_MASK_MATCH(err,affect,value) {\
112 if ((value)&(~(affect))) { \
113 client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
114 return BadMatch;\
117 #define CHK_MASK_OVERLAP(err,m1,m2) {\
118 if ((m1)&(m2)) { \
119 client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
120 return BadMatch;\
123 #define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
124 if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
125 (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
126 return er;\
128 else if ( (first)<(x)->min_key_code ) {\
129 (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
130 return er;\
133 #define CHK_KEY_RANGE(err,first,num,x) \
134 CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
136 #define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
137 if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
138 (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
139 return er;\
141 else if ( (first)<(r)->minKeyCode ) {\
142 (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
143 return er;\
146 #define CHK_REQ_KEY_RANGE(err,first,num,r) \
147 CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
149 /***====================================================================***/
152 ProcXkbUseExtension(ClientPtr client)
154 REQUEST(xkbUseExtensionReq);
155 xkbUseExtensionReply rep;
156 register int n;
157 int supported;
159 REQUEST_SIZE_MATCH(xkbUseExtensionReq);
160 if (stuff->wantedMajor != XkbMajorVersion) {
161 /* pre-release version 0.65 is compatible with 1.00 */
162 supported= ((XkbMajorVersion==1)&&
163 (stuff->wantedMajor==0)&&(stuff->wantedMinor==65));
165 else supported = 1;
167 if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) {
168 client->xkbClientFlags= _XkbClientInitialized;
169 client->vMajor= stuff->wantedMajor;
170 client->vMinor= stuff->wantedMinor;
172 else if (xkbDebugFlags&0x1) {
173 ErrorF("Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n",
174 client->index,
175 (long)client->clientAsMask,
176 stuff->wantedMajor,stuff->wantedMinor,
177 XkbMajorVersion,XkbMinorVersion);
179 rep.type = X_Reply;
180 rep.supported = supported;
181 rep.length = 0;
182 rep.sequenceNumber = client->sequence;
183 rep.serverMajor = XkbMajorVersion;
184 rep.serverMinor = XkbMinorVersion;
185 if ( client->swapped ) {
186 swaps(&rep.sequenceNumber, n);
187 swaps(&rep.serverMajor, n);
188 swaps(&rep.serverMinor, n);
190 WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep);
191 return client->noClientException;
194 /***====================================================================***/
197 ProcXkbSelectEvents(ClientPtr client)
199 unsigned legal;
200 DeviceIntPtr dev;
201 XkbInterestPtr masks;
202 REQUEST(xkbSelectEventsReq);
204 REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
206 if (!(client->xkbClientFlags&_XkbClientInitialized))
207 return BadAccess;
209 CHK_ANY_DEVICE(dev,stuff->deviceSpec);
211 if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) {
212 client->mapNotifyMask&= ~stuff->affectMap;
213 client->mapNotifyMask|= (stuff->affectMap&stuff->map);
215 if ((stuff->affectWhich&(~XkbMapNotifyMask))==0)
216 return client->noClientException;
218 masks = XkbFindClientResource((DevicePtr)dev,client);
219 if (!masks){
220 XID id = FakeClientID(client->index);
221 AddResource(id,RT_XKBCLIENT,dev);
222 masks= XkbAddClientResource((DevicePtr)dev,client,id);
224 if (masks) {
225 union {
226 CARD8 *c8;
227 CARD16 *c16;
228 CARD32 *c32;
229 } from,to;
230 register unsigned bit,ndx,maskLeft,dataLeft,size;
232 from.c8= (CARD8 *)&stuff[1];
233 dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
234 maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
235 for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
236 if ((bit&maskLeft)==0)
237 continue;
238 maskLeft&= ~bit;
239 switch (ndx) {
240 case XkbNewKeyboardNotify:
241 to.c16= &client->newKeyboardNotifyMask;
242 legal= XkbAllNewKeyboardEventsMask;
243 size= 2;
244 break;
245 case XkbStateNotify:
246 to.c16= &masks->stateNotifyMask;
247 legal= XkbAllStateEventsMask;
248 size= 2;
249 break;
250 case XkbControlsNotify:
251 to.c32= &masks->ctrlsNotifyMask;
252 legal= XkbAllControlEventsMask;
253 size= 4;
254 break;
255 case XkbIndicatorStateNotify:
256 to.c32= &masks->iStateNotifyMask;
257 legal= XkbAllIndicatorEventsMask;
258 size= 4;
259 break;
260 case XkbIndicatorMapNotify:
261 to.c32= &masks->iMapNotifyMask;
262 legal= XkbAllIndicatorEventsMask;
263 size= 4;
264 break;
265 case XkbNamesNotify:
266 to.c16= &masks->namesNotifyMask;
267 legal= XkbAllNameEventsMask;
268 size= 2;
269 break;
270 case XkbCompatMapNotify:
271 to.c8= &masks->compatNotifyMask;
272 legal= XkbAllCompatMapEventsMask;
273 size= 1;
274 break;
275 case XkbBellNotify:
276 to.c8= &masks->bellNotifyMask;
277 legal= XkbAllBellEventsMask;
278 size= 1;
279 break;
280 case XkbActionMessage:
281 to.c8= &masks->actionMessageMask;
282 legal= XkbAllActionMessagesMask;
283 size= 1;
284 break;
285 case XkbAccessXNotify:
286 to.c16= &masks->accessXNotifyMask;
287 legal= XkbAllAccessXEventsMask;
288 size= 2;
289 break;
290 case XkbExtensionDeviceNotify:
291 to.c16= &masks->extDevNotifyMask;
292 legal= XkbAllExtensionDeviceEventsMask;
293 size= 2;
294 break;
295 default:
296 client->errorValue = _XkbErrCode2(33,bit);
297 return BadValue;
300 if (stuff->clear&bit) {
301 if (size==2) to.c16[0]= 0;
302 else if (size==4) to.c32[0]= 0;
303 else to.c8[0]= 0;
305 else if (stuff->selectAll&bit) {
306 if (size==2) to.c16[0]= ~0;
307 else if (size==4) to.c32[0]= ~0;
308 else to.c8[0]= ~0;
310 else {
311 if (dataLeft<(size*2))
312 return BadLength;
313 if (size==2) {
314 CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]);
315 CHK_MASK_LEGAL(ndx,from.c16[0],legal);
316 to.c16[0]&= ~from.c16[0];
317 to.c16[0]|= (from.c16[0]&from.c16[1]);
319 else if (size==4) {
320 CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]);
321 CHK_MASK_LEGAL(ndx,from.c32[0],legal);
322 to.c32[0]&= ~from.c32[0];
323 to.c32[0]|= (from.c32[0]&from.c32[1]);
325 else {
326 CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]);
327 CHK_MASK_LEGAL(ndx,from.c8[0],legal);
328 to.c8[0]&= ~from.c8[0];
329 to.c8[0]|= (from.c8[0]&from.c8[1]);
330 size= 2;
332 from.c8+= (size*2);
333 dataLeft-= (size*2);
336 if (dataLeft>2) {
337 ErrorF("Extra data (%d bytes) after SelectEvents\n",dataLeft);
338 return BadLength;
340 return client->noClientException;
342 return BadAlloc;
345 /***====================================================================***/
347 /* FIXME: Needs to ding on all core-sending devices. */
349 ProcXkbBell(ClientPtr client)
351 REQUEST(xkbBellReq);
352 DeviceIntPtr dev;
353 WindowPtr pWin;
354 int base;
355 int newPercent,oldPitch,oldDuration;
356 pointer ctrl;
358 REQUEST_SIZE_MATCH(xkbBellReq);
360 if (!(client->xkbClientFlags&_XkbClientInitialized))
361 return BadAccess;
363 CHK_BELL_DEVICE(dev,stuff->deviceSpec);
364 CHK_ATOM_OR_NONE(stuff->name);
366 if ((stuff->forceSound)&&(stuff->eventOnly)) {
367 client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly);
368 return BadMatch;
370 if (stuff->percent < -100 || stuff->percent > 100) {
371 client->errorValue = _XkbErrCode2(0x2,stuff->percent);
372 return BadValue;
374 if (stuff->duration<-1) {
375 client->errorValue = _XkbErrCode2(0x3,stuff->duration);
376 return BadValue;
378 if (stuff->pitch<-1) {
379 client->errorValue = _XkbErrCode2(0x4,stuff->pitch);
380 return BadValue;
383 if (stuff->bellClass == XkbDfltXIClass) {
384 if (dev->kbdfeed!=NULL)
385 stuff->bellClass= KbdFeedbackClass;
386 else stuff->bellClass= BellFeedbackClass;
388 if (stuff->bellClass == KbdFeedbackClass) {
389 KbdFeedbackPtr k;
390 if (stuff->bellID==XkbDfltXIId)
391 k= dev->kbdfeed;
392 else {
393 for (k=dev->kbdfeed; k; k=k->next) {
394 if (k->ctrl.id == stuff->bellID)
395 break;
398 if (!k) {
399 client->errorValue= _XkbErrCode2(0x5,stuff->bellID);
400 return BadValue;
402 base = k->ctrl.bell;
403 ctrl = (pointer) &(k->ctrl);
404 oldPitch= k->ctrl.bell_pitch;
405 oldDuration= k->ctrl.bell_duration;
406 if (stuff->pitch!=0) {
407 if (stuff->pitch==-1)
408 k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch;
409 else k->ctrl.bell_pitch= stuff->pitch;
411 if (stuff->duration!=0) {
412 if (stuff->duration==-1)
413 k->ctrl.bell_duration= defaultKeyboardControl.bell_duration;
414 else k->ctrl.bell_duration= stuff->duration;
417 else if (stuff->bellClass == BellFeedbackClass) {
418 BellFeedbackPtr b;
419 if (stuff->bellID==XkbDfltXIId)
420 b= dev->bell;
421 else {
422 for (b=dev->bell; b; b=b->next) {
423 if (b->ctrl.id == stuff->bellID)
424 break;
427 if (!b) {
428 client->errorValue = _XkbErrCode2(0x6,stuff->bellID);
429 return BadValue;
431 base = b->ctrl.percent;
432 ctrl = (pointer) &(b->ctrl);
433 oldPitch= b->ctrl.pitch;
434 oldDuration= b->ctrl.duration;
435 if (stuff->pitch!=0) {
436 if (stuff->pitch==-1)
437 b->ctrl.pitch= defaultKeyboardControl.bell_pitch;
438 else b->ctrl.pitch= stuff->pitch;
440 if (stuff->duration!=0) {
441 if (stuff->duration==-1)
442 b->ctrl.duration= defaultKeyboardControl.bell_duration;
443 else b->ctrl.duration= stuff->duration;
446 else {
447 client->errorValue = _XkbErrCode2(0x7,stuff->bellClass);;
448 return BadValue;
450 if (stuff->window!=None) {
451 pWin= (WindowPtr)LookupIDByType(stuff->window,RT_WINDOW);
452 if (pWin==NULL) {
453 client->errorValue= stuff->window;
454 return BadValue;
457 else pWin= NULL;
459 newPercent= (base*stuff->percent)/100;
460 if (stuff->percent < 0)
461 newPercent= base+newPercent;
462 else newPercent= base-newPercent+stuff->percent;
463 XkbHandleBell(stuff->forceSound, stuff->eventOnly,
464 dev, newPercent, ctrl, stuff->bellClass,
465 stuff->name, pWin, client);
466 if ((stuff->pitch!=0)||(stuff->duration!=0)) {
467 if (stuff->bellClass == KbdFeedbackClass) {
468 KbdFeedbackPtr k;
469 k= (KbdFeedbackPtr)ctrl;
470 if (stuff->pitch!=0)
471 k->ctrl.bell_pitch= oldPitch;
472 if (stuff->duration!=0)
473 k->ctrl.bell_duration= oldDuration;
475 else {
476 BellFeedbackPtr b;
477 b= (BellFeedbackPtr)ctrl;
478 if (stuff->pitch!=0)
479 b->ctrl.pitch= oldPitch;
480 if (stuff->duration!=0)
481 b->ctrl.duration= oldDuration;
484 return Success;
487 /***====================================================================***/
490 ProcXkbGetState(ClientPtr client)
492 REQUEST(xkbGetStateReq);
493 DeviceIntPtr dev;
494 xkbGetStateReply rep;
495 XkbStateRec *xkb;
497 REQUEST_SIZE_MATCH(xkbGetStateReq);
499 if (!(client->xkbClientFlags&_XkbClientInitialized))
500 return BadAccess;
502 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
504 xkb= &dev->key->xkbInfo->state;
505 bzero(&rep,sizeof(xkbGetStateReply));
506 rep.type= X_Reply;
507 rep.sequenceNumber= client->sequence;
508 rep.length = 0;
509 rep.deviceID = dev->id;
510 rep.mods = dev->key->state&0xff;
511 rep.baseMods = xkb->base_mods;
512 rep.lockedMods = xkb->locked_mods;
513 rep.latchedMods = xkb->latched_mods;
514 rep.group = xkb->group;
515 rep.baseGroup = xkb->base_group;
516 rep.latchedGroup = xkb->latched_group;
517 rep.lockedGroup = xkb->locked_group;
518 rep.compatState = xkb->compat_state;
519 rep.ptrBtnState = xkb->ptr_buttons;
520 if (client->swapped) {
521 register int n;
522 swaps(&rep.sequenceNumber,n);
523 swaps(&rep.ptrBtnState,n);
525 WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep);
526 return client->noClientException;
529 /***====================================================================***/
532 ProcXkbLatchLockState(ClientPtr client)
534 int status;
535 DeviceIntPtr dev, tmpd;
536 XkbStateRec oldState,*newState;
537 CARD16 changed;
538 xkbStateNotify sn;
539 XkbEventCauseRec cause;
541 REQUEST(xkbLatchLockStateReq);
542 REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
544 if (!(client->xkbClientFlags & _XkbClientInitialized))
545 return BadAccess;
547 CHK_KBD_DEVICE(dev, stuff->deviceSpec);
548 CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks);
549 CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches);
551 status = Success;
553 for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
554 if ((dev == inputInfo.keyboard && tmpd->key && tmpd->coreEvents) ||
555 tmpd == dev) {
556 if (!tmpd->key->xkbInfo)
557 continue;
559 oldState = tmpd->key->xkbInfo->state;
560 newState = &tmpd->key->xkbInfo->state;
561 if (stuff->affectModLocks) {
562 newState->locked_mods &= ~stuff->affectModLocks;
563 newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks);
565 if (status == Success && stuff->lockGroup)
566 newState->locked_group = stuff->groupLock;
567 if (status == Success && stuff->affectModLatches)
568 status = XkbLatchModifiers(tmpd, stuff->affectModLatches,
569 stuff->modLatches);
570 if (status == Success && stuff->latchGroup)
571 status = XkbLatchGroup(tmpd, stuff->groupLatch);
573 if (status != Success)
574 return status;
576 XkbComputeDerivedState(tmpd->key->xkbInfo);
577 tmpd->key->state = XkbStateFieldFromRec(newState);
579 changed = XkbStateChangedFlags(&oldState, newState);
580 if (changed) {
581 sn.keycode = 0;
582 sn.eventType = 0;
583 sn.requestMajor = XkbReqCode;
584 sn.requestMinor = X_kbLatchLockState;
585 sn.changed = changed;
586 XkbSendStateNotify(tmpd, &sn);
587 changed = XkbIndicatorsToUpdate(tmpd, changed, False);
588 if (changed) {
589 XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client);
590 XkbUpdateIndicators(tmpd, changed, True, NULL, &cause);
596 return client->noClientException;
599 /***====================================================================***/
602 ProcXkbGetControls(ClientPtr client)
604 xkbGetControlsReply rep;
605 XkbControlsPtr xkb;
606 DeviceIntPtr dev;
607 register int n;
609 REQUEST(xkbGetControlsReq);
610 REQUEST_SIZE_MATCH(xkbGetControlsReq);
612 if (!(client->xkbClientFlags&_XkbClientInitialized))
613 return BadAccess;
615 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
617 xkb = dev->key->xkbInfo->desc->ctrls;
618 rep.type = X_Reply;
619 rep.length = (SIZEOF(xkbGetControlsReply)-
620 SIZEOF(xGenericReply)) >> 2;
621 rep.sequenceNumber = client->sequence;
622 rep.deviceID = ((DeviceIntPtr)dev)->id;
623 rep.numGroups = xkb->num_groups;
624 rep.groupsWrap = xkb->groups_wrap;
625 rep.internalMods = xkb->internal.mask;
626 rep.ignoreLockMods = xkb->ignore_lock.mask;
627 rep.internalRealMods = xkb->internal.real_mods;
628 rep.ignoreLockRealMods = xkb->ignore_lock.real_mods;
629 rep.internalVMods = xkb->internal.vmods;
630 rep.ignoreLockVMods = xkb->ignore_lock.vmods;
631 rep.enabledCtrls = xkb->enabled_ctrls;
632 rep.repeatDelay = xkb->repeat_delay;
633 rep.repeatInterval = xkb->repeat_interval;
634 rep.slowKeysDelay = xkb->slow_keys_delay;
635 rep.debounceDelay = xkb->debounce_delay;
636 rep.mkDelay = xkb->mk_delay;
637 rep.mkInterval = xkb->mk_interval;
638 rep.mkTimeToMax = xkb->mk_time_to_max;
639 rep.mkMaxSpeed = xkb->mk_max_speed;
640 rep.mkCurve = xkb->mk_curve;
641 rep.mkDfltBtn = xkb->mk_dflt_btn;
642 rep.axTimeout = xkb->ax_timeout;
643 rep.axtCtrlsMask = xkb->axt_ctrls_mask;
644 rep.axtCtrlsValues = xkb->axt_ctrls_values;
645 rep.axtOptsMask = xkb->axt_opts_mask;
646 rep.axtOptsValues = xkb->axt_opts_values;
647 rep.axOptions = xkb->ax_options;
648 memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize);
649 if (client->swapped) {
650 swaps(&rep.sequenceNumber, n);
651 swapl(&rep.length,n);
652 swaps(&rep.internalVMods, n);
653 swaps(&rep.ignoreLockVMods, n);
654 swapl(&rep.enabledCtrls, n);
655 swaps(&rep.repeatDelay, n);
656 swaps(&rep.repeatInterval, n);
657 swaps(&rep.slowKeysDelay, n);
658 swaps(&rep.debounceDelay, n);
659 swaps(&rep.mkDelay, n);
660 swaps(&rep.mkInterval, n);
661 swaps(&rep.mkTimeToMax, n);
662 swaps(&rep.mkMaxSpeed, n);
663 swaps(&rep.mkCurve, n);
664 swaps(&rep.axTimeout, n);
665 swapl(&rep.axtCtrlsMask, n);
666 swapl(&rep.axtCtrlsValues, n);
667 swaps(&rep.axtOptsMask, n);
668 swaps(&rep.axtOptsValues, n);
669 swaps(&rep.axOptions, n);
671 WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep);
672 return(client->noClientException);
676 ProcXkbSetControls(ClientPtr client)
678 DeviceIntPtr dev, tmpd;
679 XkbSrvInfoPtr xkbi;
680 XkbControlsPtr ctrl;
681 XkbControlsRec new,old;
682 xkbControlsNotify cn;
683 XkbEventCauseRec cause;
684 XkbSrvLedInfoPtr sli;
686 REQUEST(xkbSetControlsReq);
687 REQUEST_SIZE_MATCH(xkbSetControlsReq);
689 if (!(client->xkbClientFlags & _XkbClientInitialized))
690 return BadAccess;
692 CHK_KBD_DEVICE(dev, stuff->deviceSpec);
693 CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask);
695 for (tmpd = inputInfo.keyboard; tmpd; tmpd = tmpd->next) {
696 if ((dev == inputInfo.keyboard && tmpd->key && tmpd->coreEvents) ||
697 tmpd == dev) {
699 xkbi = tmpd->key->xkbInfo;
700 ctrl = xkbi->desc->ctrls;
701 new = *ctrl;
702 XkbSetCauseXkbReq(&cause, X_kbSetControls, client);
704 if (stuff->changeCtrls & XkbInternalModsMask) {
705 CHK_MASK_MATCH(0x02, stuff->affectInternalMods,
706 stuff->internalMods);
707 CHK_MASK_MATCH(0x03, stuff->affectInternalVMods,
708 stuff->internalVMods);
710 new.internal.real_mods &= ~(stuff->affectInternalMods);
711 new.internal.real_mods |= (stuff->affectInternalMods &
712 stuff->internalMods);
713 new.internal.vmods &= ~(stuff->affectInternalVMods);
714 new.internal.vmods |= (stuff->affectInternalVMods &
715 stuff->internalVMods);
716 new.internal.mask = new.internal.real_mods |
717 XkbMaskForVMask(xkbi->desc,
718 new.internal.vmods);
721 if (stuff->changeCtrls & XkbIgnoreLockModsMask) {
722 CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods,
723 stuff->ignoreLockMods);
724 CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods,
725 stuff->ignoreLockVMods);
727 new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods);
728 new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods &
729 stuff->ignoreLockMods);
730 new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods);
731 new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods &
732 stuff->ignoreLockVMods);
733 new.ignore_lock.mask = new.ignore_lock.real_mods |
734 XkbMaskForVMask(xkbi->desc,
735 new.ignore_lock.vmods);
738 CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls,
739 stuff->enabledCtrls);
740 if (stuff->affectEnabledCtrls) {
741 CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls,
742 XkbAllBooleanCtrlsMask);
744 new.enabled_ctrls &= ~(stuff->affectEnabledCtrls);
745 new.enabled_ctrls |= (stuff->affectEnabledCtrls &
746 stuff->enabledCtrls);
749 if (stuff->changeCtrls & XkbRepeatKeysMask) {
750 if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) {
751 client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay,
752 stuff->repeatInterval);
753 return BadValue;
756 new.repeat_delay = stuff->repeatDelay;
757 new.repeat_interval = stuff->repeatInterval;
760 if (stuff->changeCtrls & XkbSlowKeysMask) {
761 if (stuff->slowKeysDelay < 1) {
762 client->errorValue = _XkbErrCode2(0x09,
763 stuff->slowKeysDelay);
764 return BadValue;
767 new.slow_keys_delay = stuff->slowKeysDelay;
770 if (stuff->changeCtrls & XkbBounceKeysMask) {
771 if (stuff->debounceDelay < 1) {
772 client->errorValue = _XkbErrCode2(0x0A,
773 stuff->debounceDelay);
774 return BadValue;
777 new.debounce_delay = stuff->debounceDelay;
780 if (stuff->changeCtrls & XkbMouseKeysMask) {
781 if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) {
782 client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn);
783 return BadValue;
786 new.mk_dflt_btn = stuff->mkDfltBtn;
789 if (stuff->changeCtrls & XkbMouseKeysAccelMask) {
790 if (stuff->mkDelay < 1 || stuff->mkInterval < 1 ||
791 stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 ||
792 stuff->mkCurve < -1000) {
793 client->errorValue = _XkbErrCode2(0x0C,0);
794 return BadValue;
797 new.mk_delay = stuff->mkDelay;
798 new.mk_interval = stuff->mkInterval;
799 new.mk_time_to_max = stuff->mkTimeToMax;
800 new.mk_max_speed = stuff->mkMaxSpeed;
801 new.mk_curve = stuff->mkCurve;
802 AccessXComputeCurveFactor(xkbi, &new);
805 if (stuff->changeCtrls & XkbGroupsWrapMask) {
806 unsigned act, num;
808 act = XkbOutOfRangeGroupAction(stuff->groupsWrap);
809 switch (act) {
810 case XkbRedirectIntoRange:
811 num = XkbOutOfRangeGroupNumber(stuff->groupsWrap);
812 if (num >= new.num_groups) {
813 client->errorValue = _XkbErrCode3(0x0D, new.num_groups,
814 num);
815 return BadValue;
817 case XkbWrapIntoRange:
818 case XkbClampIntoRange:
819 break;
820 default:
821 client->errorValue = _XkbErrCode2(0x0E, act);
822 return BadValue;
825 new.groups_wrap= stuff->groupsWrap;
828 CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask);
829 if (stuff->changeCtrls & XkbAccessXKeysMask) {
830 new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask;
832 else {
833 if (stuff->changeCtrls & XkbStickyKeysMask) {
834 new.ax_options &= ~(XkbAX_SKOptionsMask);
835 new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask);
838 if (stuff->changeCtrls & XkbAccessXFeedbackMask) {
839 new.ax_options &= ~(XkbAX_FBOptionsMask);
840 new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask);
844 if (stuff->changeCtrls & XkbAccessXTimeoutMask) {
845 if (stuff->axTimeout < 1) {
846 client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout);
847 return BadValue;
849 CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask,
850 stuff->axtCtrlsValues);
851 CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask,
852 XkbAllBooleanCtrlsMask);
853 CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues);
854 CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask);
855 new.ax_timeout = stuff->axTimeout;
856 new.axt_ctrls_mask = stuff->axtCtrlsMask;
857 new.axt_ctrls_values = (stuff->axtCtrlsValues &
858 stuff->axtCtrlsMask);
859 new.axt_opts_mask = stuff->axtOptsMask;
860 new.axt_opts_values = (stuff->axtOptsValues &
861 stuff->axtOptsMask);
864 if (stuff->changeCtrls & XkbPerKeyRepeatMask)
865 memcpy(new.per_key_repeat, stuff->perKeyRepeat,
866 XkbPerKeyBitArraySize);
868 old= *ctrl;
869 *ctrl= new;
870 XkbDDXChangeControls(tmpd, &old, ctrl);
872 if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, False)) {
873 cn.keycode = 0;
874 cn.eventType = 0;
875 cn.requestMajor = XkbReqCode;
876 cn.requestMinor = X_kbSetControls;
877 XkbSendControlsNotify(tmpd, &cn);
880 sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0);
881 if (sli)
882 XkbUpdateIndicators(tmpd, sli->usesControls, True, NULL,
883 &cause);
885 /* If sticky keys were disabled, clear all locks and latches */
886 if ((old.enabled_ctrls & XkbStickyKeysMask) &&
887 !(ctrl->enabled_ctrls & XkbStickyKeysMask))
888 XkbClearAllLatchesAndLocks(tmpd, xkbi, True, &cause);
892 return client->noClientException;
895 /***====================================================================***/
897 static int
898 XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep)
900 XkbKeyTypeRec *type;
901 unsigned i,len;
903 len= 0;
904 if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)||
905 (!xkb)||(!xkb->map)||(!xkb->map->types)) {
906 rep->present&= ~XkbKeyTypesMask;
907 rep->firstType= rep->nTypes= 0;
908 return 0;
910 type= &xkb->map->types[rep->firstType];
911 for (i=0;i<rep->nTypes;i++,type++){
912 len+= SIZEOF(xkbKeyTypeWireDesc);
913 if (type->map_count>0) {
914 len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc));
915 if (type->preserve)
916 len+= (type->map_count*SIZEOF(xkbModsWireDesc));
919 return len;
922 static char *
923 XkbWriteKeyTypes( XkbDescPtr xkb,
924 xkbGetMapReply * rep,
925 char * buf,
926 ClientPtr client)
928 XkbKeyTypePtr type;
929 unsigned i;
930 xkbKeyTypeWireDesc *wire;
932 type= &xkb->map->types[rep->firstType];
933 for (i=0;i<rep->nTypes;i++,type++) {
934 register unsigned n;
935 wire= (xkbKeyTypeWireDesc *)buf;
936 wire->mask = type->mods.mask;
937 wire->realMods = type->mods.real_mods;
938 wire->virtualMods = type->mods.vmods;
939 wire->numLevels = type->num_levels;
940 wire->nMapEntries = type->map_count;
941 wire->preserve = (type->preserve!=NULL);
942 if (client->swapped) {
943 register int n;
944 swaps(&wire->virtualMods,n);
947 buf= (char *)&wire[1];
948 if (wire->nMapEntries>0) {
949 xkbKTMapEntryWireDesc * wire;
950 XkbKTMapEntryPtr entry;
951 wire= (xkbKTMapEntryWireDesc *)buf;
952 entry= type->map;
953 for (n=0;n<type->map_count;n++,wire++,entry++) {
954 wire->active= entry->active;
955 wire->mask= entry->mods.mask;
956 wire->level= entry->level;
957 wire->realMods= entry->mods.real_mods;
958 wire->virtualMods= entry->mods.vmods;
959 if (client->swapped) {
960 register int n;
961 swaps(&wire->virtualMods,n);
964 buf= (char *)wire;
965 if (type->preserve!=NULL) {
966 xkbModsWireDesc * pwire;
967 XkbModsPtr preserve;
968 pwire= (xkbModsWireDesc *)buf;
969 preserve= type->preserve;
970 for (n=0;n<type->map_count;n++,pwire++,preserve++) {
971 pwire->mask= preserve->mask;
972 pwire->realMods= preserve->real_mods;
973 pwire->virtualMods= preserve->vmods;
974 if (client->swapped) {
975 register int n;
976 swaps(&pwire->virtualMods,n);
979 buf= (char *)pwire;
983 return buf;
986 static int
987 XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep)
989 XkbSymMapPtr symMap;
990 unsigned i,len;
991 unsigned nSyms,nSymsThisKey;
993 if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)||
994 (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) {
995 rep->present&= ~XkbKeySymsMask;
996 rep->firstKeySym= rep->nKeySyms= 0;
997 rep->totalSyms= 0;
998 return 0;
1000 len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc);
1001 symMap = &xkb->map->key_sym_map[rep->firstKeySym];
1002 for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) {
1003 if (symMap->offset!=0) {
1004 nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width;
1005 nSyms+= nSymsThisKey;
1008 len+= nSyms*4;
1009 rep->totalSyms= nSyms;
1010 return len;
1013 static int
1014 XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep)
1016 register unsigned i,nMods,bit;
1018 if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)||
1019 (!xkb)||(!xkb->server)) {
1020 rep->present&= ~XkbVirtualModsMask;
1021 rep->virtualMods= 0;
1022 return 0;
1024 for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
1025 if (rep->virtualMods&bit)
1026 nMods++;
1028 return XkbPaddedSize(nMods);
1031 static char *
1032 XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
1034 register KeySym * pSym;
1035 XkbSymMapPtr symMap;
1036 xkbSymMapWireDesc * outMap;
1037 register unsigned i;
1039 symMap = &xkb->map->key_sym_map[rep->firstKeySym];
1040 for (i=0;i<rep->nKeySyms;i++,symMap++) {
1041 outMap = (xkbSymMapWireDesc *)buf;
1042 outMap->ktIndex[0] = symMap->kt_index[0];
1043 outMap->ktIndex[1] = symMap->kt_index[1];
1044 outMap->ktIndex[2] = symMap->kt_index[2];
1045 outMap->ktIndex[3] = symMap->kt_index[3];
1046 outMap->groupInfo = symMap->group_info;
1047 outMap->width= symMap->width;
1048 outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info);
1049 buf= (char *)&outMap[1];
1050 if (outMap->nSyms==0)
1051 continue;
1053 pSym = &xkb->map->syms[symMap->offset];
1054 memcpy((char *)buf,(char *)pSym,outMap->nSyms*4);
1055 if (client->swapped) {
1056 register int n,nSyms= outMap->nSyms;
1057 swaps(&outMap->nSyms,n);
1058 while (nSyms-->0) {
1059 swapl(buf,n);
1060 buf+= 4;
1063 else buf+= outMap->nSyms*4;
1065 return buf;
1068 static int
1069 XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep)
1071 unsigned i,len,nActs;
1072 register KeyCode firstKey;
1074 if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)||
1075 (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) {
1076 rep->present&= ~XkbKeyActionsMask;
1077 rep->firstKeyAct= rep->nKeyActs= 0;
1078 rep->totalActs= 0;
1079 return 0;
1081 firstKey= rep->firstKeyAct;
1082 for (nActs=i=0;i<rep->nKeyActs;i++) {
1083 if (xkb->server->key_acts[i+firstKey]!=0)
1084 nActs+= XkbKeyNumActions(xkb,i+firstKey);
1086 len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
1087 rep->totalActs= nActs;
1088 return len;
1091 static char *
1092 XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
1093 ClientPtr client)
1095 unsigned i;
1096 CARD8 * numDesc;
1097 XkbAnyAction * actDesc;
1099 numDesc = (CARD8 *)buf;
1100 for (i=0;i<rep->nKeyActs;i++) {
1101 if (xkb->server->key_acts[i+rep->firstKeyAct]==0)
1102 numDesc[i] = 0;
1103 else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
1105 buf+= XkbPaddedSize(rep->nKeyActs);
1107 actDesc = (XkbAnyAction *)buf;
1108 for (i=0;i<rep->nKeyActs;i++) {
1109 if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) {
1110 unsigned int num;
1111 num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
1112 memcpy((char *)actDesc,
1113 (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)),
1114 num*SIZEOF(xkbActionWireDesc));
1115 actDesc+= num;
1118 buf = (char *)actDesc;
1119 return buf;
1122 static int
1123 XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep)
1125 unsigned i,len,nBhvr;
1126 XkbBehavior * bhv;
1128 if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)||
1129 (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) {
1130 rep->present&= ~XkbKeyBehaviorsMask;
1131 rep->firstKeyBehavior= rep->nKeyBehaviors= 0;
1132 rep->totalKeyBehaviors= 0;
1133 return 0;
1135 bhv= &xkb->server->behaviors[rep->firstKeyBehavior];
1136 for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) {
1137 if (bhv->type!=XkbKB_Default)
1138 nBhvr++;
1140 len= nBhvr*SIZEOF(xkbBehaviorWireDesc);
1141 rep->totalKeyBehaviors= nBhvr;
1142 return len;
1145 static char *
1146 XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
1147 ClientPtr client)
1149 unsigned i;
1150 xkbBehaviorWireDesc *wire;
1151 XkbBehavior *pBhvr;
1153 wire = (xkbBehaviorWireDesc *)buf;
1154 pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior];
1155 for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) {
1156 if (pBhvr->type!=XkbKB_Default) {
1157 wire->key= i+rep->firstKeyBehavior;
1158 wire->type= pBhvr->type;
1159 wire->data= pBhvr->data;
1160 wire++;
1163 buf = (char *)wire;
1164 return buf;
1167 static int
1168 XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep)
1170 unsigned i,len,nRtrn;
1172 if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)||
1173 (!xkb)||(!xkb->server)||(!xkb->server->explicit)) {
1174 rep->present&= ~XkbExplicitComponentsMask;
1175 rep->firstKeyExplicit= rep->nKeyExplicit= 0;
1176 rep->totalKeyExplicit= 0;
1177 return 0;
1179 for (nRtrn=i=0;i<rep->nKeyExplicit;i++) {
1180 if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0)
1181 nRtrn++;
1183 rep->totalKeyExplicit= nRtrn;
1184 len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */
1185 return len;
1188 static char *
1189 XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
1191 unsigned i;
1192 char * start;
1193 unsigned char * pExp;
1195 start= buf;
1196 pExp= &xkb->server->explicit[rep->firstKeyExplicit];
1197 for (i=0;i<rep->nKeyExplicit;i++,pExp++) {
1198 if (*pExp!=0) {
1199 *buf++= i+rep->firstKeyExplicit;
1200 *buf++= *pExp;
1203 i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
1204 return buf+i;
1207 static int
1208 XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep)
1210 unsigned i,len,nRtrn;
1212 if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)||
1213 (!xkb)||(!xkb->map)||(!xkb->map->modmap)) {
1214 rep->present&= ~XkbModifierMapMask;
1215 rep->firstModMapKey= rep->nModMapKeys= 0;
1216 rep->totalModMapKeys= 0;
1217 return 0;
1219 for (nRtrn=i=0;i<rep->nModMapKeys;i++) {
1220 if (xkb->map->modmap[i+rep->firstModMapKey]!=0)
1221 nRtrn++;
1223 rep->totalModMapKeys= nRtrn;
1224 len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */
1225 return len;
1228 static char *
1229 XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
1230 ClientPtr client)
1232 unsigned i;
1233 char * start;
1234 unsigned char * pMap;
1236 start= buf;
1237 pMap= &xkb->map->modmap[rep->firstModMapKey];
1238 for (i=0;i<rep->nModMapKeys;i++,pMap++) {
1239 if (*pMap!=0) {
1240 *buf++= i+rep->firstModMapKey;
1241 *buf++= *pMap;
1244 i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
1245 return buf+i;
1248 static int
1249 XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep)
1251 unsigned i,len,nRtrn;
1253 if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)||
1254 (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) {
1255 rep->present&= ~XkbVirtualModMapMask;
1256 rep->firstVModMapKey= rep->nVModMapKeys= 0;
1257 rep->totalVModMapKeys= 0;
1258 return 0;
1260 for (nRtrn=i=0;i<rep->nVModMapKeys-1;i++) {
1261 if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0)
1262 nRtrn++;
1264 rep->totalVModMapKeys= nRtrn;
1265 len= nRtrn*SIZEOF(xkbVModMapWireDesc);
1266 return len;
1269 static char *
1270 XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
1271 ClientPtr client)
1273 unsigned i;
1274 xkbVModMapWireDesc * wire;
1275 unsigned short * pMap;
1277 wire= (xkbVModMapWireDesc *)buf;
1278 pMap= &xkb->server->vmodmap[rep->firstVModMapKey];
1279 for (i=0;i<rep->nVModMapKeys-1;i++,pMap++) {
1280 if (*pMap!=0) {
1281 wire->key= i+rep->firstVModMapKey;
1282 wire->vmods= *pMap;
1283 wire++;
1286 return (char *)wire;
1289 static Status
1290 XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep)
1292 int len;
1294 rep->minKeyCode= xkb->min_key_code;
1295 rep->maxKeyCode= xkb->max_key_code;
1296 len= XkbSizeKeyTypes(xkb,rep);
1297 len+= XkbSizeKeySyms(xkb,rep);
1298 len+= XkbSizeKeyActions(xkb,rep);
1299 len+= XkbSizeKeyBehaviors(xkb,rep);
1300 len+= XkbSizeVirtualMods(xkb,rep);
1301 len+= XkbSizeExplicit(xkb,rep);
1302 len+= XkbSizeModifierMap(xkb,rep);
1303 len+= XkbSizeVirtualModMap(xkb,rep);
1304 rep->length+= (len/4);
1305 return Success;
1308 static int
1309 XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep)
1311 unsigned i,len;
1312 char *desc,*start;
1314 len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
1315 start= desc= (char *)ALLOCATE_LOCAL(len);
1316 if (!start)
1317 return BadAlloc;
1318 if ( rep->nTypes>0 )
1319 desc = XkbWriteKeyTypes(xkb,rep,desc,client);
1320 if ( rep->nKeySyms>0 )
1321 desc = XkbWriteKeySyms(xkb,rep,desc,client);
1322 if ( rep->nKeyActs>0 )
1323 desc = XkbWriteKeyActions(xkb,rep,desc,client);
1324 if ( rep->totalKeyBehaviors>0 )
1325 desc = XkbWriteKeyBehaviors(xkb,rep,desc,client);
1326 if ( rep->virtualMods ) {
1327 register int sz,bit;
1328 for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
1329 if (rep->virtualMods&bit) {
1330 desc[sz++]= xkb->server->vmods[i];
1333 desc+= XkbPaddedSize(sz);
1335 if ( rep->totalKeyExplicit>0 )
1336 desc= XkbWriteExplicit(xkb,rep,desc,client);
1337 if ( rep->totalModMapKeys>0 )
1338 desc= XkbWriteModifierMap(xkb,rep,desc,client);
1339 if ( rep->totalVModMapKeys>0 )
1340 desc= XkbWriteVirtualModMap(xkb,rep,desc,client);
1341 if ((desc-start)!=(len)) {
1342 ErrorF("BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n",
1343 len, (unsigned long)(desc-start));
1345 if (client->swapped) {
1346 register int n;
1347 swaps(&rep->sequenceNumber,n);
1348 swapl(&rep->length,n);
1349 swaps(&rep->present,n);
1350 swaps(&rep->totalSyms,n);
1351 swaps(&rep->totalActs,n);
1353 WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep);
1354 WriteToClient(client, len, start);
1355 DEALLOCATE_LOCAL((char *)start);
1356 return client->noClientException;
1360 ProcXkbGetMap(ClientPtr client)
1362 DeviceIntPtr dev;
1363 xkbGetMapReply rep;
1364 XkbDescRec *xkb;
1365 int n,status;
1367 REQUEST(xkbGetMapReq);
1368 REQUEST_SIZE_MATCH(xkbGetMapReq);
1370 if (!(client->xkbClientFlags&_XkbClientInitialized))
1371 return BadAccess;
1373 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
1374 CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial);
1375 CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask);
1376 CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask);
1378 xkb= dev->key->xkbInfo->desc;
1379 bzero(&rep,sizeof(xkbGetMapReply));
1380 rep.type= X_Reply;
1381 rep.sequenceNumber= client->sequence;
1382 rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2;
1383 rep.deviceID = dev->id;
1384 rep.present = stuff->partial|stuff->full;
1385 rep.minKeyCode = xkb->min_key_code;
1386 rep.maxKeyCode = xkb->max_key_code;
1387 if ( stuff->full&XkbKeyTypesMask ) {
1388 rep.firstType = 0;
1389 rep.nTypes = xkb->map->num_types;
1391 else if (stuff->partial&XkbKeyTypesMask) {
1392 if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) {
1393 client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types,
1394 stuff->firstType,stuff->nTypes);
1395 return BadValue;
1397 rep.firstType = stuff->firstType;
1398 rep.nTypes = stuff->nTypes;
1400 else rep.nTypes = 0;
1401 rep.totalTypes = xkb->map->num_types;
1403 n= XkbNumKeys(xkb);
1404 if ( stuff->full&XkbKeySymsMask ) {
1405 rep.firstKeySym = xkb->min_key_code;
1406 rep.nKeySyms = n;
1408 else if (stuff->partial&XkbKeySymsMask) {
1409 CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb);
1410 rep.firstKeySym = stuff->firstKeySym;
1411 rep.nKeySyms = stuff->nKeySyms;
1413 else rep.nKeySyms = 0;
1414 rep.totalSyms= 0;
1416 if ( stuff->full&XkbKeyActionsMask ) {
1417 rep.firstKeyAct= xkb->min_key_code;
1418 rep.nKeyActs= n;
1420 else if (stuff->partial&XkbKeyActionsMask) {
1421 CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb);
1422 rep.firstKeyAct= stuff->firstKeyAct;
1423 rep.nKeyActs= stuff->nKeyActs;
1425 else rep.nKeyActs= 0;
1426 rep.totalActs= 0;
1428 if ( stuff->full&XkbKeyBehaviorsMask ) {
1429 rep.firstKeyBehavior = xkb->min_key_code;
1430 rep.nKeyBehaviors = n;
1432 else if (stuff->partial&XkbKeyBehaviorsMask) {
1433 CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb);
1434 rep.firstKeyBehavior= stuff->firstKeyBehavior;
1435 rep.nKeyBehaviors= stuff->nKeyBehaviors;
1437 else rep.nKeyBehaviors = 0;
1438 rep.totalKeyBehaviors= 0;
1440 if (stuff->full&XkbVirtualModsMask)
1441 rep.virtualMods= ~0;
1442 else if (stuff->partial&XkbVirtualModsMask)
1443 rep.virtualMods= stuff->virtualMods;
1445 if (stuff->full&XkbExplicitComponentsMask) {
1446 rep.firstKeyExplicit= xkb->min_key_code;
1447 rep.nKeyExplicit= n;
1449 else if (stuff->partial&XkbExplicitComponentsMask) {
1450 CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb);
1451 rep.firstKeyExplicit= stuff->firstKeyExplicit;
1452 rep.nKeyExplicit= stuff->nKeyExplicit;
1454 else rep.nKeyExplicit = 0;
1455 rep.totalKeyExplicit= 0;
1457 if (stuff->full&XkbModifierMapMask) {
1458 rep.firstModMapKey= xkb->min_key_code;
1459 rep.nModMapKeys= n;
1461 else if (stuff->partial&XkbModifierMapMask) {
1462 CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb);
1463 rep.firstModMapKey= stuff->firstModMapKey;
1464 rep.nModMapKeys= stuff->nModMapKeys;
1466 else rep.nModMapKeys = 0;
1467 rep.totalModMapKeys= 0;
1469 if (stuff->full&XkbVirtualModMapMask) {
1470 rep.firstVModMapKey= xkb->min_key_code;
1471 rep.nVModMapKeys= n;
1473 else if (stuff->partial&XkbVirtualModMapMask) {
1474 CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb);
1475 rep.firstVModMapKey= stuff->firstVModMapKey;
1476 rep.nVModMapKeys= stuff->nVModMapKeys;
1478 else rep.nVModMapKeys = 0;
1479 rep.totalVModMapKeys= 0;
1481 if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success)
1482 return status;
1483 return XkbSendMap(client,xkb,&rep);
1486 /***====================================================================***/
1488 static int
1489 CheckKeyTypes( ClientPtr client,
1490 XkbDescPtr xkb,
1491 xkbSetMapReq * req,
1492 xkbKeyTypeWireDesc **wireRtrn,
1493 int * nMapsRtrn,
1494 CARD8 * mapWidthRtrn)
1496 unsigned nMaps;
1497 register unsigned i,n;
1498 register CARD8 * map;
1499 register xkbKeyTypeWireDesc *wire = *wireRtrn;
1501 if (req->firstType>((unsigned)xkb->map->num_types)) {
1502 *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types);
1503 return 0;
1505 if (req->flags&XkbSetMapResizeTypes) {
1506 nMaps = req->firstType+req->nTypes;
1507 if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */
1508 *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4);
1509 return 0;
1512 else if (req->present&XkbKeyTypesMask) {
1513 nMaps = xkb->map->num_types;
1514 if ((req->firstType+req->nTypes)>nMaps) {
1515 *nMapsRtrn = req->firstType+req->nTypes;
1516 return 0;
1519 else {
1520 *nMapsRtrn = xkb->map->num_types;
1521 for (i=0;i<xkb->map->num_types;i++) {
1522 mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1524 return 1;
1527 for (i=0;i<req->firstType;i++) {
1528 mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1530 for (i=0;i<req->nTypes;i++) {
1531 unsigned width;
1532 if (client->swapped) {
1533 register int s;
1534 swaps(&wire->virtualMods,s);
1536 n= i+req->firstType;
1537 width= wire->numLevels;
1538 if (width<1) {
1539 *nMapsRtrn= _XkbErrCode3(0x04,n,width);
1540 return 0;
1542 else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */
1543 *nMapsRtrn= _XkbErrCode3(0x05,n,width);
1544 return 0;
1546 else if ((width!=2)&&
1547 ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)||
1548 (n==XkbAlphabeticIndex))) {
1549 /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
1550 *nMapsRtrn= _XkbErrCode3(0x05,n,width);
1551 return 0;
1553 if (wire->nMapEntries>0) {
1554 xkbKTSetMapEntryWireDesc * mapWire;
1555 xkbModsWireDesc * preWire;
1556 mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1];
1557 preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
1558 for (n=0;n<wire->nMapEntries;n++) {
1559 if (client->swapped) {
1560 register int s;
1561 swaps(&mapWire[n].virtualMods,s);
1563 if (mapWire[n].realMods&(~wire->realMods)) {
1564 *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods,
1565 wire->realMods);
1566 return 0;
1568 if (mapWire[n].virtualMods&(~wire->virtualMods)) {
1569 *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods);
1570 return 0;
1572 if (mapWire[n].level>=wire->numLevels) {
1573 *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels,
1574 mapWire[n].level);
1575 return 0;
1577 if (wire->preserve) {
1578 if (client->swapped) {
1579 register int s;
1580 swaps(&preWire[n].virtualMods,s);
1582 if (preWire[n].realMods&(~mapWire[n].realMods)) {
1583 *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods,
1584 mapWire[n].realMods);
1585 return 0;
1587 if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) {
1588 *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods);
1589 return 0;
1593 if (wire->preserve)
1594 map= (CARD8 *)&preWire[wire->nMapEntries];
1595 else map= (CARD8 *)&mapWire[wire->nMapEntries];
1597 else map= (CARD8 *)&wire[1];
1598 mapWidthRtrn[i+req->firstType] = wire->numLevels;
1599 wire= (xkbKeyTypeWireDesc *)map;
1601 for (i=req->firstType+req->nTypes;i<nMaps;i++) {
1602 mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1604 *nMapsRtrn = nMaps;
1605 *wireRtrn = wire;
1606 return 1;
1609 static int
1610 CheckKeySyms( ClientPtr client,
1611 XkbDescPtr xkb,
1612 xkbSetMapReq * req,
1613 int nTypes,
1614 CARD8 * mapWidths,
1615 CARD16 * symsPerKey,
1616 xkbSymMapWireDesc ** wireRtrn,
1617 int * errorRtrn)
1619 register unsigned i;
1620 XkbSymMapPtr map;
1621 xkbSymMapWireDesc* wire = *wireRtrn;
1623 if (!(XkbKeySymsMask&req->present))
1624 return 1;
1625 CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0);
1626 map = &xkb->map->key_sym_map[xkb->min_key_code];
1627 for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) {
1628 register int g,ng,w;
1629 ng= XkbNumGroups(map->group_info);
1630 for (w=g=0;g<ng;g++) {
1631 if (map->kt_index[g]>=(unsigned)nTypes) {
1632 *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]);
1633 return 0;
1635 if (mapWidths[map->kt_index[g]]>w)
1636 w= mapWidths[map->kt_index[g]];
1638 symsPerKey[i] = w*ng;
1640 for (i=0;i<req->nKeySyms;i++) {
1641 KeySym *pSyms;
1642 register unsigned nG;
1643 if (client->swapped) {
1644 swaps(&wire->nSyms,nG);
1646 nG = XkbNumGroups(wire->groupInfo);
1647 if (nG>XkbNumKbdGroups) {
1648 *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG);
1649 return 0;
1651 if (nG>0) {
1652 register int g,w;
1653 for (g=w=0;g<nG;g++) {
1654 if (wire->ktIndex[g]>=(unsigned)nTypes) {
1655 *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g,
1656 wire->ktIndex[g]);
1657 return 0;
1659 if (mapWidths[wire->ktIndex[g]]>w)
1660 w= mapWidths[wire->ktIndex[g]];
1662 if (wire->width!=w) {
1663 *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width);
1664 return 0;
1666 w*= nG;
1667 symsPerKey[i+req->firstKeySym] = w;
1668 if (w!=wire->nSyms) {
1669 *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w);
1670 return 0;
1673 else if (wire->nSyms!=0) {
1674 *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms);
1675 return 0;
1677 pSyms = (KeySym *)&wire[1];
1678 wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
1681 map = &xkb->map->key_sym_map[i];
1682 for (;i<=(unsigned)xkb->max_key_code;i++,map++) {
1683 register int g,nG,w;
1684 nG= XkbKeyNumGroups(xkb,i);
1685 for (w=g=0;g<nG;g++) {
1686 if (map->kt_index[g]>=(unsigned)nTypes) {
1687 *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]);
1688 return 0;
1690 if (mapWidths[map->kt_index[g]]>w)
1691 w= mapWidths[map->kt_index[g]];
1693 symsPerKey[i] = w*nG;
1695 *wireRtrn = wire;
1696 return 1;
1699 static int
1700 CheckKeyActions( XkbDescPtr xkb,
1701 xkbSetMapReq * req,
1702 int nTypes,
1703 CARD8 * mapWidths,
1704 CARD16 * symsPerKey,
1705 CARD8 ** wireRtrn,
1706 int * nActsRtrn)
1708 int nActs;
1709 CARD8 * wire = *wireRtrn;
1710 register unsigned i;
1712 if (!(XkbKeyActionsMask&req->present))
1713 return 1;
1714 CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0);
1715 for (nActs=i=0;i<req->nKeyActs;i++) {
1716 if (wire[0]!=0) {
1717 if (wire[0]==symsPerKey[i+req->firstKeyAct])
1718 nActs+= wire[0];
1719 else {
1720 *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]);
1721 return 0;
1724 wire++;
1726 if (req->nKeyActs%4)
1727 wire+= 4-(req->nKeyActs%4);
1728 *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs);
1729 *nActsRtrn = nActs;
1730 return 1;
1733 static int
1734 CheckKeyBehaviors( XkbDescPtr xkb,
1735 xkbSetMapReq * req,
1736 xkbBehaviorWireDesc ** wireRtrn,
1737 int * errorRtrn)
1739 register xkbBehaviorWireDesc * wire = *wireRtrn;
1740 register XkbServerMapPtr server = xkb->server;
1741 register unsigned i;
1742 unsigned first,last;
1744 if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) {
1745 req->present&= ~XkbKeyBehaviorsMask;
1746 req->nKeyBehaviors= 0;
1747 return 1;
1749 first= req->firstKeyBehavior;
1750 last= req->firstKeyBehavior+req->nKeyBehaviors-1;
1751 if (first<req->minKeyCode) {
1752 *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode);
1753 return 0;
1755 if (last>req->maxKeyCode) {
1756 *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode);
1757 return 0;
1760 for (i=0;i<req->totalKeyBehaviors;i++,wire++) {
1761 if ((wire->key<first)||(wire->key>last)) {
1762 *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key);
1763 return 0;
1765 if ((wire->type&XkbKB_Permanent)&&
1766 ((server->behaviors[wire->key].type!=wire->type)||
1767 (server->behaviors[wire->key].data!=wire->data))) {
1768 *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type);
1769 return 0;
1771 if ((wire->type==XkbKB_RadioGroup)&&
1772 ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) {
1773 *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data,
1774 XkbMaxRadioGroups);
1775 return 0;
1777 if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) {
1778 CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0);
1781 *wireRtrn = wire;
1782 return 1;
1785 static int
1786 CheckVirtualMods( XkbDescRec * xkb,
1787 xkbSetMapReq * req,
1788 CARD8 ** wireRtrn,
1789 int * errorRtrn)
1791 register CARD8 *wire = *wireRtrn;
1792 register unsigned i,nMods,bit;
1794 if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
1795 return 1;
1796 for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
1797 if (req->virtualMods&bit)
1798 nMods++;
1800 *wireRtrn= (wire+XkbPaddedSize(nMods));
1801 return 1;
1804 static int
1805 CheckKeyExplicit( XkbDescPtr xkb,
1806 xkbSetMapReq * req,
1807 CARD8 ** wireRtrn,
1808 int * errorRtrn)
1810 register CARD8 * wire = *wireRtrn;
1811 CARD8 * start;
1812 register unsigned i;
1813 int first,last;
1815 if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) {
1816 req->present&= ~XkbExplicitComponentsMask;
1817 req->nKeyExplicit= 0;
1818 return 1;
1820 first= req->firstKeyExplicit;
1821 last= first+req->nKeyExplicit-1;
1822 if (first<req->minKeyCode) {
1823 *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode);
1824 return 0;
1826 if (last>req->maxKeyCode) {
1827 *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode);
1828 return 0;
1830 start= wire;
1831 for (i=0;i<req->totalKeyExplicit;i++,wire+=2) {
1832 if ((wire[0]<first)||(wire[0]>last)) {
1833 *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]);
1834 return 0;
1836 if (wire[1]&(~XkbAllExplicitMask)) {
1837 *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]);
1838 return 0;
1841 wire+= XkbPaddedSize(wire-start)-(wire-start);
1842 *wireRtrn= wire;
1843 return 1;
1846 static int
1847 CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn)
1849 register CARD8 * wire = *wireRtrn;
1850 CARD8 * start;
1851 register unsigned i;
1852 int first,last;
1854 if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) {
1855 req->present&= ~XkbModifierMapMask;
1856 req->nModMapKeys= 0;
1857 return 1;
1859 first= req->firstModMapKey;
1860 last= first+req->nModMapKeys-1;
1861 if (first<req->minKeyCode) {
1862 *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode);
1863 return 0;
1865 if (last>req->maxKeyCode) {
1866 *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode);
1867 return 0;
1869 start= wire;
1870 for (i=0;i<req->totalModMapKeys;i++,wire+=2) {
1871 if ((wire[0]<first)||(wire[0]>last)) {
1872 *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]);
1873 return 0;
1876 wire+= XkbPaddedSize(wire-start)-(wire-start);
1877 *wireRtrn= wire;
1878 return 1;
1881 static int
1882 CheckVirtualModMap( XkbDescPtr xkb,
1883 xkbSetMapReq *req,
1884 xkbVModMapWireDesc **wireRtrn,
1885 int *errRtrn)
1887 register xkbVModMapWireDesc * wire = *wireRtrn;
1888 register unsigned i;
1889 int first,last;
1891 if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) {
1892 req->present&= ~XkbVirtualModMapMask;
1893 req->nVModMapKeys= 0;
1894 return 1;
1896 first= req->firstVModMapKey;
1897 last= first+req->nVModMapKeys-1;
1898 if (first<req->minKeyCode) {
1899 *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode);
1900 return 0;
1902 if (last>req->maxKeyCode) {
1903 *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode);
1904 return 0;
1906 for (i=0;i<req->totalVModMapKeys;i++,wire++) {
1907 if ((wire->key<first)||(wire->key>last)) {
1908 *errRtrn = _XkbErrCode4(0x73,first,last,wire->key);
1909 return 0;
1912 *wireRtrn= wire;
1913 return 1;
1916 static char *
1917 SetKeyTypes( XkbDescPtr xkb,
1918 xkbSetMapReq * req,
1919 xkbKeyTypeWireDesc * wire,
1920 XkbChangesPtr changes)
1922 register unsigned i;
1923 unsigned first,last;
1924 CARD8 *map;
1926 if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) {
1927 i= req->firstType+req->nTypes;
1928 if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) {
1929 return NULL;
1932 if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types)
1933 xkb->map->num_types= req->firstType+req->nTypes;
1935 for (i=0;i<req->nTypes;i++) {
1936 XkbKeyTypePtr pOld;
1937 register unsigned n;
1939 if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries,
1940 wire->preserve,wire->numLevels)!=Success) {
1941 return NULL;
1943 pOld = &xkb->map->types[i+req->firstType];
1944 map = (CARD8 *)&wire[1];
1946 pOld->mods.real_mods = wire->realMods;
1947 pOld->mods.vmods= wire->virtualMods;
1948 pOld->num_levels = wire->numLevels;
1949 pOld->map_count= wire->nMapEntries;
1951 pOld->mods.mask= pOld->mods.real_mods|
1952 XkbMaskForVMask(xkb,pOld->mods.vmods);
1954 if (wire->nMapEntries) {
1955 xkbKTSetMapEntryWireDesc *mapWire;
1956 xkbModsWireDesc *preWire;
1957 unsigned tmp;
1958 mapWire= (xkbKTSetMapEntryWireDesc *)map;
1959 preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
1960 for (n=0;n<wire->nMapEntries;n++) {
1961 pOld->map[n].active= 1;
1962 pOld->map[n].mods.mask= mapWire[n].realMods;
1963 pOld->map[n].mods.real_mods= mapWire[n].realMods;
1964 pOld->map[n].mods.vmods= mapWire[n].virtualMods;
1965 pOld->map[n].level= mapWire[n].level;
1966 if (mapWire[n].virtualMods!=0) {
1967 tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods);
1968 pOld->map[n].active= (tmp!=0);
1969 pOld->map[n].mods.mask|= tmp;
1971 if (wire->preserve) {
1972 pOld->preserve[n].real_mods= preWire[n].realMods;
1973 pOld->preserve[n].vmods= preWire[n].virtualMods;
1974 tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods);
1975 pOld->preserve[n].mask= preWire[n].realMods|tmp;
1978 if (wire->preserve)
1979 map= (CARD8 *)&preWire[wire->nMapEntries];
1980 else map= (CARD8 *)&mapWire[wire->nMapEntries];
1982 else map= (CARD8 *)&wire[1];
1983 wire = (xkbKeyTypeWireDesc *)map;
1985 first= req->firstType;
1986 last= first+req->nTypes-1; /* last changed type */
1987 if (changes->map.changed&XkbKeyTypesMask) {
1988 int oldLast;
1989 oldLast= changes->map.first_type+changes->map.num_types-1;
1990 if (changes->map.first_type<first)
1991 first= changes->map.first_type;
1992 if (oldLast>last)
1993 last= oldLast;
1995 changes->map.changed|= XkbKeyTypesMask;
1996 changes->map.first_type = first;
1997 changes->map.num_types = (last-first)+1;
1998 return (char *)wire;
2001 static char *
2002 SetKeySyms( ClientPtr client,
2003 XkbDescPtr xkb,
2004 xkbSetMapReq * req,
2005 xkbSymMapWireDesc * wire,
2006 XkbChangesPtr changes,
2007 DeviceIntPtr dev)
2009 register unsigned i,s;
2010 XkbSymMapPtr oldMap;
2011 KeySym * newSyms;
2012 KeySym * pSyms;
2013 unsigned first,last;
2015 oldMap = &xkb->map->key_sym_map[req->firstKeySym];
2016 for (i=0;i<req->nKeySyms;i++,oldMap++) {
2017 pSyms = (KeySym *)&wire[1];
2018 if (wire->nSyms>0) {
2019 newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms);
2020 for (s=0;s<wire->nSyms;s++) {
2021 newSyms[s]= pSyms[s];
2023 if (client->swapped) {
2024 int n;
2025 for (s=0;s<wire->nSyms;s++) {
2026 swapl(&newSyms[s],n);
2030 oldMap->kt_index[0] = wire->ktIndex[0];
2031 oldMap->kt_index[1] = wire->ktIndex[1];
2032 oldMap->kt_index[2] = wire->ktIndex[2];
2033 oldMap->kt_index[3] = wire->ktIndex[3];
2034 oldMap->group_info = wire->groupInfo;
2035 oldMap->width = wire->width;
2036 wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
2038 first= req->firstKeySym;
2039 last= first+req->nKeySyms-1;
2040 if (changes->map.changed&XkbKeySymsMask) {
2041 int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1);
2042 if (changes->map.first_key_sym<first)
2043 first= changes->map.first_key_sym;
2044 if (oldLast>last)
2045 last= oldLast;
2047 changes->map.changed|= XkbKeySymsMask;
2048 changes->map.first_key_sym = first;
2049 changes->map.num_key_syms = (last-first+1);
2051 s= 0;
2052 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
2053 if (XkbKeyNumGroups(xkb,i)>s)
2054 s= XkbKeyNumGroups(xkb,i);
2056 if (s!=xkb->ctrls->num_groups) {
2057 xkbControlsNotify cn;
2058 XkbControlsRec old;
2059 cn.keycode= 0;
2060 cn.eventType= 0;
2061 cn.requestMajor= XkbReqCode;
2062 cn.requestMinor= X_kbSetMap;
2063 old= *xkb->ctrls;
2064 xkb->ctrls->num_groups= s;
2065 if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,False))
2066 XkbSendControlsNotify(dev,&cn);
2068 return (char *)wire;
2071 static char *
2072 SetKeyActions( XkbDescPtr xkb,
2073 xkbSetMapReq * req,
2074 CARD8 * wire,
2075 XkbChangesPtr changes)
2077 register unsigned i,first,last;
2078 CARD8 * nActs = wire;
2079 XkbAction * newActs;
2081 wire+= XkbPaddedSize(req->nKeyActs);
2082 for (i=0;i<req->nKeyActs;i++) {
2083 if (nActs[i]==0)
2084 xkb->server->key_acts[i+req->firstKeyAct]= 0;
2085 else {
2086 newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]);
2087 memcpy((char *)newActs,(char *)wire,
2088 nActs[i]*SIZEOF(xkbActionWireDesc));
2089 wire+= nActs[i]*SIZEOF(xkbActionWireDesc);
2092 first= req->firstKeyAct;
2093 last= (first+req->nKeyActs-1);
2094 if (changes->map.changed&XkbKeyActionsMask) {
2095 int oldLast;
2096 oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
2097 if (changes->map.first_key_act<first)
2098 first= changes->map.first_key_act;
2099 if (oldLast>last)
2100 last= oldLast;
2102 changes->map.changed|= XkbKeyActionsMask;
2103 changes->map.first_key_act= first;
2104 changes->map.num_key_acts= (last-first+1);
2105 return (char *)wire;
2108 static char *
2109 SetKeyBehaviors( XkbSrvInfoPtr xkbi,
2110 xkbSetMapReq *req,
2111 xkbBehaviorWireDesc *wire,
2112 XkbChangesPtr changes)
2114 register unsigned i;
2115 int maxRG = -1;
2116 XkbDescPtr xkb = xkbi->desc;
2117 XkbServerMapPtr server = xkb->server;
2118 unsigned first,last;
2120 first= req->firstKeyBehavior;
2121 last= req->firstKeyBehavior+req->nKeyBehaviors-1;
2122 bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior));
2123 for (i=0;i<req->totalKeyBehaviors;i++) {
2124 if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) {
2125 server->behaviors[wire->key].type= wire->type;
2126 server->behaviors[wire->key].data= wire->data;
2127 if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG))
2128 maxRG= wire->data + 1;
2130 wire++;
2133 if (maxRG>(int)xkbi->nRadioGroups) {
2134 int sz = maxRG*sizeof(XkbRadioGroupRec);
2135 if (xkbi->radioGroups)
2136 xkbi->radioGroups=(XkbRadioGroupPtr)_XkbRealloc(xkbi->radioGroups,sz);
2137 else xkbi->radioGroups= (XkbRadioGroupPtr)_XkbCalloc(1, sz);
2138 if (xkbi->radioGroups) {
2139 if (xkbi->nRadioGroups)
2140 bzero(&xkbi->radioGroups[xkbi->nRadioGroups],
2141 (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec));
2142 xkbi->nRadioGroups= maxRG;
2144 else xkbi->nRadioGroups= 0;
2145 /* should compute members here */
2147 if (changes->map.changed&XkbKeyBehaviorsMask) {
2148 unsigned oldLast;
2149 oldLast= changes->map.first_key_behavior+
2150 changes->map.num_key_behaviors-1;
2151 if (changes->map.first_key_behavior<req->firstKeyBehavior)
2152 first= changes->map.first_key_behavior;
2153 if (oldLast>last)
2154 last= oldLast;
2156 changes->map.changed|= XkbKeyBehaviorsMask;
2157 changes->map.first_key_behavior = first;
2158 changes->map.num_key_behaviors = (last-first+1);
2159 return (char *)wire;
2162 static char *
2163 SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
2164 XkbChangesPtr changes)
2166 register int i,bit,nMods;
2167 XkbServerMapPtr srv = xkbi->desc->server;
2169 if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
2170 return (char *)wire;
2171 for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
2172 if (req->virtualMods&bit) {
2173 if (srv->vmods[i]!=wire[nMods]) {
2174 changes->map.changed|= XkbVirtualModsMask;
2175 changes->map.vmods|= bit;
2176 srv->vmods[i]= wire[nMods];
2178 nMods++;
2181 return (char *)(wire+XkbPaddedSize(nMods));
2184 static char *
2185 SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
2186 XkbChangesPtr changes)
2188 register unsigned i,first,last;
2189 XkbServerMapPtr xkb = xkbi->desc->server;
2190 CARD8 * start;
2192 start= wire;
2193 first= req->firstKeyExplicit;
2194 last= req->firstKeyExplicit+req->nKeyExplicit-1;
2195 bzero(&xkb->explicit[first],req->nKeyExplicit);
2196 for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) {
2197 xkb->explicit[wire[0]]= wire[1];
2199 if (first>0) {
2200 if (changes->map.changed&XkbExplicitComponentsMask) {
2201 int oldLast;
2202 oldLast= changes->map.first_key_explicit+
2203 changes->map.num_key_explicit-1;
2204 if (changes->map.first_key_explicit<first)
2205 first= changes->map.first_key_explicit;
2206 if (oldLast>last)
2207 last= oldLast;
2209 changes->map.first_key_explicit= first;
2210 changes->map.num_key_explicit= (last-first)+1;
2212 wire+= XkbPaddedSize(wire-start)-(wire-start);
2213 return (char *)wire;
2216 static char *
2217 SetModifierMap( XkbSrvInfoPtr xkbi,
2218 xkbSetMapReq * req,
2219 CARD8 * wire,
2220 XkbChangesPtr changes)
2222 register unsigned i,first,last;
2223 XkbClientMapPtr xkb = xkbi->desc->map;
2224 CARD8 * start;
2226 start= wire;
2227 first= req->firstModMapKey;
2228 last= req->firstModMapKey+req->nModMapKeys-1;
2229 bzero(&xkb->modmap[first],req->nModMapKeys);
2230 for (i=0;i<req->totalModMapKeys;i++,wire+= 2) {
2231 xkb->modmap[wire[0]]= wire[1];
2233 if (first>0) {
2234 if (changes->map.changed&XkbModifierMapMask) {
2235 int oldLast;
2236 oldLast= changes->map.first_modmap_key+
2237 changes->map.num_modmap_keys-1;
2238 if (changes->map.first_modmap_key<first)
2239 first= changes->map.first_modmap_key;
2240 if (oldLast>last)
2241 last= oldLast;
2243 changes->map.first_modmap_key= first;
2244 changes->map.num_modmap_keys= (last-first)+1;
2246 wire+= XkbPaddedSize(wire-start)-(wire-start);
2247 return (char *)wire;
2250 static char *
2251 SetVirtualModMap( XkbSrvInfoPtr xkbi,
2252 xkbSetMapReq * req,
2253 xkbVModMapWireDesc * wire,
2254 XkbChangesPtr changes)
2256 register unsigned i,first,last;
2257 XkbServerMapPtr srv = xkbi->desc->server;
2259 first= req->firstVModMapKey;
2260 last= req->firstVModMapKey+req->nVModMapKeys-1;
2261 bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short));
2262 for (i=0;i<req->totalVModMapKeys;i++,wire++) {
2263 srv->vmodmap[wire->key]= wire->vmods;
2265 if (first>0) {
2266 if (changes->map.changed&XkbVirtualModMapMask) {
2267 int oldLast;
2268 oldLast= changes->map.first_vmodmap_key+
2269 changes->map.num_vmodmap_keys-1;
2270 if (changes->map.first_vmodmap_key<first)
2271 first= changes->map.first_vmodmap_key;
2272 if (oldLast>last)
2273 last= oldLast;
2275 changes->map.first_vmodmap_key= first;
2276 changes->map.num_vmodmap_keys= (last-first)+1;
2278 return (char *)wire;
2281 /* FIXME: Needs to set map on all core-sending devices. */
2283 ProcXkbSetMap(ClientPtr client)
2285 DeviceIntPtr dev;
2286 XkbSrvInfoPtr xkbi;
2287 XkbDescPtr xkb;
2288 XkbChangesRec change;
2289 XkbEventCauseRec cause;
2290 int nTypes = 0,nActions,error;
2291 char * tmp;
2292 CARD8 mapWidths[XkbMaxLegalKeyCode+1];
2293 CARD16 symsPerKey[XkbMaxLegalKeyCode+1];
2294 Bool sentNKN;
2296 REQUEST(xkbSetMapReq);
2297 REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
2299 if (!(client->xkbClientFlags&_XkbClientInitialized))
2300 return BadAccess;
2302 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
2303 CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
2305 XkbSetCauseXkbReq(&cause,X_kbSetMap,client);
2306 xkbi= dev->key->xkbInfo;
2307 xkb = xkbi->desc;
2309 if ((xkb->min_key_code!=stuff->minKeyCode)||
2310 (xkb->max_key_code!=stuff->maxKeyCode)) {
2311 if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */
2312 stuff->minKeyCode= xkb->min_key_code;
2313 stuff->maxKeyCode= xkb->max_key_code;
2315 else {
2316 if (!XkbIsLegalKeycode(stuff->minKeyCode)) {
2317 client->errorValue= _XkbErrCode3(2,stuff->minKeyCode,
2318 stuff->maxKeyCode);
2319 return BadValue;
2321 if (stuff->minKeyCode>stuff->maxKeyCode) {
2322 client->errorValue= _XkbErrCode3(3,stuff->minKeyCode,
2323 stuff->maxKeyCode);
2324 return BadMatch;
2329 tmp = (char *)&stuff[1];
2330 if ((stuff->present&XkbKeyTypesMask)&&
2331 (!CheckKeyTypes(client,xkb,stuff,(xkbKeyTypeWireDesc **)&tmp,
2332 &nTypes,mapWidths))) {
2333 client->errorValue = nTypes;
2334 return BadValue;
2336 if ((stuff->present&XkbKeySymsMask)&&
2337 (!CheckKeySyms(client,xkb,stuff,nTypes,mapWidths,symsPerKey,
2338 (xkbSymMapWireDesc **)&tmp,&error))) {
2339 client->errorValue = error;
2340 return BadValue;
2343 if ((stuff->present&XkbKeyActionsMask)&&
2344 (!CheckKeyActions(xkb,stuff,nTypes,mapWidths,symsPerKey,
2345 (CARD8 **)&tmp,&nActions))) {
2346 client->errorValue = nActions;
2347 return BadValue;
2350 if ((stuff->present&XkbKeyBehaviorsMask)&&
2351 (!CheckKeyBehaviors(xkb,stuff,(xkbBehaviorWireDesc**)&tmp,&error))) {
2352 client->errorValue = error;
2353 return BadValue;
2356 if ((stuff->present&XkbVirtualModsMask)&&
2357 (!CheckVirtualMods(xkb,stuff,(CARD8 **)&tmp,&error))) {
2358 client->errorValue= error;
2359 return BadValue;
2361 if ((stuff->present&XkbExplicitComponentsMask)&&
2362 (!CheckKeyExplicit(xkb,stuff,(CARD8 **)&tmp,&error))) {
2363 client->errorValue= error;
2364 return BadValue;
2366 if ((stuff->present&XkbModifierMapMask)&&
2367 (!CheckModifierMap(xkb,stuff,(CARD8 **)&tmp,&error))) {
2368 client->errorValue= error;
2369 return BadValue;
2371 if ((stuff->present&XkbVirtualModMapMask)&&
2372 (!CheckVirtualModMap(xkb,stuff,(xkbVModMapWireDesc **)&tmp,&error))) {
2373 client->errorValue= error;
2374 return BadValue;
2376 if (((tmp-((char *)stuff))/4)!=stuff->length) {
2377 ErrorF("Internal error! Bad length in XkbSetMap (after check)\n");
2378 client->errorValue = tmp-((char *)&stuff[1]);
2379 return BadLength;
2381 bzero(&change,sizeof(change));
2382 sentNKN= False;
2383 if ((xkb->min_key_code!=stuff->minKeyCode)||
2384 (xkb->max_key_code!=stuff->maxKeyCode)) {
2385 Status status;
2386 xkbNewKeyboardNotify nkn;
2387 nkn.deviceID= nkn.oldDeviceID= dev->id;
2388 nkn.oldMinKeyCode= xkb->min_key_code;
2389 nkn.oldMaxKeyCode= xkb->max_key_code;
2390 status= XkbChangeKeycodeRange(xkb,stuff->minKeyCode,stuff->maxKeyCode,
2391 &change);
2392 if (status!=Success)
2393 return status;
2394 nkn.minKeyCode= xkb->min_key_code;
2395 nkn.maxKeyCode= xkb->max_key_code;
2396 nkn.requestMajor= XkbReqCode;
2397 nkn.requestMinor= X_kbSetMap;
2398 nkn.changed= XkbNKN_KeycodesMask;
2399 XkbSendNewKeyboardNotify(dev,&nkn);
2400 sentNKN= True;
2402 tmp = (char *)&stuff[1];
2403 if (stuff->present&XkbKeyTypesMask) {
2404 tmp = SetKeyTypes(xkb,stuff,(xkbKeyTypeWireDesc *)tmp,&change);
2405 if (!tmp) goto allocFailure;
2407 if (stuff->present&XkbKeySymsMask) {
2408 tmp = SetKeySyms(client,xkb,stuff,(xkbSymMapWireDesc *)tmp,&change,dev);
2409 if (!tmp) goto allocFailure;
2411 if (stuff->present&XkbKeyActionsMask) {
2412 tmp = SetKeyActions(xkb,stuff,(CARD8 *)tmp,&change);
2413 if (!tmp) goto allocFailure;
2415 if (stuff->present&XkbKeyBehaviorsMask) {
2416 tmp= SetKeyBehaviors(xkbi,stuff,(xkbBehaviorWireDesc *)tmp,&change);
2417 if (!tmp) goto allocFailure;
2419 if (stuff->present&XkbVirtualModsMask)
2420 tmp= SetVirtualMods(xkbi,stuff,(CARD8 *)tmp,&change);
2421 if (stuff->present&XkbExplicitComponentsMask)
2422 tmp= SetKeyExplicit(xkbi,stuff,(CARD8 *)tmp,&change);
2423 if (stuff->present&XkbModifierMapMask)
2424 tmp= SetModifierMap(xkbi,stuff,(CARD8 *)tmp,&change);
2425 if (stuff->present&XkbVirtualModMapMask)
2426 tmp= SetVirtualModMap(xkbi,stuff,(xkbVModMapWireDesc *)tmp,&change);
2427 if (((tmp-((char *)stuff))/4)!=stuff->length) {
2428 ErrorF("Internal error! Bad length in XkbSetMap (after set)\n");
2429 client->errorValue = tmp-((char *)&stuff[1]);
2430 return BadLength;
2432 if (stuff->flags&XkbSetMapRecomputeActions) {
2433 KeyCode first,last,firstMM,lastMM;
2434 if (change.map.num_key_syms>0) {
2435 first= change.map.first_key_sym;
2436 last= first+change.map.num_key_syms-1;
2438 else first= last= 0;
2439 if (change.map.num_modmap_keys>0) {
2440 firstMM= change.map.first_modmap_key;
2441 lastMM= first+change.map.num_modmap_keys-1;
2443 else firstMM= lastMM= 0;
2444 if ((last>0) && (lastMM>0)) {
2445 if (firstMM<first)
2446 first= firstMM;
2447 if (lastMM>last)
2448 last= lastMM;
2450 else if (lastMM>0) {
2451 first= firstMM;
2452 last= lastMM;
2454 if (last>0) {
2455 unsigned check= 0;
2456 XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause);
2457 if (check)
2458 XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
2461 if (!sentNKN)
2462 XkbSendNotification(dev,&change,&cause);
2464 XkbUpdateCoreDescription(dev,False);
2465 return client->noClientException;
2466 allocFailure:
2467 return BadAlloc;
2470 /***====================================================================***/
2472 static Status
2473 XkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat,
2474 xkbGetCompatMapReply * rep)
2476 unsigned size,nGroups;
2478 nGroups= 0;
2479 if (rep->groups!=0) {
2480 register int i,bit;
2481 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
2482 if (rep->groups&bit)
2483 nGroups++;
2486 size= nGroups*SIZEOF(xkbModsWireDesc);
2487 size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc));
2488 rep->length= size/4;
2489 return Success;
2492 static int
2493 XkbSendCompatMap( ClientPtr client,
2494 XkbCompatMapPtr compat,
2495 xkbGetCompatMapReply * rep)
2497 char * data;
2498 int size;
2500 size= rep->length*4;
2501 if (size>0) {
2502 data = (char *)ALLOCATE_LOCAL(size);
2503 if (data) {
2504 register unsigned i,bit;
2505 xkbModsWireDesc * grp;
2506 XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI];
2507 xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
2508 for (i=0;i<rep->nSI;i++,sym++,wire++) {
2509 wire->sym= sym->sym;
2510 wire->mods= sym->mods;
2511 wire->match= sym->match;
2512 wire->virtualMod= sym->virtual_mod;
2513 wire->flags= sym->flags;
2514 memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc);
2515 if (client->swapped) {
2516 register int n;
2517 swapl(&wire->sym,n);
2520 if (rep->groups) {
2521 grp = (xkbModsWireDesc *)wire;
2522 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
2523 if (rep->groups&bit) {
2524 grp->mask= compat->groups[i].mask;
2525 grp->realMods= compat->groups[i].real_mods;
2526 grp->virtualMods= compat->groups[i].vmods;
2527 if (client->swapped) {
2528 register int n;
2529 swaps(&grp->virtualMods,n);
2531 grp++;
2534 wire= (xkbSymInterpretWireDesc*)grp;
2537 else return BadAlloc;
2539 else data= NULL;
2541 if (client->swapped) {
2542 register int n;
2543 swaps(&rep->sequenceNumber,n);
2544 swapl(&rep->length,n);
2545 swaps(&rep->firstSI,n);
2546 swaps(&rep->nSI,n);
2547 swaps(&rep->nTotalSI,n);
2550 WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep);
2551 if (data) {
2552 WriteToClient(client, size, data);
2553 DEALLOCATE_LOCAL((char *)data);
2555 return client->noClientException;
2559 ProcXkbGetCompatMap(ClientPtr client)
2561 xkbGetCompatMapReply rep;
2562 DeviceIntPtr dev;
2563 XkbDescPtr xkb;
2564 XkbCompatMapPtr compat;
2566 REQUEST(xkbGetCompatMapReq);
2567 REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
2569 if (!(client->xkbClientFlags&_XkbClientInitialized))
2570 return BadAccess;
2572 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
2574 xkb = dev->key->xkbInfo->desc;
2575 compat= xkb->compat;
2577 rep.type = X_Reply;
2578 rep.deviceID = dev->id;
2579 rep.sequenceNumber = client->sequence;
2580 rep.length = 0;
2581 rep.firstSI = stuff->firstSI;
2582 rep.nSI = stuff->nSI;
2583 if (stuff->getAllSI) {
2584 rep.firstSI = 0;
2585 rep.nSI = compat->num_si;
2587 else if ((((unsigned)stuff->nSI)>0)&&
2588 ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) {
2589 client->errorValue = _XkbErrCode2(0x05,compat->num_si);
2590 return BadValue;
2592 rep.nTotalSI = compat->num_si;
2593 rep.groups= stuff->groups;
2594 XkbComputeGetCompatMapReplySize(compat,&rep);
2595 return XkbSendCompatMap(client,compat,&rep);
2598 /* FIXME: Needs to set compat map on all core-sending devices. */
2600 ProcXkbSetCompatMap(ClientPtr client)
2602 DeviceIntPtr dev;
2603 XkbSrvInfoPtr xkbi;
2604 XkbDescPtr xkb;
2605 XkbCompatMapPtr compat;
2606 char * data;
2607 int nGroups;
2608 register unsigned i,bit;
2610 REQUEST(xkbSetCompatMapReq);
2611 REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
2613 if (!(client->xkbClientFlags&_XkbClientInitialized))
2614 return BadAccess;
2616 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
2618 data = (char *)&stuff[1];
2619 xkbi = dev->key->xkbInfo;
2620 xkb= xkbi->desc;
2621 compat= xkb->compat;
2622 if ((stuff->nSI>0)||(stuff->truncateSI)) {
2623 xkbSymInterpretWireDesc *wire;
2624 if (stuff->firstSI>compat->num_si) {
2625 client->errorValue = _XkbErrCode2(0x02,compat->num_si);
2626 return BadValue;
2628 wire= (xkbSymInterpretWireDesc *)data;
2629 wire+= stuff->nSI;
2630 data = (char *)wire;
2632 nGroups= 0;
2633 if (stuff->groups!=0) {
2634 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
2635 if ( stuff->groups&bit )
2636 nGroups++;
2639 data+= nGroups*SIZEOF(xkbModsWireDesc);
2640 if (((data-((char *)stuff))/4)!=stuff->length) {
2641 return BadLength;
2643 data = (char *)&stuff[1];
2644 if (stuff->nSI>0) {
2645 xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
2646 XkbSymInterpretPtr sym;
2647 if ((unsigned)(stuff->firstSI+stuff->nSI)>compat->num_si) {
2648 compat->num_si= stuff->firstSI+stuff->nSI;
2649 compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret,
2650 compat->num_si,
2651 XkbSymInterpretRec);
2652 if (!compat->sym_interpret) {
2653 compat->num_si= 0;
2654 return BadAlloc;
2657 else if (stuff->truncateSI) {
2658 compat->num_si = stuff->firstSI+stuff->nSI;
2660 sym = &compat->sym_interpret[stuff->firstSI];
2661 for (i=0;i<stuff->nSI;i++,wire++,sym++) {
2662 if (client->swapped) {
2663 register int n;
2664 swapl(&wire->sym,n);
2666 sym->sym= wire->sym;
2667 sym->mods= wire->mods;
2668 sym->match= wire->match;
2669 sym->flags= wire->flags;
2670 sym->virtual_mod= wire->virtualMod;
2671 memcpy((char *)&sym->act,(char *)&wire->act,
2672 SIZEOF(xkbActionWireDesc));
2674 data = (char *)wire;
2676 else if (stuff->truncateSI) {
2677 compat->num_si = stuff->firstSI;
2680 if (stuff->groups!=0) {
2681 register unsigned i,bit;
2682 xkbModsWireDesc *wire = (xkbModsWireDesc *)data;
2683 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
2684 if (stuff->groups&bit) {
2685 if (client->swapped) {
2686 register int n;
2687 swaps(&wire->virtualMods,n);
2689 compat->groups[i].mask= wire->realMods;
2690 compat->groups[i].real_mods= wire->realMods;
2691 compat->groups[i].vmods= wire->virtualMods;
2692 if (wire->virtualMods!=0) {
2693 unsigned tmp;
2694 tmp= XkbMaskForVMask(xkb,wire->virtualMods);
2695 compat->groups[i].mask|= tmp;
2697 data+= SIZEOF(xkbModsWireDesc);
2698 wire= (xkbModsWireDesc *)data;
2702 i= XkbPaddedSize((data-((char *)stuff)));
2703 if ((i/4)!=stuff->length) {
2704 ErrorF("Internal length error on read in ProcXkbSetCompatMap\n");
2705 return BadLength;
2708 if (dev->xkb_interest) {
2709 xkbCompatMapNotify ev;
2710 ev.deviceID = dev->id;
2711 ev.changedGroups = stuff->groups;
2712 ev.firstSI = stuff->firstSI;
2713 ev.nSI = stuff->nSI;
2714 ev.nTotalSI = compat->num_si;
2715 XkbSendCompatMapNotify(dev,&ev);
2718 if (stuff->recomputeActions) {
2719 XkbChangesRec change;
2720 unsigned check;
2721 XkbEventCauseRec cause;
2723 XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client);
2724 bzero(&change,sizeof(XkbChangesRec));
2725 XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check,
2726 &cause);
2727 if (check)
2728 XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
2729 XkbUpdateCoreDescription(dev,False);
2730 XkbSendNotification(dev,&change,&cause);
2732 return client->noClientException;
2735 /***====================================================================***/
2738 ProcXkbGetIndicatorState(ClientPtr client)
2740 xkbGetIndicatorStateReply rep;
2741 XkbSrvLedInfoPtr sli;
2742 DeviceIntPtr dev;
2743 register int i;
2745 REQUEST(xkbGetIndicatorStateReq);
2746 REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
2748 if (!(client->xkbClientFlags&_XkbClientInitialized))
2749 return BadAccess;
2751 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
2753 sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
2754 XkbXI_IndicatorStateMask);
2755 if (!sli)
2756 return BadAlloc;
2758 rep.type = X_Reply;
2759 rep.sequenceNumber = client->sequence;
2760 rep.length = 0;
2761 rep.deviceID = dev->id;
2762 rep.state = sli->effectiveState;
2764 if (client->swapped) {
2765 swaps(&rep.sequenceNumber,i);
2766 swapl(&rep.state,i);
2768 WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep);
2769 return client->noClientException;
2772 /***====================================================================***/
2774 static Status
2775 XkbComputeGetIndicatorMapReplySize(
2776 XkbIndicatorPtr indicators,
2777 xkbGetIndicatorMapReply *rep)
2779 register int i,bit;
2780 int nIndicators;
2782 rep->realIndicators = indicators->phys_indicators;
2783 for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
2784 if (rep->which&bit)
2785 nIndicators++;
2787 rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4;
2788 return Success;
2791 static int
2792 XkbSendIndicatorMap( ClientPtr client,
2793 XkbIndicatorPtr indicators,
2794 xkbGetIndicatorMapReply * rep)
2796 int length;
2797 CARD8 * map;
2798 register int i;
2799 register unsigned bit;
2801 length = rep->length*4;
2802 if (length>0) {
2803 CARD8 *to;
2804 to= map= (CARD8 *)ALLOCATE_LOCAL(length);
2805 if (map) {
2806 xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to;
2807 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
2808 if (rep->which&bit) {
2809 wire->flags= indicators->maps[i].flags;
2810 wire->whichGroups= indicators->maps[i].which_groups;
2811 wire->groups= indicators->maps[i].groups;
2812 wire->whichMods= indicators->maps[i].which_mods;
2813 wire->mods= indicators->maps[i].mods.mask;
2814 wire->realMods= indicators->maps[i].mods.real_mods;
2815 wire->virtualMods= indicators->maps[i].mods.vmods;
2816 wire->ctrls= indicators->maps[i].ctrls;
2817 if (client->swapped) {
2818 register int n;
2819 swaps(&wire->virtualMods,n);
2820 swapl(&wire->ctrls,n);
2822 wire++;
2825 to = (CARD8 *)wire;
2826 if ((to-map)!=length) {
2827 client->errorValue = _XkbErrCode2(0xff,length);
2828 return BadLength;
2831 else return BadAlloc;
2833 else map = NULL;
2834 if (client->swapped) {
2835 swaps(&rep->sequenceNumber,i);
2836 swapl(&rep->length,i);
2837 swapl(&rep->which,i);
2838 swapl(&rep->realIndicators,i);
2840 WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep);
2841 if (map) {
2842 WriteToClient(client, length, (char *)map);
2843 DEALLOCATE_LOCAL((char *)map);
2845 return client->noClientException;
2849 ProcXkbGetIndicatorMap(ClientPtr client)
2851 xkbGetIndicatorMapReply rep;
2852 DeviceIntPtr dev;
2853 XkbDescPtr xkb;
2854 XkbIndicatorPtr leds;
2856 REQUEST(xkbGetIndicatorMapReq);
2857 REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
2859 if (!(client->xkbClientFlags&_XkbClientInitialized))
2860 return BadAccess;
2862 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
2864 xkb= dev->key->xkbInfo->desc;
2865 leds= xkb->indicators;
2867 rep.type = X_Reply;
2868 rep.sequenceNumber = client->sequence;
2869 rep.length = 0;
2870 rep.deviceID = dev->id;
2871 rep.which = stuff->which;
2872 XkbComputeGetIndicatorMapReplySize(leds,&rep);
2873 return XkbSendIndicatorMap(client,leds,&rep);
2876 /* FIXME: Needs to set indicator map on all core-sending devices. */
2878 ProcXkbSetIndicatorMap(ClientPtr client)
2880 register int i,bit;
2881 int nIndicators,why;
2882 DeviceIntPtr dev;
2883 XkbSrvInfoPtr xkbi;
2884 xkbIndicatorMapWireDesc *from;
2885 XkbSrvLedInfoPtr sli;
2886 XkbEventCauseRec cause;
2888 REQUEST(xkbSetIndicatorMapReq);
2889 REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
2891 if (!(client->xkbClientFlags&_XkbClientInitialized))
2892 return BadAccess;
2894 dev = _XkbLookupKeyboard(stuff->deviceSpec,&why);
2895 if (!dev) {
2896 client->errorValue = _XkbErrCode2(why,stuff->deviceSpec);
2897 return XkbKeyboardErrorCode;
2899 xkbi= dev->key->xkbInfo;
2901 if (stuff->which==0)
2902 return client->noClientException;
2904 for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
2905 if (stuff->which&bit)
2906 nIndicators++;
2908 if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+
2909 (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) {
2910 return BadLength;
2913 sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
2914 XkbXI_IndicatorMapsMask);
2915 if (!sli)
2916 return BadAlloc;
2918 from = (xkbIndicatorMapWireDesc *)&stuff[1];
2919 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
2920 if (stuff->which&bit) {
2921 if (client->swapped) {
2922 register int n;
2923 swaps(&from->virtualMods,n);
2924 swapl(&from->ctrls,n);
2926 CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup);
2927 CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods);
2928 from++;
2932 from = (xkbIndicatorMapWireDesc *)&stuff[1];
2933 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
2934 if (stuff->which&bit) {
2935 sli->maps[i].flags = from->flags;
2936 sli->maps[i].which_groups = from->whichGroups;
2937 sli->maps[i].groups = from->groups;
2938 sli->maps[i].which_mods = from->whichMods;
2939 sli->maps[i].mods.mask = from->mods;
2940 sli->maps[i].mods.real_mods = from->mods;
2941 sli->maps[i].mods.vmods= from->virtualMods;
2942 sli->maps[i].ctrls = from->ctrls;
2943 if (from->virtualMods!=0) {
2944 unsigned tmp;
2945 tmp= XkbMaskForVMask(xkbi->desc,from->virtualMods);
2946 sli->maps[i].mods.mask= from->mods|tmp;
2948 from++;
2952 XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client);
2953 XkbApplyLedMapChanges(dev,sli,stuff->which,NULL,NULL,&cause);
2954 return client->noClientException;
2957 /***====================================================================***/
2960 ProcXkbGetNamedIndicator(ClientPtr client)
2962 DeviceIntPtr dev;
2963 xkbGetNamedIndicatorReply rep;
2964 register int i = 0;
2965 XkbSrvLedInfoPtr sli;
2966 XkbIndicatorMapPtr map = NULL;
2968 REQUEST(xkbGetNamedIndicatorReq);
2969 REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
2971 if (!(client->xkbClientFlags&_XkbClientInitialized))
2972 return BadAccess;
2974 CHK_LED_DEVICE(dev,stuff->deviceSpec);
2975 CHK_ATOM_ONLY(stuff->indicator);
2977 sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0);
2978 if (!sli)
2979 return BadAlloc;
2981 i= 0;
2982 map= NULL;
2983 if ((sli->names)&&(sli->maps)) {
2984 for (i=0;i<XkbNumIndicators;i++) {
2985 if (stuff->indicator==sli->names[i]) {
2986 map= &sli->maps[i];
2987 break;
2992 rep.type= X_Reply;
2993 rep.length = 0;
2994 rep.sequenceNumber = client->sequence;
2995 rep.deviceID = dev->id;
2996 rep.indicator= stuff->indicator;
2997 if (map!=NULL) {
2998 rep.found= True;
2999 rep.on= ((sli->effectiveState&(1<<i))!=0);
3000 rep.realIndicator= ((sli->physIndicators&(1<<i))!=0);
3001 rep.ndx= i;
3002 rep.flags= map->flags;
3003 rep.whichGroups= map->which_groups;
3004 rep.groups= map->groups;
3005 rep.whichMods= map->which_mods;
3006 rep.mods= map->mods.mask;
3007 rep.realMods= map->mods.real_mods;
3008 rep.virtualMods= map->mods.vmods;
3009 rep.ctrls= map->ctrls;
3010 rep.supported= True;
3012 else {
3013 rep.found= False;
3014 rep.on= False;
3015 rep.realIndicator= False;
3016 rep.ndx= XkbNoIndicator;
3017 rep.flags= 0;
3018 rep.whichGroups= 0;
3019 rep.groups= 0;
3020 rep.whichMods= 0;
3021 rep.mods= 0;
3022 rep.realMods= 0;
3023 rep.virtualMods= 0;
3024 rep.ctrls= 0;
3025 rep.supported= True;
3027 if ( client->swapped ) {
3028 register int n;
3029 swapl(&rep.length,n);
3030 swaps(&rep.sequenceNumber,n);
3031 swapl(&rep.indicator,n);
3032 swaps(&rep.virtualMods,n);
3033 swapl(&rep.ctrls,n);
3036 WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep);
3037 return client->noClientException;
3040 /* FIXME: Needs to set indicator on all core-sending devices. */
3042 ProcXkbSetNamedIndicator(ClientPtr client)
3044 DeviceIntPtr dev,kbd;
3045 XkbIndicatorMapPtr map;
3046 XkbSrvLedInfoPtr sli;
3047 register int led = 0;
3048 unsigned extDevReason;
3049 unsigned statec,namec,mapc;
3050 XkbEventCauseRec cause;
3051 xkbExtensionDeviceNotify ed;
3052 XkbChangesRec changes;
3054 REQUEST(xkbSetNamedIndicatorReq);
3055 REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
3057 if (!(client->xkbClientFlags&_XkbClientInitialized))
3058 return BadAccess;
3060 CHK_LED_DEVICE(dev,stuff->deviceSpec);
3061 CHK_ATOM_ONLY(stuff->indicator);
3062 CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup);
3063 CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods);
3065 extDevReason= 0;
3067 sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,
3068 XkbXI_IndicatorsMask);
3069 if (!sli)
3070 return BadAlloc;
3072 statec= mapc= namec= 0;
3073 map= NULL;
3074 if (sli->names && sli->maps) {
3075 for (led=0;(led<XkbNumIndicators)&&(map==NULL);led++) {
3076 if (sli->names[led]==stuff->indicator) {
3077 map= &sli->maps[led];
3078 break;
3082 if (map==NULL) {
3083 if (!stuff->createMap)
3084 return client->noClientException;
3085 for (led=0,map=NULL;(led<XkbNumIndicators)&&(map==NULL);led++) {
3086 if ((sli->names)&&(sli->maps)&&(sli->names[led]==None)&&
3087 (!XkbIM_InUse(&sli->maps[led]))) {
3088 map= &sli->maps[led];
3089 sli->names[led]= stuff->indicator;
3090 break;
3093 if (map==NULL)
3094 return client->noClientException;
3095 namec|= (1<<led);
3096 sli->namesPresent|= ((stuff->indicator!=None)?(1<<led):0);
3097 extDevReason|= XkbXI_IndicatorNamesMask;
3100 if (stuff->setMap) {
3101 map->flags = stuff->flags;
3102 map->which_groups = stuff->whichGroups;
3103 map->groups = stuff->groups;
3104 map->which_mods = stuff->whichMods;
3105 map->mods.mask = stuff->realMods;
3106 map->mods.real_mods = stuff->realMods;
3107 map->mods.vmods= stuff->virtualMods;
3108 map->ctrls = stuff->ctrls;
3109 mapc|= (1<<led);
3111 if ((stuff->setState)&&((map->flags&XkbIM_NoExplicit)==0)) {
3112 if (stuff->on) sli->explicitState|= (1<<led);
3113 else sli->explicitState&= ~(1<<led);
3114 statec|= ((sli->effectiveState^sli->explicitState)&(1<<led));
3116 bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
3117 bzero((char *)&changes,sizeof(XkbChangesRec));
3118 XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client);
3119 if (namec)
3120 XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
3121 if (mapc)
3122 XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
3123 if (statec)
3124 XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
3126 kbd= dev;
3127 if ((sli->flags&XkbSLI_HasOwnState)==0)
3128 kbd= (DeviceIntPtr)LookupKeyboardDevice();
3129 XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
3130 return client->noClientException;
3133 /***====================================================================***/
3135 static CARD32
3136 _XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
3138 register unsigned int i,bit,nAtoms;
3139 register CARD32 atomsPresent;
3141 for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
3142 if (atoms[i]!=None) {
3143 atomsPresent|= bit;
3144 nAtoms++;
3147 if (count)
3148 *count= nAtoms;
3149 return atomsPresent;
3152 static char *
3153 _XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap)
3155 register unsigned int i;
3156 Atom *atm;
3158 atm = (Atom *)wire;
3159 for (i=0;i<maxAtoms;i++) {
3160 if (atoms[i]!=None) {
3161 *atm= atoms[i];
3162 if (swap) {
3163 register int n;
3164 swapl(atm,n);
3166 atm++;
3169 return (char *)atm;
3172 static Status
3173 XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep)
3175 register unsigned which,length;
3176 register int i;
3178 rep->minKeyCode= xkb->min_key_code;
3179 rep->maxKeyCode= xkb->max_key_code;
3180 which= rep->which;
3181 length= 0;
3182 if (xkb->names!=NULL) {
3183 if (which&XkbKeycodesNameMask) length++;
3184 if (which&XkbGeometryNameMask) length++;
3185 if (which&XkbSymbolsNameMask) length++;
3186 if (which&XkbPhysSymbolsNameMask) length++;
3187 if (which&XkbTypesNameMask) length++;
3188 if (which&XkbCompatNameMask) length++;
3190 else which&= ~XkbComponentNamesMask;
3192 if (xkb->map!=NULL) {
3193 if (which&XkbKeyTypeNamesMask)
3194 length+= xkb->map->num_types;
3195 rep->nTypes= xkb->map->num_types;
3196 if (which&XkbKTLevelNamesMask) {
3197 XkbKeyTypePtr pType = xkb->map->types;
3198 int nKTLevels = 0;
3200 length+= XkbPaddedSize(xkb->map->num_types)/4;
3201 for (i=0;i<xkb->map->num_types;i++,pType++) {
3202 if (pType->level_names!=NULL)
3203 nKTLevels+= pType->num_levels;
3205 rep->nKTLevels= nKTLevels;
3206 length+= nKTLevels;
3209 else {
3210 rep->nTypes= 0;
3211 rep->nKTLevels= 0;
3212 which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask);
3215 rep->minKeyCode= xkb->min_key_code;
3216 rep->maxKeyCode= xkb->max_key_code;
3217 rep->indicators= 0;
3218 rep->virtualMods= 0;
3219 rep->groupNames= 0;
3220 if (xkb->names!=NULL) {
3221 if (which&XkbIndicatorNamesMask) {
3222 int nLeds;
3223 rep->indicators=
3224 _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds);
3225 length+= nLeds;
3226 if (nLeds==0)
3227 which&= ~XkbIndicatorNamesMask;
3230 if (which&XkbVirtualModNamesMask) {
3231 int nVMods;
3232 rep->virtualMods=
3233 _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods);
3234 length+= nVMods;
3235 if (nVMods==0)
3236 which&= ~XkbVirtualModNamesMask;
3239 if (which&XkbGroupNamesMask) {
3240 int nGroups;
3241 rep->groupNames=
3242 _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups);
3243 length+= nGroups;
3244 if (nGroups==0)
3245 which&= ~XkbGroupNamesMask;
3248 if ((which&XkbKeyNamesMask)&&(xkb->names->keys))
3249 length+= rep->nKeys;
3250 else which&= ~XkbKeyNamesMask;
3252 if ((which&XkbKeyAliasesMask)&&
3253 (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) {
3254 rep->nKeyAliases= xkb->names->num_key_aliases;
3255 length+= rep->nKeyAliases*2;
3257 else {
3258 which&= ~XkbKeyAliasesMask;
3259 rep->nKeyAliases= 0;
3262 if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0))
3263 length+= xkb->names->num_rg;
3264 else which&= ~XkbRGNamesMask;
3266 else {
3267 which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask);
3268 which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask);
3269 which&= ~XkbRGNamesMask;
3272 rep->length= length;
3273 rep->which= which;
3274 return Success;
3277 static int
3278 XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep)
3280 register unsigned i,length,which;
3281 char * start;
3282 char * desc;
3283 register int n;
3285 length= rep->length*4;
3286 which= rep->which;
3287 if (client->swapped) {
3288 swaps(&rep->sequenceNumber,n);
3289 swapl(&rep->length,n);
3290 swapl(&rep->which,n);
3291 swaps(&rep->virtualMods,n);
3292 swapl(&rep->indicators,n);
3295 start = desc = (char *)ALLOCATE_LOCAL(length);
3296 if ( !start )
3297 return BadAlloc;
3298 if (xkb->names) {
3299 if (which&XkbKeycodesNameMask) {
3300 *((CARD32 *)desc)= xkb->names->keycodes;
3301 if (client->swapped) {
3302 swapl(desc,n);
3304 desc+= 4;
3306 if (which&XkbGeometryNameMask) {
3307 *((CARD32 *)desc)= xkb->names->geometry;
3308 if (client->swapped) {
3309 swapl(desc,n);
3311 desc+= 4;
3313 if (which&XkbSymbolsNameMask) {
3314 *((CARD32 *)desc)= xkb->names->symbols;
3315 if (client->swapped) {
3316 swapl(desc,n);
3318 desc+= 4;
3320 if (which&XkbPhysSymbolsNameMask) {
3321 register CARD32 *atm= (CARD32 *)desc;
3322 atm[0]= (CARD32)xkb->names->phys_symbols;
3323 if (client->swapped) {
3324 swapl(&atm[0],n);
3326 desc+= 4;
3328 if (which&XkbTypesNameMask) {
3329 *((CARD32 *)desc)= (CARD32)xkb->names->types;
3330 if (client->swapped) {
3331 swapl(desc,n);
3333 desc+= 4;
3335 if (which&XkbCompatNameMask) {
3336 *((CARD32 *)desc)= (CARD32)xkb->names->compat;
3337 if (client->swapped) {
3338 swapl(desc,n);
3340 desc+= 4;
3342 if (which&XkbKeyTypeNamesMask) {
3343 register CARD32 *atm= (CARD32 *)desc;
3344 register XkbKeyTypePtr type= xkb->map->types;
3346 for (i=0;i<xkb->map->num_types;i++,atm++,type++) {
3347 *atm= (CARD32)type->name;
3348 if (client->swapped) {
3349 swapl(atm,n);
3352 desc= (char *)atm;
3354 if (which&XkbKTLevelNamesMask && xkb->map) {
3355 XkbKeyTypePtr type = xkb->map->types;
3356 register CARD32 *atm;
3357 for (i=0;i<rep->nTypes;i++,type++) {
3358 *desc++ = type->num_levels;
3360 desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes;
3362 atm= (CARD32 *)desc;
3363 type = xkb->map->types;
3364 for (i=0;i<xkb->map->num_types;i++,type++) {
3365 register unsigned l;
3366 if (type->level_names) {
3367 for (l=0;l<type->num_levels;l++,atm++) {
3368 *atm= type->level_names[l];
3369 if (client->swapped) {
3370 swapl(atm,n);
3373 desc+= type->num_levels*4;
3377 if (which&XkbIndicatorNamesMask) {
3378 desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators,
3379 client->swapped);
3381 if (which&XkbVirtualModNamesMask) {
3382 desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods,
3383 client->swapped);
3385 if (which&XkbGroupNamesMask) {
3386 desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups,
3387 client->swapped);
3389 if (which&XkbKeyNamesMask) {
3390 for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) {
3391 *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey];
3394 if (which&XkbKeyAliasesMask) {
3395 XkbKeyAliasPtr pAl;
3396 pAl= xkb->names->key_aliases;
3397 for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) {
3398 *((XkbKeyAliasPtr)desc)= *pAl;
3401 if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) {
3402 register CARD32 *atm= (CARD32 *)desc;
3403 for (i=0;i<rep->nRadioGroups;i++,atm++) {
3404 *atm= (CARD32)xkb->names->radio_groups[i];
3405 if (client->swapped) {
3406 swapl(atm,n);
3409 desc+= rep->nRadioGroups*4;
3413 if ((desc-start)!=(length)) {
3414 ErrorF("BOGUS LENGTH in write names, expected %d, got %ld\n",
3415 length, (unsigned long)(desc-start));
3417 WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep);
3418 WriteToClient(client, length, start);
3419 DEALLOCATE_LOCAL((char *)start);
3420 return client->noClientException;
3424 ProcXkbGetNames(ClientPtr client)
3426 DeviceIntPtr dev;
3427 XkbDescPtr xkb;
3428 xkbGetNamesReply rep;
3430 REQUEST(xkbGetNamesReq);
3431 REQUEST_SIZE_MATCH(xkbGetNamesReq);
3433 if (!(client->xkbClientFlags&_XkbClientInitialized))
3434 return BadAccess;
3436 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
3437 CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
3439 xkb = dev->key->xkbInfo->desc;
3440 rep.type= X_Reply;
3441 rep.sequenceNumber= client->sequence;
3442 rep.length = 0;
3443 rep.deviceID = dev->id;
3444 rep.which = stuff->which;
3445 rep.nTypes = xkb->map->num_types;
3446 rep.firstKey = xkb->min_key_code;
3447 rep.nKeys = XkbNumKeys(xkb);
3448 if (xkb->names!=NULL) {
3449 rep.nKeyAliases= xkb->names->num_key_aliases;
3450 rep.nRadioGroups = xkb->names->num_rg;
3452 else {
3453 rep.nKeyAliases= rep.nRadioGroups= 0;
3455 XkbComputeGetNamesReplySize(xkb,&rep);
3456 return XkbSendNames(client,xkb,&rep);
3459 /***====================================================================***/
3461 static CARD32 *
3462 _XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError)
3464 register int i;
3466 for (i=0;i<nAtoms;i++,wire++) {
3467 if (swapped) {
3468 register int n;
3469 swapl(wire,n);
3471 if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) {
3472 *pError= ((Atom)*wire);
3473 return NULL;
3476 return wire;
3479 static CARD32 *
3480 _XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped,
3481 Atom *pError)
3483 register unsigned i,bit;
3485 for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
3486 if ((present&bit)==0)
3487 continue;
3488 if (swapped) {
3489 register int n;
3490 swapl(wire,n);
3492 if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) {
3493 *pError= (Atom)*wire;
3494 return NULL;
3496 wire++;
3498 return wire;
3501 static Atom *
3502 _XkbCopyMaskedAtoms( Atom *wire,
3503 Atom *dest,
3504 int nAtoms,
3505 CARD32 present)
3507 register int i,bit;
3509 for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
3510 if ((present&bit)==0)
3511 continue;
3512 dest[i]= *wire++;
3514 return wire;
3517 static Bool
3518 _XkbCheckTypeName(Atom name,int typeNdx)
3520 char * str;
3522 str= NameForAtom(name);
3523 if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)||
3524 (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0))
3525 return False;
3526 return True;
3529 /* FIXME: Needs to set names on all core-sending devices. */
3531 ProcXkbSetNames(ClientPtr client)
3533 DeviceIntPtr dev;
3534 XkbDescRec *xkb;
3535 XkbNamesRec *names;
3536 xkbNamesNotify nn;
3537 CARD32 *tmp;
3538 Atom bad;
3540 REQUEST(xkbSetNamesReq);
3541 REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
3543 if (!(client->xkbClientFlags&_XkbClientInitialized))
3544 return BadAccess;
3546 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
3547 CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
3549 xkb = dev->key->xkbInfo->desc;
3550 names = xkb->names;
3551 tmp = (CARD32 *)&stuff[1];
3553 if (stuff->which&XkbKeycodesNameMask) {
3554 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
3555 if (!tmp) {
3556 client->errorValue = bad;
3557 return BadAtom;
3560 if (stuff->which&XkbGeometryNameMask) {
3561 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
3562 if (!tmp) {
3563 client->errorValue = bad;
3564 return BadAtom;
3567 if (stuff->which&XkbSymbolsNameMask) {
3568 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
3569 if (!tmp) {
3570 client->errorValue = bad;
3571 return BadAtom;
3574 if (stuff->which&XkbPhysSymbolsNameMask) {
3575 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
3576 if (!tmp) {
3577 client->errorValue= bad;
3578 return BadAtom;
3581 if (stuff->which&XkbTypesNameMask) {
3582 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
3583 if (!tmp) {
3584 client->errorValue = bad;
3585 return BadAtom;
3588 if (stuff->which&XkbCompatNameMask) {
3589 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
3590 if (!tmp) {
3591 client->errorValue = bad;
3592 return BadAtom;
3595 if (stuff->which&XkbKeyTypeNamesMask) {
3596 register int i;
3597 CARD32 *old;
3598 if ( stuff->nTypes<1 ) {
3599 client->errorValue = _XkbErrCode2(0x02,stuff->nTypes);
3600 return BadValue;
3602 if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) {
3603 client->errorValue = _XkbErrCode4(0x03,stuff->firstType,
3604 stuff->nTypes,
3605 xkb->map->num_types);
3606 return BadValue;
3608 if (((unsigned)stuff->firstType)<=XkbLastRequiredType) {
3609 client->errorValue = _XkbErrCode2(0x04,stuff->firstType);
3610 return BadAccess;
3612 old= tmp;
3613 tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad);
3614 if (!tmp) {
3615 client->errorValue= bad;
3616 return BadAtom;
3618 for (i=0;i<stuff->nTypes;i++,old++) {
3619 if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i))
3620 client->errorValue= _XkbErrCode2(0x05,i);
3623 if (stuff->which&XkbKTLevelNamesMask) {
3624 register unsigned i;
3625 XkbKeyTypePtr type;
3626 CARD8 * width;
3627 if ( stuff->nKTLevels<1 ) {
3628 client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels);
3629 return BadValue;
3631 if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>=
3632 xkb->map->num_types) {
3633 client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel,
3634 stuff->nKTLevels,xkb->map->num_types);
3635 return BadValue;
3637 width = (CARD8 *)tmp;
3638 tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
3639 type = &xkb->map->types[stuff->firstKTLevel];
3640 for (i=0;i<stuff->nKTLevels;i++,type++) {
3641 if (width[i]==0)
3642 continue;
3643 else if (width[i]!=type->num_levels) {
3644 client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel,
3645 type->num_levels,width[i]);
3646 return BadMatch;
3648 tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad);
3649 if (!tmp) {
3650 client->errorValue= bad;
3651 return BadAtom;
3655 if (stuff->which&XkbIndicatorNamesMask) {
3656 if (stuff->indicators==0) {
3657 client->errorValue= 0x08;
3658 return BadMatch;
3660 tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators,
3661 client->swapped,&bad);
3662 if (!tmp) {
3663 client->errorValue= bad;
3664 return BadAtom;
3667 if (stuff->which&XkbVirtualModNamesMask) {
3668 if (stuff->virtualMods==0) {
3669 client->errorValue= 0x09;
3670 return BadMatch;
3672 tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods,
3673 (CARD32)stuff->virtualMods,
3674 client->swapped,&bad);
3675 if (!tmp) {
3676 client->errorValue = bad;
3677 return BadAtom;
3680 if (stuff->which&XkbGroupNamesMask) {
3681 if (stuff->groupNames==0) {
3682 client->errorValue= 0x0a;
3683 return BadMatch;
3685 tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups,
3686 (CARD32)stuff->groupNames,
3687 client->swapped,&bad);
3688 if (!tmp) {
3689 client->errorValue = bad;
3690 return BadAtom;
3693 if (stuff->which&XkbKeyNamesMask) {
3694 if (stuff->firstKey<(unsigned)xkb->min_key_code) {
3695 client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code,
3696 stuff->firstKey);
3697 return BadValue;
3699 if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)||
3700 (stuff->nKeys<1)) {
3701 client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code,
3702 stuff->firstKey,stuff->nKeys);
3703 return BadValue;
3705 tmp+= stuff->nKeys;
3707 if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) {
3708 tmp+= stuff->nKeyAliases*2;
3710 if (stuff->which&XkbRGNamesMask) {
3711 if ( stuff->nRadioGroups<1 ) {
3712 client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups);
3713 return BadValue;
3715 tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad);
3716 if (!tmp) {
3717 client->errorValue= bad;
3718 return BadAtom;
3721 if ((tmp-((CARD32 *)stuff))!=stuff->length) {
3722 client->errorValue = stuff->length;
3723 return BadLength;
3725 if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups,
3726 stuff->nKeyAliases)!=Success) {
3727 return BadAlloc;
3730 /* everything is okay -- update names */
3731 bzero(&nn,sizeof(xkbNamesNotify));
3732 nn.changed= stuff->which;
3733 tmp = (CARD32 *)&stuff[1];
3734 if (stuff->which&XkbKeycodesNameMask)
3735 names->keycodes= *tmp++;
3736 if (stuff->which&XkbGeometryNameMask)
3737 names->geometry= *tmp++;
3738 if (stuff->which&XkbSymbolsNameMask)
3739 names->symbols= *tmp++;
3740 if (stuff->which&XkbPhysSymbolsNameMask)
3741 names->phys_symbols= *tmp++;
3742 if (stuff->which&XkbTypesNameMask)
3743 names->types= *tmp++;
3744 if (stuff->which&XkbCompatNameMask)
3745 names->compat= *tmp++;
3746 if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) {
3747 register unsigned i;
3748 register XkbKeyTypePtr type;
3750 type= &xkb->map->types[stuff->firstType];
3751 for (i=0;i<stuff->nTypes;i++,type++) {
3752 type->name= *tmp++;
3754 nn.firstType= stuff->firstType;
3755 nn.nTypes= stuff->nTypes;
3757 if (stuff->which&XkbKTLevelNamesMask) {
3758 register XkbKeyTypePtr type;
3759 register unsigned i;
3760 CARD8 *width;
3762 width = (CARD8 *)tmp;
3763 tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
3764 type= &xkb->map->types[stuff->firstKTLevel];
3765 for (i=0;i<stuff->nKTLevels;i++,type++) {
3766 if (width[i]>0) {
3767 if (type->level_names) {
3768 register unsigned n;
3769 for (n=0;n<width[i];n++) {
3770 type->level_names[n]= tmp[n];
3773 tmp+= width[i];
3776 nn.firstLevelName= 0;
3777 nn.nLevelNames= stuff->nTypes;
3779 if (stuff->which&XkbIndicatorNamesMask) {
3780 tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators,
3781 stuff->indicators);
3782 nn.changedIndicators= stuff->indicators;
3784 if (stuff->which&XkbVirtualModNamesMask) {
3785 tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods,
3786 stuff->virtualMods);
3787 nn.changedVirtualMods= stuff->virtualMods;
3789 if (stuff->which&XkbGroupNamesMask) {
3790 tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups,
3791 stuff->groupNames);
3792 nn.changedVirtualMods= stuff->groupNames;
3794 if (stuff->which&XkbKeyNamesMask) {
3795 memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp,
3796 stuff->nKeys*XkbKeyNameLength);
3797 tmp+= stuff->nKeys;
3798 nn.firstKey= stuff->firstKey;
3799 nn.nKeys= stuff->nKeys;
3801 if (stuff->which&XkbKeyAliasesMask) {
3802 if (stuff->nKeyAliases>0) {
3803 register int na= stuff->nKeyAliases;
3804 if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success)
3805 return BadAlloc;
3806 memcpy((char *)names->key_aliases,(char *)tmp,
3807 stuff->nKeyAliases*sizeof(XkbKeyAliasRec));
3808 tmp+= stuff->nKeyAliases*2;
3810 else if (names->key_aliases!=NULL) {
3811 _XkbFree(names->key_aliases);
3812 names->key_aliases= NULL;
3813 names->num_key_aliases= 0;
3815 nn.nAliases= names->num_key_aliases;
3817 if (stuff->which&XkbRGNamesMask) {
3818 if (stuff->nRadioGroups>0) {
3819 register unsigned i,nrg;
3820 nrg= stuff->nRadioGroups;
3821 if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success)
3822 return BadAlloc;
3824 for (i=0;i<stuff->nRadioGroups;i++) {
3825 names->radio_groups[i]= tmp[i];
3827 tmp+= stuff->nRadioGroups;
3829 else if (names->radio_groups) {
3830 _XkbFree(names->radio_groups);
3831 names->radio_groups= NULL;
3832 names->num_rg= 0;
3834 nn.nRadioGroups= names->num_rg;
3836 if (nn.changed) {
3837 Bool needExtEvent;
3838 needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0;
3839 XkbSendNamesNotify(dev,&nn);
3840 if (needExtEvent) {
3841 XkbSrvLedInfoPtr sli;
3842 xkbExtensionDeviceNotify edev;
3843 register int i;
3844 register unsigned bit;
3846 sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
3847 XkbXI_IndicatorsMask);
3848 sli->namesPresent= 0;
3849 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
3850 if (names->indicators[i]!=None)
3851 sli->namesPresent|= bit;
3853 bzero(&edev,sizeof(xkbExtensionDeviceNotify));
3854 edev.reason= XkbXI_IndicatorNamesMask;
3855 edev.ledClass= KbdFeedbackClass;
3856 edev.ledID= dev->kbdfeed->ctrl.id;
3857 edev.ledsDefined= sli->namesPresent|sli->mapsPresent;
3858 edev.ledState= sli->effectiveState;
3859 edev.firstBtn= 0;
3860 edev.nBtns= 0;
3861 edev.supported= XkbXI_AllFeaturesMask;
3862 edev.unsupported= 0;
3863 XkbSendExtensionDeviceNotify(dev,client,&edev);
3866 return client->noClientException;
3869 /***====================================================================***/
3871 #include <X11/extensions/XKBgeom.h>
3873 #define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4)
3875 static char *
3876 XkbWriteCountedString(char *wire,char *str,Bool swap)
3878 CARD16 len,*pLen;
3880 len= (str?strlen(str):0);
3881 pLen= (CARD16 *)wire;
3882 *pLen= len;
3883 if (swap) {
3884 register int n;
3885 swaps(pLen,n);
3887 memcpy(&wire[2],str,len);
3888 wire+= ((2+len+3)/4)*4;
3889 return wire;
3892 static int
3893 XkbSizeGeomProperties(XkbGeometryPtr geom)
3895 register int i,size;
3896 XkbPropertyPtr prop;
3898 for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
3899 size+= XkbSizeCountedString(prop->name);
3900 size+= XkbSizeCountedString(prop->value);
3902 return size;
3905 static char *
3906 XkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap)
3908 register int i;
3909 register XkbPropertyPtr prop;
3911 for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
3912 wire= XkbWriteCountedString(wire,prop->name,swap);
3913 wire= XkbWriteCountedString(wire,prop->value,swap);
3915 return wire;
3918 static int
3919 XkbSizeGeomKeyAliases(XkbGeometryPtr geom)
3921 return geom->num_key_aliases*(2*XkbKeyNameLength);
3924 static char *
3925 XkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap)
3927 register int sz;
3929 sz= geom->num_key_aliases*(XkbKeyNameLength*2);
3930 if (sz>0) {
3931 memcpy(wire,(char *)geom->key_aliases,sz);
3932 wire+= sz;
3934 return wire;
3937 static int
3938 XkbSizeGeomColors(XkbGeometryPtr geom)
3940 register int i,size;
3941 register XkbColorPtr color;
3943 for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) {
3944 size+= XkbSizeCountedString(color->spec);
3946 return size;
3949 static char *
3950 XkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap)
3952 register int i;
3953 register XkbColorPtr color;
3955 for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
3956 wire= XkbWriteCountedString(wire,color->spec,swap);
3958 return wire;
3961 static int
3962 XkbSizeGeomShapes(XkbGeometryPtr geom)
3964 register int i,size;
3965 register XkbShapePtr shape;
3967 for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
3968 register int n;
3969 register XkbOutlinePtr ol;
3970 size+= SIZEOF(xkbShapeWireDesc);
3971 for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
3972 size+= SIZEOF(xkbOutlineWireDesc);
3973 size+= ol->num_points*SIZEOF(xkbPointWireDesc);
3976 return size;
3979 static char *
3980 XkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap)
3982 int i;
3983 XkbShapePtr shape;
3984 xkbShapeWireDesc * shapeWire;
3986 for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
3987 register int o;
3988 XkbOutlinePtr ol;
3989 xkbOutlineWireDesc * olWire;
3990 shapeWire= (xkbShapeWireDesc *)wire;
3991 shapeWire->name= shape->name;
3992 shapeWire->nOutlines= shape->num_outlines;
3993 if (shape->primary!=NULL)
3994 shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary);
3995 else shapeWire->primaryNdx= XkbNoShape;
3996 if (shape->approx!=NULL)
3997 shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx);
3998 else shapeWire->approxNdx= XkbNoShape;
3999 if (swap) {
4000 register int n;
4001 swapl(&shapeWire->name,n);
4003 wire= (char *)&shapeWire[1];
4004 for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
4005 register int p;
4006 XkbPointPtr pt;
4007 xkbPointWireDesc * ptWire;
4008 olWire= (xkbOutlineWireDesc *)wire;
4009 olWire->nPoints= ol->num_points;
4010 olWire->cornerRadius= ol->corner_radius;
4011 wire= (char *)&olWire[1];
4012 ptWire= (xkbPointWireDesc *)wire;
4013 for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
4014 ptWire[p].x= pt->x;
4015 ptWire[p].y= pt->y;
4016 if (swap) {
4017 register int n;
4018 swaps(&ptWire[p].x,n);
4019 swaps(&ptWire[p].y,n);
4022 wire= (char *)&ptWire[ol->num_points];
4025 return wire;
4028 static int
4029 XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
4031 register int i,size;
4033 for (i=size=0;i<num_doodads;i++,doodad++) {
4034 size+= SIZEOF(xkbAnyDoodadWireDesc);
4035 if (doodad->any.type==XkbTextDoodad) {
4036 size+= XkbSizeCountedString(doodad->text.text);
4037 size+= XkbSizeCountedString(doodad->text.font);
4039 else if (doodad->any.type==XkbLogoDoodad) {
4040 size+= XkbSizeCountedString(doodad->logo.logo_name);
4043 return size;
4046 static char *
4047 XkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap)
4049 register int i;
4050 xkbDoodadWireDesc * doodadWire;
4052 for (i=0;i<num_doodads;i++,doodad++) {
4053 doodadWire= (xkbDoodadWireDesc *)wire;
4054 wire= (char *)&doodadWire[1];
4055 bzero(doodadWire,SIZEOF(xkbDoodadWireDesc));
4056 doodadWire->any.name= doodad->any.name;
4057 doodadWire->any.type= doodad->any.type;
4058 doodadWire->any.priority= doodad->any.priority;
4059 doodadWire->any.top= doodad->any.top;
4060 doodadWire->any.left= doodad->any.left;
4061 if (swap) {
4062 register int n;
4063 swapl(&doodadWire->any.name,n);
4064 swaps(&doodadWire->any.top,n);
4065 swaps(&doodadWire->any.left,n);
4067 switch (doodad->any.type) {
4068 case XkbOutlineDoodad:
4069 case XkbSolidDoodad:
4070 doodadWire->shape.angle= doodad->shape.angle;
4071 doodadWire->shape.colorNdx= doodad->shape.color_ndx;
4072 doodadWire->shape.shapeNdx= doodad->shape.shape_ndx;
4073 if (swap) {
4074 register int n;
4075 swaps(&doodadWire->shape.angle,n);
4077 break;
4078 case XkbTextDoodad:
4079 doodadWire->text.angle= doodad->text.angle;
4080 doodadWire->text.width= doodad->text.width;
4081 doodadWire->text.height= doodad->text.height;
4082 doodadWire->text.colorNdx= doodad->text.color_ndx;
4083 if (swap) {
4084 register int n;
4085 swaps(&doodadWire->text.angle,n);
4086 swaps(&doodadWire->text.width,n);
4087 swaps(&doodadWire->text.height,n);
4089 wire= XkbWriteCountedString(wire,doodad->text.text,swap);
4090 wire= XkbWriteCountedString(wire,doodad->text.font,swap);
4091 break;
4092 case XkbIndicatorDoodad:
4093 doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx;
4094 doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx;
4095 doodadWire->indicator.offColorNdx=
4096 doodad->indicator.off_color_ndx;
4097 break;
4098 case XkbLogoDoodad:
4099 doodadWire->logo.angle= doodad->logo.angle;
4100 doodadWire->logo.colorNdx= doodad->logo.color_ndx;
4101 doodadWire->logo.shapeNdx= doodad->logo.shape_ndx;
4102 wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap);
4103 break;
4104 default:
4105 ErrorF("Unknown doodad type %d in XkbWriteGeomDoodads\n",
4106 doodad->any.type);
4107 ErrorF("Ignored\n");
4108 break;
4111 return wire;
4114 static char *
4115 XkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap)
4117 register int r;
4118 XkbOverlayRowPtr row;
4119 xkbOverlayWireDesc * olWire;
4121 olWire= (xkbOverlayWireDesc *)wire;
4122 olWire->name= ol->name;
4123 olWire->nRows= ol->num_rows;
4124 if (swap) {
4125 register int n;
4126 swapl(&olWire->name,n);
4128 wire= (char *)&olWire[1];
4129 for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
4130 unsigned int k;
4131 XkbOverlayKeyPtr key;
4132 xkbOverlayRowWireDesc * rowWire;
4133 rowWire= (xkbOverlayRowWireDesc *)wire;
4134 rowWire->rowUnder= row->row_under;
4135 rowWire->nKeys= row->num_keys;
4136 wire= (char *)&rowWire[1];
4137 for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
4138 xkbOverlayKeyWireDesc * keyWire;
4139 keyWire= (xkbOverlayKeyWireDesc *)wire;
4140 memcpy(keyWire->over,key->over.name,XkbKeyNameLength);
4141 memcpy(keyWire->under,key->under.name,XkbKeyNameLength);
4142 wire= (char *)&keyWire[1];
4145 return wire;
4148 static int
4149 XkbSizeGeomSections(XkbGeometryPtr geom)
4151 register int i,size;
4152 XkbSectionPtr section;
4154 for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) {
4155 size+= SIZEOF(xkbSectionWireDesc);
4156 if (section->rows) {
4157 int r;
4158 XkbRowPtr row;
4159 for (r=0,row=section->rows;r<section->num_rows;row++,r++) {
4160 size+= SIZEOF(xkbRowWireDesc);
4161 size+= row->num_keys*SIZEOF(xkbKeyWireDesc);
4164 if (section->doodads)
4165 size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads);
4166 if (section->overlays) {
4167 int o;
4168 XkbOverlayPtr ol;
4169 for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
4170 int r;
4171 XkbOverlayRowPtr row;
4172 size+= SIZEOF(xkbOverlayWireDesc);
4173 for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
4174 size+= SIZEOF(xkbOverlayRowWireDesc);
4175 size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc);
4180 return size;
4183 static char *
4184 XkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap)
4186 register int i;
4187 XkbSectionPtr section;
4188 xkbSectionWireDesc * sectionWire;
4190 for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
4191 sectionWire= (xkbSectionWireDesc *)wire;
4192 sectionWire->name= section->name;
4193 sectionWire->top= section->top;
4194 sectionWire->left= section->left;
4195 sectionWire->width= section->width;
4196 sectionWire->height= section->height;
4197 sectionWire->angle= section->angle;
4198 sectionWire->priority= section->priority;
4199 sectionWire->nRows= section->num_rows;
4200 sectionWire->nDoodads= section->num_doodads;
4201 sectionWire->nOverlays= section->num_overlays;
4202 sectionWire->pad= 0;
4203 if (swap) {
4204 register int n;
4205 swapl(&sectionWire->name,n);
4206 swaps(&sectionWire->top,n);
4207 swaps(&sectionWire->left,n);
4208 swaps(&sectionWire->width,n);
4209 swaps(&sectionWire->height,n);
4210 swaps(&sectionWire->angle,n);
4212 wire= (char *)&sectionWire[1];
4213 if (section->rows) {
4214 int r;
4215 XkbRowPtr row;
4216 xkbRowWireDesc * rowWire;
4217 for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
4218 rowWire= (xkbRowWireDesc *)wire;
4219 rowWire->top= row->top;
4220 rowWire->left= row->left;
4221 rowWire->nKeys= row->num_keys;
4222 rowWire->vertical= row->vertical;
4223 rowWire->pad= 0;
4224 if (swap) {
4225 register int n;
4226 swaps(&rowWire->top,n);
4227 swaps(&rowWire->left,n);
4229 wire= (char *)&rowWire[1];
4230 if (row->keys) {
4231 int k;
4232 XkbKeyPtr key;
4233 xkbKeyWireDesc * keyWire;
4234 keyWire= (xkbKeyWireDesc *)wire;
4235 for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
4236 memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength);
4237 keyWire[k].gap= key->gap;
4238 keyWire[k].shapeNdx= key->shape_ndx;
4239 keyWire[k].colorNdx= key->color_ndx;
4240 if (swap) {
4241 register int n;
4242 swaps(&keyWire[k].gap,n);
4245 wire= (char *)&keyWire[row->num_keys];
4249 if (section->doodads) {
4250 wire= XkbWriteGeomDoodads(wire,
4251 section->num_doodads,section->doodads,
4252 swap);
4254 if (section->overlays) {
4255 register int o;
4256 for (o=0;o<section->num_overlays;o++) {
4257 wire= XkbWriteGeomOverlay(wire,&section->overlays[o],swap);
4261 return wire;
4264 static Status
4265 XkbComputeGetGeometryReplySize( XkbGeometryPtr geom,
4266 xkbGetGeometryReply * rep,
4267 Atom name)
4269 int len;
4271 if (geom!=NULL) {
4272 len= XkbSizeCountedString(geom->label_font);
4273 len+= XkbSizeGeomProperties(geom);
4274 len+= XkbSizeGeomColors(geom);
4275 len+= XkbSizeGeomShapes(geom);
4276 len+= XkbSizeGeomSections(geom);
4277 len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads);
4278 len+= XkbSizeGeomKeyAliases(geom);
4279 rep->length= len/4;
4280 rep->found= True;
4281 rep->name= geom->name;
4282 rep->widthMM= geom->width_mm;
4283 rep->heightMM= geom->height_mm;
4284 rep->nProperties= geom->num_properties;
4285 rep->nColors= geom->num_colors;
4286 rep->nShapes= geom->num_shapes;
4287 rep->nSections= geom->num_sections;
4288 rep->nDoodads= geom->num_doodads;
4289 rep->nKeyAliases= geom->num_key_aliases;
4290 rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color);
4291 rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color);
4293 else {
4294 rep->length= 0;
4295 rep->found= False;
4296 rep->name= name;
4297 rep->widthMM= rep->heightMM= 0;
4298 rep->nProperties= rep->nColors= rep->nShapes= 0;
4299 rep->nSections= rep->nDoodads= 0;
4300 rep->nKeyAliases= 0;
4301 rep->labelColorNdx= rep->baseColorNdx= 0;
4303 return Success;
4306 static int
4307 XkbSendGeometry( ClientPtr client,
4308 XkbGeometryPtr geom,
4309 xkbGetGeometryReply * rep,
4310 Bool freeGeom)
4312 char *desc,*start;
4313 int len;
4315 if (geom!=NULL) {
4316 len= rep->length*4;
4317 start= desc= (char *)ALLOCATE_LOCAL(len);
4318 if (!start)
4319 return BadAlloc;
4320 desc= XkbWriteCountedString(desc,geom->label_font,client->swapped);
4321 if ( rep->nProperties>0 )
4322 desc = XkbWriteGeomProperties(desc,geom,client->swapped);
4323 if ( rep->nColors>0 )
4324 desc = XkbWriteGeomColors(desc,geom,client->swapped);
4325 if ( rep->nShapes>0 )
4326 desc = XkbWriteGeomShapes(desc,geom,client->swapped);
4327 if ( rep->nSections>0 )
4328 desc = XkbWriteGeomSections(desc,geom,client->swapped);
4329 if ( rep->nDoodads>0 )
4330 desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads,
4331 client->swapped);
4332 if ( rep->nKeyAliases>0 )
4333 desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped);
4334 if ((desc-start)!=(len)) {
4335 ErrorF("BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n",
4336 len, (unsigned long)(desc-start));
4339 else {
4340 len= 0;
4341 start= NULL;
4343 if (client->swapped) {
4344 register int n;
4345 swaps(&rep->sequenceNumber,n);
4346 swapl(&rep->length,n);
4347 swapl(&rep->name,n);
4348 swaps(&rep->widthMM,n);
4349 swaps(&rep->heightMM,n);
4350 swaps(&rep->nProperties,n);
4351 swaps(&rep->nColors,n);
4352 swaps(&rep->nShapes,n);
4353 swaps(&rep->nSections,n);
4354 swaps(&rep->nDoodads,n);
4355 swaps(&rep->nKeyAliases,n);
4357 WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep);
4358 if (len>0)
4359 WriteToClient(client, len, start);
4360 if (start!=NULL)
4361 DEALLOCATE_LOCAL((char *)start);
4362 if (freeGeom)
4363 XkbFreeGeometry(geom,XkbGeomAllMask,True);
4364 return client->noClientException;
4368 ProcXkbGetGeometry(ClientPtr client)
4370 DeviceIntPtr dev;
4371 xkbGetGeometryReply rep;
4372 XkbGeometryPtr geom;
4373 Bool shouldFree;
4374 Status status;
4376 REQUEST(xkbGetGeometryReq);
4377 REQUEST_SIZE_MATCH(xkbGetGeometryReq);
4379 if (!(client->xkbClientFlags&_XkbClientInitialized))
4380 return BadAccess;
4382 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
4383 CHK_ATOM_OR_NONE(stuff->name);
4385 geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree);
4386 rep.type= X_Reply;
4387 rep.deviceID= dev->id;
4388 rep.sequenceNumber= client->sequence;
4389 rep.length= 0;
4390 status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name);
4391 if (status!=Success)
4392 return status;
4393 else return XkbSendGeometry(client,geom,&rep,shouldFree);
4396 /***====================================================================***/
4398 static char *
4399 _GetCountedString(char **wire_inout,Bool swap)
4401 char * wire,*str;
4402 CARD16 len,*plen;
4404 wire= *wire_inout;
4405 plen= (CARD16 *)wire;
4406 if (swap) {
4407 register int n;
4408 swaps(plen,n);
4410 len= *plen;
4411 str= (char *)_XkbAlloc(len+1);
4412 if (str) {
4413 memcpy(str,&wire[2],len);
4414 str[len]= '\0';
4416 wire+= XkbPaddedSize(len+2);
4417 *wire_inout= wire;
4418 return str;
4421 static Status
4422 _CheckSetDoodad( char ** wire_inout,
4423 XkbGeometryPtr geom,
4424 XkbSectionPtr section,
4425 ClientPtr client)
4427 char * wire;
4428 xkbDoodadWireDesc * dWire;
4429 XkbDoodadPtr doodad;
4431 dWire= (xkbDoodadWireDesc *)(*wire_inout);
4432 wire= (char *)&dWire[1];
4433 if (client->swapped) {
4434 register int n;
4435 swapl(&dWire->any.name,n);
4436 swaps(&dWire->any.top,n);
4437 swaps(&dWire->any.left,n);
4438 swaps(&dWire->any.angle,n);
4440 CHK_ATOM_ONLY(dWire->any.name);
4441 doodad= XkbAddGeomDoodad(geom,section,dWire->any.name);
4442 if (!doodad)
4443 return BadAlloc;
4444 doodad->any.type= dWire->any.type;
4445 doodad->any.priority= dWire->any.priority;
4446 doodad->any.top= dWire->any.top;
4447 doodad->any.left= dWire->any.left;
4448 doodad->any.angle= dWire->any.angle;
4449 switch (doodad->any.type) {
4450 case XkbOutlineDoodad:
4451 case XkbSolidDoodad:
4452 if (dWire->shape.colorNdx>=geom->num_colors) {
4453 client->errorValue= _XkbErrCode3(0x40,geom->num_colors,
4454 dWire->shape.colorNdx);
4455 return BadMatch;
4457 if (dWire->shape.shapeNdx>=geom->num_shapes) {
4458 client->errorValue= _XkbErrCode3(0x41,geom->num_shapes,
4459 dWire->shape.shapeNdx);
4460 return BadMatch;
4462 doodad->shape.color_ndx= dWire->shape.colorNdx;
4463 doodad->shape.shape_ndx= dWire->shape.shapeNdx;
4464 break;
4465 case XkbTextDoodad:
4466 if (dWire->text.colorNdx>=geom->num_colors) {
4467 client->errorValue= _XkbErrCode3(0x42,geom->num_colors,
4468 dWire->text.colorNdx);
4469 return BadMatch;
4471 if (client->swapped) {
4472 register int n;
4473 swaps(&dWire->text.width,n);
4474 swaps(&dWire->text.height,n);
4476 doodad->text.width= dWire->text.width;
4477 doodad->text.height= dWire->text.height;
4478 doodad->text.color_ndx= dWire->text.colorNdx;
4479 doodad->text.text= _GetCountedString(&wire,client->swapped);
4480 doodad->text.font= _GetCountedString(&wire,client->swapped);
4481 break;
4482 case XkbIndicatorDoodad:
4483 if (dWire->indicator.onColorNdx>=geom->num_colors) {
4484 client->errorValue= _XkbErrCode3(0x43,geom->num_colors,
4485 dWire->indicator.onColorNdx);
4486 return BadMatch;
4488 if (dWire->indicator.offColorNdx>=geom->num_colors) {
4489 client->errorValue= _XkbErrCode3(0x44,geom->num_colors,
4490 dWire->indicator.offColorNdx);
4491 return BadMatch;
4493 if (dWire->indicator.shapeNdx>=geom->num_shapes) {
4494 client->errorValue= _XkbErrCode3(0x45,geom->num_shapes,
4495 dWire->indicator.shapeNdx);
4496 return BadMatch;
4498 doodad->indicator.shape_ndx= dWire->indicator.shapeNdx;
4499 doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx;
4500 doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx;
4501 break;
4502 case XkbLogoDoodad:
4503 if (dWire->logo.colorNdx>=geom->num_colors) {
4504 client->errorValue= _XkbErrCode3(0x46,geom->num_colors,
4505 dWire->logo.colorNdx);
4506 return BadMatch;
4508 if (dWire->logo.shapeNdx>=geom->num_shapes) {
4509 client->errorValue= _XkbErrCode3(0x47,geom->num_shapes,
4510 dWire->logo.shapeNdx);
4511 return BadMatch;
4513 doodad->logo.color_ndx= dWire->logo.colorNdx;
4514 doodad->logo.shape_ndx= dWire->logo.shapeNdx;
4515 doodad->logo.logo_name= _GetCountedString(&wire,client->swapped);
4516 break;
4517 default:
4518 client->errorValue= _XkbErrCode2(0x4F,dWire->any.type);
4519 return BadValue;
4521 *wire_inout= wire;
4522 return Success;
4525 static Status
4526 _CheckSetOverlay( char ** wire_inout,
4527 XkbGeometryPtr geom,
4528 XkbSectionPtr section,
4529 ClientPtr client)
4531 register int r;
4532 char * wire;
4533 XkbOverlayPtr ol;
4534 xkbOverlayWireDesc * olWire;
4535 xkbOverlayRowWireDesc * rWire;
4537 wire= *wire_inout;
4538 olWire= (xkbOverlayWireDesc *)wire;
4539 if (client->swapped) {
4540 register int n;
4541 swapl(&olWire->name,n);
4543 CHK_ATOM_ONLY(olWire->name);
4544 ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows);
4545 rWire= (xkbOverlayRowWireDesc *)&olWire[1];
4546 for (r=0;r<olWire->nRows;r++) {
4547 register int k;
4548 xkbOverlayKeyWireDesc * kWire;
4549 XkbOverlayRowPtr row;
4551 if (rWire->rowUnder>section->num_rows) {
4552 client->errorValue= _XkbErrCode4(0x20,r,section->num_rows,
4553 rWire->rowUnder);
4554 return BadMatch;
4556 row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys);
4557 kWire= (xkbOverlayKeyWireDesc *)&rWire[1];
4558 for (k=0;k<rWire->nKeys;k++,kWire++) {
4559 if (XkbAddGeomOverlayKey(ol,row,
4560 (char *)kWire->over,(char *)kWire->under)==NULL) {
4561 client->errorValue= _XkbErrCode3(0x21,r,k);
4562 return BadMatch;
4565 rWire= (xkbOverlayRowWireDesc *)kWire;
4567 olWire= (xkbOverlayWireDesc *)rWire;
4568 wire= (char *)olWire;
4569 *wire_inout= wire;
4570 return Success;
4573 static Status
4574 _CheckSetSections( XkbGeometryPtr geom,
4575 xkbSetGeometryReq * req,
4576 char ** wire_inout,
4577 ClientPtr client)
4579 Status status;
4580 register int s;
4581 char * wire;
4582 xkbSectionWireDesc * sWire;
4583 XkbSectionPtr section;
4585 wire= *wire_inout;
4586 if (req->nSections<1)
4587 return Success;
4588 sWire= (xkbSectionWireDesc *)wire;
4589 for (s=0;s<req->nSections;s++) {
4590 register int r;
4591 xkbRowWireDesc * rWire;
4592 if (client->swapped) {
4593 register int n;
4594 swapl(&sWire->name,n);
4595 swaps(&sWire->top,n);
4596 swaps(&sWire->left,n);
4597 swaps(&sWire->width,n);
4598 swaps(&sWire->height,n);
4599 swaps(&sWire->angle,n);
4601 CHK_ATOM_ONLY(sWire->name);
4602 section= XkbAddGeomSection(geom,sWire->name,sWire->nRows,
4603 sWire->nDoodads,sWire->nOverlays);
4604 if (!section)
4605 return BadAlloc;
4606 section->priority= sWire->priority;
4607 section->top= sWire->top;
4608 section->left= sWire->left;
4609 section->width= sWire->width;
4610 section->height= sWire->height;
4611 section->angle= sWire->angle;
4612 rWire= (xkbRowWireDesc *)&sWire[1];
4613 for (r=0;r<sWire->nRows;r++) {
4614 register int k;
4615 XkbRowPtr row;
4616 xkbKeyWireDesc * kWire;
4617 if (client->swapped) {
4618 register int n;
4619 swaps(&rWire->top,n);
4620 swaps(&rWire->left,n);
4622 row= XkbAddGeomRow(section,rWire->nKeys);
4623 if (!row)
4624 return BadAlloc;
4625 row->top= rWire->top;
4626 row->left= rWire->left;
4627 row->vertical= rWire->vertical;
4628 kWire= (xkbKeyWireDesc *)&rWire[1];
4629 for (k=0;k<rWire->nKeys;k++) {
4630 XkbKeyPtr key;
4631 key= XkbAddGeomKey(row);
4632 if (!key)
4633 return BadAlloc;
4634 memcpy(key->name.name,kWire[k].name,XkbKeyNameLength);
4635 key->gap= kWire[k].gap;
4636 key->shape_ndx= kWire[k].shapeNdx;
4637 key->color_ndx= kWire[k].colorNdx;
4638 if (key->shape_ndx>=geom->num_shapes) {
4639 client->errorValue= _XkbErrCode3(0x10,key->shape_ndx,
4640 geom->num_shapes);
4641 return BadMatch;
4643 if (key->color_ndx>=geom->num_colors) {
4644 client->errorValue= _XkbErrCode3(0x11,key->color_ndx,
4645 geom->num_colors);
4646 return BadMatch;
4649 rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys];
4651 wire= (char *)rWire;
4652 if (sWire->nDoodads>0) {
4653 register int d;
4654 for (d=0;d<sWire->nDoodads;d++) {
4655 status=_CheckSetDoodad(&wire,geom,section,client);
4656 if (status!=Success)
4657 return status;
4660 if (sWire->nOverlays>0) {
4661 register int o;
4662 for (o=0;o<sWire->nOverlays;o++) {
4663 status= _CheckSetOverlay(&wire,geom,section,client);
4664 if (status!=Success)
4665 return status;
4668 sWire= (xkbSectionWireDesc *)wire;
4670 wire= (char *)sWire;
4671 *wire_inout= wire;
4672 return Success;
4675 static Status
4676 _CheckSetShapes( XkbGeometryPtr geom,
4677 xkbSetGeometryReq * req,
4678 char ** wire_inout,
4679 ClientPtr client)
4681 register int i;
4682 char * wire;
4684 wire= *wire_inout;
4685 if (req->nShapes<1) {
4686 client->errorValue= _XkbErrCode2(0x06,req->nShapes);
4687 return BadValue;
4689 else {
4690 xkbShapeWireDesc * shapeWire;
4691 XkbShapePtr shape;
4692 register int o;
4693 shapeWire= (xkbShapeWireDesc *)wire;
4694 for (i=0;i<req->nShapes;i++) {
4695 xkbOutlineWireDesc * olWire;
4696 XkbOutlinePtr ol;
4697 shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines);
4698 if (!shape)
4699 return BadAlloc;
4700 olWire= (xkbOutlineWireDesc *)(&shapeWire[1]);
4701 for (o=0;o<shapeWire->nOutlines;o++) {
4702 register int p;
4703 XkbPointPtr pt;
4704 xkbPointWireDesc * ptWire;
4706 ol= XkbAddGeomOutline(shape,olWire->nPoints);
4707 if (!ol)
4708 return BadAlloc;
4709 ol->corner_radius= olWire->cornerRadius;
4710 ptWire= (xkbPointWireDesc *)&olWire[1];
4711 for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) {
4712 pt->x= ptWire[p].x;
4713 pt->y= ptWire[p].y;
4714 if (client->swapped) {
4715 register int n;
4716 swaps(&pt->x,n);
4717 swaps(&pt->y,n);
4720 ol->num_points= olWire->nPoints;
4721 olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]);
4723 if (shapeWire->primaryNdx!=XkbNoShape)
4724 shape->primary= &shape->outlines[shapeWire->primaryNdx];
4725 if (shapeWire->approxNdx!=XkbNoShape)
4726 shape->approx= &shape->outlines[shapeWire->approxNdx];
4727 shapeWire= (xkbShapeWireDesc *)olWire;
4729 wire= (char *)shapeWire;
4731 if (geom->num_shapes!=req->nShapes) {
4732 client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes);
4733 return BadMatch;
4736 *wire_inout= wire;
4737 return Success;
4740 static Status
4741 _CheckSetGeom( XkbGeometryPtr geom,
4742 xkbSetGeometryReq * req,
4743 ClientPtr client)
4745 register int i;
4746 Status status;
4747 char * wire;
4749 wire= (char *)&req[1];
4750 geom->label_font= _GetCountedString(&wire,client->swapped);
4752 for (i=0;i<req->nProperties;i++) {
4753 char *name,*val;
4754 name= _GetCountedString(&wire,client->swapped);
4755 if (!name)
4756 return BadAlloc;
4757 val= _GetCountedString(&wire,client->swapped);
4758 if (!val) {
4759 xfree(name);
4760 return BadAlloc;
4762 if (XkbAddGeomProperty(geom,name,val)==NULL) {
4763 xfree(name);
4764 xfree(val);
4765 return BadAlloc;
4767 xfree(name);
4768 xfree(val);
4771 if (req->nColors<2) {
4772 client->errorValue= _XkbErrCode3(0x01,2,req->nColors);
4773 return BadValue;
4775 if (req->baseColorNdx>req->nColors) {
4776 client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx);
4777 return BadMatch;
4779 if (req->labelColorNdx>req->nColors) {
4780 client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx);
4781 return BadMatch;
4783 if (req->labelColorNdx==req->baseColorNdx) {
4784 client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx,
4785 req->labelColorNdx);
4786 return BadMatch;
4789 for (i=0;i<req->nColors;i++) {
4790 char *name;
4791 name= _GetCountedString(&wire,client->swapped);
4792 if (!name)
4793 return BadAlloc;
4794 if (!XkbAddGeomColor(geom,name,geom->num_colors)) {
4795 xfree(name);
4796 return BadAlloc;
4798 xfree(name);
4800 if (req->nColors!=geom->num_colors) {
4801 client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors);
4802 return BadMatch;
4804 geom->label_color= &geom->colors[req->labelColorNdx];
4805 geom->base_color= &geom->colors[req->baseColorNdx];
4807 if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success)
4808 return status;
4810 if ((status=_CheckSetSections(geom,req,&wire,client))!=Success)
4811 return status;
4813 for (i=0;i<req->nDoodads;i++) {
4814 status=_CheckSetDoodad(&wire,geom,NULL,client);
4815 if (status!=Success)
4816 return status;
4819 for (i=0;i<req->nKeyAliases;i++) {
4820 if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL)
4821 return BadAlloc;
4822 wire+= 2*XkbKeyNameLength;
4824 return Success;
4827 /* FIXME: Needs to set geom on all core-sending devices. */
4829 ProcXkbSetGeometry(ClientPtr client)
4831 DeviceIntPtr dev;
4832 XkbGeometryPtr geom,old;
4833 XkbGeometrySizesRec sizes;
4834 Status status;
4835 XkbDescPtr xkb;
4836 Bool new_name;
4837 xkbNewKeyboardNotify nkn;
4839 REQUEST(xkbSetGeometryReq);
4840 REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
4842 if (!(client->xkbClientFlags&_XkbClientInitialized))
4843 return BadAccess;
4845 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
4846 CHK_ATOM_OR_NONE(stuff->name);
4848 xkb= dev->key->xkbInfo->desc;
4849 old= xkb->geom;
4850 xkb->geom= NULL;
4852 sizes.which= XkbGeomAllMask;
4853 sizes.num_properties= stuff->nProperties;
4854 sizes.num_colors= stuff->nColors;
4855 sizes.num_shapes= stuff->nShapes;
4856 sizes.num_sections= stuff->nSections;
4857 sizes.num_doodads= stuff->nDoodads;
4858 sizes.num_key_aliases= stuff->nKeyAliases;
4859 if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) {
4860 xkb->geom= old;
4861 return status;
4863 geom= xkb->geom;
4864 geom->name= stuff->name;
4865 geom->width_mm= stuff->widthMM;
4866 geom->height_mm= stuff->heightMM;
4867 if ((status= _CheckSetGeom(geom,stuff,client))!=Success) {
4868 XkbFreeGeometry(geom,XkbGeomAllMask,True);
4869 xkb->geom= old;
4870 return status;
4872 new_name= (xkb->names->geometry!=geom->name);
4873 xkb->names->geometry= geom->name;
4874 if (old)
4875 XkbFreeGeometry(old,XkbGeomAllMask,True);
4876 if (new_name) {
4877 xkbNamesNotify nn;
4878 bzero(&nn,sizeof(xkbNamesNotify));
4879 nn.changed= XkbGeometryNameMask;
4880 XkbSendNamesNotify(dev,&nn);
4882 nkn.deviceID= nkn.oldDeviceID= dev->id;
4883 nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code;
4884 nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code;
4885 nkn.requestMajor= XkbReqCode;
4886 nkn.requestMinor= X_kbSetGeometry;
4887 nkn.changed= XkbNKN_GeometryMask;
4888 XkbSendNewKeyboardNotify(dev,&nkn);
4889 return Success;
4892 /***====================================================================***/
4895 ProcXkbPerClientFlags(ClientPtr client)
4897 DeviceIntPtr dev;
4898 xkbPerClientFlagsReply rep;
4899 XkbInterestPtr interest;
4901 REQUEST(xkbPerClientFlagsReq);
4902 REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
4904 if (!(client->xkbClientFlags&_XkbClientInitialized))
4905 return BadAccess;
4907 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
4908 CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask);
4909 CHK_MASK_MATCH(0x02,stuff->change,stuff->value);
4911 interest = XkbFindClientResource((DevicePtr)dev,client);
4912 rep.type= X_Reply;
4913 rep.length = 0;
4914 rep.sequenceNumber = client->sequence;
4915 if (stuff->change) {
4916 client->xkbClientFlags&= ~stuff->change;
4917 client->xkbClientFlags|= stuff->value;
4919 if (stuff->change&XkbPCF_AutoResetControlsMask) {
4920 Bool want;
4921 want= stuff->value&XkbPCF_AutoResetControlsMask;
4922 if (interest && !want) {
4923 interest->autoCtrls= interest->autoCtrlValues= 0;
4925 else if (want && (!interest)) {
4926 XID id = FakeClientID(client->index);
4927 AddResource(id,RT_XKBCLIENT,dev);
4928 interest= XkbAddClientResource((DevicePtr)dev,client,id);
4929 if (!interest)
4930 return BadAlloc;
4932 if (interest && want ) {
4933 register unsigned affect;
4934 affect= stuff->ctrlsToChange;
4936 CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask);
4937 CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls);
4938 CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues);
4940 interest->autoCtrls&= ~affect;
4941 interest->autoCtrlValues&= ~affect;
4942 interest->autoCtrls|= stuff->autoCtrls&affect;
4943 interest->autoCtrlValues|= stuff->autoCtrlValues&affect;
4946 rep.supported = XkbPCF_AllFlagsMask;
4947 rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask;
4948 if (interest) {
4949 rep.autoCtrls= interest->autoCtrls;
4950 rep.autoCtrlValues= interest->autoCtrlValues;
4952 else {
4953 rep.autoCtrls= rep.autoCtrlValues= 0;
4955 if ( client->swapped ) {
4956 register int n;
4957 swaps(&rep.sequenceNumber, n);
4958 swapl(&rep.supported,n);
4959 swapl(&rep.value,n);
4960 swapl(&rep.autoCtrls,n);
4961 swapl(&rep.autoCtrlValues,n);
4963 WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep);
4964 return client->noClientException;
4967 /***====================================================================***/
4969 /* all latin-1 alphanumerics, plus parens, minus, underscore, slash */
4970 /* and wildcards */
4971 static unsigned char componentSpecLegal[] = {
4972 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87,
4973 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
4974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4975 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
4978 /* same as above but accepts percent, plus and bar too */
4979 static unsigned char componentExprLegal[] = {
4980 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87,
4981 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17,
4982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4983 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
4986 static char *
4987 GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn)
4989 int len;
4990 register int i;
4991 unsigned char *wire,*str,*tmp,*legal;
4993 if (allowExpr) legal= &componentExprLegal[0];
4994 else legal= &componentSpecLegal[0];
4996 wire= *pWire;
4997 len= (*(unsigned char *)wire++);
4998 if (len>0) {
4999 str= (unsigned char *)_XkbCalloc(1, len+1);
5000 if (str) {
5001 tmp= str;
5002 for (i=0;i<len;i++) {
5003 if (legal[(*wire)/8]&(1<<((*wire)%8)))
5004 *tmp++= *wire++;
5005 else wire++;
5007 if (tmp!=str)
5008 *tmp++= '\0';
5009 else {
5010 _XkbFree(str);
5011 str= NULL;
5014 else {
5015 *errRtrn= BadAlloc;
5018 else {
5019 str= NULL;
5021 *pWire= wire;
5022 return (char *)str;
5025 /***====================================================================***/
5028 ProcXkbListComponents(ClientPtr client)
5030 DeviceIntPtr dev;
5031 xkbListComponentsReply rep;
5032 unsigned len;
5033 int status;
5034 unsigned char * str;
5035 XkbSrvListInfoRec list;
5037 REQUEST(xkbListComponentsReq);
5038 REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
5040 if (!(client->xkbClientFlags&_XkbClientInitialized))
5041 return BadAccess;
5043 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
5045 status= Success;
5046 str= (unsigned char *)&stuff[1];
5047 bzero(&list,sizeof(XkbSrvListInfoRec));
5048 list.maxRtrn= stuff->maxNames;
5049 list.pattern[_XkbListKeymaps]= GetComponentSpec(&str,False,&status);
5050 list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,False,&status);
5051 list.pattern[_XkbListTypes]= GetComponentSpec(&str,False,&status);
5052 list.pattern[_XkbListCompat]= GetComponentSpec(&str,False,&status);
5053 list.pattern[_XkbListSymbols]= GetComponentSpec(&str,False,&status);
5054 list.pattern[_XkbListGeometry]= GetComponentSpec(&str,False,&status);
5055 if (status!=Success)
5056 return status;
5057 len= str-((unsigned char *)stuff);
5058 if ((XkbPaddedSize(len)/4)!=stuff->length)
5059 return BadLength;
5060 if ((status=XkbDDXList(dev,&list,client))!=Success) {
5061 if (list.pool) {
5062 _XkbFree(list.pool);
5063 list.pool= NULL;
5065 return status;
5067 bzero(&rep,sizeof(xkbListComponentsReply));
5068 rep.type= X_Reply;
5069 rep.deviceID = dev->id;
5070 rep.sequenceNumber = client->sequence;
5071 rep.length = XkbPaddedSize(list.nPool)/4;
5072 rep.nKeymaps = list.nFound[_XkbListKeymaps];
5073 rep.nKeycodes = list.nFound[_XkbListKeycodes];
5074 rep.nTypes = list.nFound[_XkbListTypes];
5075 rep.nCompatMaps = list.nFound[_XkbListCompat];
5076 rep.nSymbols = list.nFound[_XkbListSymbols];
5077 rep.nGeometries = list.nFound[_XkbListGeometry];
5078 rep.extra= 0;
5079 if (list.nTotal>list.maxRtrn)
5080 rep.extra = (list.nTotal-list.maxRtrn);
5081 if (client->swapped) {
5082 register int n;
5083 swaps(&rep.sequenceNumber,n);
5084 swapl(&rep.length,n);
5085 swaps(&rep.nKeymaps,n);
5086 swaps(&rep.nKeycodes,n);
5087 swaps(&rep.nTypes,n);
5088 swaps(&rep.nCompatMaps,n);
5089 swaps(&rep.nSymbols,n);
5090 swaps(&rep.nGeometries,n);
5091 swaps(&rep.extra,n);
5093 WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep);
5094 if (list.nPool && list.pool) {
5095 WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool);
5096 _XkbFree(list.pool);
5097 list.pool= NULL;
5099 return client->noClientException;
5102 /***====================================================================***/
5105 ProcXkbGetKbdByName(ClientPtr client)
5107 DeviceIntPtr dev;
5108 DeviceIntPtr tmpd;
5109 XkbFileInfo finfo;
5110 xkbGetKbdByNameReply rep;
5111 xkbGetMapReply mrep;
5112 xkbGetCompatMapReply crep;
5113 xkbGetIndicatorMapReply irep;
5114 xkbGetNamesReply nrep;
5115 xkbGetGeometryReply grep;
5116 XkbComponentNamesRec names;
5117 XkbDescPtr xkb;
5118 unsigned char * str;
5119 char mapFile[PATH_MAX];
5120 unsigned len;
5121 unsigned fwant,fneed,reported;
5122 int status;
5123 Bool geom_changed;
5124 XkbSrvLedInfoPtr old_sli;
5125 XkbSrvLedInfoPtr sli;
5127 REQUEST(xkbGetKbdByNameReq);
5128 REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
5130 if (!(client->xkbClientFlags&_XkbClientInitialized))
5131 return BadAccess;
5133 CHK_KBD_DEVICE(dev,stuff->deviceSpec);
5135 xkb = dev->key->xkbInfo->desc;
5136 status= Success;
5137 str= (unsigned char *)&stuff[1];
5138 names.keymap= GetComponentSpec(&str,True,&status);
5139 names.keycodes= GetComponentSpec(&str,True,&status);
5140 names.types= GetComponentSpec(&str,True,&status);
5141 names.compat= GetComponentSpec(&str,True,&status);
5142 names.symbols= GetComponentSpec(&str,True,&status);
5143 names.geometry= GetComponentSpec(&str,True,&status);
5144 if (status!=Success)
5145 return status;
5146 len= str-((unsigned char *)stuff);
5147 if ((XkbPaddedSize(len)/4)!=stuff->length)
5148 return BadLength;
5150 CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask);
5151 CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask);
5153 if (stuff->load)
5154 fwant= XkbGBN_AllComponentsMask;
5155 else fwant= stuff->want|stuff->need;
5156 if (!names.keymap) {
5157 if ((!names.compat)&&
5158 (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) {
5159 names.compat= _XkbDupString("%");
5161 if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) {
5162 names.types= _XkbDupString("%");
5164 if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) {
5165 names.symbols= _XkbDupString("%");
5167 geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0));
5168 if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) {
5169 names.geometry= _XkbDupString("%");
5170 geom_changed= False;
5173 else {
5174 geom_changed= True;
5177 bzero(mapFile,PATH_MAX);
5178 rep.type= X_Reply;
5179 rep.deviceID = dev->id;
5180 rep.sequenceNumber = client->sequence;
5181 rep.length = 0;
5182 rep.minKeyCode = xkb->min_key_code;
5183 rep.maxKeyCode = xkb->max_key_code;
5184 rep.loaded= False;
5185 fwant= XkbConvertGetByNameComponents(True,stuff->want)|XkmVirtualModsMask;
5186 fneed= XkbConvertGetByNameComponents(True,stuff->need);
5187 rep.reported= XkbConvertGetByNameComponents(False,fwant|fneed);
5188 if (stuff->load) {
5189 fneed|= XkmKeymapRequired;
5190 fwant|= XkmKeymapLegal;
5192 if ((fwant|fneed)&XkmSymbolsMask) {
5193 fneed|= XkmKeyNamesIndex|XkmTypesIndex;
5194 fwant|= XkmIndicatorsIndex;
5197 /* We pass dev in here so we can get the old names out if needed. */
5198 rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&finfo,
5199 mapFile,PATH_MAX);
5200 rep.newKeyboard= False;
5201 rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0;
5203 stuff->want|= stuff->need;
5204 if (finfo.xkb==NULL)
5205 rep.reported= 0;
5206 else {
5207 if (stuff->load)
5208 rep.loaded= True;
5209 if (stuff->load ||
5210 ((rep.reported&XkbGBN_SymbolsMask) && (finfo.xkb->compat))) {
5211 XkbChangesRec changes;
5212 bzero(&changes,sizeof(changes));
5213 XkbUpdateDescActions(finfo.xkb,
5214 finfo.xkb->min_key_code,XkbNumKeys(finfo.xkb),
5215 &changes);
5218 if (finfo.xkb->map==NULL)
5219 rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask);
5220 else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) {
5221 mrep.type= X_Reply;
5222 mrep.deviceID = dev->id;
5223 mrep.sequenceNumber= client->sequence;
5224 mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2);
5225 mrep.minKeyCode = finfo.xkb->min_key_code;
5226 mrep.maxKeyCode = finfo.xkb->max_key_code;
5227 mrep.present = 0;
5228 mrep.totalSyms = mrep.totalActs =
5229 mrep.totalKeyBehaviors= mrep.totalKeyExplicit=
5230 mrep.totalModMapKeys= 0;
5231 if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) {
5232 mrep.present|= XkbKeyTypesMask;
5233 mrep.firstType = 0;
5234 mrep.nTypes = mrep.totalTypes= finfo.xkb->map->num_types;
5236 else {
5237 mrep.firstType = mrep.nTypes= 0;
5238 mrep.totalTypes= 0;
5240 if (rep.reported&XkbGBN_ClientSymbolsMask) {
5241 mrep.present|= (XkbKeySymsMask|XkbModifierMapMask);
5242 mrep.firstKeySym = mrep.firstModMapKey= finfo.xkb->min_key_code;
5243 mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(finfo.xkb);
5245 else {
5246 mrep.firstKeySym= mrep.firstModMapKey= 0;
5247 mrep.nKeySyms= mrep.nModMapKeys= 0;
5249 if (rep.reported&XkbGBN_ServerSymbolsMask) {
5250 mrep.present|= XkbAllServerInfoMask;
5251 mrep.virtualMods= ~0;
5252 mrep.firstKeyAct = mrep.firstKeyBehavior =
5253 mrep.firstKeyExplicit = finfo.xkb->min_key_code;
5254 mrep.nKeyActs = mrep.nKeyBehaviors =
5255 mrep.nKeyExplicit = XkbNumKeys(finfo.xkb);
5257 else {
5258 mrep.virtualMods= 0;
5259 mrep.firstKeyAct= mrep.firstKeyBehavior=
5260 mrep.firstKeyExplicit = 0;
5261 mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0;
5263 XkbComputeGetMapReplySize(finfo.xkb,&mrep);
5264 rep.length+= SIZEOF(xGenericReply)/4+mrep.length;
5266 if (finfo.xkb->compat==NULL)
5267 rep.reported&= ~XkbGBN_CompatMapMask;
5268 else if (rep.reported&XkbGBN_CompatMapMask) {
5269 crep.type= X_Reply;
5270 crep.deviceID= dev->id;
5271 crep.sequenceNumber= client->sequence;
5272 crep.length= 0;
5273 crep.groups= XkbAllGroupsMask;
5274 crep.firstSI= 0;
5275 crep.nSI= crep.nTotalSI= finfo.xkb->compat->num_si;
5276 XkbComputeGetCompatMapReplySize(finfo.xkb->compat,&crep);
5277 rep.length+= SIZEOF(xGenericReply)/4+crep.length;
5279 if (finfo.xkb->indicators==NULL)
5280 rep.reported&= ~XkbGBN_IndicatorMapMask;
5281 else if (rep.reported&XkbGBN_IndicatorMapMask) {
5282 irep.type= X_Reply;
5283 irep.deviceID= dev->id;
5284 irep.sequenceNumber= client->sequence;
5285 irep.length= 0;
5286 irep.which= XkbAllIndicatorsMask;
5287 XkbComputeGetIndicatorMapReplySize(finfo.xkb->indicators,&irep);
5288 rep.length+= SIZEOF(xGenericReply)/4+irep.length;
5290 if (finfo.xkb->names==NULL)
5291 rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask);
5292 else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) {
5293 nrep.type= X_Reply;
5294 nrep.deviceID= dev->id;
5295 nrep.sequenceNumber= client->sequence;
5296 nrep.length= 0;
5297 nrep.minKeyCode= finfo.xkb->min_key_code;
5298 nrep.maxKeyCode= finfo.xkb->max_key_code;
5299 if (rep.reported&XkbGBN_OtherNamesMask) {
5300 nrep.which= XkbAllNamesMask;
5301 if (finfo.xkb->map!=NULL)
5302 nrep.nTypes= finfo.xkb->map->num_types;
5303 else nrep.nTypes= 0;
5304 nrep.nKTLevels= 0;
5305 nrep.groupNames= XkbAllGroupsMask;
5306 nrep.virtualMods= XkbAllVirtualModsMask;
5307 nrep.indicators= XkbAllIndicatorsMask;
5308 nrep.nRadioGroups= finfo.xkb->names->num_rg;
5310 else {
5311 nrep.which= 0;
5312 nrep.nTypes= 0;
5313 nrep.nKTLevels= 0;
5314 nrep.groupNames= 0;
5315 nrep.virtualMods= 0;
5316 nrep.indicators= 0;
5317 nrep.nRadioGroups= 0;
5319 if (rep.reported&XkbGBN_KeyNamesMask) {
5320 nrep.which|= XkbKeyNamesMask;
5321 nrep.firstKey= finfo.xkb->min_key_code;
5322 nrep.nKeys= XkbNumKeys(finfo.xkb);
5323 nrep.nKeyAliases= finfo.xkb->names->num_key_aliases;
5324 if (nrep.nKeyAliases)
5325 nrep.which|= XkbKeyAliasesMask;
5327 else {
5328 nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask);
5329 nrep.firstKey= nrep.nKeys= 0;
5330 nrep.nKeyAliases= 0;
5332 XkbComputeGetNamesReplySize(finfo.xkb,&nrep);
5333 rep.length+= SIZEOF(xGenericReply)/4+nrep.length;
5335 if (finfo.xkb->geom==NULL)
5336 rep.reported&= ~XkbGBN_GeometryMask;
5337 else if (rep.reported&XkbGBN_GeometryMask) {
5338 grep.type= X_Reply;
5339 grep.deviceID= dev->id;
5340 grep.sequenceNumber= client->sequence;
5341 grep.length= 0;
5342 grep.found= True;
5343 grep.pad= 0;
5344 grep.widthMM= grep.heightMM= 0;
5345 grep.nProperties= grep.nColors= grep.nShapes= 0;
5346 grep.nSections= grep.nDoodads= 0;
5347 grep.baseColorNdx= grep.labelColorNdx= 0;
5348 XkbComputeGetGeometryReplySize(finfo.xkb->geom,&grep,None);
5349 rep.length+= SIZEOF(xGenericReply)/4+grep.length;
5353 reported= rep.reported;
5354 if ( client->swapped ) {
5355 register int n;
5356 swaps(&rep.sequenceNumber,n);
5357 swapl(&rep.length,n);
5358 swaps(&rep.found,n);
5359 swaps(&rep.reported,n);
5361 WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep);
5362 if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask))
5363 XkbSendMap(client,finfo.xkb,&mrep);
5364 if (reported&XkbGBN_CompatMapMask)
5365 XkbSendCompatMap(client,finfo.xkb->compat,&crep);
5366 if (reported&XkbGBN_IndicatorMapMask)
5367 XkbSendIndicatorMap(client,finfo.xkb->indicators,&irep);
5368 if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask))
5369 XkbSendNames(client,finfo.xkb,&nrep);
5370 if (reported&XkbGBN_GeometryMask)
5371 XkbSendGeometry(client,finfo.xkb->geom,&grep,False);
5372 if (rep.loaded) {
5373 XkbDescPtr old_xkb;
5374 xkbNewKeyboardNotify nkn;
5375 int i,nG,nTG;
5376 old_xkb= xkb;
5377 xkb= finfo.xkb;
5378 dev->key->xkbInfo->desc= xkb;
5379 finfo.xkb= old_xkb; /* so it'll get freed automatically */
5381 *xkb->ctrls= *old_xkb->ctrls;
5382 for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
5383 nG= XkbKeyNumGroups(xkb,i);
5384 if (nG>=XkbNumKbdGroups) {
5385 nTG= XkbNumKbdGroups;
5386 break;
5388 if (nG>nTG) {
5389 nTG= nG;
5392 xkb->ctrls->num_groups= nTG;
5394 for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
5395 if (tmpd == dev ||
5396 (dev->id == inputInfo.keyboard->id && tmpd->key &&
5397 tmpd->coreEvents)) {
5399 memcpy(tmpd->key->modifierMap, xkb->map->modmap,
5400 xkb->max_key_code + 1);
5401 if (tmpd != dev)
5402 XkbCopyKeymap(dev->key->xkbInfo->desc,
5403 tmpd->key->xkbInfo->desc, True);
5404 XkbUpdateCoreDescription(tmpd, True);
5406 if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
5407 old_sli = tmpd->kbdfeed->xkb_sli;
5408 tmpd->kbdfeed->xkb_sli = NULL;
5409 sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
5410 if (sli) {
5411 sli->explicitState = old_sli->explicitState;
5412 sli->effectiveState = old_sli->effectiveState;
5414 tmpd->kbdfeed->xkb_sli = sli;
5415 XkbFreeSrvLedInfo(old_sli);
5420 /* this should be either a MN or an NKN, depending on whether or not
5421 * the keycode range changed? */
5422 nkn.deviceID= nkn.oldDeviceID= dev->id;
5423 nkn.minKeyCode= finfo.xkb->min_key_code;
5424 nkn.maxKeyCode= finfo.xkb->max_key_code;
5425 nkn.oldMinKeyCode= xkb->min_key_code;
5426 nkn.oldMaxKeyCode= xkb->max_key_code;
5427 nkn.requestMajor= XkbReqCode;
5428 nkn.requestMinor= X_kbGetKbdByName;
5429 nkn.changed= XkbNKN_KeycodesMask;
5430 if (geom_changed)
5431 nkn.changed|= XkbNKN_GeometryMask;
5432 XkbSendNewKeyboardNotify(dev,&nkn);
5434 if ((finfo.xkb!=NULL)&&(finfo.xkb!=xkb)) {
5435 XkbFreeKeyboard(finfo.xkb,XkbAllComponentsMask,True);
5436 finfo.xkb= NULL;
5438 if (names.keymap) { _XkbFree(names.keymap); names.keymap= NULL; }
5439 if (names.keycodes) { _XkbFree(names.keycodes); names.keycodes= NULL; }
5440 if (names.types) { _XkbFree(names.types); names.types= NULL; }
5441 if (names.compat) { _XkbFree(names.compat); names.compat= NULL; }
5442 if (names.symbols) { _XkbFree(names.symbols); names.symbols= NULL; }
5443 if (names.geometry) { _XkbFree(names.geometry); names.geometry= NULL; }
5444 return client->noClientException;
5447 /***====================================================================***/
5449 static int
5450 ComputeDeviceLedInfoSize( DeviceIntPtr dev,
5451 unsigned int what,
5452 XkbSrvLedInfoPtr sli)
5454 int nNames,nMaps;
5455 register unsigned n,bit;
5457 if (sli==NULL)
5458 return 0;
5459 nNames= nMaps= 0;
5460 if ((what&XkbXI_IndicatorNamesMask)==0)
5461 sli->namesPresent= 0;
5462 if ((what&XkbXI_IndicatorMapsMask)==0)
5463 sli->mapsPresent= 0;
5465 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
5466 if (sli->names && sli->names[n]!=None) {
5467 sli->namesPresent|= bit;
5468 nNames++;
5470 if (sli->maps && XkbIM_InUse(&sli->maps[n])) {
5471 sli->mapsPresent|= bit;
5472 nMaps++;
5475 return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc));
5478 static int
5479 CheckDeviceLedFBs( DeviceIntPtr dev,
5480 int class,
5481 int id,
5482 xkbGetDeviceInfoReply * rep,
5483 ClientPtr client)
5485 int nFBs= 0;
5486 int length= 0;
5487 Bool classOk;
5489 if (class==XkbDfltXIClass) {
5490 if (dev->kbdfeed) class= KbdFeedbackClass;
5491 else if (dev->leds) class= LedFeedbackClass;
5492 else {
5493 client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
5494 return XkbKeyboardErrorCode;
5497 classOk= False;
5498 if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
5499 KbdFeedbackPtr kf;
5500 classOk= True;
5501 for (kf= dev->kbdfeed;(kf);kf=kf->next) {
5502 if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id))
5503 continue;
5504 nFBs++;
5505 length+= SIZEOF(xkbDeviceLedsWireDesc);
5506 if (!kf->xkb_sli)
5507 kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0);
5508 length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli);
5509 if (id!=XkbAllXIIds)
5510 break;
5513 if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
5514 LedFeedbackPtr lf;
5515 classOk= True;
5516 for (lf= dev->leds;(lf);lf=lf->next) {
5517 if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id))
5518 continue;
5519 nFBs++;
5520 length+= SIZEOF(xkbDeviceLedsWireDesc);
5521 if (!lf->xkb_sli)
5522 lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0);
5523 length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli);
5524 if (id!=XkbAllXIIds)
5525 break;
5528 if (nFBs>0) {
5529 if (rep->supported&XkbXI_IndicatorsMask) {
5530 rep->nDeviceLedFBs= nFBs;
5531 rep->length+= (length/4);
5533 return Success;
5535 if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id);
5536 else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
5537 return XkbKeyboardErrorCode;
5540 static int
5541 SendDeviceLedInfo( XkbSrvLedInfoPtr sli,
5542 ClientPtr client)
5544 xkbDeviceLedsWireDesc wire;
5545 int length;
5547 length= 0;
5548 wire.ledClass= sli->class;
5549 wire.ledID= sli->id;
5550 wire.namesPresent= sli->namesPresent;
5551 wire.mapsPresent= sli->mapsPresent;
5552 wire.physIndicators= sli->physIndicators;
5553 wire.state= sli->effectiveState;
5554 if (client->swapped) {
5555 register int n;
5556 swaps(&wire.ledClass,n);
5557 swaps(&wire.ledID,n);
5558 swapl(&wire.namesPresent,n);
5559 swapl(&wire.mapsPresent,n);
5560 swapl(&wire.physIndicators,n);
5561 swapl(&wire.state,n);
5563 WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire);
5564 length+= SIZEOF(xkbDeviceLedsWireDesc);
5565 if (sli->namesPresent|sli->mapsPresent) {
5566 register unsigned i,bit;
5567 if (sli->namesPresent) {
5568 CARD32 awire;
5569 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
5570 if (sli->namesPresent&bit) {
5571 awire= (CARD32)sli->names[i];
5572 if (client->swapped) {
5573 register int n;
5574 swapl(&awire,n);
5576 WriteToClient(client,4,(char *)&awire);
5577 length+= 4;
5581 if (sli->mapsPresent) {
5582 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
5583 xkbIndicatorMapWireDesc iwire;
5584 if (sli->mapsPresent&bit) {
5585 iwire.flags= sli->maps[i].flags;
5586 iwire.whichGroups= sli->maps[i].which_groups;
5587 iwire.groups= sli->maps[i].groups;
5588 iwire.whichMods= sli->maps[i].which_mods;
5589 iwire.mods= sli->maps[i].mods.mask;
5590 iwire.realMods= sli->maps[i].mods.real_mods;
5591 iwire.virtualMods= sli->maps[i].mods.vmods;
5592 iwire.ctrls= sli->maps[i].ctrls;
5593 if (client->swapped) {
5594 register int n;
5595 swaps(&iwire.virtualMods,n);
5596 swapl(&iwire.ctrls,n);
5598 WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc),
5599 (char *)&iwire);
5600 length+= SIZEOF(xkbIndicatorMapWireDesc);
5605 return length;
5608 static int
5609 SendDeviceLedFBs( DeviceIntPtr dev,
5610 int class,
5611 int id,
5612 unsigned wantLength,
5613 ClientPtr client)
5615 int length= 0;
5617 if (class==XkbDfltXIClass) {
5618 if (dev->kbdfeed) class= KbdFeedbackClass;
5619 else if (dev->leds) class= LedFeedbackClass;
5621 if ((dev->kbdfeed)&&
5622 ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
5623 KbdFeedbackPtr kf;
5624 for (kf= dev->kbdfeed;(kf);kf=kf->next) {
5625 if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) {
5626 length+= SendDeviceLedInfo(kf->xkb_sli,client);
5627 if (id!=XkbAllXIIds)
5628 break;
5632 if ((dev->leds)&&
5633 ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
5634 LedFeedbackPtr lf;
5635 for (lf= dev->leds;(lf);lf=lf->next) {
5636 if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) {
5637 length+= SendDeviceLedInfo(lf->xkb_sli,client);
5638 if (id!=XkbAllXIIds)
5639 break;
5643 if (length==wantLength)
5644 return Success;
5645 else return BadLength;
5649 ProcXkbGetDeviceInfo(ClientPtr client)
5651 DeviceIntPtr dev;
5652 xkbGetDeviceInfoReply rep;
5653 int status,nDeviceLedFBs;
5654 unsigned length,nameLen;
5655 CARD16 ledClass,ledID;
5656 unsigned wanted,supported;
5657 char * str;
5659 REQUEST(xkbGetDeviceInfoReq);
5660 REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
5662 if (!(client->xkbClientFlags&_XkbClientInitialized))
5663 return BadAccess;
5665 wanted= stuff->wanted;
5667 CHK_ANY_DEVICE(dev,stuff->deviceSpec);
5668 CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask);
5670 if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns)))
5671 wanted&= ~XkbXI_ButtonActionsMask;
5672 if ((!dev->kbdfeed)&&(!dev->leds))
5673 wanted&= ~XkbXI_IndicatorsMask;
5675 nameLen= XkbSizeCountedString(dev->name);
5676 bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply));
5677 rep.type = X_Reply;
5678 rep.deviceID= dev->id;
5679 rep.sequenceNumber = client->sequence;
5680 rep.length = nameLen/4;
5681 rep.present = wanted;
5682 rep.supported = XkbXI_AllDeviceFeaturesMask;
5683 rep.unsupported = 0;
5684 rep.firstBtnWanted = rep.nBtnsWanted = 0;
5685 rep.firstBtnRtrn = rep.nBtnsRtrn = 0;
5686 if (dev->button)
5687 rep.totalBtns= dev->button->numButtons;
5688 else rep.totalBtns= 0;
5689 rep.devType= dev->type;
5690 rep.hasOwnState= (dev->key && dev->key->xkbInfo);
5691 rep.nDeviceLedFBs = 0;
5692 if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id;
5693 else rep.dfltKbdFB= XkbXINone;
5694 if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id;
5695 else rep.dfltLedFB= XkbXINone;
5697 ledClass= stuff->ledClass;
5698 ledID= stuff->ledID;
5700 rep.firstBtnWanted= rep.nBtnsWanted= 0;
5701 rep.firstBtnRtrn= rep.nBtnsRtrn= 0;
5702 if (wanted&XkbXI_ButtonActionsMask) {
5703 if (stuff->allBtns) {
5704 stuff->firstBtn= 0;
5705 stuff->nBtns= dev->button->numButtons;
5708 if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
5709 client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons,
5710 stuff->firstBtn,
5711 stuff->nBtns);
5712 return BadValue;
5714 else {
5715 rep.firstBtnWanted= stuff->firstBtn;
5716 rep.nBtnsWanted= stuff->nBtns;
5717 if (dev->button->xkb_acts!=NULL) {
5718 XkbAction *act;
5719 register int i;
5721 rep.firstBtnRtrn= stuff->firstBtn;
5722 rep.nBtnsRtrn= stuff->nBtns;
5723 act= &dev->button->xkb_acts[rep.firstBtnWanted];
5724 for (i=0;i<rep.nBtnsRtrn;i++,act++) {
5725 if (act->type!=XkbSA_NoAction)
5726 break;
5728 rep.firstBtnRtrn+= i;
5729 rep.nBtnsRtrn-= i;
5730 act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1];
5731 for (i=0;i<rep.nBtnsRtrn;i++,act--) {
5732 if (act->type!=XkbSA_NoAction)
5733 break;
5735 rep.nBtnsRtrn-= i;
5737 rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4;
5741 if (wanted&XkbXI_IndicatorsMask) {
5742 status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client);
5743 if (status!=Success)
5744 return status;
5746 length= rep.length*4;
5747 supported= rep.supported;
5748 nDeviceLedFBs = rep.nDeviceLedFBs;
5749 if (client->swapped) {
5750 register int n;
5751 swaps(&rep.sequenceNumber,n);
5752 swapl(&rep.length,n);
5753 swaps(&rep.present,n);
5754 swaps(&rep.supported,n);
5755 swaps(&rep.unsupported,n);
5756 swaps(&rep.nDeviceLedFBs,n);
5757 swapl(&rep.type,n);
5759 WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep);
5761 str= (char*) ALLOCATE_LOCAL(nameLen);
5762 if (!str)
5763 return BadAlloc;
5764 XkbWriteCountedString(str,dev->name,client->swapped);
5765 WriteToClient(client,nameLen,str);
5766 DEALLOCATE_LOCAL(str);
5767 length-= nameLen;
5769 if (rep.nBtnsRtrn>0) {
5770 int sz;
5771 xkbActionWireDesc * awire;
5772 sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc);
5773 awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn];
5774 WriteToClient(client,sz,(char *)awire);
5775 length-= sz;
5777 if (nDeviceLedFBs>0) {
5778 status= SendDeviceLedFBs(dev,ledClass,ledID,length,client);
5779 if (status!=Success)
5780 return status;
5782 else if (length!=0) {
5783 #ifdef DEBUG
5784 ErrorF("Internal Error! BadLength in ProcXkbGetDeviceInfo\n");
5785 ErrorF(" Wrote %d fewer bytes than expected\n",length);
5786 #endif
5787 return BadLength;
5789 if (stuff->wanted&(~supported)) {
5790 xkbExtensionDeviceNotify ed;
5791 bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
5792 ed.ledClass= ledClass;
5793 ed.ledID= ledID;
5794 ed.ledsDefined= 0;
5795 ed.ledState= 0;
5796 ed.firstBtn= ed.nBtns= 0;
5797 ed.reason= XkbXI_UnsupportedFeatureMask;
5798 ed.supported= supported;
5799 ed.unsupported= stuff->wanted&(~supported);
5800 XkbSendExtensionDeviceNotify(dev,client,&ed);
5802 return client->noClientException;
5805 static char *
5806 CheckSetDeviceIndicators( char * wire,
5807 DeviceIntPtr dev,
5808 int num,
5809 int * status_rtrn,
5810 ClientPtr client)
5812 xkbDeviceLedsWireDesc * ledWire;
5813 int i;
5814 XkbSrvLedInfoPtr sli;
5816 ledWire= (xkbDeviceLedsWireDesc *)wire;
5817 for (i=0;i<num;i++) {
5818 if (client->swapped) {
5819 register int n;
5820 swaps(&ledWire->ledClass,n);
5821 swaps(&ledWire->ledID,n);
5822 swapl(&ledWire->namesPresent,n);
5823 swapl(&ledWire->mapsPresent,n);
5824 swapl(&ledWire->physIndicators,n);
5827 sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
5828 XkbXI_IndicatorsMask);
5829 if (sli!=NULL) {
5830 register int n;
5831 register unsigned bit;
5832 int nMaps,nNames;
5833 CARD32 *atomWire;
5834 xkbIndicatorMapWireDesc *mapWire;
5836 nMaps= nNames= 0;
5837 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
5838 if (ledWire->namesPresent&bit)
5839 nNames++;
5840 if (ledWire->mapsPresent&bit)
5841 nMaps++;
5843 atomWire= (CARD32 *)&ledWire[1];
5844 if (nNames>0) {
5845 for (n=0;n<nNames;n++) {
5846 if (client->swapped) {
5847 register int t;
5848 swapl(atomWire,t);
5850 CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue,
5851 *status_rtrn,NULL);
5852 atomWire++;
5855 mapWire= (xkbIndicatorMapWireDesc *)atomWire;
5856 if (nMaps>0) {
5857 for (n=0;n<nMaps;n++) {
5858 if (client->swapped) {
5859 register int t;
5860 swaps(&mapWire->virtualMods,t);
5861 swapl(&mapWire->ctrls,t);
5863 CHK_MASK_LEGAL3(0x21,mapWire->whichGroups,
5864 XkbIM_UseAnyGroup,
5865 client->errorValue,
5866 *status_rtrn,NULL);
5867 CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods,
5868 client->errorValue,
5869 *status_rtrn,NULL);
5870 mapWire++;
5873 ledWire= (xkbDeviceLedsWireDesc *)mapWire;
5875 else {
5876 /* SHOULD NEVER HAPPEN */
5877 return (char *)ledWire;
5880 return (char *)ledWire;
5883 static char *
5884 SetDeviceIndicators( char * wire,
5885 DeviceIntPtr dev,
5886 unsigned changed,
5887 int num,
5888 int * status_rtrn,
5889 ClientPtr client,
5890 xkbExtensionDeviceNotify *ev)
5892 xkbDeviceLedsWireDesc * ledWire;
5893 int i;
5894 XkbEventCauseRec cause;
5895 unsigned namec,mapc,statec;
5896 xkbExtensionDeviceNotify ed;
5897 XkbChangesRec changes;
5898 DeviceIntPtr kbd;
5900 bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
5901 bzero((char *)&changes,sizeof(XkbChangesRec));
5902 XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client);
5903 ledWire= (xkbDeviceLedsWireDesc *)wire;
5904 for (i=0;i<num;i++) {
5905 register int n;
5906 register unsigned bit;
5907 CARD32 * atomWire;
5908 xkbIndicatorMapWireDesc * mapWire;
5909 XkbSrvLedInfoPtr sli;
5911 namec= mapc= statec= 0;
5912 sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
5913 XkbXI_IndicatorMapsMask);
5914 if (!sli) {
5915 /* SHOULD NEVER HAPPEN!! */
5916 return (char *)ledWire;
5919 atomWire= (CARD32 *)&ledWire[1];
5920 if (changed&XkbXI_IndicatorNamesMask) {
5921 namec= sli->namesPresent|ledWire->namesPresent;
5922 bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
5924 if (ledWire->namesPresent) {
5925 sli->namesPresent= ledWire->namesPresent;
5926 bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
5927 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
5928 if (ledWire->namesPresent&bit) {
5929 sli->names[n]= (Atom)*atomWire;
5930 if (sli->names[n]==None)
5931 ledWire->namesPresent&= ~bit;
5932 atomWire++;
5936 mapWire= (xkbIndicatorMapWireDesc *)atomWire;
5937 if (changed&XkbXI_IndicatorMapsMask) {
5938 mapc= sli->mapsPresent|ledWire->mapsPresent;
5939 sli->mapsPresent= ledWire->mapsPresent;
5940 bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec));
5942 if (ledWire->mapsPresent) {
5943 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
5944 if (ledWire->mapsPresent&bit) {
5945 sli->maps[n].flags= mapWire->flags;
5946 sli->maps[n].which_groups= mapWire->whichGroups;
5947 sli->maps[n].groups= mapWire->groups;
5948 sli->maps[n].which_mods= mapWire->whichMods;
5949 sli->maps[n].mods.mask= mapWire->mods;
5950 sli->maps[n].mods.real_mods=mapWire->realMods;
5951 sli->maps[n].mods.vmods= mapWire->virtualMods;
5952 sli->maps[n].ctrls= mapWire->ctrls;
5953 mapWire++;
5957 if (changed&XkbXI_IndicatorStateMask) {
5958 statec= sli->effectiveState^ledWire->state;
5959 sli->explicitState&= ~statec;
5960 sli->explicitState|= (ledWire->state&statec);
5962 if (namec)
5963 XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
5964 if (mapc)
5965 XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
5966 if (statec)
5967 XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
5969 kbd= dev;
5970 if ((sli->flags&XkbSLI_HasOwnState)==0)
5971 kbd= (DeviceIntPtr)LookupKeyboardDevice();
5973 XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
5974 ledWire= (xkbDeviceLedsWireDesc *)mapWire;
5976 return (char *)ledWire;
5979 /* FIXME: Needs to set info on all core-sending devices. */
5981 ProcXkbSetDeviceInfo(ClientPtr client)
5983 DeviceIntPtr dev;
5984 unsigned change;
5985 char * wire;
5986 xkbExtensionDeviceNotify ed;
5988 REQUEST(xkbSetDeviceInfoReq);
5989 REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
5991 if (!(client->xkbClientFlags&_XkbClientInitialized))
5992 return BadAccess;
5994 change= stuff->change;
5996 CHK_ANY_DEVICE(dev,stuff->deviceSpec);
5997 CHK_MASK_LEGAL(0x01,change,XkbXI_AllFeaturesMask);
5999 wire= (char *)&stuff[1];
6000 if (change&XkbXI_ButtonActionsMask) {
6001 if (!dev->button) {
6002 client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass);
6003 return XkbKeyboardErrorCode;
6005 if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
6006 client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns,
6007 dev->button->numButtons);
6008 return BadMatch;
6010 wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc));
6012 if (stuff->change&XkbXI_IndicatorsMask) {
6013 int status= Success;
6014 wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs,
6015 &status,client);
6016 if (status!=Success)
6017 return status;
6019 if (((wire-((char *)stuff))/4)!=stuff->length)
6020 return BadLength;
6022 bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
6023 ed.deviceID= dev->id;
6024 wire= (char *)&stuff[1];
6025 if (change&XkbXI_ButtonActionsMask) {
6026 int nBtns,sz,i;
6027 XkbAction * acts;
6028 DeviceIntPtr kbd;
6030 nBtns= dev->button->numButtons;
6031 acts= dev->button->xkb_acts;
6032 if (acts==NULL) {
6033 acts= _XkbTypedCalloc(nBtns,XkbAction);
6034 if (!acts)
6035 return BadAlloc;
6036 dev->button->xkb_acts= acts;
6038 sz= stuff->nBtns*SIZEOF(xkbActionWireDesc);
6039 memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz);
6040 wire+= sz;
6041 ed.reason|= XkbXI_ButtonActionsMask;
6042 ed.firstBtn= stuff->firstBtn;
6043 ed.nBtns= stuff->nBtns;
6045 if (dev->key) kbd= dev;
6046 else kbd= (DeviceIntPtr)LookupKeyboardDevice();
6047 acts= &dev->button->xkb_acts[stuff->firstBtn];
6048 for (i=0;i<stuff->nBtns;i++,acts++) {
6049 if (acts->type!=XkbSA_NoAction)
6050 XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0);
6053 if (stuff->change&XkbXI_IndicatorsMask) {
6054 int status= Success;
6055 wire= SetDeviceIndicators(wire,dev,change,stuff->nDeviceLedFBs,
6056 &status,client,&ed);
6057 if (status!=Success)
6058 return status;
6060 if ((stuff->change)&&(ed.reason))
6061 XkbSendExtensionDeviceNotify(dev,client,&ed);
6062 return client->noClientException;
6065 /***====================================================================***/
6068 ProcXkbSetDebuggingFlags(ClientPtr client)
6070 CARD32 newFlags,newCtrls,extraLength;
6071 xkbSetDebuggingFlagsReply rep;
6073 REQUEST(xkbSetDebuggingFlagsReq);
6074 REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
6076 newFlags= xkbDebugFlags&(~stuff->affectFlags);
6077 newFlags|= (stuff->flags&stuff->affectFlags);
6078 newCtrls= xkbDebugCtrls&(~stuff->affectCtrls);
6079 newCtrls|= (stuff->ctrls&stuff->affectCtrls);
6080 if (xkbDebugFlags || newFlags || stuff->msgLength) {
6081 ErrorF("XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags);
6082 if (newCtrls!=xkbDebugCtrls)
6083 ErrorF("XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls);
6085 extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq;
6086 if (stuff->msgLength>0) {
6087 char *msg;
6088 if (extraLength<XkbPaddedSize(stuff->msgLength)) {
6089 ErrorF("XkbDebug: msgLength= %d, length= %ld (should be %d)\n",
6090 stuff->msgLength,(long)extraLength,
6091 XkbPaddedSize(stuff->msgLength));
6092 return BadLength;
6094 msg= (char *)&stuff[1];
6095 if (msg[stuff->msgLength-1]!='\0') {
6096 ErrorF("XkbDebug: message not null-terminated\n");
6097 return BadValue;
6099 ErrorF("XkbDebug: %s\n",msg);
6101 xkbDebugFlags = newFlags;
6102 xkbDebugCtrls = newCtrls;
6104 XkbDisableLockActions= (xkbDebugCtrls&XkbDF_DisableLocks);
6106 rep.type= X_Reply;
6107 rep.length = 0;
6108 rep.sequenceNumber = client->sequence;
6109 rep.currentFlags = newFlags;
6110 rep.currentCtrls = newCtrls;
6111 rep.supportedFlags = ~0;
6112 rep.supportedCtrls = ~0;
6113 if ( client->swapped ) {
6114 register int n;
6115 swaps(&rep.sequenceNumber, n);
6116 swapl(&rep.currentFlags, n);
6117 swapl(&rep.currentCtrls, n);
6118 swapl(&rep.supportedFlags, n);
6119 swapl(&rep.supportedCtrls, n);
6121 WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep);
6122 return client->noClientException;
6125 /***====================================================================***/
6127 static int
6128 ProcXkbDispatch (ClientPtr client)
6130 REQUEST(xReq);
6131 switch (stuff->data)
6133 case X_kbUseExtension:
6134 return ProcXkbUseExtension(client);
6135 case X_kbSelectEvents:
6136 return ProcXkbSelectEvents(client);
6137 case X_kbBell:
6138 return ProcXkbBell(client);
6139 case X_kbGetState:
6140 return ProcXkbGetState(client);
6141 case X_kbLatchLockState:
6142 return ProcXkbLatchLockState(client);
6143 case X_kbGetControls:
6144 return ProcXkbGetControls(client);
6145 case X_kbSetControls:
6146 return ProcXkbSetControls(client);
6147 case X_kbGetMap:
6148 return ProcXkbGetMap(client);
6149 case X_kbSetMap:
6150 return ProcXkbSetMap(client);
6151 case X_kbGetCompatMap:
6152 return ProcXkbGetCompatMap(client);
6153 case X_kbSetCompatMap:
6154 return ProcXkbSetCompatMap(client);
6155 case X_kbGetIndicatorState:
6156 return ProcXkbGetIndicatorState(client);
6157 case X_kbGetIndicatorMap:
6158 return ProcXkbGetIndicatorMap(client);
6159 case X_kbSetIndicatorMap:
6160 return ProcXkbSetIndicatorMap(client);
6161 case X_kbGetNamedIndicator:
6162 return ProcXkbGetNamedIndicator(client);
6163 case X_kbSetNamedIndicator:
6164 return ProcXkbSetNamedIndicator(client);
6165 case X_kbGetNames:
6166 return ProcXkbGetNames(client);
6167 case X_kbSetNames:
6168 return ProcXkbSetNames(client);
6169 case X_kbGetGeometry:
6170 return ProcXkbGetGeometry(client);
6171 case X_kbSetGeometry:
6172 return ProcXkbSetGeometry(client);
6173 case X_kbPerClientFlags:
6174 return ProcXkbPerClientFlags(client);
6175 case X_kbListComponents:
6176 return ProcXkbListComponents(client);
6177 case X_kbGetKbdByName:
6178 return ProcXkbGetKbdByName(client);
6179 case X_kbGetDeviceInfo:
6180 return ProcXkbGetDeviceInfo(client);
6181 case X_kbSetDeviceInfo:
6182 return ProcXkbSetDeviceInfo(client);
6183 case X_kbSetDebuggingFlags:
6184 return ProcXkbSetDebuggingFlags(client);
6185 default:
6186 return BadRequest;
6190 static int
6191 XkbClientGone(pointer data,XID id)
6193 DevicePtr pXDev = (DevicePtr)data;
6195 if (!XkbRemoveResourceClient(pXDev,id)) {
6196 ErrorF("Internal Error! bad RemoveResourceClient in XkbClientGone\n");
6198 return 1;
6201 /*ARGSUSED*/
6202 static void
6203 XkbResetProc(ExtensionEntry *extEntry)
6207 void
6208 XkbExtensionInit(void)
6210 ExtensionEntry *extEntry;
6212 if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors,
6213 ProcXkbDispatch, SProcXkbDispatch,
6214 XkbResetProc, StandardMinorOpcode))) {
6215 XkbReqCode = (unsigned char)extEntry->base;
6216 XkbEventBase = (unsigned char)extEntry->eventBase;
6217 XkbErrorBase = (unsigned char)extEntry->errorBase;
6218 XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard;
6219 RT_XKBCLIENT = CreateNewResourceType(XkbClientGone);
6221 return;