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>
33 #include <X11/Xproto.h>
36 #define XKBSRV_NEED_FILE_FUNCS
38 #include "extnsionst.h"
42 #include "protocol-versions.h"
44 #include <X11/extensions/XI.h>
45 #include <X11/extensions/XKMformat.h>
48 static int XkbErrorBase
;
50 int XkbKeyboardErrorCode
;
51 CARD32 xkbDebugFlags
= 0;
52 static CARD32 xkbDebugCtrls
= 0;
54 static RESTYPE RT_XKBCLIENT
;
56 /***====================================================================***/
58 #define CHK_DEVICE(dev, id, client, access_mode, lf) {\
60 int tmprc = lf(&(dev), id, client, access_mode, &why);\
61 if (tmprc != Success) {\
62 client->errorValue = _XkbErrCode2(why, id);\
67 #define CHK_KBD_DEVICE(dev, id, client, mode) \
68 CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard)
69 #define CHK_LED_DEVICE(dev, id, client, mode) \
70 CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice)
71 #define CHK_BELL_DEVICE(dev, id, client, mode) \
72 CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice)
73 #define CHK_ANY_DEVICE(dev, id, client, mode) \
74 CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice)
76 #define CHK_ATOM_ONLY2(a,ev,er) {\
77 if (((a)==None)||(!ValidAtom((a)))) {\
82 #define CHK_ATOM_ONLY(a) \
83 CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
85 #define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
86 if (((a)!=None)&&(!ValidAtom((a)))) {\
92 #define CHK_ATOM_OR_NONE2(a,ev,er) {\
93 if (((a)!=None)&&(!ValidAtom((a)))) {\
98 #define CHK_ATOM_OR_NONE(a) \
99 CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
101 #define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\
102 if ((mask)&(~(legal))) { \
103 (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
108 #define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\
109 if ((mask)&(~(legal))) { \
110 (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
114 #define CHK_MASK_LEGAL(err,mask,legal) \
115 CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
117 #define CHK_MASK_MATCH(err,affect,value) {\
118 if ((value)&(~(affect))) { \
119 client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
123 #define CHK_MASK_OVERLAP(err,m1,m2) {\
125 client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
129 #define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
130 if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
131 (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
134 else if ( (first)<(x)->min_key_code ) {\
135 (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
139 #define CHK_KEY_RANGE(err,first,num,x) \
140 CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
142 #define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
143 if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
144 (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
147 else if ( (first)<(r)->minKeyCode ) {\
148 (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
152 #define CHK_REQ_KEY_RANGE(err,first,num,r) \
153 CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
155 /***====================================================================***/
158 ProcXkbUseExtension(ClientPtr client
)
160 REQUEST(xkbUseExtensionReq
);
161 xkbUseExtensionReply rep
;
164 REQUEST_SIZE_MATCH(xkbUseExtensionReq
);
165 if (stuff
->wantedMajor
!= SERVER_XKB_MAJOR_VERSION
) {
166 /* pre-release version 0.65 is compatible with 1.00 */
167 supported
= ((SERVER_XKB_MAJOR_VERSION
== 1) &&
168 (stuff
->wantedMajor
== 0) && (stuff
->wantedMinor
== 65));
173 if ((supported
) && (!(client
->xkbClientFlags
& _XkbClientInitialized
))) {
174 client
->xkbClientFlags
= _XkbClientInitialized
;
175 client
->vMajor
= stuff
->wantedMajor
;
176 client
->vMinor
= stuff
->wantedMinor
;
178 else if (xkbDebugFlags
& 0x1) {
180 ("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n",
181 client
->index
, (long) client
->clientAsMask
, stuff
->wantedMajor
,
182 stuff
->wantedMinor
, SERVER_XKB_MAJOR_VERSION
,
183 SERVER_XKB_MINOR_VERSION
);
185 rep
= (xkbUseExtensionReply
) {
187 .supported
= supported
,
188 .sequenceNumber
= client
->sequence
,
190 .serverMajor
= SERVER_XKB_MAJOR_VERSION
,
191 .serverMinor
= SERVER_XKB_MINOR_VERSION
193 if (client
->swapped
) {
194 swaps(&rep
.sequenceNumber
);
195 swaps(&rep
.serverMajor
);
196 swaps(&rep
.serverMinor
);
198 WriteToClient(client
, SIZEOF(xkbUseExtensionReply
), &rep
);
202 /***====================================================================***/
205 ProcXkbSelectEvents(ClientPtr client
)
209 XkbInterestPtr masks
;
211 REQUEST(xkbSelectEventsReq
);
213 REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq
);
215 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
218 CHK_ANY_DEVICE(dev
, stuff
->deviceSpec
, client
, DixUseAccess
);
220 if (((stuff
->affectWhich
& XkbMapNotifyMask
) != 0) && (stuff
->affectMap
)) {
221 client
->mapNotifyMask
&= ~stuff
->affectMap
;
222 client
->mapNotifyMask
|= (stuff
->affectMap
& stuff
->map
);
224 if ((stuff
->affectWhich
& (~XkbMapNotifyMask
)) == 0)
227 masks
= XkbFindClientResource((DevicePtr
) dev
, client
);
229 XID id
= FakeClientID(client
->index
);
231 if (!AddResource(id
, RT_XKBCLIENT
, dev
))
233 masks
= XkbAddClientResource((DevicePtr
) dev
, client
, id
);
241 register unsigned bit
, ndx
, maskLeft
, dataLeft
, size
;
243 from
.c8
= (CARD8
*) &stuff
[1];
244 dataLeft
= (stuff
->length
* 4) - SIZEOF(xkbSelectEventsReq
);
245 maskLeft
= (stuff
->affectWhich
& (~XkbMapNotifyMask
));
246 for (ndx
= 0, bit
= 1; (maskLeft
!= 0); ndx
++, bit
<<= 1) {
247 if ((bit
& maskLeft
) == 0)
251 case XkbNewKeyboardNotify
:
252 to
.c16
= &client
->newKeyboardNotifyMask
;
253 legal
= XkbAllNewKeyboardEventsMask
;
257 to
.c16
= &masks
->stateNotifyMask
;
258 legal
= XkbAllStateEventsMask
;
261 case XkbControlsNotify
:
262 to
.c32
= &masks
->ctrlsNotifyMask
;
263 legal
= XkbAllControlEventsMask
;
266 case XkbIndicatorStateNotify
:
267 to
.c32
= &masks
->iStateNotifyMask
;
268 legal
= XkbAllIndicatorEventsMask
;
271 case XkbIndicatorMapNotify
:
272 to
.c32
= &masks
->iMapNotifyMask
;
273 legal
= XkbAllIndicatorEventsMask
;
277 to
.c16
= &masks
->namesNotifyMask
;
278 legal
= XkbAllNameEventsMask
;
281 case XkbCompatMapNotify
:
282 to
.c8
= &masks
->compatNotifyMask
;
283 legal
= XkbAllCompatMapEventsMask
;
287 to
.c8
= &masks
->bellNotifyMask
;
288 legal
= XkbAllBellEventsMask
;
291 case XkbActionMessage
:
292 to
.c8
= &masks
->actionMessageMask
;
293 legal
= XkbAllActionMessagesMask
;
296 case XkbAccessXNotify
:
297 to
.c16
= &masks
->accessXNotifyMask
;
298 legal
= XkbAllAccessXEventsMask
;
301 case XkbExtensionDeviceNotify
:
302 to
.c16
= &masks
->extDevNotifyMask
;
303 legal
= XkbAllExtensionDeviceEventsMask
;
307 client
->errorValue
= _XkbErrCode2(33, bit
);
311 if (stuff
->clear
& bit
) {
319 else if (stuff
->selectAll
& bit
) {
328 if (dataLeft
< (size
* 2))
331 CHK_MASK_MATCH(ndx
, from
.c16
[0], from
.c16
[1]);
332 CHK_MASK_LEGAL(ndx
, from
.c16
[0], legal
);
333 to
.c16
[0] &= ~from
.c16
[0];
334 to
.c16
[0] |= (from
.c16
[0] & from
.c16
[1]);
336 else if (size
== 4) {
337 CHK_MASK_MATCH(ndx
, from
.c32
[0], from
.c32
[1]);
338 CHK_MASK_LEGAL(ndx
, from
.c32
[0], legal
);
339 to
.c32
[0] &= ~from
.c32
[0];
340 to
.c32
[0] |= (from
.c32
[0] & from
.c32
[1]);
343 CHK_MASK_MATCH(ndx
, from
.c8
[0], from
.c8
[1]);
344 CHK_MASK_LEGAL(ndx
, from
.c8
[0], legal
);
345 to
.c8
[0] &= ~from
.c8
[0];
346 to
.c8
[0] |= (from
.c8
[0] & from
.c8
[1]);
349 from
.c8
+= (size
* 2);
350 dataLeft
-= (size
* 2);
354 ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",
363 /***====================================================================***/
365 * Ring a bell on the given device for the given client.
368 _XkbBell(ClientPtr client
, DeviceIntPtr dev
, WindowPtr pWin
,
369 int bellClass
, int bellID
, int pitch
, int duration
,
370 int percent
, int forceSound
, int eventOnly
, Atom name
)
374 int oldPitch
, oldDuration
;
377 if (bellClass
== KbdFeedbackClass
) {
380 if (bellID
== XkbDfltXIId
)
383 for (k
= dev
->kbdfeed
; k
; k
= k
->next
) {
384 if (k
->ctrl
.id
== bellID
)
389 client
->errorValue
= _XkbErrCode2(0x5, bellID
);
393 ctrl
= (pointer
) &(k
->ctrl
);
394 oldPitch
= k
->ctrl
.bell_pitch
;
395 oldDuration
= k
->ctrl
.bell_duration
;
398 k
->ctrl
.bell_pitch
= defaultKeyboardControl
.bell_pitch
;
400 k
->ctrl
.bell_pitch
= pitch
;
404 k
->ctrl
.bell_duration
= defaultKeyboardControl
.bell_duration
;
406 k
->ctrl
.bell_duration
= duration
;
409 else if (bellClass
== BellFeedbackClass
) {
412 if (bellID
== XkbDfltXIId
)
415 for (b
= dev
->bell
; b
; b
= b
->next
) {
416 if (b
->ctrl
.id
== bellID
)
421 client
->errorValue
= _XkbErrCode2(0x6, bellID
);
424 base
= b
->ctrl
.percent
;
425 ctrl
= (pointer
) &(b
->ctrl
);
426 oldPitch
= b
->ctrl
.pitch
;
427 oldDuration
= b
->ctrl
.duration
;
430 b
->ctrl
.pitch
= defaultKeyboardControl
.bell_pitch
;
432 b
->ctrl
.pitch
= pitch
;
436 b
->ctrl
.duration
= defaultKeyboardControl
.bell_duration
;
438 b
->ctrl
.duration
= duration
;
442 client
->errorValue
= _XkbErrCode2(0x7, bellClass
);
446 newPercent
= (base
* percent
) / 100;
448 newPercent
= base
+ newPercent
;
450 newPercent
= base
- newPercent
+ percent
;
452 XkbHandleBell(forceSound
, eventOnly
,
453 dev
, newPercent
, ctrl
, bellClass
, name
, pWin
, client
);
454 if ((pitch
!= 0) || (duration
!= 0)) {
455 if (bellClass
== KbdFeedbackClass
) {
458 k
= (KbdFeedbackPtr
) ctrl
;
460 k
->ctrl
.bell_pitch
= oldPitch
;
462 k
->ctrl
.bell_duration
= oldDuration
;
467 b
= (BellFeedbackPtr
) ctrl
;
469 b
->ctrl
.pitch
= oldPitch
;
471 b
->ctrl
.duration
= oldDuration
;
479 ProcXkbBell(ClientPtr client
)
486 REQUEST_SIZE_MATCH(xkbBellReq
);
488 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
491 CHK_BELL_DEVICE(dev
, stuff
->deviceSpec
, client
, DixBellAccess
);
492 CHK_ATOM_OR_NONE(stuff
->name
);
494 /* device-independent checks request for sane values */
495 if ((stuff
->forceSound
) && (stuff
->eventOnly
)) {
497 _XkbErrCode3(0x1, stuff
->forceSound
, stuff
->eventOnly
);
500 if (stuff
->percent
< -100 || stuff
->percent
> 100) {
501 client
->errorValue
= _XkbErrCode2(0x2, stuff
->percent
);
504 if (stuff
->duration
< -1) {
505 client
->errorValue
= _XkbErrCode2(0x3, stuff
->duration
);
508 if (stuff
->pitch
< -1) {
509 client
->errorValue
= _XkbErrCode2(0x4, stuff
->pitch
);
513 if (stuff
->bellClass
== XkbDfltXIClass
) {
514 if (dev
->kbdfeed
!= NULL
)
515 stuff
->bellClass
= KbdFeedbackClass
;
517 stuff
->bellClass
= BellFeedbackClass
;
520 if (stuff
->window
!= None
) {
521 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixGetAttrAccess
);
523 client
->errorValue
= stuff
->window
;
530 /* Client wants to ring a bell on the core keyboard?
531 Ring the bell on the core keyboard (which does nothing, but if that
532 fails the client is screwed anyway), and then on all extension devices.
533 Fail if the core keyboard fails but not the extension devices. this
534 may cause some keyboards to ding and others to stay silent. Fix
535 your client to use explicit keyboards to avoid this.
537 dev is the device the client requested.
539 rc
= _XkbBell(client
, dev
, pWin
, stuff
->bellClass
, stuff
->bellID
,
540 stuff
->pitch
, stuff
->duration
, stuff
->percent
,
541 stuff
->forceSound
, stuff
->eventOnly
, stuff
->name
);
543 if ((rc
== Success
) && ((stuff
->deviceSpec
== XkbUseCoreKbd
) ||
544 (stuff
->deviceSpec
== XkbUseCorePtr
))) {
547 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
548 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
549 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
550 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
, DixBellAccess
);
552 _XkbBell(client
, other
, pWin
, stuff
->bellClass
,
553 stuff
->bellID
, stuff
->pitch
, stuff
->duration
,
554 stuff
->percent
, stuff
->forceSound
,
555 stuff
->eventOnly
, stuff
->name
);
558 rc
= Success
; /* reset to success, that's what we got for the VCK */
564 /***====================================================================***/
567 ProcXkbGetState(ClientPtr client
)
569 REQUEST(xkbGetStateReq
);
571 xkbGetStateReply rep
;
574 REQUEST_SIZE_MATCH(xkbGetStateReq
);
576 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
579 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
581 xkb
= &dev
->key
->xkbInfo
->state
;
582 rep
= (xkbGetStateReply
) {
585 .sequenceNumber
= client
->sequence
,
587 .mods
= XkbStateFieldFromRec(xkb
) & 0xff,
588 .baseMods
= xkb
->base_mods
,
589 .latchedMods
= xkb
->latched_mods
,
590 .lockedMods
= xkb
->locked_mods
,
592 .lockedGroup
= xkb
->locked_group
,
593 .baseGroup
= xkb
->base_group
,
594 .latchedGroup
= xkb
->latched_group
,
595 .compatState
= xkb
->compat_state
,
596 .ptrBtnState
= xkb
->ptr_buttons
598 if (client
->swapped
) {
599 swaps(&rep
.sequenceNumber
);
600 swaps(&rep
.ptrBtnState
);
602 WriteToClient(client
, SIZEOF(xkbGetStateReply
), &rep
);
606 /***====================================================================***/
609 ProcXkbLatchLockState(ClientPtr client
)
612 DeviceIntPtr dev
, tmpd
;
613 XkbStateRec oldState
, *newState
;
616 XkbEventCauseRec cause
;
618 REQUEST(xkbLatchLockStateReq
);
619 REQUEST_SIZE_MATCH(xkbLatchLockStateReq
);
621 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
624 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixSetAttrAccess
);
625 CHK_MASK_MATCH(0x01, stuff
->affectModLocks
, stuff
->modLocks
);
626 CHK_MASK_MATCH(0x01, stuff
->affectModLatches
, stuff
->modLatches
);
630 for (tmpd
= inputInfo
.devices
; tmpd
; tmpd
= tmpd
->next
) {
632 (!IsMaster(tmpd
) && GetMaster(tmpd
, MASTER_KEYBOARD
) == dev
)) {
633 if (!tmpd
->key
|| !tmpd
->key
->xkbInfo
)
636 oldState
= tmpd
->key
->xkbInfo
->state
;
637 newState
= &tmpd
->key
->xkbInfo
->state
;
638 if (stuff
->affectModLocks
) {
639 newState
->locked_mods
&= ~stuff
->affectModLocks
;
640 newState
->locked_mods
|=
641 (stuff
->affectModLocks
& stuff
->modLocks
);
643 if (status
== Success
&& stuff
->lockGroup
)
644 newState
->locked_group
= stuff
->groupLock
;
645 if (status
== Success
&& stuff
->affectModLatches
)
646 status
= XkbLatchModifiers(tmpd
, stuff
->affectModLatches
,
648 if (status
== Success
&& stuff
->latchGroup
)
649 status
= XkbLatchGroup(tmpd
, stuff
->groupLatch
);
651 if (status
!= Success
)
654 XkbComputeDerivedState(tmpd
->key
->xkbInfo
);
656 changed
= XkbStateChangedFlags(&oldState
, newState
);
660 sn
.requestMajor
= XkbReqCode
;
661 sn
.requestMinor
= X_kbLatchLockState
;
662 sn
.changed
= changed
;
663 XkbSendStateNotify(tmpd
, &sn
);
664 changed
= XkbIndicatorsToUpdate(tmpd
, changed
, FALSE
);
666 XkbSetCauseXkbReq(&cause
, X_kbLatchLockState
, client
);
667 XkbUpdateIndicators(tmpd
, changed
, TRUE
, NULL
, &cause
);
676 /***====================================================================***/
679 ProcXkbGetControls(ClientPtr client
)
681 xkbGetControlsReply rep
;
685 REQUEST(xkbGetControlsReq
);
686 REQUEST_SIZE_MATCH(xkbGetControlsReq
);
688 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
691 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
693 xkb
= dev
->key
->xkbInfo
->desc
->ctrls
;
694 rep
= (xkbGetControlsReply
) {
696 .deviceID
= ((DeviceIntPtr
) dev
)->id
,
697 .sequenceNumber
= client
->sequence
,
698 .length
= bytes_to_int32(SIZEOF(xkbGetControlsReply
) -
699 SIZEOF(xGenericReply
)),
700 .mkDfltBtn
= xkb
->mk_dflt_btn
,
701 .numGroups
= xkb
->num_groups
,
702 .groupsWrap
= xkb
->groups_wrap
,
703 .internalMods
= xkb
->internal
.mask
,
704 .ignoreLockMods
= xkb
->ignore_lock
.mask
,
705 .internalRealMods
= xkb
->internal
.real_mods
,
706 .ignoreLockRealMods
= xkb
->ignore_lock
.real_mods
,
707 .internalVMods
= xkb
->internal
.vmods
,
708 .ignoreLockVMods
= xkb
->ignore_lock
.vmods
,
709 .repeatDelay
= xkb
->repeat_delay
,
710 .repeatInterval
= xkb
->repeat_interval
,
711 .slowKeysDelay
= xkb
->slow_keys_delay
,
712 .debounceDelay
= xkb
->debounce_delay
,
713 .mkDelay
= xkb
->mk_delay
,
714 .mkInterval
= xkb
->mk_interval
,
715 .mkTimeToMax
= xkb
->mk_time_to_max
,
716 .mkMaxSpeed
= xkb
->mk_max_speed
,
717 .mkCurve
= xkb
->mk_curve
,
718 .axOptions
= xkb
->ax_options
,
719 .axTimeout
= xkb
->ax_timeout
,
720 .axtOptsMask
= xkb
->axt_opts_mask
,
721 .axtOptsValues
= xkb
->axt_opts_values
,
722 .axtCtrlsMask
= xkb
->axt_ctrls_mask
,
723 .axtCtrlsValues
= xkb
->axt_ctrls_values
,
724 .enabledCtrls
= xkb
->enabled_ctrls
,
726 memcpy(rep
.perKeyRepeat
, xkb
->per_key_repeat
, XkbPerKeyBitArraySize
);
727 if (client
->swapped
) {
728 swaps(&rep
.sequenceNumber
);
730 swaps(&rep
.internalVMods
);
731 swaps(&rep
.ignoreLockVMods
);
732 swapl(&rep
.enabledCtrls
);
733 swaps(&rep
.repeatDelay
);
734 swaps(&rep
.repeatInterval
);
735 swaps(&rep
.slowKeysDelay
);
736 swaps(&rep
.debounceDelay
);
738 swaps(&rep
.mkInterval
);
739 swaps(&rep
.mkTimeToMax
);
740 swaps(&rep
.mkMaxSpeed
);
742 swaps(&rep
.axTimeout
);
743 swapl(&rep
.axtCtrlsMask
);
744 swapl(&rep
.axtCtrlsValues
);
745 swaps(&rep
.axtOptsMask
);
746 swaps(&rep
.axtOptsValues
);
747 swaps(&rep
.axOptions
);
749 WriteToClient(client
, SIZEOF(xkbGetControlsReply
), &rep
);
754 ProcXkbSetControls(ClientPtr client
)
756 DeviceIntPtr dev
, tmpd
;
759 XkbControlsRec
new, old
;
760 xkbControlsNotify cn
;
761 XkbEventCauseRec cause
;
762 XkbSrvLedInfoPtr sli
;
764 REQUEST(xkbSetControlsReq
);
765 REQUEST_SIZE_MATCH(xkbSetControlsReq
);
767 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
770 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixManageAccess
);
771 CHK_MASK_LEGAL(0x01, stuff
->changeCtrls
, XkbAllControlsMask
);
773 for (tmpd
= inputInfo
.devices
; tmpd
; tmpd
= tmpd
->next
) {
774 if (!tmpd
->key
|| !tmpd
->key
->xkbInfo
)
777 (!IsMaster(tmpd
) && GetMaster(tmpd
, MASTER_KEYBOARD
) == dev
)) {
778 xkbi
= tmpd
->key
->xkbInfo
;
779 ctrl
= xkbi
->desc
->ctrls
;
781 XkbSetCauseXkbReq(&cause
, X_kbSetControls
, client
);
783 if (stuff
->changeCtrls
& XkbInternalModsMask
) {
784 CHK_MASK_MATCH(0x02, stuff
->affectInternalMods
,
785 stuff
->internalMods
);
786 CHK_MASK_MATCH(0x03, stuff
->affectInternalVMods
,
787 stuff
->internalVMods
);
789 new.internal
.real_mods
&= ~(stuff
->affectInternalMods
);
790 new.internal
.real_mods
|= (stuff
->affectInternalMods
&
791 stuff
->internalMods
);
792 new.internal
.vmods
&= ~(stuff
->affectInternalVMods
);
793 new.internal
.vmods
|= (stuff
->affectInternalVMods
&
794 stuff
->internalVMods
);
795 new.internal
.mask
= new.internal
.real_mods
|
796 XkbMaskForVMask(xkbi
->desc
, new.internal
.vmods
);
799 if (stuff
->changeCtrls
& XkbIgnoreLockModsMask
) {
800 CHK_MASK_MATCH(0x4, stuff
->affectIgnoreLockMods
,
801 stuff
->ignoreLockMods
);
802 CHK_MASK_MATCH(0x5, stuff
->affectIgnoreLockVMods
,
803 stuff
->ignoreLockVMods
);
805 new.ignore_lock
.real_mods
&= ~(stuff
->affectIgnoreLockMods
);
806 new.ignore_lock
.real_mods
|= (stuff
->affectIgnoreLockMods
&
807 stuff
->ignoreLockMods
);
808 new.ignore_lock
.vmods
&= ~(stuff
->affectIgnoreLockVMods
);
809 new.ignore_lock
.vmods
|= (stuff
->affectIgnoreLockVMods
&
810 stuff
->ignoreLockVMods
);
811 new.ignore_lock
.mask
= new.ignore_lock
.real_mods
|
812 XkbMaskForVMask(xkbi
->desc
, new.ignore_lock
.vmods
);
815 CHK_MASK_MATCH(0x06, stuff
->affectEnabledCtrls
,
816 stuff
->enabledCtrls
);
817 if (stuff
->affectEnabledCtrls
) {
818 CHK_MASK_LEGAL(0x07, stuff
->affectEnabledCtrls
,
819 XkbAllBooleanCtrlsMask
);
821 new.enabled_ctrls
&= ~(stuff
->affectEnabledCtrls
);
822 new.enabled_ctrls
|= (stuff
->affectEnabledCtrls
&
823 stuff
->enabledCtrls
);
826 if (stuff
->changeCtrls
& XkbRepeatKeysMask
) {
827 if (stuff
->repeatDelay
< 1 || stuff
->repeatInterval
< 1) {
828 client
->errorValue
= _XkbErrCode3(0x08, stuff
->repeatDelay
,
829 stuff
->repeatInterval
);
833 new.repeat_delay
= stuff
->repeatDelay
;
834 new.repeat_interval
= stuff
->repeatInterval
;
837 if (stuff
->changeCtrls
& XkbSlowKeysMask
) {
838 if (stuff
->slowKeysDelay
< 1) {
839 client
->errorValue
= _XkbErrCode2(0x09,
840 stuff
->slowKeysDelay
);
844 new.slow_keys_delay
= stuff
->slowKeysDelay
;
847 if (stuff
->changeCtrls
& XkbBounceKeysMask
) {
848 if (stuff
->debounceDelay
< 1) {
849 client
->errorValue
= _XkbErrCode2(0x0A,
850 stuff
->debounceDelay
);
854 new.debounce_delay
= stuff
->debounceDelay
;
857 if (stuff
->changeCtrls
& XkbMouseKeysMask
) {
858 if (stuff
->mkDfltBtn
> XkbMaxMouseKeysBtn
) {
859 client
->errorValue
= _XkbErrCode2(0x0B, stuff
->mkDfltBtn
);
863 new.mk_dflt_btn
= stuff
->mkDfltBtn
;
866 if (stuff
->changeCtrls
& XkbMouseKeysAccelMask
) {
867 if (stuff
->mkDelay
< 1 || stuff
->mkInterval
< 1 ||
868 stuff
->mkTimeToMax
< 1 || stuff
->mkMaxSpeed
< 1 ||
869 stuff
->mkCurve
< -1000) {
870 client
->errorValue
= _XkbErrCode2(0x0C, 0);
874 new.mk_delay
= stuff
->mkDelay
;
875 new.mk_interval
= stuff
->mkInterval
;
876 new.mk_time_to_max
= stuff
->mkTimeToMax
;
877 new.mk_max_speed
= stuff
->mkMaxSpeed
;
878 new.mk_curve
= stuff
->mkCurve
;
879 AccessXComputeCurveFactor(xkbi
, &new);
882 if (stuff
->changeCtrls
& XkbGroupsWrapMask
) {
885 act
= XkbOutOfRangeGroupAction(stuff
->groupsWrap
);
887 case XkbRedirectIntoRange
:
888 num
= XkbOutOfRangeGroupNumber(stuff
->groupsWrap
);
889 if (num
>= new.num_groups
) {
890 client
->errorValue
= _XkbErrCode3(0x0D, new.num_groups
,
894 case XkbWrapIntoRange
:
895 case XkbClampIntoRange
:
898 client
->errorValue
= _XkbErrCode2(0x0E, act
);
902 new.groups_wrap
= stuff
->groupsWrap
;
905 CHK_MASK_LEGAL(0x0F, stuff
->axOptions
, XkbAX_AllOptionsMask
);
906 if (stuff
->changeCtrls
& XkbAccessXKeysMask
) {
907 new.ax_options
= stuff
->axOptions
& XkbAX_AllOptionsMask
;
910 if (stuff
->changeCtrls
& XkbStickyKeysMask
) {
911 new.ax_options
&= ~(XkbAX_SKOptionsMask
);
912 new.ax_options
|= (stuff
->axOptions
& XkbAX_SKOptionsMask
);
915 if (stuff
->changeCtrls
& XkbAccessXFeedbackMask
) {
916 new.ax_options
&= ~(XkbAX_FBOptionsMask
);
917 new.ax_options
|= (stuff
->axOptions
& XkbAX_FBOptionsMask
);
921 if (stuff
->changeCtrls
& XkbAccessXTimeoutMask
) {
922 if (stuff
->axTimeout
< 1) {
923 client
->errorValue
= _XkbErrCode2(0x10, stuff
->axTimeout
);
926 CHK_MASK_MATCH(0x11, stuff
->axtCtrlsMask
,
927 stuff
->axtCtrlsValues
);
928 CHK_MASK_LEGAL(0x12, stuff
->axtCtrlsMask
,
929 XkbAllBooleanCtrlsMask
);
930 CHK_MASK_MATCH(0x13, stuff
->axtOptsMask
, stuff
->axtOptsValues
);
931 CHK_MASK_LEGAL(0x14, stuff
->axtOptsMask
, XkbAX_AllOptionsMask
);
932 new.ax_timeout
= stuff
->axTimeout
;
933 new.axt_ctrls_mask
= stuff
->axtCtrlsMask
;
934 new.axt_ctrls_values
= (stuff
->axtCtrlsValues
&
935 stuff
->axtCtrlsMask
);
936 new.axt_opts_mask
= stuff
->axtOptsMask
;
937 new.axt_opts_values
= (stuff
->axtOptsValues
&
941 if (stuff
->changeCtrls
& XkbPerKeyRepeatMask
) {
942 memcpy(new.per_key_repeat
, stuff
->perKeyRepeat
,
943 XkbPerKeyBitArraySize
);
944 if (xkbi
->repeatKey
&&
945 !BitIsOn(new.per_key_repeat
, xkbi
->repeatKey
)) {
946 AccessXCancelRepeatKey(xkbi
, xkbi
->repeatKey
);
952 XkbDDXChangeControls(tmpd
, &old
, ctrl
);
954 if (XkbComputeControlsNotify(tmpd
, &old
, ctrl
, &cn
, FALSE
)) {
957 cn
.requestMajor
= XkbReqCode
;
958 cn
.requestMinor
= X_kbSetControls
;
959 XkbSendControlsNotify(tmpd
, &cn
);
962 sli
= XkbFindSrvLedInfo(tmpd
, XkbDfltXIClass
, XkbDfltXIId
, 0);
964 XkbUpdateIndicators(tmpd
, sli
->usesControls
, TRUE
, NULL
,
967 /* If sticky keys were disabled, clear all locks and latches */
968 if ((old
.enabled_ctrls
& XkbStickyKeysMask
) &&
969 !(ctrl
->enabled_ctrls
& XkbStickyKeysMask
))
970 XkbClearAllLatchesAndLocks(tmpd
, xkbi
, TRUE
, &cause
);
977 /***====================================================================***/
980 XkbSizeKeyTypes(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
986 if (((rep
->present
& XkbKeyTypesMask
) == 0) || (rep
->nTypes
< 1) ||
987 (!xkb
) || (!xkb
->map
) || (!xkb
->map
->types
)) {
988 rep
->present
&= ~XkbKeyTypesMask
;
989 rep
->firstType
= rep
->nTypes
= 0;
992 type
= &xkb
->map
->types
[rep
->firstType
];
993 for (i
= 0; i
< rep
->nTypes
; i
++, type
++) {
994 len
+= SIZEOF(xkbKeyTypeWireDesc
);
995 if (type
->map_count
> 0) {
996 len
+= (type
->map_count
* SIZEOF(xkbKTMapEntryWireDesc
));
998 len
+= (type
->map_count
* SIZEOF(xkbModsWireDesc
));
1005 XkbWriteKeyTypes(XkbDescPtr xkb
,
1006 xkbGetMapReply
* rep
, char *buf
, ClientPtr client
)
1010 xkbKeyTypeWireDesc
*wire
;
1012 type
= &xkb
->map
->types
[rep
->firstType
];
1013 for (i
= 0; i
< rep
->nTypes
; i
++, type
++) {
1014 register unsigned n
;
1016 wire
= (xkbKeyTypeWireDesc
*) buf
;
1017 wire
->mask
= type
->mods
.mask
;
1018 wire
->realMods
= type
->mods
.real_mods
;
1019 wire
->virtualMods
= type
->mods
.vmods
;
1020 wire
->numLevels
= type
->num_levels
;
1021 wire
->nMapEntries
= type
->map_count
;
1022 wire
->preserve
= (type
->preserve
!= NULL
);
1023 if (client
->swapped
) {
1024 swaps(&wire
->virtualMods
);
1027 buf
= (char *) &wire
[1];
1028 if (wire
->nMapEntries
> 0) {
1029 xkbKTMapEntryWireDesc
*ewire
;
1030 XkbKTMapEntryPtr entry
;
1032 ewire
= (xkbKTMapEntryWireDesc
*) buf
;
1034 for (n
= 0; n
< type
->map_count
; n
++, ewire
++, entry
++) {
1035 ewire
->active
= entry
->active
;
1036 ewire
->mask
= entry
->mods
.mask
;
1037 ewire
->level
= entry
->level
;
1038 ewire
->realMods
= entry
->mods
.real_mods
;
1039 ewire
->virtualMods
= entry
->mods
.vmods
;
1040 if (client
->swapped
) {
1041 swaps(&ewire
->virtualMods
);
1044 buf
= (char *) ewire
;
1045 if (type
->preserve
!= NULL
) {
1046 xkbModsWireDesc
*pwire
;
1047 XkbModsPtr preserve
;
1049 pwire
= (xkbModsWireDesc
*) buf
;
1050 preserve
= type
->preserve
;
1051 for (n
= 0; n
< type
->map_count
; n
++, pwire
++, preserve
++) {
1052 pwire
->mask
= preserve
->mask
;
1053 pwire
->realMods
= preserve
->real_mods
;
1054 pwire
->virtualMods
= preserve
->vmods
;
1055 if (client
->swapped
) {
1056 swaps(&pwire
->virtualMods
);
1059 buf
= (char *) pwire
;
1067 XkbSizeKeySyms(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1069 XkbSymMapPtr symMap
;
1071 unsigned nSyms
, nSymsThisKey
;
1073 if (((rep
->present
& XkbKeySymsMask
) == 0) || (rep
->nKeySyms
< 1) ||
1074 (!xkb
) || (!xkb
->map
) || (!xkb
->map
->key_sym_map
)) {
1075 rep
->present
&= ~XkbKeySymsMask
;
1076 rep
->firstKeySym
= rep
->nKeySyms
= 0;
1080 len
= rep
->nKeySyms
* SIZEOF(xkbSymMapWireDesc
);
1081 symMap
= &xkb
->map
->key_sym_map
[rep
->firstKeySym
];
1082 for (i
= nSyms
= 0; i
< rep
->nKeySyms
; i
++, symMap
++) {
1083 if (symMap
->offset
!= 0) {
1084 nSymsThisKey
= XkbNumGroups(symMap
->group_info
) * symMap
->width
;
1085 nSyms
+= nSymsThisKey
;
1089 rep
->totalSyms
= nSyms
;
1094 XkbSizeVirtualMods(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1096 register unsigned i
, nMods
, bit
;
1098 if (((rep
->present
& XkbVirtualModsMask
) == 0) || (rep
->virtualMods
== 0) ||
1099 (!xkb
) || (!xkb
->server
)) {
1100 rep
->present
&= ~XkbVirtualModsMask
;
1101 rep
->virtualMods
= 0;
1104 for (i
= nMods
= 0, bit
= 1; i
< XkbNumVirtualMods
; i
++, bit
<<= 1) {
1105 if (rep
->virtualMods
& bit
)
1108 return XkbPaddedSize(nMods
);
1112 XkbWriteKeySyms(XkbDescPtr xkb
, xkbGetMapReply
* rep
, char *buf
,
1115 register KeySym
*pSym
;
1116 XkbSymMapPtr symMap
;
1117 xkbSymMapWireDesc
*outMap
;
1118 register unsigned i
;
1120 symMap
= &xkb
->map
->key_sym_map
[rep
->firstKeySym
];
1121 for (i
= 0; i
< rep
->nKeySyms
; i
++, symMap
++) {
1122 outMap
= (xkbSymMapWireDesc
*) buf
;
1123 outMap
->ktIndex
[0] = symMap
->kt_index
[0];
1124 outMap
->ktIndex
[1] = symMap
->kt_index
[1];
1125 outMap
->ktIndex
[2] = symMap
->kt_index
[2];
1126 outMap
->ktIndex
[3] = symMap
->kt_index
[3];
1127 outMap
->groupInfo
= symMap
->group_info
;
1128 outMap
->width
= symMap
->width
;
1129 outMap
->nSyms
= symMap
->width
* XkbNumGroups(symMap
->group_info
);
1130 buf
= (char *) &outMap
[1];
1131 if (outMap
->nSyms
== 0)
1134 pSym
= &xkb
->map
->syms
[symMap
->offset
];
1135 memcpy((char *) buf
, (char *) pSym
, outMap
->nSyms
* 4);
1136 if (client
->swapped
) {
1137 register int nSyms
= outMap
->nSyms
;
1139 swaps(&outMap
->nSyms
);
1140 while (nSyms
-- > 0) {
1146 buf
+= outMap
->nSyms
* 4;
1152 XkbSizeKeyActions(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1154 unsigned i
, len
, nActs
;
1155 register KeyCode firstKey
;
1157 if (((rep
->present
& XkbKeyActionsMask
) == 0) || (rep
->nKeyActs
< 1) ||
1158 (!xkb
) || (!xkb
->server
) || (!xkb
->server
->key_acts
)) {
1159 rep
->present
&= ~XkbKeyActionsMask
;
1160 rep
->firstKeyAct
= rep
->nKeyActs
= 0;
1164 firstKey
= rep
->firstKeyAct
;
1165 for (nActs
= i
= 0; i
< rep
->nKeyActs
; i
++) {
1166 if (xkb
->server
->key_acts
[i
+ firstKey
] != 0)
1167 nActs
+= XkbKeyNumActions(xkb
, i
+ firstKey
);
1169 len
= XkbPaddedSize(rep
->nKeyActs
) + (nActs
* SIZEOF(xkbActionWireDesc
));
1170 rep
->totalActs
= nActs
;
1175 XkbWriteKeyActions(XkbDescPtr xkb
, xkbGetMapReply
* rep
, char *buf
,
1180 XkbAnyAction
*actDesc
;
1182 numDesc
= (CARD8
*) buf
;
1183 for (i
= 0; i
< rep
->nKeyActs
; i
++) {
1184 if (xkb
->server
->key_acts
[i
+ rep
->firstKeyAct
] == 0)
1187 numDesc
[i
] = XkbKeyNumActions(xkb
, (i
+ rep
->firstKeyAct
));
1189 buf
+= XkbPaddedSize(rep
->nKeyActs
);
1191 actDesc
= (XkbAnyAction
*) buf
;
1192 for (i
= 0; i
< rep
->nKeyActs
; i
++) {
1193 if (xkb
->server
->key_acts
[i
+ rep
->firstKeyAct
] != 0) {
1196 num
= XkbKeyNumActions(xkb
, (i
+ rep
->firstKeyAct
));
1197 memcpy((char *) actDesc
,
1198 (char *) XkbKeyActionsPtr(xkb
, (i
+ rep
->firstKeyAct
)),
1199 num
* SIZEOF(xkbActionWireDesc
));
1203 buf
= (char *) actDesc
;
1208 XkbSizeKeyBehaviors(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1210 unsigned i
, len
, nBhvr
;
1213 if (((rep
->present
& XkbKeyBehaviorsMask
) == 0) || (rep
->nKeyBehaviors
< 1)
1214 || (!xkb
) || (!xkb
->server
) || (!xkb
->server
->behaviors
)) {
1215 rep
->present
&= ~XkbKeyBehaviorsMask
;
1216 rep
->firstKeyBehavior
= rep
->nKeyBehaviors
= 0;
1217 rep
->totalKeyBehaviors
= 0;
1220 bhv
= &xkb
->server
->behaviors
[rep
->firstKeyBehavior
];
1221 for (nBhvr
= i
= 0; i
< rep
->nKeyBehaviors
; i
++, bhv
++) {
1222 if (bhv
->type
!= XkbKB_Default
)
1225 len
= nBhvr
* SIZEOF(xkbBehaviorWireDesc
);
1226 rep
->totalKeyBehaviors
= nBhvr
;
1231 XkbWriteKeyBehaviors(XkbDescPtr xkb
, xkbGetMapReply
* rep
, char *buf
,
1235 xkbBehaviorWireDesc
*wire
;
1238 wire
= (xkbBehaviorWireDesc
*) buf
;
1239 pBhvr
= &xkb
->server
->behaviors
[rep
->firstKeyBehavior
];
1240 for (i
= 0; i
< rep
->nKeyBehaviors
; i
++, pBhvr
++) {
1241 if (pBhvr
->type
!= XkbKB_Default
) {
1242 wire
->key
= i
+ rep
->firstKeyBehavior
;
1243 wire
->type
= pBhvr
->type
;
1244 wire
->data
= pBhvr
->data
;
1248 buf
= (char *) wire
;
1253 XkbSizeExplicit(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1255 unsigned i
, len
, nRtrn
;
1257 if (((rep
->present
& XkbExplicitComponentsMask
) == 0) ||
1258 (rep
->nKeyExplicit
< 1) || (!xkb
) || (!xkb
->server
) ||
1259 (!xkb
->server
->explicit)) {
1260 rep
->present
&= ~XkbExplicitComponentsMask
;
1261 rep
->firstKeyExplicit
= rep
->nKeyExplicit
= 0;
1262 rep
->totalKeyExplicit
= 0;
1265 for (nRtrn
= i
= 0; i
< rep
->nKeyExplicit
; i
++) {
1266 if (xkb
->server
->explicit[i
+ rep
->firstKeyExplicit
] != 0)
1269 rep
->totalKeyExplicit
= nRtrn
;
1270 len
= XkbPaddedSize(nRtrn
* 2); /* two bytes per non-zero explicit component */
1275 XkbWriteExplicit(XkbDescPtr xkb
, xkbGetMapReply
* rep
, char *buf
,
1280 unsigned char *pExp
;
1283 pExp
= &xkb
->server
->explicit[rep
->firstKeyExplicit
];
1284 for (i
= 0; i
< rep
->nKeyExplicit
; i
++, pExp
++) {
1286 *buf
++ = i
+ rep
->firstKeyExplicit
;
1290 i
= XkbPaddedSize(buf
- start
) - (buf
- start
); /* pad to word boundary */
1295 XkbSizeModifierMap(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1297 unsigned i
, len
, nRtrn
;
1299 if (((rep
->present
& XkbModifierMapMask
) == 0) || (rep
->nModMapKeys
< 1) ||
1300 (!xkb
) || (!xkb
->map
) || (!xkb
->map
->modmap
)) {
1301 rep
->present
&= ~XkbModifierMapMask
;
1302 rep
->firstModMapKey
= rep
->nModMapKeys
= 0;
1303 rep
->totalModMapKeys
= 0;
1306 for (nRtrn
= i
= 0; i
< rep
->nModMapKeys
; i
++) {
1307 if (xkb
->map
->modmap
[i
+ rep
->firstModMapKey
] != 0)
1310 rep
->totalModMapKeys
= nRtrn
;
1311 len
= XkbPaddedSize(nRtrn
* 2); /* two bytes per non-zero modmap component */
1316 XkbWriteModifierMap(XkbDescPtr xkb
, xkbGetMapReply
* rep
, char *buf
,
1321 unsigned char *pMap
;
1324 pMap
= &xkb
->map
->modmap
[rep
->firstModMapKey
];
1325 for (i
= 0; i
< rep
->nModMapKeys
; i
++, pMap
++) {
1327 *buf
++ = i
+ rep
->firstModMapKey
;
1331 i
= XkbPaddedSize(buf
- start
) - (buf
- start
); /* pad to word boundary */
1336 XkbSizeVirtualModMap(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1338 unsigned i
, len
, nRtrn
;
1340 if (((rep
->present
& XkbVirtualModMapMask
) == 0) || (rep
->nVModMapKeys
< 1)
1341 || (!xkb
) || (!xkb
->server
) || (!xkb
->server
->vmodmap
)) {
1342 rep
->present
&= ~XkbVirtualModMapMask
;
1343 rep
->firstVModMapKey
= rep
->nVModMapKeys
= 0;
1344 rep
->totalVModMapKeys
= 0;
1347 for (nRtrn
= i
= 0; i
< rep
->nVModMapKeys
; i
++) {
1348 if (xkb
->server
->vmodmap
[i
+ rep
->firstVModMapKey
] != 0)
1351 rep
->totalVModMapKeys
= nRtrn
;
1352 len
= nRtrn
* SIZEOF(xkbVModMapWireDesc
);
1357 XkbWriteVirtualModMap(XkbDescPtr xkb
, xkbGetMapReply
* rep
, char *buf
,
1361 xkbVModMapWireDesc
*wire
;
1362 unsigned short *pMap
;
1364 wire
= (xkbVModMapWireDesc
*) buf
;
1365 pMap
= &xkb
->server
->vmodmap
[rep
->firstVModMapKey
];
1366 for (i
= 0; i
< rep
->nVModMapKeys
; i
++, pMap
++) {
1368 wire
->key
= i
+ rep
->firstVModMapKey
;
1369 wire
->vmods
= *pMap
;
1373 return (char *) wire
;
1377 XkbComputeGetMapReplySize(XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1381 rep
->minKeyCode
= xkb
->min_key_code
;
1382 rep
->maxKeyCode
= xkb
->max_key_code
;
1383 len
= XkbSizeKeyTypes(xkb
, rep
);
1384 len
+= XkbSizeKeySyms(xkb
, rep
);
1385 len
+= XkbSizeKeyActions(xkb
, rep
);
1386 len
+= XkbSizeKeyBehaviors(xkb
, rep
);
1387 len
+= XkbSizeVirtualMods(xkb
, rep
);
1388 len
+= XkbSizeExplicit(xkb
, rep
);
1389 len
+= XkbSizeModifierMap(xkb
, rep
);
1390 len
+= XkbSizeVirtualModMap(xkb
, rep
);
1391 rep
->length
+= (len
/ 4);
1396 XkbSendMap(ClientPtr client
, XkbDescPtr xkb
, xkbGetMapReply
* rep
)
1401 len
= (rep
->length
* 4) - (SIZEOF(xkbGetMapReply
) - SIZEOF(xGenericReply
));
1402 start
= desc
= calloc(1, len
);
1405 if (rep
->nTypes
> 0)
1406 desc
= XkbWriteKeyTypes(xkb
, rep
, desc
, client
);
1407 if (rep
->nKeySyms
> 0)
1408 desc
= XkbWriteKeySyms(xkb
, rep
, desc
, client
);
1409 if (rep
->nKeyActs
> 0)
1410 desc
= XkbWriteKeyActions(xkb
, rep
, desc
, client
);
1411 if (rep
->totalKeyBehaviors
> 0)
1412 desc
= XkbWriteKeyBehaviors(xkb
, rep
, desc
, client
);
1413 if (rep
->virtualMods
) {
1414 register int sz
, bit
;
1416 for (i
= sz
= 0, bit
= 1; i
< XkbNumVirtualMods
; i
++, bit
<<= 1) {
1417 if (rep
->virtualMods
& bit
) {
1418 desc
[sz
++] = xkb
->server
->vmods
[i
];
1421 desc
+= XkbPaddedSize(sz
);
1423 if (rep
->totalKeyExplicit
> 0)
1424 desc
= XkbWriteExplicit(xkb
, rep
, desc
, client
);
1425 if (rep
->totalModMapKeys
> 0)
1426 desc
= XkbWriteModifierMap(xkb
, rep
, desc
, client
);
1427 if (rep
->totalVModMapKeys
> 0)
1428 desc
= XkbWriteVirtualModMap(xkb
, rep
, desc
, client
);
1429 if ((desc
- start
) != (len
)) {
1431 ("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n",
1432 len
, (unsigned long) (desc
- start
));
1434 if (client
->swapped
) {
1435 swaps(&rep
->sequenceNumber
);
1436 swapl(&rep
->length
);
1437 swaps(&rep
->present
);
1438 swaps(&rep
->totalSyms
);
1439 swaps(&rep
->totalActs
);
1441 WriteToClient(client
, (i
= SIZEOF(xkbGetMapReply
)), rep
);
1442 WriteToClient(client
, len
, start
);
1443 free((char *) start
);
1448 ProcXkbGetMap(ClientPtr client
)
1455 REQUEST(xkbGetMapReq
);
1456 REQUEST_SIZE_MATCH(xkbGetMapReq
);
1458 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
1461 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
1462 CHK_MASK_OVERLAP(0x01, stuff
->full
, stuff
->partial
);
1463 CHK_MASK_LEGAL(0x02, stuff
->full
, XkbAllMapComponentsMask
);
1464 CHK_MASK_LEGAL(0x03, stuff
->partial
, XkbAllMapComponentsMask
);
1466 xkb
= dev
->key
->xkbInfo
->desc
;
1467 rep
= (xkbGetMapReply
) {
1469 .deviceID
= dev
->id
,
1470 .sequenceNumber
= client
->sequence
,
1471 .length
= (SIZEOF(xkbGetMapReply
) - SIZEOF(xGenericReply
)) >> 2,
1472 .present
= stuff
->partial
| stuff
->full
,
1473 .minKeyCode
= xkb
->min_key_code
,
1474 .maxKeyCode
= xkb
->max_key_code
1477 if (stuff
->full
& XkbKeyTypesMask
) {
1479 rep
.nTypes
= xkb
->map
->num_types
;
1481 else if (stuff
->partial
& XkbKeyTypesMask
) {
1482 if (((unsigned) stuff
->firstType
+ stuff
->nTypes
) > xkb
->map
->num_types
) {
1483 client
->errorValue
= _XkbErrCode4(0x04, xkb
->map
->num_types
,
1484 stuff
->firstType
, stuff
->nTypes
);
1487 rep
.firstType
= stuff
->firstType
;
1488 rep
.nTypes
= stuff
->nTypes
;
1492 rep
.totalTypes
= xkb
->map
->num_types
;
1494 n
= XkbNumKeys(xkb
);
1495 if (stuff
->full
& XkbKeySymsMask
) {
1496 rep
.firstKeySym
= xkb
->min_key_code
;
1499 else if (stuff
->partial
& XkbKeySymsMask
) {
1500 CHK_KEY_RANGE(0x05, stuff
->firstKeySym
, stuff
->nKeySyms
, xkb
);
1501 rep
.firstKeySym
= stuff
->firstKeySym
;
1502 rep
.nKeySyms
= stuff
->nKeySyms
;
1508 if (stuff
->full
& XkbKeyActionsMask
) {
1509 rep
.firstKeyAct
= xkb
->min_key_code
;
1512 else if (stuff
->partial
& XkbKeyActionsMask
) {
1513 CHK_KEY_RANGE(0x07, stuff
->firstKeyAct
, stuff
->nKeyActs
, xkb
);
1514 rep
.firstKeyAct
= stuff
->firstKeyAct
;
1515 rep
.nKeyActs
= stuff
->nKeyActs
;
1521 if (stuff
->full
& XkbKeyBehaviorsMask
) {
1522 rep
.firstKeyBehavior
= xkb
->min_key_code
;
1523 rep
.nKeyBehaviors
= n
;
1525 else if (stuff
->partial
& XkbKeyBehaviorsMask
) {
1526 CHK_KEY_RANGE(0x09, stuff
->firstKeyBehavior
, stuff
->nKeyBehaviors
, xkb
);
1527 rep
.firstKeyBehavior
= stuff
->firstKeyBehavior
;
1528 rep
.nKeyBehaviors
= stuff
->nKeyBehaviors
;
1531 rep
.nKeyBehaviors
= 0;
1532 rep
.totalKeyBehaviors
= 0;
1534 if (stuff
->full
& XkbVirtualModsMask
)
1535 rep
.virtualMods
= ~0;
1536 else if (stuff
->partial
& XkbVirtualModsMask
)
1537 rep
.virtualMods
= stuff
->virtualMods
;
1539 if (stuff
->full
& XkbExplicitComponentsMask
) {
1540 rep
.firstKeyExplicit
= xkb
->min_key_code
;
1541 rep
.nKeyExplicit
= n
;
1543 else if (stuff
->partial
& XkbExplicitComponentsMask
) {
1544 CHK_KEY_RANGE(0x0B, stuff
->firstKeyExplicit
, stuff
->nKeyExplicit
, xkb
);
1545 rep
.firstKeyExplicit
= stuff
->firstKeyExplicit
;
1546 rep
.nKeyExplicit
= stuff
->nKeyExplicit
;
1549 rep
.nKeyExplicit
= 0;
1550 rep
.totalKeyExplicit
= 0;
1552 if (stuff
->full
& XkbModifierMapMask
) {
1553 rep
.firstModMapKey
= xkb
->min_key_code
;
1554 rep
.nModMapKeys
= n
;
1556 else if (stuff
->partial
& XkbModifierMapMask
) {
1557 CHK_KEY_RANGE(0x0D, stuff
->firstModMapKey
, stuff
->nModMapKeys
, xkb
);
1558 rep
.firstModMapKey
= stuff
->firstModMapKey
;
1559 rep
.nModMapKeys
= stuff
->nModMapKeys
;
1562 rep
.nModMapKeys
= 0;
1563 rep
.totalModMapKeys
= 0;
1565 if (stuff
->full
& XkbVirtualModMapMask
) {
1566 rep
.firstVModMapKey
= xkb
->min_key_code
;
1567 rep
.nVModMapKeys
= n
;
1569 else if (stuff
->partial
& XkbVirtualModMapMask
) {
1570 CHK_KEY_RANGE(0x0F, stuff
->firstVModMapKey
, stuff
->nVModMapKeys
, xkb
);
1571 rep
.firstVModMapKey
= stuff
->firstVModMapKey
;
1572 rep
.nVModMapKeys
= stuff
->nVModMapKeys
;
1575 rep
.nVModMapKeys
= 0;
1576 rep
.totalVModMapKeys
= 0;
1578 if ((status
= XkbComputeGetMapReplySize(xkb
, &rep
)) != Success
)
1580 return XkbSendMap(client
, xkb
, &rep
);
1583 /***====================================================================***/
1586 CheckKeyTypes(ClientPtr client
,
1589 xkbKeyTypeWireDesc
** wireRtrn
,
1590 int *nMapsRtrn
, CARD8
*mapWidthRtrn
)
1593 register unsigned i
, n
;
1594 register CARD8
*map
;
1595 register xkbKeyTypeWireDesc
*wire
= *wireRtrn
;
1597 if (req
->firstType
> ((unsigned) xkb
->map
->num_types
)) {
1598 *nMapsRtrn
= _XkbErrCode3(0x01, req
->firstType
, xkb
->map
->num_types
);
1601 if (req
->flags
& XkbSetMapResizeTypes
) {
1602 nMaps
= req
->firstType
+ req
->nTypes
;
1603 if (nMaps
< XkbNumRequiredTypes
) { /* canonical types must be there */
1604 *nMapsRtrn
= _XkbErrCode4(0x02, req
->firstType
, req
->nTypes
, 4);
1608 else if (req
->present
& XkbKeyTypesMask
) {
1609 nMaps
= xkb
->map
->num_types
;
1610 if ((req
->firstType
+ req
->nTypes
) > nMaps
) {
1611 *nMapsRtrn
= req
->firstType
+ req
->nTypes
;
1616 *nMapsRtrn
= xkb
->map
->num_types
;
1617 for (i
= 0; i
< xkb
->map
->num_types
; i
++) {
1618 mapWidthRtrn
[i
] = xkb
->map
->types
[i
].num_levels
;
1623 for (i
= 0; i
< req
->firstType
; i
++) {
1624 mapWidthRtrn
[i
] = xkb
->map
->types
[i
].num_levels
;
1626 for (i
= 0; i
< req
->nTypes
; i
++) {
1629 if (client
->swapped
) {
1630 swaps(&wire
->virtualMods
);
1632 n
= i
+ req
->firstType
;
1633 width
= wire
->numLevels
;
1635 *nMapsRtrn
= _XkbErrCode3(0x04, n
, width
);
1638 else if ((n
== XkbOneLevelIndex
) && (width
!= 1)) { /* must be width 1 */
1639 *nMapsRtrn
= _XkbErrCode3(0x05, n
, width
);
1642 else if ((width
!= 2) &&
1643 ((n
== XkbTwoLevelIndex
) || (n
== XkbKeypadIndex
) ||
1644 (n
== XkbAlphabeticIndex
))) {
1645 /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
1646 *nMapsRtrn
= _XkbErrCode3(0x05, n
, width
);
1649 if (wire
->nMapEntries
> 0) {
1650 xkbKTSetMapEntryWireDesc
*mapWire
;
1651 xkbModsWireDesc
*preWire
;
1653 mapWire
= (xkbKTSetMapEntryWireDesc
*) &wire
[1];
1654 preWire
= (xkbModsWireDesc
*) &mapWire
[wire
->nMapEntries
];
1655 for (n
= 0; n
< wire
->nMapEntries
; n
++) {
1656 if (client
->swapped
) {
1657 swaps(&mapWire
[n
].virtualMods
);
1659 if (mapWire
[n
].realMods
& (~wire
->realMods
)) {
1660 *nMapsRtrn
= _XkbErrCode4(0x06, n
, mapWire
[n
].realMods
,
1664 if (mapWire
[n
].virtualMods
& (~wire
->virtualMods
)) {
1665 *nMapsRtrn
= _XkbErrCode3(0x07, n
, mapWire
[n
].virtualMods
);
1668 if (mapWire
[n
].level
>= wire
->numLevels
) {
1669 *nMapsRtrn
= _XkbErrCode4(0x08, n
, wire
->numLevels
,
1673 if (wire
->preserve
) {
1674 if (client
->swapped
) {
1675 swaps(&preWire
[n
].virtualMods
);
1677 if (preWire
[n
].realMods
& (~mapWire
[n
].realMods
)) {
1678 *nMapsRtrn
= _XkbErrCode4(0x09, n
, preWire
[n
].realMods
,
1679 mapWire
[n
].realMods
);
1682 if (preWire
[n
].virtualMods
& (~mapWire
[n
].virtualMods
)) {
1684 _XkbErrCode3(0x0a, n
, preWire
[n
].virtualMods
);
1690 map
= (CARD8
*) &preWire
[wire
->nMapEntries
];
1692 map
= (CARD8
*) &mapWire
[wire
->nMapEntries
];
1695 map
= (CARD8
*) &wire
[1];
1696 mapWidthRtrn
[i
+ req
->firstType
] = wire
->numLevels
;
1697 wire
= (xkbKeyTypeWireDesc
*) map
;
1699 for (i
= req
->firstType
+ req
->nTypes
; i
< nMaps
; i
++) {
1700 mapWidthRtrn
[i
] = xkb
->map
->types
[i
].num_levels
;
1708 CheckKeySyms(ClientPtr client
,
1713 CARD16
*symsPerKey
, xkbSymMapWireDesc
** wireRtrn
, int *errorRtrn
)
1715 register unsigned i
;
1717 xkbSymMapWireDesc
*wire
= *wireRtrn
;
1719 if (!(XkbKeySymsMask
& req
->present
))
1721 CHK_REQ_KEY_RANGE2(0x11, req
->firstKeySym
, req
->nKeySyms
, req
, (*errorRtrn
),
1723 for (i
= 0; i
< req
->nKeySyms
; i
++) {
1725 register unsigned nG
;
1727 if (client
->swapped
) {
1728 swaps(&wire
->nSyms
);
1730 nG
= XkbNumGroups(wire
->groupInfo
);
1731 if (nG
> XkbNumKbdGroups
) {
1732 *errorRtrn
= _XkbErrCode3(0x14, i
+ req
->firstKeySym
, nG
);
1738 for (g
= w
= 0; g
< nG
; g
++) {
1739 if (wire
->ktIndex
[g
] >= (unsigned) nTypes
) {
1740 *errorRtrn
= _XkbErrCode4(0x15, i
+ req
->firstKeySym
, g
,
1744 if (mapWidths
[wire
->ktIndex
[g
]] > w
)
1745 w
= mapWidths
[wire
->ktIndex
[g
]];
1747 if (wire
->width
!= w
) {
1749 _XkbErrCode3(0x16, i
+ req
->firstKeySym
, wire
->width
);
1753 symsPerKey
[i
+ req
->firstKeySym
] = w
;
1754 if (w
!= wire
->nSyms
) {
1756 _XkbErrCode4(0x16, i
+ req
->firstKeySym
, wire
->nSyms
, w
);
1760 else if (wire
->nSyms
!= 0) {
1761 *errorRtrn
= _XkbErrCode3(0x17, i
+ req
->firstKeySym
, wire
->nSyms
);
1764 pSyms
= (KeySym
*) &wire
[1];
1765 wire
= (xkbSymMapWireDesc
*) &pSyms
[wire
->nSyms
];
1768 map
= &xkb
->map
->key_sym_map
[i
];
1769 for (; i
<= (unsigned) xkb
->max_key_code
; i
++, map
++) {
1770 register int g
, nG
, w
;
1772 nG
= XkbKeyNumGroups(xkb
, i
);
1773 for (w
= g
= 0; g
< nG
; g
++) {
1774 if (map
->kt_index
[g
] >= (unsigned) nTypes
) {
1775 *errorRtrn
= _XkbErrCode4(0x18, i
, g
, map
->kt_index
[g
]);
1778 if (mapWidths
[map
->kt_index
[g
]] > w
)
1779 w
= mapWidths
[map
->kt_index
[g
]];
1781 symsPerKey
[i
] = w
* nG
;
1788 CheckKeyActions(XkbDescPtr xkb
,
1792 CARD16
*symsPerKey
, CARD8
**wireRtrn
, int *nActsRtrn
)
1795 CARD8
*wire
= *wireRtrn
;
1796 register unsigned i
;
1798 if (!(XkbKeyActionsMask
& req
->present
))
1800 CHK_REQ_KEY_RANGE2(0x21, req
->firstKeyAct
, req
->nKeyActs
, req
, (*nActsRtrn
),
1802 for (nActs
= i
= 0; i
< req
->nKeyActs
; i
++) {
1804 if (wire
[0] == symsPerKey
[i
+ req
->firstKeyAct
])
1807 *nActsRtrn
= _XkbErrCode3(0x23, i
+ req
->firstKeyAct
, wire
[0]);
1813 if (req
->nKeyActs
% 4)
1814 wire
+= 4 - (req
->nKeyActs
% 4);
1815 *wireRtrn
= (CARD8
*) (((XkbAnyAction
*) wire
) + nActs
);
1821 CheckKeyBehaviors(XkbDescPtr xkb
,
1823 xkbBehaviorWireDesc
** wireRtrn
, int *errorRtrn
)
1825 register xkbBehaviorWireDesc
*wire
= *wireRtrn
;
1826 register XkbServerMapPtr server
= xkb
->server
;
1827 register unsigned i
;
1828 unsigned first
, last
;
1830 if (((req
->present
& XkbKeyBehaviorsMask
) == 0) || (req
->nKeyBehaviors
< 1)) {
1831 req
->present
&= ~XkbKeyBehaviorsMask
;
1832 req
->nKeyBehaviors
= 0;
1835 first
= req
->firstKeyBehavior
;
1836 last
= req
->firstKeyBehavior
+ req
->nKeyBehaviors
- 1;
1837 if (first
< req
->minKeyCode
) {
1838 *errorRtrn
= _XkbErrCode3(0x31, first
, req
->minKeyCode
);
1841 if (last
> req
->maxKeyCode
) {
1842 *errorRtrn
= _XkbErrCode3(0x32, last
, req
->maxKeyCode
);
1846 for (i
= 0; i
< req
->totalKeyBehaviors
; i
++, wire
++) {
1847 if ((wire
->key
< first
) || (wire
->key
> last
)) {
1848 *errorRtrn
= _XkbErrCode4(0x33, first
, last
, wire
->key
);
1851 if ((wire
->type
& XkbKB_Permanent
) &&
1852 ((server
->behaviors
[wire
->key
].type
!= wire
->type
) ||
1853 (server
->behaviors
[wire
->key
].data
!= wire
->data
))) {
1854 *errorRtrn
= _XkbErrCode3(0x33, wire
->key
, wire
->type
);
1857 if ((wire
->type
== XkbKB_RadioGroup
) &&
1858 ((wire
->data
& (~XkbKB_RGAllowNone
)) > XkbMaxRadioGroups
)) {
1859 *errorRtrn
= _XkbErrCode4(0x34, wire
->key
, wire
->data
,
1863 if ((wire
->type
== XkbKB_Overlay1
) || (wire
->type
== XkbKB_Overlay2
)) {
1864 CHK_KEY_RANGE2(0x35, wire
->key
, 1, xkb
, *errorRtrn
, 0);
1872 CheckVirtualMods(XkbDescRec
* xkb
,
1873 xkbSetMapReq
* req
, CARD8
**wireRtrn
, int *errorRtrn
)
1875 register CARD8
*wire
= *wireRtrn
;
1876 register unsigned i
, nMods
, bit
;
1878 if (((req
->present
& XkbVirtualModsMask
) == 0) || (req
->virtualMods
== 0))
1880 for (i
= nMods
= 0, bit
= 1; i
< XkbNumVirtualMods
; i
++, bit
<<= 1) {
1881 if (req
->virtualMods
& bit
)
1884 *wireRtrn
= (wire
+ XkbPaddedSize(nMods
));
1889 CheckKeyExplicit(XkbDescPtr xkb
,
1890 xkbSetMapReq
* req
, CARD8
**wireRtrn
, int *errorRtrn
)
1892 register CARD8
*wire
= *wireRtrn
;
1894 register unsigned i
;
1897 if (((req
->present
& XkbExplicitComponentsMask
) == 0) ||
1898 (req
->nKeyExplicit
< 1)) {
1899 req
->present
&= ~XkbExplicitComponentsMask
;
1900 req
->nKeyExplicit
= 0;
1903 first
= req
->firstKeyExplicit
;
1904 last
= first
+ req
->nKeyExplicit
- 1;
1905 if (first
< req
->minKeyCode
) {
1906 *errorRtrn
= _XkbErrCode3(0x51, first
, req
->minKeyCode
);
1909 if (last
> req
->maxKeyCode
) {
1910 *errorRtrn
= _XkbErrCode3(0x52, last
, req
->maxKeyCode
);
1914 for (i
= 0; i
< req
->totalKeyExplicit
; i
++, wire
+= 2) {
1915 if ((wire
[0] < first
) || (wire
[0] > last
)) {
1916 *errorRtrn
= _XkbErrCode4(0x53, first
, last
, wire
[0]);
1919 if (wire
[1] & (~XkbAllExplicitMask
)) {
1920 *errorRtrn
= _XkbErrCode3(0x52, ~XkbAllExplicitMask
, wire
[1]);
1924 wire
+= XkbPaddedSize(wire
- start
) - (wire
- start
);
1930 CheckModifierMap(XkbDescPtr xkb
, xkbSetMapReq
* req
, CARD8
**wireRtrn
,
1933 register CARD8
*wire
= *wireRtrn
;
1935 register unsigned i
;
1938 if (((req
->present
& XkbModifierMapMask
) == 0) || (req
->nModMapKeys
< 1)) {
1939 req
->present
&= ~XkbModifierMapMask
;
1940 req
->nModMapKeys
= 0;
1943 first
= req
->firstModMapKey
;
1944 last
= first
+ req
->nModMapKeys
- 1;
1945 if (first
< req
->minKeyCode
) {
1946 *errRtrn
= _XkbErrCode3(0x61, first
, req
->minKeyCode
);
1949 if (last
> req
->maxKeyCode
) {
1950 *errRtrn
= _XkbErrCode3(0x62, last
, req
->maxKeyCode
);
1954 for (i
= 0; i
< req
->totalModMapKeys
; i
++, wire
+= 2) {
1955 if ((wire
[0] < first
) || (wire
[0] > last
)) {
1956 *errRtrn
= _XkbErrCode4(0x63, first
, last
, wire
[0]);
1960 wire
+= XkbPaddedSize(wire
- start
) - (wire
- start
);
1966 CheckVirtualModMap(XkbDescPtr xkb
,
1968 xkbVModMapWireDesc
** wireRtrn
, int *errRtrn
)
1970 register xkbVModMapWireDesc
*wire
= *wireRtrn
;
1971 register unsigned i
;
1974 if (((req
->present
& XkbVirtualModMapMask
) == 0) || (req
->nVModMapKeys
< 1)) {
1975 req
->present
&= ~XkbVirtualModMapMask
;
1976 req
->nVModMapKeys
= 0;
1979 first
= req
->firstVModMapKey
;
1980 last
= first
+ req
->nVModMapKeys
- 1;
1981 if (first
< req
->minKeyCode
) {
1982 *errRtrn
= _XkbErrCode3(0x71, first
, req
->minKeyCode
);
1985 if (last
> req
->maxKeyCode
) {
1986 *errRtrn
= _XkbErrCode3(0x72, last
, req
->maxKeyCode
);
1989 for (i
= 0; i
< req
->totalVModMapKeys
; i
++, wire
++) {
1990 if ((wire
->key
< first
) || (wire
->key
> last
)) {
1991 *errRtrn
= _XkbErrCode4(0x73, first
, last
, wire
->key
);
2000 SetKeyTypes(XkbDescPtr xkb
,
2002 xkbKeyTypeWireDesc
* wire
, XkbChangesPtr changes
)
2004 register unsigned i
;
2005 unsigned first
, last
;
2008 if ((unsigned) (req
->firstType
+ req
->nTypes
) > xkb
->map
->size_types
) {
2009 i
= req
->firstType
+ req
->nTypes
;
2010 if (XkbAllocClientMap(xkb
, XkbKeyTypesMask
, i
) != Success
) {
2014 if ((unsigned) (req
->firstType
+ req
->nTypes
) > xkb
->map
->num_types
)
2015 xkb
->map
->num_types
= req
->firstType
+ req
->nTypes
;
2017 for (i
= 0; i
< req
->nTypes
; i
++) {
2019 register unsigned n
;
2021 if (XkbResizeKeyType(xkb
, i
+ req
->firstType
, wire
->nMapEntries
,
2022 wire
->preserve
, wire
->numLevels
) != Success
) {
2025 pOld
= &xkb
->map
->types
[i
+ req
->firstType
];
2026 map
= (CARD8
*) &wire
[1];
2028 pOld
->mods
.real_mods
= wire
->realMods
;
2029 pOld
->mods
.vmods
= wire
->virtualMods
;
2030 pOld
->num_levels
= wire
->numLevels
;
2031 pOld
->map_count
= wire
->nMapEntries
;
2033 pOld
->mods
.mask
= pOld
->mods
.real_mods
|
2034 XkbMaskForVMask(xkb
, pOld
->mods
.vmods
);
2036 if (wire
->nMapEntries
) {
2037 xkbKTSetMapEntryWireDesc
*mapWire
;
2038 xkbModsWireDesc
*preWire
;
2041 mapWire
= (xkbKTSetMapEntryWireDesc
*) map
;
2042 preWire
= (xkbModsWireDesc
*) &mapWire
[wire
->nMapEntries
];
2043 for (n
= 0; n
< wire
->nMapEntries
; n
++) {
2044 pOld
->map
[n
].active
= 1;
2045 pOld
->map
[n
].mods
.mask
= mapWire
[n
].realMods
;
2046 pOld
->map
[n
].mods
.real_mods
= mapWire
[n
].realMods
;
2047 pOld
->map
[n
].mods
.vmods
= mapWire
[n
].virtualMods
;
2048 pOld
->map
[n
].level
= mapWire
[n
].level
;
2049 if (mapWire
[n
].virtualMods
!= 0) {
2050 tmp
= XkbMaskForVMask(xkb
, mapWire
[n
].virtualMods
);
2051 pOld
->map
[n
].active
= (tmp
!= 0);
2052 pOld
->map
[n
].mods
.mask
|= tmp
;
2054 if (wire
->preserve
) {
2055 pOld
->preserve
[n
].real_mods
= preWire
[n
].realMods
;
2056 pOld
->preserve
[n
].vmods
= preWire
[n
].virtualMods
;
2057 tmp
= XkbMaskForVMask(xkb
, preWire
[n
].virtualMods
);
2058 pOld
->preserve
[n
].mask
= preWire
[n
].realMods
| tmp
;
2062 map
= (CARD8
*) &preWire
[wire
->nMapEntries
];
2064 map
= (CARD8
*) &mapWire
[wire
->nMapEntries
];
2067 map
= (CARD8
*) &wire
[1];
2068 wire
= (xkbKeyTypeWireDesc
*) map
;
2070 first
= req
->firstType
;
2071 last
= first
+ req
->nTypes
- 1; /* last changed type */
2072 if (changes
->map
.changed
& XkbKeyTypesMask
) {
2075 oldLast
= changes
->map
.first_type
+ changes
->map
.num_types
- 1;
2076 if (changes
->map
.first_type
< first
)
2077 first
= changes
->map
.first_type
;
2081 changes
->map
.changed
|= XkbKeyTypesMask
;
2082 changes
->map
.first_type
= first
;
2083 changes
->map
.num_types
= (last
- first
) + 1;
2084 return (char *) wire
;
2088 SetKeySyms(ClientPtr client
,
2091 xkbSymMapWireDesc
* wire
, XkbChangesPtr changes
, DeviceIntPtr dev
)
2093 register unsigned i
, s
;
2094 XkbSymMapPtr oldMap
;
2097 unsigned first
, last
;
2099 oldMap
= &xkb
->map
->key_sym_map
[req
->firstKeySym
];
2100 for (i
= 0; i
< req
->nKeySyms
; i
++, oldMap
++) {
2101 pSyms
= (KeySym
*) &wire
[1];
2102 if (wire
->nSyms
> 0) {
2103 newSyms
= XkbResizeKeySyms(xkb
, i
+ req
->firstKeySym
, wire
->nSyms
);
2104 for (s
= 0; s
< wire
->nSyms
; s
++) {
2105 newSyms
[s
] = pSyms
[s
];
2107 if (client
->swapped
) {
2108 for (s
= 0; s
< wire
->nSyms
; s
++) {
2113 oldMap
->kt_index
[0] = wire
->ktIndex
[0];
2114 oldMap
->kt_index
[1] = wire
->ktIndex
[1];
2115 oldMap
->kt_index
[2] = wire
->ktIndex
[2];
2116 oldMap
->kt_index
[3] = wire
->ktIndex
[3];
2117 oldMap
->group_info
= wire
->groupInfo
;
2118 oldMap
->width
= wire
->width
;
2119 wire
= (xkbSymMapWireDesc
*) &pSyms
[wire
->nSyms
];
2121 first
= req
->firstKeySym
;
2122 last
= first
+ req
->nKeySyms
- 1;
2123 if (changes
->map
.changed
& XkbKeySymsMask
) {
2125 (changes
->map
.first_key_sym
+ changes
->map
.num_key_syms
- 1);
2126 if (changes
->map
.first_key_sym
< first
)
2127 first
= changes
->map
.first_key_sym
;
2131 changes
->map
.changed
|= XkbKeySymsMask
;
2132 changes
->map
.first_key_sym
= first
;
2133 changes
->map
.num_key_syms
= (last
- first
+ 1);
2136 for (i
= xkb
->min_key_code
; i
<= xkb
->max_key_code
; i
++) {
2137 if (XkbKeyNumGroups(xkb
, i
) > s
)
2138 s
= XkbKeyNumGroups(xkb
, i
);
2140 if (s
!= xkb
->ctrls
->num_groups
) {
2141 xkbControlsNotify cn
;
2146 cn
.requestMajor
= XkbReqCode
;
2147 cn
.requestMinor
= X_kbSetMap
;
2149 xkb
->ctrls
->num_groups
= s
;
2150 if (XkbComputeControlsNotify(dev
, &old
, xkb
->ctrls
, &cn
, FALSE
))
2151 XkbSendControlsNotify(dev
, &cn
);
2153 return (char *) wire
;
2157 SetKeyActions(XkbDescPtr xkb
,
2158 xkbSetMapReq
* req
, CARD8
*wire
, XkbChangesPtr changes
)
2160 register unsigned i
, first
, last
;
2161 CARD8
*nActs
= wire
;
2164 wire
+= XkbPaddedSize(req
->nKeyActs
);
2165 for (i
= 0; i
< req
->nKeyActs
; i
++) {
2167 xkb
->server
->key_acts
[i
+ req
->firstKeyAct
] = 0;
2169 newActs
= XkbResizeKeyActions(xkb
, i
+ req
->firstKeyAct
, nActs
[i
]);
2170 memcpy((char *) newActs
, (char *) wire
,
2171 nActs
[i
] * SIZEOF(xkbActionWireDesc
));
2172 wire
+= nActs
[i
] * SIZEOF(xkbActionWireDesc
);
2175 first
= req
->firstKeyAct
;
2176 last
= (first
+ req
->nKeyActs
- 1);
2177 if (changes
->map
.changed
& XkbKeyActionsMask
) {
2180 oldLast
= changes
->map
.first_key_act
+ changes
->map
.num_key_acts
- 1;
2181 if (changes
->map
.first_key_act
< first
)
2182 first
= changes
->map
.first_key_act
;
2186 changes
->map
.changed
|= XkbKeyActionsMask
;
2187 changes
->map
.first_key_act
= first
;
2188 changes
->map
.num_key_acts
= (last
- first
+ 1);
2189 return (char *) wire
;
2193 SetKeyBehaviors(XkbSrvInfoPtr xkbi
,
2195 xkbBehaviorWireDesc
* wire
, XkbChangesPtr changes
)
2197 register unsigned i
;
2199 XkbDescPtr xkb
= xkbi
->desc
;
2200 XkbServerMapPtr server
= xkb
->server
;
2201 unsigned first
, last
;
2203 first
= req
->firstKeyBehavior
;
2204 last
= req
->firstKeyBehavior
+ req
->nKeyBehaviors
- 1;
2205 memset(&server
->behaviors
[first
], 0,
2206 req
->nKeyBehaviors
* sizeof(XkbBehavior
));
2207 for (i
= 0; i
< req
->totalKeyBehaviors
; i
++) {
2208 if ((server
->behaviors
[wire
->key
].type
& XkbKB_Permanent
) == 0) {
2209 server
->behaviors
[wire
->key
].type
= wire
->type
;
2210 server
->behaviors
[wire
->key
].data
= wire
->data
;
2211 if ((wire
->type
== XkbKB_RadioGroup
) &&
2212 (((int) wire
->data
) > maxRG
))
2213 maxRG
= wire
->data
+ 1;
2218 if (maxRG
> (int) xkbi
->nRadioGroups
) {
2219 int sz
= maxRG
* sizeof(XkbRadioGroupRec
);
2221 if (xkbi
->radioGroups
)
2222 xkbi
->radioGroups
= realloc(xkbi
->radioGroups
, sz
);
2224 xkbi
->radioGroups
= calloc(1, sz
);
2225 if (xkbi
->radioGroups
) {
2226 if (xkbi
->nRadioGroups
)
2227 memset(&xkbi
->radioGroups
[xkbi
->nRadioGroups
], 0,
2228 (maxRG
- xkbi
->nRadioGroups
) * sizeof(XkbRadioGroupRec
));
2229 xkbi
->nRadioGroups
= maxRG
;
2232 xkbi
->nRadioGroups
= 0;
2233 /* should compute members here */
2235 if (changes
->map
.changed
& XkbKeyBehaviorsMask
) {
2238 oldLast
= changes
->map
.first_key_behavior
+
2239 changes
->map
.num_key_behaviors
- 1;
2240 if (changes
->map
.first_key_behavior
< req
->firstKeyBehavior
)
2241 first
= changes
->map
.first_key_behavior
;
2245 changes
->map
.changed
|= XkbKeyBehaviorsMask
;
2246 changes
->map
.first_key_behavior
= first
;
2247 changes
->map
.num_key_behaviors
= (last
- first
+ 1);
2248 return (char *) wire
;
2252 SetVirtualMods(XkbSrvInfoPtr xkbi
, xkbSetMapReq
* req
, CARD8
*wire
,
2253 XkbChangesPtr changes
)
2255 register int i
, bit
, nMods
;
2256 XkbServerMapPtr srv
= xkbi
->desc
->server
;
2258 if (((req
->present
& XkbVirtualModsMask
) == 0) || (req
->virtualMods
== 0))
2259 return (char *) wire
;
2260 for (i
= nMods
= 0, bit
= 1; i
< XkbNumVirtualMods
; i
++, bit
<<= 1) {
2261 if (req
->virtualMods
& bit
) {
2262 if (srv
->vmods
[i
] != wire
[nMods
]) {
2263 changes
->map
.changed
|= XkbVirtualModsMask
;
2264 changes
->map
.vmods
|= bit
;
2265 srv
->vmods
[i
] = wire
[nMods
];
2270 return (char *) (wire
+ XkbPaddedSize(nMods
));
2274 SetKeyExplicit(XkbSrvInfoPtr xkbi
, xkbSetMapReq
* req
, CARD8
*wire
,
2275 XkbChangesPtr changes
)
2277 register unsigned i
, first
, last
;
2278 XkbServerMapPtr xkb
= xkbi
->desc
->server
;
2282 first
= req
->firstKeyExplicit
;
2283 last
= req
->firstKeyExplicit
+ req
->nKeyExplicit
- 1;
2284 memset(&xkb
->explicit[first
], 0, req
->nKeyExplicit
);
2285 for (i
= 0; i
< req
->totalKeyExplicit
; i
++, wire
+= 2) {
2286 xkb
->explicit[wire
[0]] = wire
[1];
2289 if (changes
->map
.changed
& XkbExplicitComponentsMask
) {
2292 oldLast
= changes
->map
.first_key_explicit
+
2293 changes
->map
.num_key_explicit
- 1;
2294 if (changes
->map
.first_key_explicit
< first
)
2295 first
= changes
->map
.first_key_explicit
;
2299 changes
->map
.first_key_explicit
= first
;
2300 changes
->map
.num_key_explicit
= (last
- first
) + 1;
2302 wire
+= XkbPaddedSize(wire
- start
) - (wire
- start
);
2303 return (char *) wire
;
2307 SetModifierMap(XkbSrvInfoPtr xkbi
,
2308 xkbSetMapReq
* req
, CARD8
*wire
, XkbChangesPtr changes
)
2310 register unsigned i
, first
, last
;
2311 XkbClientMapPtr xkb
= xkbi
->desc
->map
;
2315 first
= req
->firstModMapKey
;
2316 last
= req
->firstModMapKey
+ req
->nModMapKeys
- 1;
2317 memset(&xkb
->modmap
[first
], 0, req
->nModMapKeys
);
2318 for (i
= 0; i
< req
->totalModMapKeys
; i
++, wire
+= 2) {
2319 xkb
->modmap
[wire
[0]] = wire
[1];
2322 if (changes
->map
.changed
& XkbModifierMapMask
) {
2325 oldLast
= changes
->map
.first_modmap_key
+
2326 changes
->map
.num_modmap_keys
- 1;
2327 if (changes
->map
.first_modmap_key
< first
)
2328 first
= changes
->map
.first_modmap_key
;
2332 changes
->map
.first_modmap_key
= first
;
2333 changes
->map
.num_modmap_keys
= (last
- first
) + 1;
2335 wire
+= XkbPaddedSize(wire
- start
) - (wire
- start
);
2336 return (char *) wire
;
2340 SetVirtualModMap(XkbSrvInfoPtr xkbi
,
2342 xkbVModMapWireDesc
* wire
, XkbChangesPtr changes
)
2344 register unsigned i
, first
, last
;
2345 XkbServerMapPtr srv
= xkbi
->desc
->server
;
2347 first
= req
->firstVModMapKey
;
2348 last
= req
->firstVModMapKey
+ req
->nVModMapKeys
- 1;
2349 memset(&srv
->vmodmap
[first
], 0, req
->nVModMapKeys
* sizeof(unsigned short));
2350 for (i
= 0; i
< req
->totalVModMapKeys
; i
++, wire
++) {
2351 srv
->vmodmap
[wire
->key
] = wire
->vmods
;
2354 if (changes
->map
.changed
& XkbVirtualModMapMask
) {
2357 oldLast
= changes
->map
.first_vmodmap_key
+
2358 changes
->map
.num_vmodmap_keys
- 1;
2359 if (changes
->map
.first_vmodmap_key
< first
)
2360 first
= changes
->map
.first_vmodmap_key
;
2364 changes
->map
.first_vmodmap_key
= first
;
2365 changes
->map
.num_vmodmap_keys
= (last
- first
) + 1;
2367 return (char *) wire
;
2371 * Check if the given request can be applied to the given device but don't
2372 * actually do anything..
2375 _XkbSetMapChecks(ClientPtr client
, DeviceIntPtr dev
, xkbSetMapReq
* req
,
2381 int nTypes
= 0, nActions
;
2382 CARD8 mapWidths
[XkbMaxLegalKeyCode
+ 1] = { 0 };
2383 CARD16 symsPerKey
[XkbMaxLegalKeyCode
+ 1] = { 0 };
2387 xkbi
= dev
->key
->xkbInfo
;
2390 if ((xkb
->min_key_code
!= req
->minKeyCode
) ||
2391 (xkb
->max_key_code
!= req
->maxKeyCode
)) {
2392 if (client
->vMajor
!= 1) { /* pre 1.0 versions of Xlib have a bug */
2393 req
->minKeyCode
= xkb
->min_key_code
;
2394 req
->maxKeyCode
= xkb
->max_key_code
;
2397 if (!XkbIsLegalKeycode(req
->minKeyCode
)) {
2398 client
->errorValue
=
2399 _XkbErrCode3(2, req
->minKeyCode
, req
->maxKeyCode
);
2402 if (req
->minKeyCode
> req
->maxKeyCode
) {
2403 client
->errorValue
=
2404 _XkbErrCode3(3, req
->minKeyCode
, req
->maxKeyCode
);
2410 if ((req
->present
& XkbKeyTypesMask
) &&
2411 (!CheckKeyTypes(client
, xkb
, req
, (xkbKeyTypeWireDesc
**) &values
,
2412 &nTypes
, mapWidths
))) {
2413 client
->errorValue
= nTypes
;
2417 /* symsPerKey/mapWidths must be filled regardless of client-side flags */
2418 map
= &xkb
->map
->key_sym_map
[xkb
->min_key_code
];
2419 for (i
= xkb
->min_key_code
; i
< xkb
->max_key_code
; i
++, map
++) {
2420 register int g
, ng
, w
;
2422 ng
= XkbNumGroups(map
->group_info
);
2423 for (w
= g
= 0; g
< ng
; g
++) {
2424 if (map
->kt_index
[g
] >= (unsigned) nTypes
) {
2425 client
->errorValue
= _XkbErrCode4(0x13, i
, g
, map
->kt_index
[g
]);
2428 if (mapWidths
[map
->kt_index
[g
]] > w
)
2429 w
= mapWidths
[map
->kt_index
[g
]];
2431 symsPerKey
[i
] = w
* ng
;
2434 if ((req
->present
& XkbKeySymsMask
) &&
2435 (!CheckKeySyms(client
, xkb
, req
, nTypes
, mapWidths
, symsPerKey
,
2436 (xkbSymMapWireDesc
**) &values
, &error
))) {
2437 client
->errorValue
= error
;
2441 if ((req
->present
& XkbKeyActionsMask
) &&
2442 (!CheckKeyActions(xkb
, req
, nTypes
, mapWidths
, symsPerKey
,
2443 (CARD8
**) &values
, &nActions
))) {
2444 client
->errorValue
= nActions
;
2448 if ((req
->present
& XkbKeyBehaviorsMask
) &&
2450 (xkb
, req
, (xkbBehaviorWireDesc
**) &values
, &error
))) {
2451 client
->errorValue
= error
;
2455 if ((req
->present
& XkbVirtualModsMask
) &&
2456 (!CheckVirtualMods(xkb
, req
, (CARD8
**) &values
, &error
))) {
2457 client
->errorValue
= error
;
2460 if ((req
->present
& XkbExplicitComponentsMask
) &&
2461 (!CheckKeyExplicit(xkb
, req
, (CARD8
**) &values
, &error
))) {
2462 client
->errorValue
= error
;
2465 if ((req
->present
& XkbModifierMapMask
) &&
2466 (!CheckModifierMap(xkb
, req
, (CARD8
**) &values
, &error
))) {
2467 client
->errorValue
= error
;
2470 if ((req
->present
& XkbVirtualModMapMask
) &&
2471 (!CheckVirtualModMap
2472 (xkb
, req
, (xkbVModMapWireDesc
**) &values
, &error
))) {
2473 client
->errorValue
= error
;
2477 if (((values
- ((char *) req
)) / 4) != req
->length
) {
2478 ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n");
2479 client
->errorValue
= values
- ((char *) &req
[1]);
2487 * Apply the given request on the given device.
2490 _XkbSetMap(ClientPtr client
, DeviceIntPtr dev
, xkbSetMapReq
* req
, char *values
)
2492 XkbEventCauseRec cause
;
2493 XkbChangesRec change
;
2498 xkbi
= dev
->key
->xkbInfo
;
2501 XkbSetCauseXkbReq(&cause
, X_kbSetMap
, client
);
2502 memset(&change
, 0, sizeof(change
));
2504 if ((xkb
->min_key_code
!= req
->minKeyCode
) ||
2505 (xkb
->max_key_code
!= req
->maxKeyCode
)) {
2507 xkbNewKeyboardNotify nkn
;
2509 nkn
.deviceID
= nkn
.oldDeviceID
= dev
->id
;
2510 nkn
.oldMinKeyCode
= xkb
->min_key_code
;
2511 nkn
.oldMaxKeyCode
= xkb
->max_key_code
;
2512 status
= XkbChangeKeycodeRange(xkb
, req
->minKeyCode
,
2513 req
->maxKeyCode
, &change
);
2514 if (status
!= Success
)
2515 return status
; /* oh-oh. what about the other keyboards? */
2516 nkn
.minKeyCode
= xkb
->min_key_code
;
2517 nkn
.maxKeyCode
= xkb
->max_key_code
;
2518 nkn
.requestMajor
= XkbReqCode
;
2519 nkn
.requestMinor
= X_kbSetMap
;
2520 nkn
.changed
= XkbNKN_KeycodesMask
;
2521 XkbSendNewKeyboardNotify(dev
, &nkn
);
2525 if (req
->present
& XkbKeyTypesMask
) {
2526 values
= SetKeyTypes(xkb
, req
, (xkbKeyTypeWireDesc
*) values
, &change
);
2530 if (req
->present
& XkbKeySymsMask
) {
2532 SetKeySyms(client
, xkb
, req
, (xkbSymMapWireDesc
*) values
, &change
,
2537 if (req
->present
& XkbKeyActionsMask
) {
2538 values
= SetKeyActions(xkb
, req
, (CARD8
*) values
, &change
);
2542 if (req
->present
& XkbKeyBehaviorsMask
) {
2544 SetKeyBehaviors(xkbi
, req
, (xkbBehaviorWireDesc
*) values
, &change
);
2548 if (req
->present
& XkbVirtualModsMask
)
2549 values
= SetVirtualMods(xkbi
, req
, (CARD8
*) values
, &change
);
2550 if (req
->present
& XkbExplicitComponentsMask
)
2551 values
= SetKeyExplicit(xkbi
, req
, (CARD8
*) values
, &change
);
2552 if (req
->present
& XkbModifierMapMask
)
2553 values
= SetModifierMap(xkbi
, req
, (CARD8
*) values
, &change
);
2554 if (req
->present
& XkbVirtualModMapMask
)
2556 SetVirtualModMap(xkbi
, req
, (xkbVModMapWireDesc
*) values
, &change
);
2557 if (((values
- ((char *) req
)) / 4) != req
->length
) {
2558 ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n");
2559 client
->errorValue
= values
- ((char *) &req
[1]);
2562 if (req
->flags
& XkbSetMapRecomputeActions
) {
2563 KeyCode first
, last
, firstMM
, lastMM
;
2565 if (change
.map
.num_key_syms
> 0) {
2566 first
= change
.map
.first_key_sym
;
2567 last
= first
+ change
.map
.num_key_syms
- 1;
2571 if (change
.map
.num_modmap_keys
> 0) {
2572 firstMM
= change
.map
.first_modmap_key
;
2573 lastMM
= first
+ change
.map
.num_modmap_keys
- 1;
2576 firstMM
= lastMM
= 0;
2577 if ((last
> 0) && (lastMM
> 0)) {
2578 if (firstMM
< first
)
2583 else if (lastMM
> 0) {
2590 XkbUpdateActions(dev
, first
, (last
- first
+ 1), &change
, &check
,
2593 XkbCheckSecondaryEffects(xkbi
, check
, &change
, &cause
);
2597 XkbSendNotification(dev
, &change
, &cause
);
2605 ProcXkbSetMap(ClientPtr client
)
2611 REQUEST(xkbSetMapReq
);
2612 REQUEST_AT_LEAST_SIZE(xkbSetMapReq
);
2614 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
2617 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixManageAccess
);
2618 CHK_MASK_LEGAL(0x01, stuff
->present
, XkbAllMapComponentsMask
);
2620 tmp
= (char *) &stuff
[1];
2622 /* Check if we can to the SetMap on the requested device. If this
2623 succeeds, do the same thing for all extension devices (if needed).
2624 If any of them fails, fail. */
2625 rc
= _XkbSetMapChecks(client
, dev
, stuff
, tmp
);
2630 if (stuff
->deviceSpec
== XkbUseCoreKbd
) {
2633 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
2634 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
2635 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
2636 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
2638 if (rc
== Success
) {
2639 rc
= _XkbSetMapChecks(client
, other
, stuff
, tmp
);
2647 /* We know now that we will succed with the SetMap. In theory anyway. */
2648 rc
= _XkbSetMap(client
, dev
, stuff
, tmp
);
2652 if (stuff
->deviceSpec
== XkbUseCoreKbd
) {
2655 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
2656 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
2657 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
2658 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
2661 _XkbSetMap(client
, other
, stuff
, tmp
);
2662 /* ignore rc. if the SetMap failed although the check above
2663 reported true there isn't much we can do. we still need to
2664 set all other devices, hoping that at least they stay in
2673 /***====================================================================***/
2676 XkbComputeGetCompatMapReplySize(XkbCompatMapPtr compat
,
2677 xkbGetCompatMapReply
* rep
)
2679 unsigned size
, nGroups
;
2682 if (rep
->groups
!= 0) {
2683 register int i
, bit
;
2685 for (i
= 0, bit
= 1; i
< XkbNumKbdGroups
; i
++, bit
<<= 1) {
2686 if (rep
->groups
& bit
)
2690 size
= nGroups
* SIZEOF(xkbModsWireDesc
);
2691 size
+= (rep
->nSI
* SIZEOF(xkbSymInterpretWireDesc
));
2692 rep
->length
= size
/ 4;
2697 XkbSendCompatMap(ClientPtr client
,
2698 XkbCompatMapPtr compat
, xkbGetCompatMapReply
* rep
)
2703 size
= rep
->length
* 4;
2705 data
= malloc(size
);
2707 register unsigned i
, bit
;
2708 xkbModsWireDesc
*grp
;
2709 XkbSymInterpretPtr sym
= &compat
->sym_interpret
[rep
->firstSI
];
2710 xkbSymInterpretWireDesc
*wire
= (xkbSymInterpretWireDesc
*) data
;
2712 for (i
= 0; i
< rep
->nSI
; i
++, sym
++, wire
++) {
2713 wire
->sym
= sym
->sym
;
2714 wire
->mods
= sym
->mods
;
2715 wire
->match
= sym
->match
;
2716 wire
->virtualMod
= sym
->virtual_mod
;
2717 wire
->flags
= sym
->flags
;
2718 memcpy((char *) &wire
->act
, (char *) &sym
->act
,
2719 sz_xkbActionWireDesc
);
2720 if (client
->swapped
) {
2725 grp
= (xkbModsWireDesc
*) wire
;
2726 for (i
= 0, bit
= 1; i
< XkbNumKbdGroups
; i
++, bit
<<= 1) {
2727 if (rep
->groups
& bit
) {
2728 grp
->mask
= compat
->groups
[i
].mask
;
2729 grp
->realMods
= compat
->groups
[i
].real_mods
;
2730 grp
->virtualMods
= compat
->groups
[i
].vmods
;
2731 if (client
->swapped
) {
2732 swaps(&grp
->virtualMods
);
2737 wire
= (xkbSymInterpretWireDesc
*) grp
;
2746 if (client
->swapped
) {
2747 swaps(&rep
->sequenceNumber
);
2748 swapl(&rep
->length
);
2749 swaps(&rep
->firstSI
);
2751 swaps(&rep
->nTotalSI
);
2754 WriteToClient(client
, SIZEOF(xkbGetCompatMapReply
), rep
);
2756 WriteToClient(client
, size
, data
);
2757 free((char *) data
);
2763 ProcXkbGetCompatMap(ClientPtr client
)
2765 xkbGetCompatMapReply rep
;
2768 XkbCompatMapPtr compat
;
2770 REQUEST(xkbGetCompatMapReq
);
2771 REQUEST_SIZE_MATCH(xkbGetCompatMapReq
);
2773 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
2776 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
2778 xkb
= dev
->key
->xkbInfo
->desc
;
2779 compat
= xkb
->compat
;
2781 rep
= (xkbGetCompatMapReply
) {
2783 .sequenceNumber
= client
->sequence
,
2785 .deviceID
= dev
->id
,
2786 .firstSI
= stuff
->firstSI
,
2789 if (stuff
->getAllSI
) {
2791 rep
.nSI
= compat
->num_si
;
2793 else if ((((unsigned) stuff
->nSI
) > 0) &&
2794 ((unsigned) (stuff
->firstSI
+ stuff
->nSI
- 1) >= compat
->num_si
)) {
2795 client
->errorValue
= _XkbErrCode2(0x05, compat
->num_si
);
2798 rep
.nTotalSI
= compat
->num_si
;
2799 rep
.groups
= stuff
->groups
;
2800 XkbComputeGetCompatMapReplySize(compat
, &rep
);
2801 return XkbSendCompatMap(client
, compat
, &rep
);
2805 * Apply the given request on the given device.
2806 * If dryRun is TRUE, then value checks are performed, but the device isn't
2810 _XkbSetCompatMap(ClientPtr client
, DeviceIntPtr dev
,
2811 xkbSetCompatMapReq
* req
, char *data
, BOOL dryRun
)
2815 XkbCompatMapPtr compat
;
2819 xkbi
= dev
->key
->xkbInfo
;
2821 compat
= xkb
->compat
;
2823 if ((req
->nSI
> 0) || (req
->truncateSI
)) {
2824 xkbSymInterpretWireDesc
*wire
;
2826 if (req
->firstSI
> compat
->num_si
) {
2827 client
->errorValue
= _XkbErrCode2(0x02, compat
->num_si
);
2830 wire
= (xkbSymInterpretWireDesc
*) data
;
2832 data
= (char *) wire
;
2836 if (req
->groups
!= 0) {
2837 for (i
= 0, bit
= 1; i
< XkbNumKbdGroups
; i
++, bit
<<= 1) {
2838 if (req
->groups
& bit
)
2842 data
+= nGroups
* SIZEOF(xkbModsWireDesc
);
2843 if (((data
- ((char *) req
)) / 4) != req
->length
) {
2847 /* Done all the checks we can do */
2851 data
= (char *) &req
[1];
2853 xkbSymInterpretWireDesc
*wire
= (xkbSymInterpretWireDesc
*) data
;
2854 XkbSymInterpretPtr sym
;
2855 unsigned int skipped
= 0;
2857 if ((unsigned) (req
->firstSI
+ req
->nSI
) > compat
->num_si
) {
2858 compat
->num_si
= req
->firstSI
+ req
->nSI
;
2859 compat
->sym_interpret
= realloc(compat
->sym_interpret
,
2861 sizeof(XkbSymInterpretRec
));
2862 if (!compat
->sym_interpret
) {
2867 else if (req
->truncateSI
) {
2868 compat
->num_si
= req
->firstSI
+ req
->nSI
;
2870 sym
= &compat
->sym_interpret
[req
->firstSI
];
2871 for (i
= 0; i
< req
->nSI
; i
++, wire
++) {
2872 if (client
->swapped
) {
2875 if (wire
->sym
== NoSymbol
&& wire
->match
== XkbSI_AnyOfOrNone
&&
2876 (wire
->mods
& 0xff) == 0xff &&
2877 wire
->act
.type
== XkbSA_XFree86Private
) {
2878 ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private "
2879 "action from client\n");
2883 sym
->sym
= wire
->sym
;
2884 sym
->mods
= wire
->mods
;
2885 sym
->match
= wire
->match
;
2886 sym
->flags
= wire
->flags
;
2887 sym
->virtual_mod
= wire
->virtualMod
;
2888 memcpy((char *) &sym
->act
, (char *) &wire
->act
,
2889 SIZEOF(xkbActionWireDesc
));
2893 if (req
->firstSI
+ req
->nSI
< compat
->num_si
)
2894 memmove(sym
, sym
+ skipped
,
2895 (compat
->num_si
- req
->firstSI
- req
->nSI
) *
2897 compat
->num_si
-= skipped
;
2899 data
= (char *) wire
;
2901 else if (req
->truncateSI
) {
2902 compat
->num_si
= req
->firstSI
;
2905 if (req
->groups
!= 0) {
2906 xkbModsWireDesc
*wire
= (xkbModsWireDesc
*) data
;
2908 for (i
= 0, bit
= 1; i
< XkbNumKbdGroups
; i
++, bit
<<= 1) {
2909 if (req
->groups
& bit
) {
2910 if (client
->swapped
) {
2911 swaps(&wire
->virtualMods
);
2913 compat
->groups
[i
].mask
= wire
->realMods
;
2914 compat
->groups
[i
].real_mods
= wire
->realMods
;
2915 compat
->groups
[i
].vmods
= wire
->virtualMods
;
2916 if (wire
->virtualMods
!= 0) {
2919 tmp
= XkbMaskForVMask(xkb
, wire
->virtualMods
);
2920 compat
->groups
[i
].mask
|= tmp
;
2922 data
+= SIZEOF(xkbModsWireDesc
);
2923 wire
= (xkbModsWireDesc
*) data
;
2927 i
= XkbPaddedSize((data
- ((char *) req
)));
2928 if ((i
/ 4) != req
->length
) {
2929 ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n");
2933 if (dev
->xkb_interest
) {
2934 xkbCompatMapNotify ev
;
2936 ev
.deviceID
= dev
->id
;
2937 ev
.changedGroups
= req
->groups
;
2938 ev
.firstSI
= req
->firstSI
;
2940 ev
.nTotalSI
= compat
->num_si
;
2941 XkbSendCompatMapNotify(dev
, &ev
);
2944 if (req
->recomputeActions
) {
2945 XkbChangesRec change
;
2947 XkbEventCauseRec cause
;
2949 XkbSetCauseXkbReq(&cause
, X_kbSetCompatMap
, client
);
2950 memset(&change
, 0, sizeof(XkbChangesRec
));
2951 XkbUpdateActions(dev
, xkb
->min_key_code
, XkbNumKeys(xkb
), &change
,
2954 XkbCheckSecondaryEffects(xkbi
, check
, &change
, &cause
);
2955 XkbSendNotification(dev
, &change
, &cause
);
2961 ProcXkbSetCompatMap(ClientPtr client
)
2967 REQUEST(xkbSetCompatMapReq
);
2968 REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq
);
2970 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
2973 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixManageAccess
);
2975 data
= (char *) &stuff
[1];
2977 /* check first using a dry-run */
2978 rc
= _XkbSetCompatMap(client
, dev
, stuff
, data
, TRUE
);
2981 if (stuff
->deviceSpec
== XkbUseCoreKbd
) {
2984 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
2985 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
2986 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
2987 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
2989 if (rc
== Success
) {
2991 rc
= _XkbSetCompatMap(client
, other
, stuff
, data
, TRUE
);
2999 /* Yay, the dry-runs succeed. Let's apply */
3000 rc
= _XkbSetCompatMap(client
, dev
, stuff
, data
, FALSE
);
3003 if (stuff
->deviceSpec
== XkbUseCoreKbd
) {
3006 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
3007 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
3008 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
3009 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
3011 if (rc
== Success
) {
3012 rc
= _XkbSetCompatMap(client
, other
, stuff
, data
, FALSE
);
3023 /***====================================================================***/
3026 ProcXkbGetIndicatorState(ClientPtr client
)
3028 xkbGetIndicatorStateReply rep
;
3029 XkbSrvLedInfoPtr sli
;
3032 REQUEST(xkbGetIndicatorStateReq
);
3033 REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq
);
3035 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
3038 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixReadAccess
);
3040 sli
= XkbFindSrvLedInfo(dev
, XkbDfltXIClass
, XkbDfltXIId
,
3041 XkbXI_IndicatorStateMask
);
3045 rep
= (xkbGetIndicatorStateReply
) {
3047 .deviceID
= dev
->id
,
3048 .sequenceNumber
= client
->sequence
,
3050 .state
= sli
->effectiveState
3053 if (client
->swapped
) {
3054 swaps(&rep
.sequenceNumber
);
3057 WriteToClient(client
, SIZEOF(xkbGetIndicatorStateReply
), &rep
);
3061 /***====================================================================***/
3064 XkbComputeGetIndicatorMapReplySize(XkbIndicatorPtr indicators
,
3065 xkbGetIndicatorMapReply
* rep
)
3067 register int i
, bit
;
3070 rep
->realIndicators
= indicators
->phys_indicators
;
3071 for (i
= nIndicators
= 0, bit
= 1; i
< XkbNumIndicators
; i
++, bit
<<= 1) {
3072 if (rep
->which
& bit
)
3075 rep
->length
= (nIndicators
* SIZEOF(xkbIndicatorMapWireDesc
)) / 4;
3076 rep
->nIndicators
= nIndicators
;
3081 XkbSendIndicatorMap(ClientPtr client
,
3082 XkbIndicatorPtr indicators
, xkbGetIndicatorMapReply
* rep
)
3087 register unsigned bit
;
3089 length
= rep
->length
* 4;
3093 to
= map
= malloc(length
);
3095 xkbIndicatorMapWireDesc
*wire
= (xkbIndicatorMapWireDesc
*) to
;
3097 for (i
= 0, bit
= 1; i
< XkbNumIndicators
; i
++, bit
<<= 1) {
3098 if (rep
->which
& bit
) {
3099 wire
->flags
= indicators
->maps
[i
].flags
;
3100 wire
->whichGroups
= indicators
->maps
[i
].which_groups
;
3101 wire
->groups
= indicators
->maps
[i
].groups
;
3102 wire
->whichMods
= indicators
->maps
[i
].which_mods
;
3103 wire
->mods
= indicators
->maps
[i
].mods
.mask
;
3104 wire
->realMods
= indicators
->maps
[i
].mods
.real_mods
;
3105 wire
->virtualMods
= indicators
->maps
[i
].mods
.vmods
;
3106 wire
->ctrls
= indicators
->maps
[i
].ctrls
;
3107 if (client
->swapped
) {
3108 swaps(&wire
->virtualMods
);
3109 swapl(&wire
->ctrls
);
3114 to
= (CARD8
*) wire
;
3115 if ((to
- map
) != length
) {
3116 client
->errorValue
= _XkbErrCode2(0xff, length
);
3126 if (client
->swapped
) {
3127 swaps(&rep
->sequenceNumber
);
3128 swapl(&rep
->length
);
3130 swapl(&rep
->realIndicators
);
3132 WriteToClient(client
, SIZEOF(xkbGetIndicatorMapReply
), rep
);
3134 WriteToClient(client
, length
, map
);
3141 ProcXkbGetIndicatorMap(ClientPtr client
)
3143 xkbGetIndicatorMapReply rep
;
3146 XkbIndicatorPtr leds
;
3148 REQUEST(xkbGetIndicatorMapReq
);
3149 REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq
);
3151 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
3154 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
3156 xkb
= dev
->key
->xkbInfo
->desc
;
3157 leds
= xkb
->indicators
;
3159 rep
= (xkbGetIndicatorMapReply
) {
3161 .deviceID
= dev
->id
,
3162 .sequenceNumber
= client
->sequence
,
3164 .which
= stuff
->which
3166 XkbComputeGetIndicatorMapReplySize(leds
, &rep
);
3167 return XkbSendIndicatorMap(client
, leds
, &rep
);
3171 * Apply the given map to the given device. Which specifies which components
3175 _XkbSetIndicatorMap(ClientPtr client
, DeviceIntPtr dev
,
3176 int which
, xkbIndicatorMapWireDesc
* desc
)
3179 XkbSrvLedInfoPtr sli
;
3180 XkbEventCauseRec cause
;
3183 xkbi
= dev
->key
->xkbInfo
;
3185 sli
= XkbFindSrvLedInfo(dev
, XkbDfltXIClass
, XkbDfltXIId
,
3186 XkbXI_IndicatorMapsMask
);
3190 for (i
= 0, bit
= 1; i
< XkbNumIndicators
; i
++, bit
<<= 1) {
3192 sli
->maps
[i
].flags
= desc
->flags
;
3193 sli
->maps
[i
].which_groups
= desc
->whichGroups
;
3194 sli
->maps
[i
].groups
= desc
->groups
;
3195 sli
->maps
[i
].which_mods
= desc
->whichMods
;
3196 sli
->maps
[i
].mods
.mask
= desc
->mods
;
3197 sli
->maps
[i
].mods
.real_mods
= desc
->mods
;
3198 sli
->maps
[i
].mods
.vmods
= desc
->virtualMods
;
3199 sli
->maps
[i
].ctrls
= desc
->ctrls
;
3200 if (desc
->virtualMods
!= 0) {
3203 tmp
= XkbMaskForVMask(xkbi
->desc
, desc
->virtualMods
);
3204 sli
->maps
[i
].mods
.mask
= desc
->mods
| tmp
;
3210 XkbSetCauseXkbReq(&cause
, X_kbSetIndicatorMap
, client
);
3211 XkbApplyLedMapChanges(dev
, sli
, which
, NULL
, NULL
, &cause
);
3217 ProcXkbSetIndicatorMap(ClientPtr client
)
3222 xkbIndicatorMapWireDesc
*from
;
3225 REQUEST(xkbSetIndicatorMapReq
);
3226 REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq
);
3228 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
3231 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixSetAttrAccess
);
3233 if (stuff
->which
== 0)
3236 for (nIndicators
= i
= 0, bit
= 1; i
< XkbNumIndicators
; i
++, bit
<<= 1) {
3237 if (stuff
->which
& bit
)
3240 if (stuff
->length
!= ((SIZEOF(xkbSetIndicatorMapReq
) +
3241 (nIndicators
* SIZEOF(xkbIndicatorMapWireDesc
))) /
3246 from
= (xkbIndicatorMapWireDesc
*) &stuff
[1];
3247 for (i
= 0, bit
= 1; i
< XkbNumIndicators
; i
++, bit
<<= 1) {
3248 if (stuff
->which
& bit
) {
3249 if (client
->swapped
) {
3250 swaps(&from
->virtualMods
);
3251 swapl(&from
->ctrls
);
3253 CHK_MASK_LEGAL(i
, from
->whichGroups
, XkbIM_UseAnyGroup
);
3254 CHK_MASK_LEGAL(i
, from
->whichMods
, XkbIM_UseAnyMods
);
3259 from
= (xkbIndicatorMapWireDesc
*) &stuff
[1];
3260 rc
= _XkbSetIndicatorMap(client
, dev
, stuff
->which
, from
);
3264 if (stuff
->deviceSpec
== XkbUseCoreKbd
) {
3267 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
3268 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
3269 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
3270 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
3273 _XkbSetIndicatorMap(client
, other
, stuff
->which
, from
);
3281 /***====================================================================***/
3284 ProcXkbGetNamedIndicator(ClientPtr client
)
3287 xkbGetNamedIndicatorReply rep
;
3289 XkbSrvLedInfoPtr sli
;
3290 XkbIndicatorMapPtr map
= NULL
;
3292 REQUEST(xkbGetNamedIndicatorReq
);
3293 REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq
);
3295 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
3298 CHK_LED_DEVICE(dev
, stuff
->deviceSpec
, client
, DixReadAccess
);
3299 CHK_ATOM_ONLY(stuff
->indicator
);
3301 sli
= XkbFindSrvLedInfo(dev
, stuff
->ledClass
, stuff
->ledID
, 0);
3307 if ((sli
->names
) && (sli
->maps
)) {
3308 for (i
= 0; i
< XkbNumIndicators
; i
++) {
3309 if (stuff
->indicator
== sli
->names
[i
]) {
3310 map
= &sli
->maps
[i
];
3316 rep
= (xkbGetNamedIndicatorReply
) {
3318 .sequenceNumber
= client
->sequence
,
3320 .deviceID
= dev
->id
,
3321 .indicator
= stuff
->indicator
3325 rep
.on
= ((sli
->effectiveState
& (1 << i
)) != 0);
3326 rep
.realIndicator
= ((sli
->physIndicators
& (1 << i
)) != 0);
3328 rep
.flags
= map
->flags
;
3329 rep
.whichGroups
= map
->which_groups
;
3330 rep
.groups
= map
->groups
;
3331 rep
.whichMods
= map
->which_mods
;
3332 rep
.mods
= map
->mods
.mask
;
3333 rep
.realMods
= map
->mods
.real_mods
;
3334 rep
.virtualMods
= map
->mods
.vmods
;
3335 rep
.ctrls
= map
->ctrls
;
3336 rep
.supported
= TRUE
;
3341 rep
.realIndicator
= FALSE
;
3342 rep
.ndx
= XkbNoIndicator
;
3344 rep
.whichGroups
= 0;
3349 rep
.virtualMods
= 0;
3351 rep
.supported
= TRUE
;
3353 if (client
->swapped
) {
3355 swaps(&rep
.sequenceNumber
);
3356 swapl(&rep
.indicator
);
3357 swaps(&rep
.virtualMods
);
3361 WriteToClient(client
, SIZEOF(xkbGetNamedIndicatorReply
), &rep
);
3366 * Find the IM on the device.
3367 * Returns the map, or NULL if the map doesn't exist.
3368 * If the return value is NULL, led_return is undefined. Otherwise, led_return
3369 * is set to the led index of the map.
3371 static XkbIndicatorMapPtr
3372 _XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli
, Atom indicator
, int *led_return
)
3374 XkbIndicatorMapPtr map
;
3376 /* search for the right indicator */
3378 if (sli
->names
&& sli
->maps
) {
3381 for (led
= 0; (led
< XkbNumIndicators
) && (map
== NULL
); led
++) {
3382 if (sli
->names
[led
] == indicator
) {
3383 map
= &sli
->maps
[led
];
3394 * Creates an indicator map on the device. If dryRun is TRUE, it only checks
3395 * if creation is possible, but doesn't actually create it.
3398 _XkbCreateIndicatorMap(DeviceIntPtr dev
, Atom indicator
,
3399 int ledClass
, int ledID
,
3400 XkbIndicatorMapPtr
* map_return
, int *led_return
,
3403 XkbSrvLedInfoPtr sli
;
3404 XkbIndicatorMapPtr map
;
3407 sli
= XkbFindSrvLedInfo(dev
, ledClass
, ledID
, XkbXI_IndicatorsMask
);
3411 map
= _XkbFindNamedIndicatorMap(sli
, indicator
, &led
);
3414 /* find first unused indicator maps and assign the name to it */
3415 for (led
= 0, map
= NULL
; (led
< XkbNumIndicators
) && (map
== NULL
);
3417 if ((sli
->names
) && (sli
->maps
) && (sli
->names
[led
] == None
) &&
3418 (!XkbIM_InUse(&sli
->maps
[led
]))) {
3419 map
= &sli
->maps
[led
];
3421 sli
->names
[led
] = indicator
;
3436 _XkbSetNamedIndicator(ClientPtr client
, DeviceIntPtr dev
,
3437 xkbSetNamedIndicatorReq
* stuff
)
3439 unsigned int extDevReason
;
3440 unsigned int statec
, namec
, mapc
;
3441 XkbSrvLedInfoPtr sli
;
3443 XkbIndicatorMapPtr map
;
3445 XkbEventCauseRec cause
;
3446 xkbExtensionDeviceNotify ed
;
3447 XkbChangesRec changes
;
3450 rc
= _XkbCreateIndicatorMap(dev
, stuff
->indicator
, stuff
->ledClass
,
3451 stuff
->ledID
, &map
, &led
, FALSE
);
3452 if (rc
!= Success
|| !map
) /* oh-oh */
3455 sli
= XkbFindSrvLedInfo(dev
, stuff
->ledClass
, stuff
->ledID
,
3456 XkbXI_IndicatorsMask
);
3460 namec
= mapc
= statec
= 0;
3463 namec
|= (1 << led
);
3464 sli
->namesPresent
|= ((stuff
->indicator
!= None
) ? (1 << led
) : 0);
3465 extDevReason
|= XkbXI_IndicatorNamesMask
;
3467 if (stuff
->setMap
) {
3468 map
->flags
= stuff
->flags
;
3469 map
->which_groups
= stuff
->whichGroups
;
3470 map
->groups
= stuff
->groups
;
3471 map
->which_mods
= stuff
->whichMods
;
3472 map
->mods
.mask
= stuff
->realMods
;
3473 map
->mods
.real_mods
= stuff
->realMods
;
3474 map
->mods
.vmods
= stuff
->virtualMods
;
3475 map
->ctrls
= stuff
->ctrls
;
3479 if ((stuff
->setState
) && ((map
->flags
& XkbIM_NoExplicit
) == 0)) {
3481 sli
->explicitState
|= (1 << led
);
3483 sli
->explicitState
&= ~(1 << led
);
3484 statec
|= ((sli
->effectiveState
^ sli
->explicitState
) & (1 << led
));
3487 memset((char *) &ed
, 0, sizeof(xkbExtensionDeviceNotify
));
3488 memset((char *) &changes
, 0, sizeof(XkbChangesRec
));
3489 XkbSetCauseXkbReq(&cause
, X_kbSetNamedIndicator
, client
);
3491 XkbApplyLedNameChanges(dev
, sli
, namec
, &ed
, &changes
, &cause
);
3493 XkbApplyLedMapChanges(dev
, sli
, mapc
, &ed
, &changes
, &cause
);
3495 XkbApplyLedStateChanges(dev
, sli
, statec
, &ed
, &changes
, &cause
);
3498 if ((sli
->flags
& XkbSLI_HasOwnState
) == 0)
3499 kbd
= inputInfo
.keyboard
;
3500 XkbFlushLedEvents(dev
, kbd
, sli
, &ed
, &changes
, &cause
);
3506 ProcXkbSetNamedIndicator(ClientPtr client
)
3511 XkbIndicatorMapPtr map
;
3513 REQUEST(xkbSetNamedIndicatorReq
);
3514 REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq
);
3516 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
3519 CHK_LED_DEVICE(dev
, stuff
->deviceSpec
, client
, DixSetAttrAccess
);
3520 CHK_ATOM_ONLY(stuff
->indicator
);
3521 CHK_MASK_LEGAL(0x10, stuff
->whichGroups
, XkbIM_UseAnyGroup
);
3522 CHK_MASK_LEGAL(0x11, stuff
->whichMods
, XkbIM_UseAnyMods
);
3524 /* Dry-run for checks */
3525 rc
= _XkbCreateIndicatorMap(dev
, stuff
->indicator
,
3526 stuff
->ledClass
, stuff
->ledID
,
3528 if (rc
!= Success
|| !map
) /* couldn't be created or didn't exist */
3531 if (stuff
->deviceSpec
== XkbUseCoreKbd
||
3532 stuff
->deviceSpec
== XkbUseCorePtr
) {
3535 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
3536 if ((other
!= dev
) && !IsMaster(other
) &&
3537 GetMaster(other
, MASTER_KEYBOARD
) == dev
&& (other
->kbdfeed
||
3539 (XaceHook(XACE_DEVICE_ACCESS
, client
, other
, DixSetAttrAccess
)
3541 rc
= _XkbCreateIndicatorMap(other
, stuff
->indicator
,
3542 stuff
->ledClass
, stuff
->ledID
, &map
,
3544 if (rc
!= Success
|| !map
)
3550 /* All checks passed, let's do it */
3551 rc
= _XkbSetNamedIndicator(client
, dev
, stuff
);
3555 if (stuff
->deviceSpec
== XkbUseCoreKbd
||
3556 stuff
->deviceSpec
== XkbUseCorePtr
) {
3559 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
3560 if ((other
!= dev
) && !IsMaster(other
) &&
3561 GetMaster(other
, MASTER_KEYBOARD
) == dev
&& (other
->kbdfeed
||
3563 (XaceHook(XACE_DEVICE_ACCESS
, client
, other
, DixSetAttrAccess
)
3565 _XkbSetNamedIndicator(client
, other
, stuff
);
3573 /***====================================================================***/
3576 _XkbCountAtoms(Atom
*atoms
, int maxAtoms
, int *count
)
3578 register unsigned int i
, bit
, nAtoms
;
3579 register CARD32 atomsPresent
;
3581 for (i
= nAtoms
= atomsPresent
= 0, bit
= 1; i
< maxAtoms
; i
++, bit
<<= 1) {
3582 if (atoms
[i
] != None
) {
3583 atomsPresent
|= bit
;
3589 return atomsPresent
;
3593 _XkbWriteAtoms(char *wire
, Atom
*atoms
, int maxAtoms
, int swap
)
3595 register unsigned int i
;
3598 atm
= (Atom
*) wire
;
3599 for (i
= 0; i
< maxAtoms
; i
++) {
3600 if (atoms
[i
] != None
) {
3608 return (char *) atm
;
3612 XkbComputeGetNamesReplySize(XkbDescPtr xkb
, xkbGetNamesReply
* rep
)
3614 register unsigned which
, length
;
3617 rep
->minKeyCode
= xkb
->min_key_code
;
3618 rep
->maxKeyCode
= xkb
->max_key_code
;
3621 if (xkb
->names
!= NULL
) {
3622 if (which
& XkbKeycodesNameMask
)
3624 if (which
& XkbGeometryNameMask
)
3626 if (which
& XkbSymbolsNameMask
)
3628 if (which
& XkbPhysSymbolsNameMask
)
3630 if (which
& XkbTypesNameMask
)
3632 if (which
& XkbCompatNameMask
)
3636 which
&= ~XkbComponentNamesMask
;
3638 if (xkb
->map
!= NULL
) {
3639 if (which
& XkbKeyTypeNamesMask
)
3640 length
+= xkb
->map
->num_types
;
3641 rep
->nTypes
= xkb
->map
->num_types
;
3642 if (which
& XkbKTLevelNamesMask
) {
3643 XkbKeyTypePtr pType
= xkb
->map
->types
;
3646 length
+= XkbPaddedSize(xkb
->map
->num_types
) / 4;
3647 for (i
= 0; i
< xkb
->map
->num_types
; i
++, pType
++) {
3648 if (pType
->level_names
!= NULL
)
3649 nKTLevels
+= pType
->num_levels
;
3651 rep
->nKTLevels
= nKTLevels
;
3652 length
+= nKTLevels
;
3658 which
&= ~(XkbKeyTypeNamesMask
| XkbKTLevelNamesMask
);
3661 rep
->minKeyCode
= xkb
->min_key_code
;
3662 rep
->maxKeyCode
= xkb
->max_key_code
;
3663 rep
->indicators
= 0;
3664 rep
->virtualMods
= 0;
3665 rep
->groupNames
= 0;
3666 if (xkb
->names
!= NULL
) {
3667 if (which
& XkbIndicatorNamesMask
) {
3671 _XkbCountAtoms(xkb
->names
->indicators
, XkbNumIndicators
,
3675 which
&= ~XkbIndicatorNamesMask
;
3678 if (which
& XkbVirtualModNamesMask
) {
3682 _XkbCountAtoms(xkb
->names
->vmods
, XkbNumVirtualMods
, &nVMods
);
3685 which
&= ~XkbVirtualModNamesMask
;
3688 if (which
& XkbGroupNamesMask
) {
3692 _XkbCountAtoms(xkb
->names
->groups
, XkbNumKbdGroups
, &nGroups
);
3695 which
&= ~XkbGroupNamesMask
;
3698 if ((which
& XkbKeyNamesMask
) && (xkb
->names
->keys
))
3699 length
+= rep
->nKeys
;
3701 which
&= ~XkbKeyNamesMask
;
3703 if ((which
& XkbKeyAliasesMask
) &&
3704 (xkb
->names
->key_aliases
) && (xkb
->names
->num_key_aliases
> 0)) {
3705 rep
->nKeyAliases
= xkb
->names
->num_key_aliases
;
3706 length
+= rep
->nKeyAliases
* 2;
3709 which
&= ~XkbKeyAliasesMask
;
3710 rep
->nKeyAliases
= 0;
3713 if ((which
& XkbRGNamesMask
) && (xkb
->names
->num_rg
> 0))
3714 length
+= xkb
->names
->num_rg
;
3716 which
&= ~XkbRGNamesMask
;
3719 which
&= ~(XkbIndicatorNamesMask
| XkbVirtualModNamesMask
);
3720 which
&= ~(XkbGroupNamesMask
| XkbKeyNamesMask
| XkbKeyAliasesMask
);
3721 which
&= ~XkbRGNamesMask
;
3724 rep
->length
= length
;
3730 XkbSendNames(ClientPtr client
, XkbDescPtr xkb
, xkbGetNamesReply
* rep
)
3732 register unsigned i
, length
, which
;
3736 length
= rep
->length
* 4;
3738 if (client
->swapped
) {
3739 swaps(&rep
->sequenceNumber
);
3740 swapl(&rep
->length
);
3742 swaps(&rep
->virtualMods
);
3743 swapl(&rep
->indicators
);
3746 start
= desc
= calloc(1, length
);
3750 if (which
& XkbKeycodesNameMask
) {
3751 *((CARD32
*) desc
) = xkb
->names
->keycodes
;
3752 if (client
->swapped
) {
3753 swapl((int *) desc
);
3757 if (which
& XkbGeometryNameMask
) {
3758 *((CARD32
*) desc
) = xkb
->names
->geometry
;
3759 if (client
->swapped
) {
3760 swapl((int *) desc
);
3764 if (which
& XkbSymbolsNameMask
) {
3765 *((CARD32
*) desc
) = xkb
->names
->symbols
;
3766 if (client
->swapped
) {
3767 swapl((int *) desc
);
3771 if (which
& XkbPhysSymbolsNameMask
) {
3772 register CARD32
*atm
= (CARD32
*) desc
;
3774 atm
[0] = (CARD32
) xkb
->names
->phys_symbols
;
3775 if (client
->swapped
) {
3780 if (which
& XkbTypesNameMask
) {
3781 *((CARD32
*) desc
) = (CARD32
) xkb
->names
->types
;
3782 if (client
->swapped
) {
3783 swapl((int *) desc
);
3787 if (which
& XkbCompatNameMask
) {
3788 *((CARD32
*) desc
) = (CARD32
) xkb
->names
->compat
;
3789 if (client
->swapped
) {
3790 swapl((int *) desc
);
3794 if (which
& XkbKeyTypeNamesMask
) {
3795 register CARD32
*atm
= (CARD32
*) desc
;
3796 register XkbKeyTypePtr type
= xkb
->map
->types
;
3798 for (i
= 0; i
< xkb
->map
->num_types
; i
++, atm
++, type
++) {
3799 *atm
= (CARD32
) type
->name
;
3800 if (client
->swapped
) {
3804 desc
= (char *) atm
;
3806 if (which
& XkbKTLevelNamesMask
&& xkb
->map
) {
3807 XkbKeyTypePtr type
= xkb
->map
->types
;
3808 register CARD32
*atm
;
3810 for (i
= 0; i
< rep
->nTypes
; i
++, type
++) {
3811 *desc
++ = type
->num_levels
;
3813 desc
+= XkbPaddedSize(rep
->nTypes
) - rep
->nTypes
;
3815 atm
= (CARD32
*) desc
;
3816 type
= xkb
->map
->types
;
3817 for (i
= 0; i
< xkb
->map
->num_types
; i
++, type
++) {
3818 register unsigned l
;
3820 if (type
->level_names
) {
3821 for (l
= 0; l
< type
->num_levels
; l
++, atm
++) {
3822 *atm
= type
->level_names
[l
];
3823 if (client
->swapped
) {
3827 desc
+= type
->num_levels
* 4;
3831 if (which
& XkbIndicatorNamesMask
) {
3833 _XkbWriteAtoms(desc
, xkb
->names
->indicators
, XkbNumIndicators
,
3836 if (which
& XkbVirtualModNamesMask
) {
3837 desc
= _XkbWriteAtoms(desc
, xkb
->names
->vmods
, XkbNumVirtualMods
,
3840 if (which
& XkbGroupNamesMask
) {
3841 desc
= _XkbWriteAtoms(desc
, xkb
->names
->groups
, XkbNumKbdGroups
,
3844 if (which
& XkbKeyNamesMask
) {
3845 for (i
= 0; i
< rep
->nKeys
; i
++, desc
+= sizeof(XkbKeyNameRec
)) {
3846 *((XkbKeyNamePtr
) desc
) = xkb
->names
->keys
[i
+ rep
->firstKey
];
3849 if (which
& XkbKeyAliasesMask
) {
3852 pAl
= xkb
->names
->key_aliases
;
3853 for (i
= 0; i
< rep
->nKeyAliases
;
3854 i
++, pAl
++, desc
+= 2 * XkbKeyNameLength
) {
3855 *((XkbKeyAliasPtr
) desc
) = *pAl
;
3858 if ((which
& XkbRGNamesMask
) && (rep
->nRadioGroups
> 0)) {
3859 register CARD32
*atm
= (CARD32
*) desc
;
3861 for (i
= 0; i
< rep
->nRadioGroups
; i
++, atm
++) {
3862 *atm
= (CARD32
) xkb
->names
->radio_groups
[i
];
3863 if (client
->swapped
) {
3867 desc
+= rep
->nRadioGroups
* 4;
3871 if ((desc
- start
) != (length
)) {
3872 ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n",
3873 length
, (unsigned long) (desc
- start
));
3875 WriteToClient(client
, SIZEOF(xkbGetNamesReply
), rep
);
3876 WriteToClient(client
, length
, start
);
3877 free((char *) start
);
3882 ProcXkbGetNames(ClientPtr client
)
3886 xkbGetNamesReply rep
;
3888 REQUEST(xkbGetNamesReq
);
3889 REQUEST_SIZE_MATCH(xkbGetNamesReq
);
3891 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
3894 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
3895 CHK_MASK_LEGAL(0x01, stuff
->which
, XkbAllNamesMask
);
3897 xkb
= dev
->key
->xkbInfo
->desc
;
3898 rep
= (xkbGetNamesReply
) {
3900 .deviceID
= dev
->id
,
3901 .sequenceNumber
= client
->sequence
,
3903 .which
= stuff
->which
,
3904 .nTypes
= xkb
->map
->num_types
,
3905 .firstKey
= xkb
->min_key_code
,
3906 .nKeys
= XkbNumKeys(xkb
),
3907 .nKeyAliases
= xkb
->names
? xkb
->names
->num_key_aliases
: 0,
3908 .nRadioGroups
= xkb
->names
? xkb
->names
->num_rg
: 0
3910 XkbComputeGetNamesReplySize(xkb
, &rep
);
3911 return XkbSendNames(client
, xkb
, &rep
);
3914 /***====================================================================***/
3917 _XkbCheckAtoms(CARD32
*wire
, int nAtoms
, int swapped
, Atom
*pError
)
3921 for (i
= 0; i
< nAtoms
; i
++, wire
++) {
3925 if ((((Atom
) *wire
) != None
) && (!ValidAtom((Atom
) *wire
))) {
3926 *pError
= ((Atom
) *wire
);
3934 _XkbCheckMaskedAtoms(CARD32
*wire
, int nAtoms
, CARD32 present
, int swapped
,
3937 register unsigned i
, bit
;
3939 for (i
= 0, bit
= 1; (i
< nAtoms
) && (present
); i
++, bit
<<= 1) {
3940 if ((present
& bit
) == 0)
3945 if ((((Atom
) *wire
) != None
) && (!ValidAtom(((Atom
) *wire
)))) {
3946 *pError
= (Atom
) *wire
;
3955 _XkbCopyMaskedAtoms(Atom
*wire
, Atom
*dest
, int nAtoms
, CARD32 present
)
3957 register int i
, bit
;
3959 for (i
= 0, bit
= 1; (i
< nAtoms
) && (present
); i
++, bit
<<= 1) {
3960 if ((present
& bit
) == 0)
3968 _XkbCheckTypeName(Atom name
, int typeNdx
)
3972 str
= NameForAtom(name
);
3973 if ((strcmp(str
, "ONE_LEVEL") == 0) || (strcmp(str
, "TWO_LEVEL") == 0) ||
3974 (strcmp(str
, "ALPHABETIC") == 0) || (strcmp(str
, "KEYPAD") == 0))
3980 * Check the device-dependent data in the request against the device. Returns
3981 * Success, or the appropriate error code.
3984 _XkbSetNamesCheck(ClientPtr client
, DeviceIntPtr dev
,
3985 xkbSetNamesReq
* stuff
, CARD32
*data
)
3992 xkb
= dev
->key
->xkbInfo
->desc
;
3994 if (stuff
->which
& XkbKeyTypeNamesMask
) {
3998 if (stuff
->nTypes
< 1) {
3999 client
->errorValue
= _XkbErrCode2(0x02, stuff
->nTypes
);
4002 if ((unsigned) (stuff
->firstType
+ stuff
->nTypes
- 1) >=
4003 xkb
->map
->num_types
) {
4004 client
->errorValue
=
4005 _XkbErrCode4(0x03, stuff
->firstType
, stuff
->nTypes
,
4006 xkb
->map
->num_types
);
4009 if (((unsigned) stuff
->firstType
) <= XkbLastRequiredType
) {
4010 client
->errorValue
= _XkbErrCode2(0x04, stuff
->firstType
);
4014 tmp
= _XkbCheckAtoms(tmp
, stuff
->nTypes
, client
->swapped
, &bad
);
4016 client
->errorValue
= bad
;
4019 for (i
= 0; i
< stuff
->nTypes
; i
++, old
++) {
4020 if (!_XkbCheckTypeName((Atom
) *old
, stuff
->firstType
+ i
))
4021 client
->errorValue
= _XkbErrCode2(0x05, i
);
4024 if (stuff
->which
& XkbKTLevelNamesMask
) {
4029 if (stuff
->nKTLevels
< 1) {
4030 client
->errorValue
= _XkbErrCode2(0x05, stuff
->nKTLevels
);
4033 if ((unsigned) (stuff
->firstKTLevel
+ stuff
->nKTLevels
- 1) >=
4034 xkb
->map
->num_types
) {
4035 client
->errorValue
= _XkbErrCode4(0x06, stuff
->firstKTLevel
,
4037 xkb
->map
->num_types
);
4040 width
= (CARD8
*) tmp
;
4041 tmp
= (CARD32
*) (((char *) tmp
) + XkbPaddedSize(stuff
->nKTLevels
));
4042 type
= &xkb
->map
->types
[stuff
->firstKTLevel
];
4043 for (i
= 0; i
< stuff
->nKTLevels
; i
++, type
++) {
4046 else if (width
[i
] != type
->num_levels
) {
4047 client
->errorValue
= _XkbErrCode4(0x07, i
+ stuff
->firstKTLevel
,
4048 type
->num_levels
, width
[i
]);
4051 tmp
= _XkbCheckAtoms(tmp
, width
[i
], client
->swapped
, &bad
);
4053 client
->errorValue
= bad
;
4058 if (stuff
->which
& XkbIndicatorNamesMask
) {
4059 if (stuff
->indicators
== 0) {
4060 client
->errorValue
= 0x08;
4063 tmp
= _XkbCheckMaskedAtoms(tmp
, XkbNumIndicators
, stuff
->indicators
,
4064 client
->swapped
, &bad
);
4066 client
->errorValue
= bad
;
4070 if (stuff
->which
& XkbVirtualModNamesMask
) {
4071 if (stuff
->virtualMods
== 0) {
4072 client
->errorValue
= 0x09;
4075 tmp
= _XkbCheckMaskedAtoms(tmp
, XkbNumVirtualMods
,
4076 (CARD32
) stuff
->virtualMods
,
4077 client
->swapped
, &bad
);
4079 client
->errorValue
= bad
;
4083 if (stuff
->which
& XkbGroupNamesMask
) {
4084 if (stuff
->groupNames
== 0) {
4085 client
->errorValue
= 0x0a;
4088 tmp
= _XkbCheckMaskedAtoms(tmp
, XkbNumKbdGroups
,
4089 (CARD32
) stuff
->groupNames
,
4090 client
->swapped
, &bad
);
4092 client
->errorValue
= bad
;
4096 if (stuff
->which
& XkbKeyNamesMask
) {
4097 if (stuff
->firstKey
< (unsigned) xkb
->min_key_code
) {
4098 client
->errorValue
= _XkbErrCode3(0x0b, xkb
->min_key_code
,
4102 if (((unsigned) (stuff
->firstKey
+ stuff
->nKeys
- 1) >
4103 xkb
->max_key_code
) || (stuff
->nKeys
< 1)) {
4104 client
->errorValue
=
4105 _XkbErrCode4(0x0c, xkb
->max_key_code
, stuff
->firstKey
,
4109 tmp
+= stuff
->nKeys
;
4111 if ((stuff
->which
& XkbKeyAliasesMask
) && (stuff
->nKeyAliases
> 0)) {
4112 tmp
+= stuff
->nKeyAliases
* 2;
4114 if (stuff
->which
& XkbRGNamesMask
) {
4115 if (stuff
->nRadioGroups
< 1) {
4116 client
->errorValue
= _XkbErrCode2(0x0d, stuff
->nRadioGroups
);
4119 tmp
= _XkbCheckAtoms(tmp
, stuff
->nRadioGroups
, client
->swapped
, &bad
);
4121 client
->errorValue
= bad
;
4125 if ((tmp
- ((CARD32
*) stuff
)) != stuff
->length
) {
4126 client
->errorValue
= stuff
->length
;
4134 _XkbSetNames(ClientPtr client
, DeviceIntPtr dev
, xkbSetNamesReq
* stuff
)
4141 tmp
= (CARD32
*) &stuff
[1];
4142 xkb
= dev
->key
->xkbInfo
->desc
;
4145 if (XkbAllocNames(xkb
, stuff
->which
, stuff
->nRadioGroups
,
4146 stuff
->nKeyAliases
) != Success
) {
4150 memset(&nn
, 0, sizeof(xkbNamesNotify
));
4151 nn
.changed
= stuff
->which
;
4152 tmp
= (CARD32
*) &stuff
[1];
4153 if (stuff
->which
& XkbKeycodesNameMask
)
4154 names
->keycodes
= *tmp
++;
4155 if (stuff
->which
& XkbGeometryNameMask
)
4156 names
->geometry
= *tmp
++;
4157 if (stuff
->which
& XkbSymbolsNameMask
)
4158 names
->symbols
= *tmp
++;
4159 if (stuff
->which
& XkbPhysSymbolsNameMask
)
4160 names
->phys_symbols
= *tmp
++;
4161 if (stuff
->which
& XkbTypesNameMask
)
4162 names
->types
= *tmp
++;
4163 if (stuff
->which
& XkbCompatNameMask
)
4164 names
->compat
= *tmp
++;
4165 if ((stuff
->which
& XkbKeyTypeNamesMask
) && (stuff
->nTypes
> 0)) {
4166 register unsigned i
;
4167 register XkbKeyTypePtr type
;
4169 type
= &xkb
->map
->types
[stuff
->firstType
];
4170 for (i
= 0; i
< stuff
->nTypes
; i
++, type
++) {
4171 type
->name
= *tmp
++;
4173 nn
.firstType
= stuff
->firstType
;
4174 nn
.nTypes
= stuff
->nTypes
;
4176 if (stuff
->which
& XkbKTLevelNamesMask
) {
4177 register XkbKeyTypePtr type
;
4178 register unsigned i
;
4181 width
= (CARD8
*) tmp
;
4182 tmp
= (CARD32
*) (((char *) tmp
) + XkbPaddedSize(stuff
->nKTLevels
));
4183 type
= &xkb
->map
->types
[stuff
->firstKTLevel
];
4184 for (i
= 0; i
< stuff
->nKTLevels
; i
++, type
++) {
4186 if (type
->level_names
) {
4187 register unsigned n
;
4189 for (n
= 0; n
< width
[i
]; n
++) {
4190 type
->level_names
[n
] = tmp
[n
];
4196 nn
.firstLevelName
= 0;
4197 nn
.nLevelNames
= stuff
->nTypes
;
4199 if (stuff
->which
& XkbIndicatorNamesMask
) {
4200 tmp
= _XkbCopyMaskedAtoms(tmp
, names
->indicators
, XkbNumIndicators
,
4202 nn
.changedIndicators
= stuff
->indicators
;
4204 if (stuff
->which
& XkbVirtualModNamesMask
) {
4205 tmp
= _XkbCopyMaskedAtoms(tmp
, names
->vmods
, XkbNumVirtualMods
,
4206 stuff
->virtualMods
);
4207 nn
.changedVirtualMods
= stuff
->virtualMods
;
4209 if (stuff
->which
& XkbGroupNamesMask
) {
4210 tmp
= _XkbCopyMaskedAtoms(tmp
, names
->groups
, XkbNumKbdGroups
,
4212 nn
.changedVirtualMods
= stuff
->groupNames
;
4214 if (stuff
->which
& XkbKeyNamesMask
) {
4215 memcpy((char *) &names
->keys
[stuff
->firstKey
], (char *) tmp
,
4216 stuff
->nKeys
* XkbKeyNameLength
);
4217 tmp
+= stuff
->nKeys
;
4218 nn
.firstKey
= stuff
->firstKey
;
4219 nn
.nKeys
= stuff
->nKeys
;
4221 if (stuff
->which
& XkbKeyAliasesMask
) {
4222 if (stuff
->nKeyAliases
> 0) {
4223 register int na
= stuff
->nKeyAliases
;
4225 if (XkbAllocNames(xkb
, XkbKeyAliasesMask
, 0, na
) != Success
)
4227 memcpy((char *) names
->key_aliases
, (char *) tmp
,
4228 stuff
->nKeyAliases
* sizeof(XkbKeyAliasRec
));
4229 tmp
+= stuff
->nKeyAliases
* 2;
4231 else if (names
->key_aliases
!= NULL
) {
4232 free(names
->key_aliases
);
4233 names
->key_aliases
= NULL
;
4234 names
->num_key_aliases
= 0;
4236 nn
.nAliases
= names
->num_key_aliases
;
4238 if (stuff
->which
& XkbRGNamesMask
) {
4239 if (stuff
->nRadioGroups
> 0) {
4240 register unsigned i
, nrg
;
4242 nrg
= stuff
->nRadioGroups
;
4243 if (XkbAllocNames(xkb
, XkbRGNamesMask
, nrg
, 0) != Success
)
4246 for (i
= 0; i
< stuff
->nRadioGroups
; i
++) {
4247 names
->radio_groups
[i
] = tmp
[i
];
4249 tmp
+= stuff
->nRadioGroups
;
4251 else if (names
->radio_groups
) {
4252 free(names
->radio_groups
);
4253 names
->radio_groups
= NULL
;
4256 nn
.nRadioGroups
= names
->num_rg
;
4261 needExtEvent
= (nn
.changed
& XkbIndicatorNamesMask
) != 0;
4262 XkbSendNamesNotify(dev
, &nn
);
4264 XkbSrvLedInfoPtr sli
;
4265 xkbExtensionDeviceNotify edev
;
4267 register unsigned bit
;
4269 sli
= XkbFindSrvLedInfo(dev
, XkbDfltXIClass
, XkbDfltXIId
,
4270 XkbXI_IndicatorsMask
);
4271 sli
->namesPresent
= 0;
4272 for (i
= 0, bit
= 1; i
< XkbNumIndicators
; i
++, bit
<<= 1) {
4273 if (names
->indicators
[i
] != None
)
4274 sli
->namesPresent
|= bit
;
4276 memset(&edev
, 0, sizeof(xkbExtensionDeviceNotify
));
4277 edev
.reason
= XkbXI_IndicatorNamesMask
;
4278 edev
.ledClass
= KbdFeedbackClass
;
4279 edev
.ledID
= dev
->kbdfeed
->ctrl
.id
;
4280 edev
.ledsDefined
= sli
->namesPresent
| sli
->mapsPresent
;
4281 edev
.ledState
= sli
->effectiveState
;
4284 edev
.supported
= XkbXI_AllFeaturesMask
;
4285 edev
.unsupported
= 0;
4286 XkbSendExtensionDeviceNotify(dev
, client
, &edev
);
4293 ProcXkbSetNames(ClientPtr client
)
4300 REQUEST(xkbSetNamesReq
);
4301 REQUEST_AT_LEAST_SIZE(xkbSetNamesReq
);
4303 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
4306 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixManageAccess
);
4307 CHK_MASK_LEGAL(0x01, stuff
->which
, XkbAllNamesMask
);
4309 /* check device-independent stuff */
4310 tmp
= (CARD32
*) &stuff
[1];
4312 if (stuff
->which
& XkbKeycodesNameMask
) {
4313 tmp
= _XkbCheckAtoms(tmp
, 1, client
->swapped
, &bad
);
4315 client
->errorValue
= bad
;
4319 if (stuff
->which
& XkbGeometryNameMask
) {
4320 tmp
= _XkbCheckAtoms(tmp
, 1, client
->swapped
, &bad
);
4322 client
->errorValue
= bad
;
4326 if (stuff
->which
& XkbSymbolsNameMask
) {
4327 tmp
= _XkbCheckAtoms(tmp
, 1, client
->swapped
, &bad
);
4329 client
->errorValue
= bad
;
4333 if (stuff
->which
& XkbPhysSymbolsNameMask
) {
4334 tmp
= _XkbCheckAtoms(tmp
, 1, client
->swapped
, &bad
);
4336 client
->errorValue
= bad
;
4340 if (stuff
->which
& XkbTypesNameMask
) {
4341 tmp
= _XkbCheckAtoms(tmp
, 1, client
->swapped
, &bad
);
4343 client
->errorValue
= bad
;
4347 if (stuff
->which
& XkbCompatNameMask
) {
4348 tmp
= _XkbCheckAtoms(tmp
, 1, client
->swapped
, &bad
);
4350 client
->errorValue
= bad
;
4355 /* start of device-dependent tests */
4356 rc
= _XkbSetNamesCheck(client
, dev
, stuff
, tmp
);
4360 if (stuff
->deviceSpec
== XkbUseCoreKbd
) {
4363 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
4364 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
4365 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
4367 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
4369 if (rc
== Success
) {
4370 rc
= _XkbSetNamesCheck(client
, other
, stuff
, tmp
);
4378 /* everything is okay -- update names */
4380 rc
= _XkbSetNames(client
, dev
, stuff
);
4384 if (stuff
->deviceSpec
== XkbUseCoreKbd
) {
4387 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
4388 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
4389 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
4391 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
4394 _XkbSetNames(client
, other
, stuff
);
4399 /* everything is okay -- update names */
4404 /***====================================================================***/
4406 #include "xkbgeom.h"
4408 #define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4)
4411 * Write the zero-terminated string str into wire as a pascal string with a
4412 * 16-bit length field prefixed before the actual string.
4414 * @param wire The destination array, usually the wire struct
4415 * @param str The source string as zero-terminated C string
4416 * @param swap If TRUE, the length field is swapped.
4418 * @return The input string in the format <string length><string> with a
4419 * (swapped) 16 bit string length, non-zero terminated.
4422 XkbWriteCountedString(char *wire
, char *str
, Bool swap
)
4424 CARD16 len
, *pLen
, paddedLen
;
4430 pLen
= (CARD16
*) wire
;
4435 paddedLen
= pad_to_int32(sizeof(len
) + len
) - sizeof(len
);
4436 strncpy(&wire
[sizeof(len
)], str
, paddedLen
);
4437 wire
+= sizeof(len
) + paddedLen
;
4442 XkbSizeGeomProperties(XkbGeometryPtr geom
)
4444 register int i
, size
;
4445 XkbPropertyPtr prop
;
4447 for (size
= i
= 0, prop
= geom
->properties
; i
< geom
->num_properties
;
4449 size
+= XkbSizeCountedString(prop
->name
);
4450 size
+= XkbSizeCountedString(prop
->value
);
4456 XkbWriteGeomProperties(char *wire
, XkbGeometryPtr geom
, Bool swap
)
4459 register XkbPropertyPtr prop
;
4461 for (i
= 0, prop
= geom
->properties
; i
< geom
->num_properties
; i
++, prop
++) {
4462 wire
= XkbWriteCountedString(wire
, prop
->name
, swap
);
4463 wire
= XkbWriteCountedString(wire
, prop
->value
, swap
);
4469 XkbSizeGeomKeyAliases(XkbGeometryPtr geom
)
4471 return geom
->num_key_aliases
* (2 * XkbKeyNameLength
);
4475 XkbWriteGeomKeyAliases(char *wire
, XkbGeometryPtr geom
, Bool swap
)
4479 sz
= geom
->num_key_aliases
* (XkbKeyNameLength
* 2);
4481 memcpy(wire
, (char *) geom
->key_aliases
, sz
);
4488 XkbSizeGeomColors(XkbGeometryPtr geom
)
4490 register int i
, size
;
4491 register XkbColorPtr color
;
4493 for (i
= size
= 0, color
= geom
->colors
; i
< geom
->num_colors
; i
++, color
++) {
4494 size
+= XkbSizeCountedString(color
->spec
);
4500 XkbWriteGeomColors(char *wire
, XkbGeometryPtr geom
, Bool swap
)
4503 register XkbColorPtr color
;
4505 for (i
= 0, color
= geom
->colors
; i
< geom
->num_colors
; i
++, color
++) {
4506 wire
= XkbWriteCountedString(wire
, color
->spec
, swap
);
4512 XkbSizeGeomShapes(XkbGeometryPtr geom
)
4514 register int i
, size
;
4515 register XkbShapePtr shape
;
4517 for (i
= size
= 0, shape
= geom
->shapes
; i
< geom
->num_shapes
; i
++, shape
++) {
4519 register XkbOutlinePtr ol
;
4521 size
+= SIZEOF(xkbShapeWireDesc
);
4522 for (n
= 0, ol
= shape
->outlines
; n
< shape
->num_outlines
; n
++, ol
++) {
4523 size
+= SIZEOF(xkbOutlineWireDesc
);
4524 size
+= ol
->num_points
* SIZEOF(xkbPointWireDesc
);
4531 XkbWriteGeomShapes(char *wire
, XkbGeometryPtr geom
, Bool swap
)
4535 xkbShapeWireDesc
*shapeWire
;
4537 for (i
= 0, shape
= geom
->shapes
; i
< geom
->num_shapes
; i
++, shape
++) {
4540 xkbOutlineWireDesc
*olWire
;
4542 shapeWire
= (xkbShapeWireDesc
*) wire
;
4543 shapeWire
->name
= shape
->name
;
4544 shapeWire
->nOutlines
= shape
->num_outlines
;
4545 if (shape
->primary
!= NULL
)
4546 shapeWire
->primaryNdx
= XkbOutlineIndex(shape
, shape
->primary
);
4548 shapeWire
->primaryNdx
= XkbNoShape
;
4549 if (shape
->approx
!= NULL
)
4550 shapeWire
->approxNdx
= XkbOutlineIndex(shape
, shape
->approx
);
4552 shapeWire
->approxNdx
= XkbNoShape
;
4555 swapl(&shapeWire
->name
);
4557 wire
= (char *) &shapeWire
[1];
4558 for (o
= 0, ol
= shape
->outlines
; o
< shape
->num_outlines
; o
++, ol
++) {
4561 xkbPointWireDesc
*ptWire
;
4563 olWire
= (xkbOutlineWireDesc
*) wire
;
4564 olWire
->nPoints
= ol
->num_points
;
4565 olWire
->cornerRadius
= ol
->corner_radius
;
4567 wire
= (char *) &olWire
[1];
4568 ptWire
= (xkbPointWireDesc
*) wire
;
4569 for (p
= 0, pt
= ol
->points
; p
< ol
->num_points
; p
++, pt
++) {
4570 ptWire
[p
].x
= pt
->x
;
4571 ptWire
[p
].y
= pt
->y
;
4573 swaps(&ptWire
[p
].x
);
4574 swaps(&ptWire
[p
].y
);
4577 wire
= (char *) &ptWire
[ol
->num_points
];
4584 XkbSizeGeomDoodads(int num_doodads
, XkbDoodadPtr doodad
)
4586 register int i
, size
;
4588 for (i
= size
= 0; i
< num_doodads
; i
++, doodad
++) {
4589 size
+= SIZEOF(xkbAnyDoodadWireDesc
);
4590 if (doodad
->any
.type
== XkbTextDoodad
) {
4591 size
+= XkbSizeCountedString(doodad
->text
.text
);
4592 size
+= XkbSizeCountedString(doodad
->text
.font
);
4594 else if (doodad
->any
.type
== XkbLogoDoodad
) {
4595 size
+= XkbSizeCountedString(doodad
->logo
.logo_name
);
4602 XkbWriteGeomDoodads(char *wire
, int num_doodads
, XkbDoodadPtr doodad
, Bool swap
)
4605 xkbDoodadWireDesc
*doodadWire
;
4607 for (i
= 0; i
< num_doodads
; i
++, doodad
++) {
4608 doodadWire
= (xkbDoodadWireDesc
*) wire
;
4609 wire
= (char *) &doodadWire
[1];
4610 memset(doodadWire
, 0, SIZEOF(xkbDoodadWireDesc
));
4611 doodadWire
->any
.name
= doodad
->any
.name
;
4612 doodadWire
->any
.type
= doodad
->any
.type
;
4613 doodadWire
->any
.priority
= doodad
->any
.priority
;
4614 doodadWire
->any
.top
= doodad
->any
.top
;
4615 doodadWire
->any
.left
= doodad
->any
.left
;
4617 swapl(&doodadWire
->any
.name
);
4618 swaps(&doodadWire
->any
.top
);
4619 swaps(&doodadWire
->any
.left
);
4621 switch (doodad
->any
.type
) {
4622 case XkbOutlineDoodad
:
4623 case XkbSolidDoodad
:
4624 doodadWire
->shape
.angle
= doodad
->shape
.angle
;
4625 doodadWire
->shape
.colorNdx
= doodad
->shape
.color_ndx
;
4626 doodadWire
->shape
.shapeNdx
= doodad
->shape
.shape_ndx
;
4628 swaps(&doodadWire
->shape
.angle
);
4632 doodadWire
->text
.angle
= doodad
->text
.angle
;
4633 doodadWire
->text
.width
= doodad
->text
.width
;
4634 doodadWire
->text
.height
= doodad
->text
.height
;
4635 doodadWire
->text
.colorNdx
= doodad
->text
.color_ndx
;
4637 swaps(&doodadWire
->text
.angle
);
4638 swaps(&doodadWire
->text
.width
);
4639 swaps(&doodadWire
->text
.height
);
4641 wire
= XkbWriteCountedString(wire
, doodad
->text
.text
, swap
);
4642 wire
= XkbWriteCountedString(wire
, doodad
->text
.font
, swap
);
4644 case XkbIndicatorDoodad
:
4645 doodadWire
->indicator
.shapeNdx
= doodad
->indicator
.shape_ndx
;
4646 doodadWire
->indicator
.onColorNdx
= doodad
->indicator
.on_color_ndx
;
4647 doodadWire
->indicator
.offColorNdx
= doodad
->indicator
.off_color_ndx
;
4650 doodadWire
->logo
.angle
= doodad
->logo
.angle
;
4651 doodadWire
->logo
.colorNdx
= doodad
->logo
.color_ndx
;
4652 doodadWire
->logo
.shapeNdx
= doodad
->logo
.shape_ndx
;
4653 wire
= XkbWriteCountedString(wire
, doodad
->logo
.logo_name
, swap
);
4656 ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n",
4658 ErrorF("[xkb] Ignored\n");
4666 XkbWriteGeomOverlay(char *wire
, XkbOverlayPtr ol
, Bool swap
)
4669 XkbOverlayRowPtr row
;
4670 xkbOverlayWireDesc
*olWire
;
4672 olWire
= (xkbOverlayWireDesc
*) wire
;
4673 olWire
->name
= ol
->name
;
4674 olWire
->nRows
= ol
->num_rows
;
4678 swapl(&olWire
->name
);
4680 wire
= (char *) &olWire
[1];
4681 for (r
= 0, row
= ol
->rows
; r
< ol
->num_rows
; r
++, row
++) {
4683 XkbOverlayKeyPtr key
;
4684 xkbOverlayRowWireDesc
*rowWire
;
4686 rowWire
= (xkbOverlayRowWireDesc
*) wire
;
4687 rowWire
->rowUnder
= row
->row_under
;
4688 rowWire
->nKeys
= row
->num_keys
;
4690 wire
= (char *) &rowWire
[1];
4691 for (k
= 0, key
= row
->keys
; k
< row
->num_keys
; k
++, key
++) {
4692 xkbOverlayKeyWireDesc
*keyWire
;
4694 keyWire
= (xkbOverlayKeyWireDesc
*) wire
;
4695 memcpy(keyWire
->over
, key
->over
.name
, XkbKeyNameLength
);
4696 memcpy(keyWire
->under
, key
->under
.name
, XkbKeyNameLength
);
4697 wire
= (char *) &keyWire
[1];
4704 XkbSizeGeomSections(XkbGeometryPtr geom
)
4706 register int i
, size
;
4707 XkbSectionPtr section
;
4709 for (i
= size
= 0, section
= geom
->sections
; i
< geom
->num_sections
;
4711 size
+= SIZEOF(xkbSectionWireDesc
);
4712 if (section
->rows
) {
4716 for (r
= 0, row
= section
->rows
; r
< section
->num_rows
; row
++, r
++) {
4717 size
+= SIZEOF(xkbRowWireDesc
);
4718 size
+= row
->num_keys
* SIZEOF(xkbKeyWireDesc
);
4721 if (section
->doodads
)
4722 size
+= XkbSizeGeomDoodads(section
->num_doodads
, section
->doodads
);
4723 if (section
->overlays
) {
4727 for (o
= 0, ol
= section
->overlays
; o
< section
->num_overlays
;
4730 XkbOverlayRowPtr row
;
4732 size
+= SIZEOF(xkbOverlayWireDesc
);
4733 for (r
= 0, row
= ol
->rows
; r
< ol
->num_rows
; r
++, row
++) {
4734 size
+= SIZEOF(xkbOverlayRowWireDesc
);
4735 size
+= row
->num_keys
* SIZEOF(xkbOverlayKeyWireDesc
);
4744 XkbWriteGeomSections(char *wire
, XkbGeometryPtr geom
, Bool swap
)
4747 XkbSectionPtr section
;
4748 xkbSectionWireDesc
*sectionWire
;
4750 for (i
= 0, section
= geom
->sections
; i
< geom
->num_sections
;
4752 sectionWire
= (xkbSectionWireDesc
*) wire
;
4753 sectionWire
->name
= section
->name
;
4754 sectionWire
->top
= section
->top
;
4755 sectionWire
->left
= section
->left
;
4756 sectionWire
->width
= section
->width
;
4757 sectionWire
->height
= section
->height
;
4758 sectionWire
->angle
= section
->angle
;
4759 sectionWire
->priority
= section
->priority
;
4760 sectionWire
->nRows
= section
->num_rows
;
4761 sectionWire
->nDoodads
= section
->num_doodads
;
4762 sectionWire
->nOverlays
= section
->num_overlays
;
4763 sectionWire
->pad
= 0;
4765 swapl(§ionWire
->name
);
4766 swaps(§ionWire
->top
);
4767 swaps(§ionWire
->left
);
4768 swaps(§ionWire
->width
);
4769 swaps(§ionWire
->height
);
4770 swaps(§ionWire
->angle
);
4772 wire
= (char *) §ionWire
[1];
4773 if (section
->rows
) {
4776 xkbRowWireDesc
*rowWire
;
4778 for (r
= 0, row
= section
->rows
; r
< section
->num_rows
; r
++, row
++) {
4779 rowWire
= (xkbRowWireDesc
*) wire
;
4780 rowWire
->top
= row
->top
;
4781 rowWire
->left
= row
->left
;
4782 rowWire
->nKeys
= row
->num_keys
;
4783 rowWire
->vertical
= row
->vertical
;
4786 swaps(&rowWire
->top
);
4787 swaps(&rowWire
->left
);
4789 wire
= (char *) &rowWire
[1];
4793 xkbKeyWireDesc
*keyWire
;
4795 keyWire
= (xkbKeyWireDesc
*) wire
;
4796 for (k
= 0, key
= row
->keys
; k
< row
->num_keys
; k
++, key
++) {
4797 memcpy(keyWire
[k
].name
, key
->name
.name
,
4799 keyWire
[k
].gap
= key
->gap
;
4800 keyWire
[k
].shapeNdx
= key
->shape_ndx
;
4801 keyWire
[k
].colorNdx
= key
->color_ndx
;
4803 swaps(&keyWire
[k
].gap
);
4806 wire
= (char *) &keyWire
[row
->num_keys
];
4810 if (section
->doodads
) {
4811 wire
= XkbWriteGeomDoodads(wire
,
4812 section
->num_doodads
, section
->doodads
,
4815 if (section
->overlays
) {
4818 for (o
= 0; o
< section
->num_overlays
; o
++) {
4819 wire
= XkbWriteGeomOverlay(wire
, §ion
->overlays
[o
], swap
);
4827 XkbComputeGetGeometryReplySize(XkbGeometryPtr geom
,
4828 xkbGetGeometryReply
* rep
, Atom name
)
4833 len
= XkbSizeCountedString(geom
->label_font
);
4834 len
+= XkbSizeGeomProperties(geom
);
4835 len
+= XkbSizeGeomColors(geom
);
4836 len
+= XkbSizeGeomShapes(geom
);
4837 len
+= XkbSizeGeomSections(geom
);
4838 len
+= XkbSizeGeomDoodads(geom
->num_doodads
, geom
->doodads
);
4839 len
+= XkbSizeGeomKeyAliases(geom
);
4840 rep
->length
= len
/ 4;
4842 rep
->name
= geom
->name
;
4843 rep
->widthMM
= geom
->width_mm
;
4844 rep
->heightMM
= geom
->height_mm
;
4845 rep
->nProperties
= geom
->num_properties
;
4846 rep
->nColors
= geom
->num_colors
;
4847 rep
->nShapes
= geom
->num_shapes
;
4848 rep
->nSections
= geom
->num_sections
;
4849 rep
->nDoodads
= geom
->num_doodads
;
4850 rep
->nKeyAliases
= geom
->num_key_aliases
;
4851 rep
->baseColorNdx
= XkbGeomColorIndex(geom
, geom
->base_color
);
4852 rep
->labelColorNdx
= XkbGeomColorIndex(geom
, geom
->label_color
);
4858 rep
->widthMM
= rep
->heightMM
= 0;
4859 rep
->nProperties
= rep
->nColors
= rep
->nShapes
= 0;
4860 rep
->nSections
= rep
->nDoodads
= 0;
4861 rep
->nKeyAliases
= 0;
4862 rep
->labelColorNdx
= rep
->baseColorNdx
= 0;
4868 XkbSendGeometry(ClientPtr client
,
4869 XkbGeometryPtr geom
, xkbGetGeometryReply
* rep
, Bool freeGeom
)
4875 len
= rep
->length
* 4;
4876 start
= desc
= malloc(len
);
4879 desc
= XkbWriteCountedString(desc
, geom
->label_font
, client
->swapped
);
4880 if (rep
->nProperties
> 0)
4881 desc
= XkbWriteGeomProperties(desc
, geom
, client
->swapped
);
4882 if (rep
->nColors
> 0)
4883 desc
= XkbWriteGeomColors(desc
, geom
, client
->swapped
);
4884 if (rep
->nShapes
> 0)
4885 desc
= XkbWriteGeomShapes(desc
, geom
, client
->swapped
);
4886 if (rep
->nSections
> 0)
4887 desc
= XkbWriteGeomSections(desc
, geom
, client
->swapped
);
4888 if (rep
->nDoodads
> 0)
4889 desc
= XkbWriteGeomDoodads(desc
, geom
->num_doodads
, geom
->doodads
,
4891 if (rep
->nKeyAliases
> 0)
4892 desc
= XkbWriteGeomKeyAliases(desc
, geom
, client
->swapped
);
4893 if ((desc
- start
) != (len
)) {
4895 ("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n",
4896 len
, (unsigned long) (desc
- start
));
4903 if (client
->swapped
) {
4904 swaps(&rep
->sequenceNumber
);
4905 swapl(&rep
->length
);
4907 swaps(&rep
->widthMM
);
4908 swaps(&rep
->heightMM
);
4909 swaps(&rep
->nProperties
);
4910 swaps(&rep
->nColors
);
4911 swaps(&rep
->nShapes
);
4912 swaps(&rep
->nSections
);
4913 swaps(&rep
->nDoodads
);
4914 swaps(&rep
->nKeyAliases
);
4916 WriteToClient(client
, SIZEOF(xkbGetGeometryReply
), rep
);
4918 WriteToClient(client
, len
, start
);
4920 free((char *) start
);
4922 XkbFreeGeometry(geom
, XkbGeomAllMask
, TRUE
);
4927 ProcXkbGetGeometry(ClientPtr client
)
4930 xkbGetGeometryReply rep
;
4931 XkbGeometryPtr geom
;
4935 REQUEST(xkbGetGeometryReq
);
4936 REQUEST_SIZE_MATCH(xkbGetGeometryReq
);
4938 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
4941 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
4942 CHK_ATOM_OR_NONE(stuff
->name
);
4944 geom
= XkbLookupNamedGeometry(dev
, stuff
->name
, &shouldFree
);
4945 rep
= (xkbGetGeometryReply
) {
4947 .deviceID
= dev
->id
,
4948 .sequenceNumber
= client
->sequence
,
4951 status
= XkbComputeGetGeometryReplySize(geom
, &rep
, stuff
->name
);
4952 if (status
!= Success
)
4955 return XkbSendGeometry(client
, geom
, &rep
, shouldFree
);
4958 /***====================================================================***/
4961 _GetCountedString(char **wire_inout
, Bool swap
)
4967 plen
= (CARD16
*) wire
;
4972 str
= malloc(len
+ 1);
4974 memcpy(str
, &wire
[2], len
);
4977 wire
+= XkbPaddedSize(len
+ 2);
4983 _CheckSetDoodad(char **wire_inout
,
4984 XkbGeometryPtr geom
, XkbSectionPtr section
, ClientPtr client
)
4987 xkbDoodadWireDesc
*dWire
;
4988 XkbDoodadPtr doodad
;
4990 dWire
= (xkbDoodadWireDesc
*) (*wire_inout
);
4991 wire
= (char *) &dWire
[1];
4992 if (client
->swapped
) {
4993 swapl(&dWire
->any
.name
);
4994 swaps(&dWire
->any
.top
);
4995 swaps(&dWire
->any
.left
);
4996 swaps(&dWire
->any
.angle
);
4998 CHK_ATOM_ONLY(dWire
->any
.name
);
4999 doodad
= XkbAddGeomDoodad(geom
, section
, dWire
->any
.name
);
5002 doodad
->any
.type
= dWire
->any
.type
;
5003 doodad
->any
.priority
= dWire
->any
.priority
;
5004 doodad
->any
.top
= dWire
->any
.top
;
5005 doodad
->any
.left
= dWire
->any
.left
;
5006 doodad
->any
.angle
= dWire
->any
.angle
;
5007 switch (doodad
->any
.type
) {
5008 case XkbOutlineDoodad
:
5009 case XkbSolidDoodad
:
5010 if (dWire
->shape
.colorNdx
>= geom
->num_colors
) {
5011 client
->errorValue
= _XkbErrCode3(0x40, geom
->num_colors
,
5012 dWire
->shape
.colorNdx
);
5015 if (dWire
->shape
.shapeNdx
>= geom
->num_shapes
) {
5016 client
->errorValue
= _XkbErrCode3(0x41, geom
->num_shapes
,
5017 dWire
->shape
.shapeNdx
);
5020 doodad
->shape
.color_ndx
= dWire
->shape
.colorNdx
;
5021 doodad
->shape
.shape_ndx
= dWire
->shape
.shapeNdx
;
5024 if (dWire
->text
.colorNdx
>= geom
->num_colors
) {
5025 client
->errorValue
= _XkbErrCode3(0x42, geom
->num_colors
,
5026 dWire
->text
.colorNdx
);
5029 if (client
->swapped
) {
5030 swaps(&dWire
->text
.width
);
5031 swaps(&dWire
->text
.height
);
5033 doodad
->text
.width
= dWire
->text
.width
;
5034 doodad
->text
.height
= dWire
->text
.height
;
5035 doodad
->text
.color_ndx
= dWire
->text
.colorNdx
;
5036 doodad
->text
.text
= _GetCountedString(&wire
, client
->swapped
);
5037 doodad
->text
.font
= _GetCountedString(&wire
, client
->swapped
);
5039 case XkbIndicatorDoodad
:
5040 if (dWire
->indicator
.onColorNdx
>= geom
->num_colors
) {
5041 client
->errorValue
= _XkbErrCode3(0x43, geom
->num_colors
,
5042 dWire
->indicator
.onColorNdx
);
5045 if (dWire
->indicator
.offColorNdx
>= geom
->num_colors
) {
5046 client
->errorValue
= _XkbErrCode3(0x44, geom
->num_colors
,
5047 dWire
->indicator
.offColorNdx
);
5050 if (dWire
->indicator
.shapeNdx
>= geom
->num_shapes
) {
5051 client
->errorValue
= _XkbErrCode3(0x45, geom
->num_shapes
,
5052 dWire
->indicator
.shapeNdx
);
5055 doodad
->indicator
.shape_ndx
= dWire
->indicator
.shapeNdx
;
5056 doodad
->indicator
.on_color_ndx
= dWire
->indicator
.onColorNdx
;
5057 doodad
->indicator
.off_color_ndx
= dWire
->indicator
.offColorNdx
;
5060 if (dWire
->logo
.colorNdx
>= geom
->num_colors
) {
5061 client
->errorValue
= _XkbErrCode3(0x46, geom
->num_colors
,
5062 dWire
->logo
.colorNdx
);
5065 if (dWire
->logo
.shapeNdx
>= geom
->num_shapes
) {
5066 client
->errorValue
= _XkbErrCode3(0x47, geom
->num_shapes
,
5067 dWire
->logo
.shapeNdx
);
5070 doodad
->logo
.color_ndx
= dWire
->logo
.colorNdx
;
5071 doodad
->logo
.shape_ndx
= dWire
->logo
.shapeNdx
;
5072 doodad
->logo
.logo_name
= _GetCountedString(&wire
, client
->swapped
);
5075 client
->errorValue
= _XkbErrCode2(0x4F, dWire
->any
.type
);
5083 _CheckSetOverlay(char **wire_inout
,
5084 XkbGeometryPtr geom
, XkbSectionPtr section
, ClientPtr client
)
5089 xkbOverlayWireDesc
*olWire
;
5090 xkbOverlayRowWireDesc
*rWire
;
5093 olWire
= (xkbOverlayWireDesc
*) wire
;
5094 if (client
->swapped
) {
5095 swapl(&olWire
->name
);
5097 CHK_ATOM_ONLY(olWire
->name
);
5098 ol
= XkbAddGeomOverlay(section
, olWire
->name
, olWire
->nRows
);
5099 rWire
= (xkbOverlayRowWireDesc
*) &olWire
[1];
5100 for (r
= 0; r
< olWire
->nRows
; r
++) {
5102 xkbOverlayKeyWireDesc
*kWire
;
5103 XkbOverlayRowPtr row
;
5105 if (rWire
->rowUnder
> section
->num_rows
) {
5106 client
->errorValue
= _XkbErrCode4(0x20, r
, section
->num_rows
,
5110 row
= XkbAddGeomOverlayRow(ol
, rWire
->rowUnder
, rWire
->nKeys
);
5111 kWire
= (xkbOverlayKeyWireDesc
*) &rWire
[1];
5112 for (k
= 0; k
< rWire
->nKeys
; k
++, kWire
++) {
5113 if (XkbAddGeomOverlayKey(ol
, row
,
5114 (char *) kWire
->over
,
5115 (char *) kWire
->under
) == NULL
) {
5116 client
->errorValue
= _XkbErrCode3(0x21, r
, k
);
5120 rWire
= (xkbOverlayRowWireDesc
*) kWire
;
5122 olWire
= (xkbOverlayWireDesc
*) rWire
;
5123 wire
= (char *) olWire
;
5129 _CheckSetSections(XkbGeometryPtr geom
,
5130 xkbSetGeometryReq
* req
, char **wire_inout
, ClientPtr client
)
5135 xkbSectionWireDesc
*sWire
;
5136 XkbSectionPtr section
;
5139 if (req
->nSections
< 1)
5141 sWire
= (xkbSectionWireDesc
*) wire
;
5142 for (s
= 0; s
< req
->nSections
; s
++) {
5144 xkbRowWireDesc
*rWire
;
5146 if (client
->swapped
) {
5147 swapl(&sWire
->name
);
5149 swaps(&sWire
->left
);
5150 swaps(&sWire
->width
);
5151 swaps(&sWire
->height
);
5152 swaps(&sWire
->angle
);
5154 CHK_ATOM_ONLY(sWire
->name
);
5155 section
= XkbAddGeomSection(geom
, sWire
->name
, sWire
->nRows
,
5156 sWire
->nDoodads
, sWire
->nOverlays
);
5159 section
->priority
= sWire
->priority
;
5160 section
->top
= sWire
->top
;
5161 section
->left
= sWire
->left
;
5162 section
->width
= sWire
->width
;
5163 section
->height
= sWire
->height
;
5164 section
->angle
= sWire
->angle
;
5165 rWire
= (xkbRowWireDesc
*) &sWire
[1];
5166 for (r
= 0; r
< sWire
->nRows
; r
++) {
5169 xkbKeyWireDesc
*kWire
;
5171 if (client
->swapped
) {
5173 swaps(&rWire
->left
);
5175 row
= XkbAddGeomRow(section
, rWire
->nKeys
);
5178 row
->top
= rWire
->top
;
5179 row
->left
= rWire
->left
;
5180 row
->vertical
= rWire
->vertical
;
5181 kWire
= (xkbKeyWireDesc
*) &rWire
[1];
5182 for (k
= 0; k
< rWire
->nKeys
; k
++) {
5185 key
= XkbAddGeomKey(row
);
5188 memcpy(key
->name
.name
, kWire
[k
].name
, XkbKeyNameLength
);
5189 key
->gap
= kWire
[k
].gap
;
5190 key
->shape_ndx
= kWire
[k
].shapeNdx
;
5191 key
->color_ndx
= kWire
[k
].colorNdx
;
5192 if (key
->shape_ndx
>= geom
->num_shapes
) {
5193 client
->errorValue
= _XkbErrCode3(0x10, key
->shape_ndx
,
5197 if (key
->color_ndx
>= geom
->num_colors
) {
5198 client
->errorValue
= _XkbErrCode3(0x11, key
->color_ndx
,
5203 rWire
= (xkbRowWireDesc
*) &kWire
[rWire
->nKeys
];
5205 wire
= (char *) rWire
;
5206 if (sWire
->nDoodads
> 0) {
5209 for (d
= 0; d
< sWire
->nDoodads
; d
++) {
5210 status
= _CheckSetDoodad(&wire
, geom
, section
, client
);
5211 if (status
!= Success
)
5215 if (sWire
->nOverlays
> 0) {
5218 for (o
= 0; o
< sWire
->nOverlays
; o
++) {
5219 status
= _CheckSetOverlay(&wire
, geom
, section
, client
);
5220 if (status
!= Success
)
5224 sWire
= (xkbSectionWireDesc
*) wire
;
5226 wire
= (char *) sWire
;
5232 _CheckSetShapes(XkbGeometryPtr geom
,
5233 xkbSetGeometryReq
* req
, char **wire_inout
, ClientPtr client
)
5239 if (req
->nShapes
< 1) {
5240 client
->errorValue
= _XkbErrCode2(0x06, req
->nShapes
);
5244 xkbShapeWireDesc
*shapeWire
;
5248 shapeWire
= (xkbShapeWireDesc
*) wire
;
5249 for (i
= 0; i
< req
->nShapes
; i
++) {
5250 xkbOutlineWireDesc
*olWire
;
5254 XkbAddGeomShape(geom
, shapeWire
->name
, shapeWire
->nOutlines
);
5257 olWire
= (xkbOutlineWireDesc
*) (&shapeWire
[1]);
5258 for (o
= 0; o
< shapeWire
->nOutlines
; o
++) {
5261 xkbPointWireDesc
*ptWire
;
5263 ol
= XkbAddGeomOutline(shape
, olWire
->nPoints
);
5266 ol
->corner_radius
= olWire
->cornerRadius
;
5267 ptWire
= (xkbPointWireDesc
*) &olWire
[1];
5268 for (p
= 0, pt
= ol
->points
; p
< olWire
->nPoints
; p
++, pt
++) {
5269 pt
->x
= ptWire
[p
].x
;
5270 pt
->y
= ptWire
[p
].y
;
5271 if (client
->swapped
) {
5276 ol
->num_points
= olWire
->nPoints
;
5277 olWire
= (xkbOutlineWireDesc
*) (&ptWire
[olWire
->nPoints
]);
5279 if (shapeWire
->primaryNdx
!= XkbNoShape
)
5280 shape
->primary
= &shape
->outlines
[shapeWire
->primaryNdx
];
5281 if (shapeWire
->approxNdx
!= XkbNoShape
)
5282 shape
->approx
= &shape
->outlines
[shapeWire
->approxNdx
];
5283 shapeWire
= (xkbShapeWireDesc
*) olWire
;
5285 wire
= (char *) shapeWire
;
5287 if (geom
->num_shapes
!= req
->nShapes
) {
5288 client
->errorValue
= _XkbErrCode3(0x07, geom
->num_shapes
, req
->nShapes
);
5297 _CheckSetGeom(XkbGeometryPtr geom
, xkbSetGeometryReq
* req
, ClientPtr client
)
5303 wire
= (char *) &req
[1];
5304 geom
->label_font
= _GetCountedString(&wire
, client
->swapped
);
5306 for (i
= 0; i
< req
->nProperties
; i
++) {
5309 name
= _GetCountedString(&wire
, client
->swapped
);
5312 val
= _GetCountedString(&wire
, client
->swapped
);
5317 if (XkbAddGeomProperty(geom
, name
, val
) == NULL
) {
5326 if (req
->nColors
< 2) {
5327 client
->errorValue
= _XkbErrCode3(0x01, 2, req
->nColors
);
5330 if (req
->baseColorNdx
> req
->nColors
) {
5331 client
->errorValue
=
5332 _XkbErrCode3(0x03, req
->nColors
, req
->baseColorNdx
);
5335 if (req
->labelColorNdx
> req
->nColors
) {
5336 client
->errorValue
=
5337 _XkbErrCode3(0x03, req
->nColors
, req
->labelColorNdx
);
5340 if (req
->labelColorNdx
== req
->baseColorNdx
) {
5341 client
->errorValue
= _XkbErrCode3(0x04, req
->baseColorNdx
,
5342 req
->labelColorNdx
);
5346 for (i
= 0; i
< req
->nColors
; i
++) {
5349 name
= _GetCountedString(&wire
, client
->swapped
);
5352 if (!XkbAddGeomColor(geom
, name
, geom
->num_colors
)) {
5358 if (req
->nColors
!= geom
->num_colors
) {
5359 client
->errorValue
= _XkbErrCode3(0x05, req
->nColors
, geom
->num_colors
);
5362 geom
->label_color
= &geom
->colors
[req
->labelColorNdx
];
5363 geom
->base_color
= &geom
->colors
[req
->baseColorNdx
];
5365 if ((status
= _CheckSetShapes(geom
, req
, &wire
, client
)) != Success
)
5368 if ((status
= _CheckSetSections(geom
, req
, &wire
, client
)) != Success
)
5371 for (i
= 0; i
< req
->nDoodads
; i
++) {
5372 status
= _CheckSetDoodad(&wire
, geom
, NULL
, client
);
5373 if (status
!= Success
)
5377 for (i
= 0; i
< req
->nKeyAliases
; i
++) {
5378 if (XkbAddGeomKeyAlias(geom
, &wire
[XkbKeyNameLength
], wire
) == NULL
)
5380 wire
+= 2 * XkbKeyNameLength
;
5386 _XkbSetGeometry(ClientPtr client
, DeviceIntPtr dev
, xkbSetGeometryReq
* stuff
)
5390 xkbNewKeyboardNotify nkn
;
5391 XkbGeometryPtr geom
, old
;
5392 XkbGeometrySizesRec sizes
;
5395 xkb
= dev
->key
->xkbInfo
->desc
;
5399 sizes
.which
= XkbGeomAllMask
;
5400 sizes
.num_properties
= stuff
->nProperties
;
5401 sizes
.num_colors
= stuff
->nColors
;
5402 sizes
.num_shapes
= stuff
->nShapes
;
5403 sizes
.num_sections
= stuff
->nSections
;
5404 sizes
.num_doodads
= stuff
->nDoodads
;
5405 sizes
.num_key_aliases
= stuff
->nKeyAliases
;
5406 if ((status
= XkbAllocGeometry(xkb
, &sizes
)) != Success
) {
5411 geom
->name
= stuff
->name
;
5412 geom
->width_mm
= stuff
->widthMM
;
5413 geom
->height_mm
= stuff
->heightMM
;
5414 if ((status
= _CheckSetGeom(geom
, stuff
, client
)) != Success
) {
5415 XkbFreeGeometry(geom
, XkbGeomAllMask
, TRUE
);
5419 new_name
= (xkb
->names
->geometry
!= geom
->name
);
5420 xkb
->names
->geometry
= geom
->name
;
5422 XkbFreeGeometry(old
, XkbGeomAllMask
, TRUE
);
5426 memset(&nn
, 0, sizeof(xkbNamesNotify
));
5427 nn
.changed
= XkbGeometryNameMask
;
5428 XkbSendNamesNotify(dev
, &nn
);
5430 nkn
.deviceID
= nkn
.oldDeviceID
= dev
->id
;
5431 nkn
.minKeyCode
= nkn
.oldMinKeyCode
= xkb
->min_key_code
;
5432 nkn
.maxKeyCode
= nkn
.oldMaxKeyCode
= xkb
->max_key_code
;
5433 nkn
.requestMajor
= XkbReqCode
;
5434 nkn
.requestMinor
= X_kbSetGeometry
;
5435 nkn
.changed
= XkbNKN_GeometryMask
;
5436 XkbSendNewKeyboardNotify(dev
, &nkn
);
5441 ProcXkbSetGeometry(ClientPtr client
)
5446 REQUEST(xkbSetGeometryReq
);
5447 REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq
);
5449 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
5452 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixManageAccess
);
5453 CHK_ATOM_OR_NONE(stuff
->name
);
5455 rc
= _XkbSetGeometry(client
, dev
, stuff
);
5459 if (stuff
->deviceSpec
== XkbUseCoreKbd
) {
5462 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
5463 if ((other
!= dev
) && other
->key
&& !IsMaster(other
) &&
5464 GetMaster(other
, MASTER_KEYBOARD
) == dev
) {
5465 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
5468 _XkbSetGeometry(client
, other
, stuff
);
5476 /***====================================================================***/
5479 ProcXkbPerClientFlags(ClientPtr client
)
5482 xkbPerClientFlagsReply rep
;
5483 XkbInterestPtr interest
;
5484 Mask access_mode
= DixGetAttrAccess
| DixSetAttrAccess
;
5486 REQUEST(xkbPerClientFlagsReq
);
5487 REQUEST_SIZE_MATCH(xkbPerClientFlagsReq
);
5489 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
5492 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, access_mode
);
5493 CHK_MASK_LEGAL(0x01, stuff
->change
, XkbPCF_AllFlagsMask
);
5494 CHK_MASK_MATCH(0x02, stuff
->change
, stuff
->value
);
5496 interest
= XkbFindClientResource((DevicePtr
) dev
, client
);
5497 if (stuff
->change
) {
5498 client
->xkbClientFlags
&= ~stuff
->change
;
5499 client
->xkbClientFlags
|= stuff
->value
;
5501 if (stuff
->change
& XkbPCF_AutoResetControlsMask
) {
5504 want
= stuff
->value
& XkbPCF_AutoResetControlsMask
;
5505 if (interest
&& !want
) {
5506 interest
->autoCtrls
= interest
->autoCtrlValues
= 0;
5508 else if (want
&& (!interest
)) {
5509 XID id
= FakeClientID(client
->index
);
5511 if (!AddResource(id
, RT_XKBCLIENT
, dev
))
5513 interest
= XkbAddClientResource((DevicePtr
) dev
, client
, id
);
5517 if (interest
&& want
) {
5518 register unsigned affect
;
5520 affect
= stuff
->ctrlsToChange
;
5522 CHK_MASK_LEGAL(0x03, affect
, XkbAllBooleanCtrlsMask
);
5523 CHK_MASK_MATCH(0x04, affect
, stuff
->autoCtrls
);
5524 CHK_MASK_MATCH(0x05, stuff
->autoCtrls
, stuff
->autoCtrlValues
);
5526 interest
->autoCtrls
&= ~affect
;
5527 interest
->autoCtrlValues
&= ~affect
;
5528 interest
->autoCtrls
|= stuff
->autoCtrls
& affect
;
5529 interest
->autoCtrlValues
|= stuff
->autoCtrlValues
& affect
;
5533 rep
= (xkbPerClientFlagsReply
) {
5535 .sequenceNumber
= client
->sequence
,
5537 .supported
= XkbPCF_AllFlagsMask
,
5538 .value
= client
->xkbClientFlags
& XkbPCF_AllFlagsMask
,
5539 .autoCtrls
= interest
? interest
->autoCtrls
: 0,
5540 .autoCtrlValues
= interest
? interest
->autoCtrlValues
: 0,
5542 if (client
->swapped
) {
5543 swaps(&rep
.sequenceNumber
);
5544 swapl(&rep
.supported
);
5546 swapl(&rep
.autoCtrls
);
5547 swapl(&rep
.autoCtrlValues
);
5549 WriteToClient(client
, SIZEOF(xkbPerClientFlagsReply
), &rep
);
5553 /***====================================================================***/
5555 /* all latin-1 alphanumerics, plus parens, minus, underscore, slash */
5557 static unsigned char componentSpecLegal
[] = {
5558 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87,
5559 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
5560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5561 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
5564 /* same as above but accepts percent, plus and bar too */
5565 static unsigned char componentExprLegal
[] = {
5566 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87,
5567 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17,
5568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5569 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
5573 GetComponentSpec(unsigned char **pWire
, Bool allowExpr
, int *errRtrn
)
5577 unsigned char *wire
, *str
, *tmp
, *legal
;
5580 legal
= &componentExprLegal
[0];
5582 legal
= &componentSpecLegal
[0];
5585 len
= (*(unsigned char *) wire
++);
5587 str
= calloc(1, len
+ 1);
5590 for (i
= 0; i
< len
; i
++) {
5591 if (legal
[(*wire
) / 8] & (1 << ((*wire
) % 8)))
5604 *errRtrn
= BadAlloc
;
5611 return (char *) str
;
5614 /***====================================================================***/
5617 ProcXkbListComponents(ClientPtr client
)
5620 xkbListComponentsReply rep
;
5626 REQUEST(xkbListComponentsReq
);
5627 REQUEST_AT_LEAST_SIZE(xkbListComponentsReq
);
5629 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
5632 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
5634 /* The request is followed by six Pascal strings (i.e. size in characters
5635 * followed by a string pattern) describing what the client wants us to
5636 * list. We don't care, but might as well check they haven't got the
5638 str
= (unsigned char *) &stuff
[1];
5639 for (i
= 0; i
< 6; i
++) {
5640 size
= *((uint8_t *)str
);
5641 len
= (str
+ size
+ 1) - ((unsigned char *) stuff
);
5642 if ((XkbPaddedSize(len
) / 4) > stuff
->length
)
5646 if ((XkbPaddedSize(len
) / 4) != stuff
->length
)
5648 rep
= (xkbListComponentsReply
) {
5650 .deviceID
= dev
->id
,
5651 .sequenceNumber
= client
->sequence
,
5661 if (client
->swapped
) {
5662 swaps(&rep
.sequenceNumber
);
5664 swaps(&rep
.nKeymaps
);
5665 swaps(&rep
.nKeycodes
);
5667 swaps(&rep
.nCompatMaps
);
5668 swaps(&rep
.nSymbols
);
5669 swaps(&rep
.nGeometries
);
5672 WriteToClient(client
, SIZEOF(xkbListComponentsReply
), &rep
);
5676 /***====================================================================***/
5679 ProcXkbGetKbdByName(ClientPtr client
)
5683 DeviceIntPtr master
;
5684 xkbGetKbdByNameReply rep
= { 0 };
5685 xkbGetMapReply mrep
= { 0 };
5686 xkbGetCompatMapReply crep
= { 0 };
5687 xkbGetIndicatorMapReply irep
= { 0 };
5688 xkbGetNamesReply nrep
= { 0 };
5689 xkbGetGeometryReply grep
= { 0 };
5690 XkbComponentNamesRec names
= { 0 };
5691 XkbDescPtr xkb
, new;
5693 char mapFile
[PATH_MAX
];
5695 unsigned fwant
, fneed
, reported
;
5698 XkbSrvLedInfoPtr old_sli
;
5699 XkbSrvLedInfoPtr sli
;
5700 Mask access_mode
= DixGetAttrAccess
| DixManageAccess
;
5702 REQUEST(xkbGetKbdByNameReq
);
5703 REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq
);
5705 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
5708 CHK_KBD_DEVICE(dev
, stuff
->deviceSpec
, client
, access_mode
);
5709 master
= GetMaster(dev
, MASTER_KEYBOARD
);
5711 xkb
= dev
->key
->xkbInfo
->desc
;
5713 str
= (unsigned char *) &stuff
[1];
5714 if (GetComponentSpec(&str
, TRUE
, &status
)) /* keymap, unsupported */
5716 names
.keycodes
= GetComponentSpec(&str
, TRUE
, &status
);
5717 names
.types
= GetComponentSpec(&str
, TRUE
, &status
);
5718 names
.compat
= GetComponentSpec(&str
, TRUE
, &status
);
5719 names
.symbols
= GetComponentSpec(&str
, TRUE
, &status
);
5720 names
.geometry
= GetComponentSpec(&str
, TRUE
, &status
);
5721 if (status
!= Success
)
5723 len
= str
- ((unsigned char *) stuff
);
5724 if ((XkbPaddedSize(len
) / 4) != stuff
->length
)
5727 CHK_MASK_LEGAL(0x01, stuff
->want
, XkbGBN_AllComponentsMask
);
5728 CHK_MASK_LEGAL(0x02, stuff
->need
, XkbGBN_AllComponentsMask
);
5731 fwant
= XkbGBN_AllComponentsMask
;
5733 fwant
= stuff
->want
| stuff
->need
;
5734 if ((!names
.compat
) &&
5735 (fwant
& (XkbGBN_CompatMapMask
| XkbGBN_IndicatorMapMask
))) {
5736 names
.compat
= Xstrdup("%");
5738 if ((!names
.types
) && (fwant
& (XkbGBN_TypesMask
))) {
5739 names
.types
= Xstrdup("%");
5741 if ((!names
.symbols
) && (fwant
& XkbGBN_SymbolsMask
)) {
5742 names
.symbols
= Xstrdup("%");
5744 geom_changed
= ((names
.geometry
!= NULL
) &&
5745 (strcmp(names
.geometry
, "%") != 0));
5746 if ((!names
.geometry
) && (fwant
& XkbGBN_GeometryMask
)) {
5747 names
.geometry
= Xstrdup("%");
5748 geom_changed
= FALSE
;
5751 memset(mapFile
, 0, PATH_MAX
);
5753 rep
.deviceID
= dev
->id
;
5754 rep
.sequenceNumber
= client
->sequence
;
5756 rep
.minKeyCode
= xkb
->min_key_code
;
5757 rep
.maxKeyCode
= xkb
->max_key_code
;
5760 XkbConvertGetByNameComponents(TRUE
, stuff
->want
) | XkmVirtualModsMask
;
5761 fneed
= XkbConvertGetByNameComponents(TRUE
, stuff
->need
);
5762 rep
.reported
= XkbConvertGetByNameComponents(FALSE
, fwant
| fneed
);
5764 fneed
|= XkmKeymapRequired
;
5765 fwant
|= XkmKeymapLegal
;
5767 if ((fwant
| fneed
) & XkmSymbolsMask
) {
5768 fneed
|= XkmKeyNamesIndex
| XkmTypesIndex
;
5769 fwant
|= XkmIndicatorsIndex
;
5772 /* We pass dev in here so we can get the old names out if needed. */
5773 rep
.found
= XkbDDXLoadKeymapByNames(dev
, &names
, fwant
, fneed
, &new,
5775 rep
.newKeyboard
= FALSE
;
5776 rep
.pad1
= rep
.pad2
= rep
.pad3
= rep
.pad4
= 0;
5778 stuff
->want
|= stuff
->need
;
5785 ((rep
.reported
& XkbGBN_SymbolsMask
) && (new->compat
))) {
5786 XkbChangesRec changes
;
5788 memset(&changes
, 0, sizeof(changes
));
5789 XkbUpdateDescActions(new,
5790 new->min_key_code
, XkbNumKeys(new), &changes
);
5793 if (new->map
== NULL
)
5794 rep
.reported
&= ~(XkbGBN_SymbolsMask
| XkbGBN_TypesMask
);
5795 else if (rep
.reported
& (XkbGBN_SymbolsMask
| XkbGBN_TypesMask
)) {
5796 mrep
.type
= X_Reply
;
5797 mrep
.deviceID
= dev
->id
;
5798 mrep
.sequenceNumber
= client
->sequence
;
5800 ((SIZEOF(xkbGetMapReply
) - SIZEOF(xGenericReply
)) >> 2);
5801 mrep
.minKeyCode
= new->min_key_code
;
5802 mrep
.maxKeyCode
= new->max_key_code
;
5804 mrep
.totalSyms
= mrep
.totalActs
=
5805 mrep
.totalKeyBehaviors
= mrep
.totalKeyExplicit
=
5806 mrep
.totalModMapKeys
= mrep
.totalVModMapKeys
= 0;
5807 if (rep
.reported
& (XkbGBN_TypesMask
| XkbGBN_ClientSymbolsMask
)) {
5808 mrep
.present
|= XkbKeyTypesMask
;
5810 mrep
.nTypes
= mrep
.totalTypes
= new->map
->num_types
;
5813 mrep
.firstType
= mrep
.nTypes
= 0;
5814 mrep
.totalTypes
= 0;
5816 if (rep
.reported
& XkbGBN_ClientSymbolsMask
) {
5817 mrep
.present
|= (XkbKeySymsMask
| XkbModifierMapMask
);
5818 mrep
.firstKeySym
= mrep
.firstModMapKey
= new->min_key_code
;
5819 mrep
.nKeySyms
= mrep
.nModMapKeys
= XkbNumKeys(new);
5822 mrep
.firstKeySym
= mrep
.firstModMapKey
= 0;
5823 mrep
.nKeySyms
= mrep
.nModMapKeys
= 0;
5825 if (rep
.reported
& XkbGBN_ServerSymbolsMask
) {
5826 mrep
.present
|= XkbAllServerInfoMask
;
5827 mrep
.virtualMods
= ~0;
5828 mrep
.firstKeyAct
= mrep
.firstKeyBehavior
=
5829 mrep
.firstKeyExplicit
= new->min_key_code
;
5830 mrep
.nKeyActs
= mrep
.nKeyBehaviors
=
5831 mrep
.nKeyExplicit
= XkbNumKeys(new);
5832 mrep
.firstVModMapKey
= new->min_key_code
;
5833 mrep
.nVModMapKeys
= XkbNumKeys(new);
5836 mrep
.virtualMods
= 0;
5837 mrep
.firstKeyAct
= mrep
.firstKeyBehavior
=
5838 mrep
.firstKeyExplicit
= 0;
5839 mrep
.nKeyActs
= mrep
.nKeyBehaviors
= mrep
.nKeyExplicit
= 0;
5841 XkbComputeGetMapReplySize(new, &mrep
);
5842 rep
.length
+= SIZEOF(xGenericReply
) / 4 + mrep
.length
;
5844 if (new->compat
== NULL
)
5845 rep
.reported
&= ~XkbGBN_CompatMapMask
;
5846 else if (rep
.reported
& XkbGBN_CompatMapMask
) {
5847 crep
.type
= X_Reply
;
5848 crep
.deviceID
= dev
->id
;
5849 crep
.sequenceNumber
= client
->sequence
;
5851 crep
.groups
= XkbAllGroupsMask
;
5853 crep
.nSI
= crep
.nTotalSI
= new->compat
->num_si
;
5854 XkbComputeGetCompatMapReplySize(new->compat
, &crep
);
5855 rep
.length
+= SIZEOF(xGenericReply
) / 4 + crep
.length
;
5857 if (new->indicators
== NULL
)
5858 rep
.reported
&= ~XkbGBN_IndicatorMapMask
;
5859 else if (rep
.reported
& XkbGBN_IndicatorMapMask
) {
5860 irep
.type
= X_Reply
;
5861 irep
.deviceID
= dev
->id
;
5862 irep
.sequenceNumber
= client
->sequence
;
5864 irep
.which
= XkbAllIndicatorsMask
;
5865 XkbComputeGetIndicatorMapReplySize(new->indicators
, &irep
);
5866 rep
.length
+= SIZEOF(xGenericReply
) / 4 + irep
.length
;
5868 if (new->names
== NULL
)
5869 rep
.reported
&= ~(XkbGBN_OtherNamesMask
| XkbGBN_KeyNamesMask
);
5870 else if (rep
.reported
& (XkbGBN_OtherNamesMask
| XkbGBN_KeyNamesMask
)) {
5871 nrep
.type
= X_Reply
;
5872 nrep
.deviceID
= dev
->id
;
5873 nrep
.sequenceNumber
= client
->sequence
;
5875 nrep
.minKeyCode
= new->min_key_code
;
5876 nrep
.maxKeyCode
= new->max_key_code
;
5877 if (rep
.reported
& XkbGBN_OtherNamesMask
) {
5878 nrep
.which
= XkbAllNamesMask
;
5879 if (new->map
!= NULL
)
5880 nrep
.nTypes
= new->map
->num_types
;
5884 nrep
.groupNames
= XkbAllGroupsMask
;
5885 nrep
.virtualMods
= XkbAllVirtualModsMask
;
5886 nrep
.indicators
= XkbAllIndicatorsMask
;
5887 nrep
.nRadioGroups
= new->names
->num_rg
;
5893 nrep
.groupNames
= 0;
5894 nrep
.virtualMods
= 0;
5895 nrep
.indicators
= 0;
5896 nrep
.nRadioGroups
= 0;
5898 if (rep
.reported
& XkbGBN_KeyNamesMask
) {
5899 nrep
.which
|= XkbKeyNamesMask
;
5900 nrep
.firstKey
= new->min_key_code
;
5901 nrep
.nKeys
= XkbNumKeys(new);
5902 nrep
.nKeyAliases
= new->names
->num_key_aliases
;
5903 if (nrep
.nKeyAliases
)
5904 nrep
.which
|= XkbKeyAliasesMask
;
5907 nrep
.which
&= ~(XkbKeyNamesMask
| XkbKeyAliasesMask
);
5908 nrep
.firstKey
= nrep
.nKeys
= 0;
5909 nrep
.nKeyAliases
= 0;
5911 XkbComputeGetNamesReplySize(new, &nrep
);
5912 rep
.length
+= SIZEOF(xGenericReply
) / 4 + nrep
.length
;
5914 if (new->geom
== NULL
)
5915 rep
.reported
&= ~XkbGBN_GeometryMask
;
5916 else if (rep
.reported
& XkbGBN_GeometryMask
) {
5917 grep
.type
= X_Reply
;
5918 grep
.deviceID
= dev
->id
;
5919 grep
.sequenceNumber
= client
->sequence
;
5923 grep
.widthMM
= grep
.heightMM
= 0;
5924 grep
.nProperties
= grep
.nColors
= grep
.nShapes
= 0;
5925 grep
.nSections
= grep
.nDoodads
= 0;
5926 grep
.baseColorNdx
= grep
.labelColorNdx
= 0;
5927 XkbComputeGetGeometryReplySize(new->geom
, &grep
, None
);
5928 rep
.length
+= SIZEOF(xGenericReply
) / 4 + grep
.length
;
5932 reported
= rep
.reported
;
5933 if (client
->swapped
) {
5934 swaps(&rep
.sequenceNumber
);
5937 swaps(&rep
.reported
);
5939 WriteToClient(client
, SIZEOF(xkbGetKbdByNameReply
), &rep
);
5940 if (reported
& (XkbGBN_SymbolsMask
| XkbGBN_TypesMask
))
5941 XkbSendMap(client
, new, &mrep
);
5942 if (reported
& XkbGBN_CompatMapMask
)
5943 XkbSendCompatMap(client
, new->compat
, &crep
);
5944 if (reported
& XkbGBN_IndicatorMapMask
)
5945 XkbSendIndicatorMap(client
, new->indicators
, &irep
);
5946 if (reported
& (XkbGBN_KeyNamesMask
| XkbGBN_OtherNamesMask
))
5947 XkbSendNames(client
, new, &nrep
);
5948 if (reported
& XkbGBN_GeometryMask
)
5949 XkbSendGeometry(client
, new->geom
, &grep
, FALSE
);
5952 xkbNewKeyboardNotify nkn
;
5957 dev
->key
->xkbInfo
->desc
= xkb
;
5958 new = old_xkb
; /* so it'll get freed automatically */
5960 *xkb
->ctrls
= *old_xkb
->ctrls
;
5961 for (nG
= nTG
= 0, i
= xkb
->min_key_code
; i
<= xkb
->max_key_code
; i
++) {
5962 nG
= XkbKeyNumGroups(xkb
, i
);
5963 if (nG
>= XkbNumKbdGroups
) {
5964 nTG
= XkbNumKbdGroups
;
5971 xkb
->ctrls
->num_groups
= nTG
;
5973 nkn
.deviceID
= nkn
.oldDeviceID
= dev
->id
;
5974 nkn
.minKeyCode
= new->min_key_code
;
5975 nkn
.maxKeyCode
= new->max_key_code
;
5976 nkn
.oldMinKeyCode
= xkb
->min_key_code
;
5977 nkn
.oldMaxKeyCode
= xkb
->max_key_code
;
5978 nkn
.requestMajor
= XkbReqCode
;
5979 nkn
.requestMinor
= X_kbGetKbdByName
;
5980 nkn
.changed
= XkbNKN_KeycodesMask
;
5982 nkn
.changed
|= XkbNKN_GeometryMask
;
5983 XkbSendNewKeyboardNotify(dev
, &nkn
);
5985 /* Update the map and LED info on the device itself, as well as
5986 * any slaves if it's an MD, or its MD if it's an SD and was the
5987 * last device used on that MD. */
5988 for (tmpd
= inputInfo
.devices
; tmpd
; tmpd
= tmpd
->next
) {
5989 if (tmpd
!= dev
&& GetMaster(tmpd
, MASTER_KEYBOARD
) != dev
&&
5990 (tmpd
!= master
|| dev
!= master
->lastSlave
))
5994 XkbCopyDeviceKeymap(tmpd
, dev
);
5996 if (tmpd
->kbdfeed
&& tmpd
->kbdfeed
->xkb_sli
) {
5997 old_sli
= tmpd
->kbdfeed
->xkb_sli
;
5998 tmpd
->kbdfeed
->xkb_sli
= NULL
;
5999 sli
= XkbAllocSrvLedInfo(tmpd
, tmpd
->kbdfeed
, NULL
, 0);
6001 sli
->explicitState
= old_sli
->explicitState
;
6002 sli
->effectiveState
= old_sli
->effectiveState
;
6004 tmpd
->kbdfeed
->xkb_sli
= sli
;
6005 XkbFreeSrvLedInfo(old_sli
);
6009 if ((new != NULL
) && (new != xkb
)) {
6010 XkbFreeKeyboard(new, XkbAllComponentsMask
, TRUE
);
6013 XkbFreeComponentNames(&names
, FALSE
);
6017 /***====================================================================***/
6020 ComputeDeviceLedInfoSize(DeviceIntPtr dev
,
6021 unsigned int what
, XkbSrvLedInfoPtr sli
)
6024 register unsigned n
, bit
;
6029 if ((what
& XkbXI_IndicatorNamesMask
) == 0)
6030 sli
->namesPresent
= 0;
6031 if ((what
& XkbXI_IndicatorMapsMask
) == 0)
6032 sli
->mapsPresent
= 0;
6034 for (n
= 0, bit
= 1; n
< XkbNumIndicators
; n
++, bit
<<= 1) {
6035 if (sli
->names
&& sli
->names
[n
] != None
) {
6036 sli
->namesPresent
|= bit
;
6039 if (sli
->maps
&& XkbIM_InUse(&sli
->maps
[n
])) {
6040 sli
->mapsPresent
|= bit
;
6044 return (nNames
* 4) + (nMaps
* SIZEOF(xkbIndicatorMapWireDesc
));
6048 CheckDeviceLedFBs(DeviceIntPtr dev
,
6050 int id
, xkbGetDeviceInfoReply
* rep
, ClientPtr client
)
6056 if (class == XkbDfltXIClass
) {
6058 class = KbdFeedbackClass
;
6060 class = LedFeedbackClass
;
6062 client
->errorValue
= _XkbErrCode2(XkbErr_BadClass
, class);
6063 return XkbKeyboardErrorCode
;
6067 if ((dev
->kbdfeed
) &&
6068 ((class == KbdFeedbackClass
) || (class == XkbAllXIClasses
))) {
6072 for (kf
= dev
->kbdfeed
; (kf
); kf
= kf
->next
) {
6073 if ((id
!= XkbAllXIIds
) && (id
!= XkbDfltXIId
) &&
6074 (id
!= kf
->ctrl
.id
))
6077 length
+= SIZEOF(xkbDeviceLedsWireDesc
);
6079 kf
->xkb_sli
= XkbAllocSrvLedInfo(dev
, kf
, NULL
, 0);
6080 length
+= ComputeDeviceLedInfoSize(dev
, rep
->present
, kf
->xkb_sli
);
6081 if (id
!= XkbAllXIIds
)
6086 ((class == LedFeedbackClass
) || (class == XkbAllXIClasses
))) {
6090 for (lf
= dev
->leds
; (lf
); lf
= lf
->next
) {
6091 if ((id
!= XkbAllXIIds
) && (id
!= XkbDfltXIId
) &&
6092 (id
!= lf
->ctrl
.id
))
6095 length
+= SIZEOF(xkbDeviceLedsWireDesc
);
6097 lf
->xkb_sli
= XkbAllocSrvLedInfo(dev
, NULL
, lf
, 0);
6098 length
+= ComputeDeviceLedInfoSize(dev
, rep
->present
, lf
->xkb_sli
);
6099 if (id
!= XkbAllXIIds
)
6104 rep
->nDeviceLedFBs
= nFBs
;
6105 rep
->length
+= (length
/ 4);
6109 client
->errorValue
= _XkbErrCode2(XkbErr_BadId
, id
);
6111 client
->errorValue
= _XkbErrCode2(XkbErr_BadClass
, class);
6112 return XkbKeyboardErrorCode
;
6116 SendDeviceLedInfo(XkbSrvLedInfoPtr sli
, ClientPtr client
)
6118 xkbDeviceLedsWireDesc wire
;
6122 wire
.ledClass
= sli
->class;
6123 wire
.ledID
= sli
->id
;
6124 wire
.namesPresent
= sli
->namesPresent
;
6125 wire
.mapsPresent
= sli
->mapsPresent
;
6126 wire
.physIndicators
= sli
->physIndicators
;
6127 wire
.state
= sli
->effectiveState
;
6128 if (client
->swapped
) {
6129 swaps(&wire
.ledClass
);
6131 swapl(&wire
.namesPresent
);
6132 swapl(&wire
.mapsPresent
);
6133 swapl(&wire
.physIndicators
);
6136 WriteToClient(client
, SIZEOF(xkbDeviceLedsWireDesc
), &wire
);
6137 length
+= SIZEOF(xkbDeviceLedsWireDesc
);
6138 if (sli
->namesPresent
| sli
->mapsPresent
) {
6139 register unsigned i
, bit
;
6141 if (sli
->namesPresent
) {
6144 for (i
= 0, bit
= 1; i
< XkbNumIndicators
; i
++, bit
<<= 1) {
6145 if (sli
->namesPresent
& bit
) {
6146 awire
= (CARD32
) sli
->names
[i
];
6147 if (client
->swapped
) {
6150 WriteToClient(client
, 4, &awire
);
6155 if (sli
->mapsPresent
) {
6156 for (i
= 0, bit
= 1; i
< XkbNumIndicators
; i
++, bit
<<= 1) {
6157 xkbIndicatorMapWireDesc iwire
;
6159 if (sli
->mapsPresent
& bit
) {
6160 iwire
.flags
= sli
->maps
[i
].flags
;
6161 iwire
.whichGroups
= sli
->maps
[i
].which_groups
;
6162 iwire
.groups
= sli
->maps
[i
].groups
;
6163 iwire
.whichMods
= sli
->maps
[i
].which_mods
;
6164 iwire
.mods
= sli
->maps
[i
].mods
.mask
;
6165 iwire
.realMods
= sli
->maps
[i
].mods
.real_mods
;
6166 iwire
.virtualMods
= sli
->maps
[i
].mods
.vmods
;
6167 iwire
.ctrls
= sli
->maps
[i
].ctrls
;
6168 if (client
->swapped
) {
6169 swaps(&iwire
.virtualMods
);
6170 swapl(&iwire
.ctrls
);
6172 WriteToClient(client
, SIZEOF(xkbIndicatorMapWireDesc
),
6174 length
+= SIZEOF(xkbIndicatorMapWireDesc
);
6183 SendDeviceLedFBs(DeviceIntPtr dev
,
6184 int class, int id
, unsigned wantLength
, ClientPtr client
)
6188 if (class == XkbDfltXIClass
) {
6190 class = KbdFeedbackClass
;
6192 class = LedFeedbackClass
;
6194 if ((dev
->kbdfeed
) &&
6195 ((class == KbdFeedbackClass
) || (class == XkbAllXIClasses
))) {
6198 for (kf
= dev
->kbdfeed
; (kf
); kf
= kf
->next
) {
6199 if ((id
== XkbAllXIIds
) || (id
== XkbDfltXIId
) ||
6200 (id
== kf
->ctrl
.id
)) {
6201 length
+= SendDeviceLedInfo(kf
->xkb_sli
, client
);
6202 if (id
!= XkbAllXIIds
)
6208 ((class == LedFeedbackClass
) || (class == XkbAllXIClasses
))) {
6211 for (lf
= dev
->leds
; (lf
); lf
= lf
->next
) {
6212 if ((id
== XkbAllXIIds
) || (id
== XkbDfltXIId
) ||
6213 (id
== lf
->ctrl
.id
)) {
6214 length
+= SendDeviceLedInfo(lf
->xkb_sli
, client
);
6215 if (id
!= XkbAllXIIds
)
6220 if (length
== wantLength
)
6227 ProcXkbGetDeviceInfo(ClientPtr client
)
6230 xkbGetDeviceInfoReply rep
;
6231 int status
, nDeviceLedFBs
;
6232 unsigned length
, nameLen
;
6233 CARD16 ledClass
, ledID
;
6237 REQUEST(xkbGetDeviceInfoReq
);
6238 REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq
);
6240 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
6243 wanted
= stuff
->wanted
;
6245 CHK_ANY_DEVICE(dev
, stuff
->deviceSpec
, client
, DixGetAttrAccess
);
6246 CHK_MASK_LEGAL(0x01, wanted
, XkbXI_AllDeviceFeaturesMask
);
6248 if ((!dev
->button
) || ((stuff
->nBtns
< 1) && (!stuff
->allBtns
)))
6249 wanted
&= ~XkbXI_ButtonActionsMask
;
6250 if ((!dev
->kbdfeed
) && (!dev
->leds
))
6251 wanted
&= ~XkbXI_IndicatorsMask
;
6253 nameLen
= XkbSizeCountedString(dev
->name
);
6254 rep
= (xkbGetDeviceInfoReply
) {
6256 .deviceID
= dev
->id
,
6257 .sequenceNumber
= client
->sequence
,
6258 .length
= nameLen
/ 4,
6260 .supported
= XkbXI_AllDeviceFeaturesMask
,
6263 .firstBtnWanted
= 0,
6267 .totalBtns
= dev
->button
? dev
->button
->numButtons
: 0,
6268 .hasOwnState
= (dev
->key
&& dev
->key
->xkbInfo
),
6269 .dfltKbdFB
= dev
->kbdfeed
? dev
->kbdfeed
->ctrl
.id
: XkbXINone
,
6270 .dfltLedFB
= dev
->leds
? dev
->leds
->ctrl
.id
: XkbXINone
,
6271 .devType
= dev
->xinput_type
6274 ledClass
= stuff
->ledClass
;
6275 ledID
= stuff
->ledID
;
6277 if (wanted
& XkbXI_ButtonActionsMask
) {
6278 if (stuff
->allBtns
) {
6279 stuff
->firstBtn
= 0;
6280 stuff
->nBtns
= dev
->button
->numButtons
;
6283 if ((stuff
->firstBtn
+ stuff
->nBtns
) > dev
->button
->numButtons
) {
6284 client
->errorValue
= _XkbErrCode4(0x02, dev
->button
->numButtons
,
6285 stuff
->firstBtn
, stuff
->nBtns
);
6289 rep
.firstBtnWanted
= stuff
->firstBtn
;
6290 rep
.nBtnsWanted
= stuff
->nBtns
;
6291 if (dev
->button
->xkb_acts
!= NULL
) {
6295 rep
.firstBtnRtrn
= stuff
->firstBtn
;
6296 rep
.nBtnsRtrn
= stuff
->nBtns
;
6297 act
= &dev
->button
->xkb_acts
[rep
.firstBtnWanted
];
6298 for (i
= 0; i
< rep
.nBtnsRtrn
; i
++, act
++) {
6299 if (act
->type
!= XkbSA_NoAction
)
6302 rep
.firstBtnRtrn
+= i
;
6305 &dev
->button
->xkb_acts
[rep
.firstBtnRtrn
+ rep
.nBtnsRtrn
-
6307 for (i
= 0; i
< rep
.nBtnsRtrn
; i
++, act
--) {
6308 if (act
->type
!= XkbSA_NoAction
)
6313 rep
.length
+= (rep
.nBtnsRtrn
* SIZEOF(xkbActionWireDesc
)) / 4;
6317 if (wanted
& XkbXI_IndicatorsMask
) {
6318 status
= CheckDeviceLedFBs(dev
, ledClass
, ledID
, &rep
, client
);
6319 if (status
!= Success
)
6322 length
= rep
.length
* 4;
6323 nDeviceLedFBs
= rep
.nDeviceLedFBs
;
6324 if (client
->swapped
) {
6325 swaps(&rep
.sequenceNumber
);
6327 swaps(&rep
.present
);
6328 swaps(&rep
.supported
);
6329 swaps(&rep
.unsupported
);
6330 swaps(&rep
.nDeviceLedFBs
);
6331 swaps(&rep
.dfltKbdFB
);
6332 swaps(&rep
.dfltLedFB
);
6333 swapl(&rep
.devType
);
6335 WriteToClient(client
, SIZEOF(xkbGetDeviceInfoReply
), &rep
);
6337 str
= malloc(nameLen
);
6340 XkbWriteCountedString(str
, dev
->name
, client
->swapped
);
6341 WriteToClient(client
, nameLen
, str
);
6345 if (rep
.nBtnsRtrn
> 0) {
6347 xkbActionWireDesc
*awire
;
6349 sz
= rep
.nBtnsRtrn
* SIZEOF(xkbActionWireDesc
);
6350 awire
= (xkbActionWireDesc
*) &dev
->button
->xkb_acts
[rep
.firstBtnRtrn
];
6351 WriteToClient(client
, sz
, awire
);
6354 if (nDeviceLedFBs
> 0) {
6355 status
= SendDeviceLedFBs(dev
, ledClass
, ledID
, length
, client
);
6356 if (status
!= Success
)
6359 else if (length
!= 0) {
6360 ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n");
6361 ErrorF("[xkb] Wrote %d fewer bytes than expected\n",
6369 CheckSetDeviceIndicators(char *wire
,
6371 int num
, int *status_rtrn
, ClientPtr client
)
6373 xkbDeviceLedsWireDesc
*ledWire
;
6375 XkbSrvLedInfoPtr sli
;
6377 ledWire
= (xkbDeviceLedsWireDesc
*) wire
;
6378 for (i
= 0; i
< num
; i
++) {
6379 if (client
->swapped
) {
6380 swaps(&ledWire
->ledClass
);
6381 swaps(&ledWire
->ledID
);
6382 swapl(&ledWire
->namesPresent
);
6383 swapl(&ledWire
->mapsPresent
);
6384 swapl(&ledWire
->physIndicators
);
6387 sli
= XkbFindSrvLedInfo(dev
, ledWire
->ledClass
, ledWire
->ledID
,
6388 XkbXI_IndicatorsMask
);
6391 register unsigned bit
;
6394 xkbIndicatorMapWireDesc
*mapWire
;
6397 for (n
= 0, bit
= 1; n
< XkbNumIndicators
; n
++, bit
<<= 1) {
6398 if (ledWire
->namesPresent
& bit
)
6400 if (ledWire
->mapsPresent
& bit
)
6403 atomWire
= (CARD32
*) &ledWire
[1];
6405 for (n
= 0; n
< nNames
; n
++) {
6406 if (client
->swapped
) {
6409 CHK_ATOM_OR_NONE3(((Atom
) (*atomWire
)), client
->errorValue
,
6410 *status_rtrn
, NULL
);
6414 mapWire
= (xkbIndicatorMapWireDesc
*) atomWire
;
6416 for (n
= 0; n
< nMaps
; n
++) {
6417 if (client
->swapped
) {
6418 swaps(&mapWire
->virtualMods
);
6419 swapl(&mapWire
->ctrls
);
6421 CHK_MASK_LEGAL3(0x21, mapWire
->whichGroups
,
6423 client
->errorValue
, *status_rtrn
, NULL
);
6424 CHK_MASK_LEGAL3(0x22, mapWire
->whichMods
, XkbIM_UseAnyMods
,
6425 client
->errorValue
, *status_rtrn
, NULL
);
6429 ledWire
= (xkbDeviceLedsWireDesc
*) mapWire
;
6432 /* SHOULD NEVER HAPPEN */
6433 return (char *) ledWire
;
6436 return (char *) ledWire
;
6440 SetDeviceIndicators(char *wire
,
6445 ClientPtr client
, xkbExtensionDeviceNotify
* ev
)
6447 xkbDeviceLedsWireDesc
*ledWire
;
6449 XkbEventCauseRec cause
;
6450 unsigned namec
, mapc
, statec
;
6451 xkbExtensionDeviceNotify ed
;
6452 XkbChangesRec changes
;
6455 memset((char *) &ed
, 0, sizeof(xkbExtensionDeviceNotify
));
6456 memset((char *) &changes
, 0, sizeof(XkbChangesRec
));
6457 XkbSetCauseXkbReq(&cause
, X_kbSetDeviceInfo
, client
);
6458 ledWire
= (xkbDeviceLedsWireDesc
*) wire
;
6459 for (i
= 0; i
< num
; i
++) {
6461 register unsigned bit
;
6463 xkbIndicatorMapWireDesc
*mapWire
;
6464 XkbSrvLedInfoPtr sli
;
6466 namec
= mapc
= statec
= 0;
6467 sli
= XkbFindSrvLedInfo(dev
, ledWire
->ledClass
, ledWire
->ledID
,
6468 XkbXI_IndicatorMapsMask
);
6470 /* SHOULD NEVER HAPPEN!! */
6471 return (char *) ledWire
;
6474 atomWire
= (CARD32
*) &ledWire
[1];
6475 if (changed
& XkbXI_IndicatorNamesMask
) {
6476 namec
= sli
->namesPresent
| ledWire
->namesPresent
;
6477 memset((char *) sli
->names
, 0, XkbNumIndicators
* sizeof(Atom
));
6479 if (ledWire
->namesPresent
) {
6480 sli
->namesPresent
= ledWire
->namesPresent
;
6481 memset((char *) sli
->names
, 0, XkbNumIndicators
* sizeof(Atom
));
6482 for (n
= 0, bit
= 1; n
< XkbNumIndicators
; n
++, bit
<<= 1) {
6483 if (ledWire
->namesPresent
& bit
) {
6484 sli
->names
[n
] = (Atom
) *atomWire
;
6485 if (sli
->names
[n
] == None
)
6486 ledWire
->namesPresent
&= ~bit
;
6491 mapWire
= (xkbIndicatorMapWireDesc
*) atomWire
;
6492 if (changed
& XkbXI_IndicatorMapsMask
) {
6493 mapc
= sli
->mapsPresent
| ledWire
->mapsPresent
;
6494 sli
->mapsPresent
= ledWire
->mapsPresent
;
6495 memset((char *) sli
->maps
, 0,
6496 XkbNumIndicators
* sizeof(XkbIndicatorMapRec
));
6498 if (ledWire
->mapsPresent
) {
6499 for (n
= 0, bit
= 1; n
< XkbNumIndicators
; n
++, bit
<<= 1) {
6500 if (ledWire
->mapsPresent
& bit
) {
6501 sli
->maps
[n
].flags
= mapWire
->flags
;
6502 sli
->maps
[n
].which_groups
= mapWire
->whichGroups
;
6503 sli
->maps
[n
].groups
= mapWire
->groups
;
6504 sli
->maps
[n
].which_mods
= mapWire
->whichMods
;
6505 sli
->maps
[n
].mods
.mask
= mapWire
->mods
;
6506 sli
->maps
[n
].mods
.real_mods
= mapWire
->realMods
;
6507 sli
->maps
[n
].mods
.vmods
= mapWire
->virtualMods
;
6508 sli
->maps
[n
].ctrls
= mapWire
->ctrls
;
6513 if (changed
& XkbXI_IndicatorStateMask
) {
6514 statec
= sli
->effectiveState
^ ledWire
->state
;
6515 sli
->explicitState
&= ~statec
;
6516 sli
->explicitState
|= (ledWire
->state
& statec
);
6519 XkbApplyLedNameChanges(dev
, sli
, namec
, &ed
, &changes
, &cause
);
6521 XkbApplyLedMapChanges(dev
, sli
, mapc
, &ed
, &changes
, &cause
);
6523 XkbApplyLedStateChanges(dev
, sli
, statec
, &ed
, &changes
, &cause
);
6526 if ((sli
->flags
& XkbSLI_HasOwnState
) == 0)
6527 kbd
= inputInfo
.keyboard
;
6529 XkbFlushLedEvents(dev
, kbd
, sli
, &ed
, &changes
, &cause
);
6530 ledWire
= (xkbDeviceLedsWireDesc
*) mapWire
;
6532 return (char *) ledWire
;
6536 _XkbSetDeviceInfo(ClientPtr client
, DeviceIntPtr dev
,
6537 xkbSetDeviceInfoReq
* stuff
)
6541 wire
= (char *) &stuff
[1];
6542 if (stuff
->change
& XkbXI_ButtonActionsMask
) {
6544 client
->errorValue
= _XkbErrCode2(XkbErr_BadClass
, ButtonClass
);
6545 return XkbKeyboardErrorCode
;
6547 if ((stuff
->firstBtn
+ stuff
->nBtns
) > dev
->button
->numButtons
) {
6548 client
->errorValue
=
6549 _XkbErrCode4(0x02, stuff
->firstBtn
, stuff
->nBtns
,
6550 dev
->button
->numButtons
);
6553 wire
+= (stuff
->nBtns
* SIZEOF(xkbActionWireDesc
));
6555 if (stuff
->change
& XkbXI_IndicatorsMask
) {
6556 int status
= Success
;
6558 wire
= CheckSetDeviceIndicators(wire
, dev
, stuff
->nDeviceLedFBs
,
6560 if (status
!= Success
)
6563 if (((wire
- ((char *) stuff
)) / 4) != stuff
->length
)
6570 _XkbSetDeviceInfoCheck(ClientPtr client
, DeviceIntPtr dev
,
6571 xkbSetDeviceInfoReq
* stuff
)
6574 xkbExtensionDeviceNotify ed
;
6576 memset((char *) &ed
, 0, SIZEOF(xkbExtensionDeviceNotify
));
6577 ed
.deviceID
= dev
->id
;
6578 wire
= (char *) &stuff
[1];
6579 if (stuff
->change
& XkbXI_ButtonActionsMask
) {
6584 nBtns
= dev
->button
->numButtons
;
6585 acts
= dev
->button
->xkb_acts
;
6587 acts
= calloc(nBtns
, sizeof(XkbAction
));
6590 dev
->button
->xkb_acts
= acts
;
6592 sz
= stuff
->nBtns
* SIZEOF(xkbActionWireDesc
);
6593 memcpy((char *) &acts
[stuff
->firstBtn
], (char *) wire
, sz
);
6595 ed
.reason
|= XkbXI_ButtonActionsMask
;
6596 ed
.firstBtn
= stuff
->firstBtn
;
6597 ed
.nBtns
= stuff
->nBtns
;
6602 kbd
= inputInfo
.keyboard
;
6603 acts
= &dev
->button
->xkb_acts
[stuff
->firstBtn
];
6604 for (i
= 0; i
< stuff
->nBtns
; i
++, acts
++) {
6605 if (acts
->type
!= XkbSA_NoAction
)
6606 XkbSetActionKeyMods(kbd
->key
->xkbInfo
->desc
, acts
, 0);
6609 if (stuff
->change
& XkbXI_IndicatorsMask
) {
6610 int status
= Success
;
6612 wire
= SetDeviceIndicators(wire
, dev
, stuff
->change
,
6613 stuff
->nDeviceLedFBs
, &status
, client
, &ed
);
6614 if (status
!= Success
)
6617 if ((stuff
->change
) && (ed
.reason
))
6618 XkbSendExtensionDeviceNotify(dev
, client
, &ed
);
6623 ProcXkbSetDeviceInfo(ClientPtr client
)
6628 REQUEST(xkbSetDeviceInfoReq
);
6629 REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq
);
6631 if (!(client
->xkbClientFlags
& _XkbClientInitialized
))
6634 CHK_ANY_DEVICE(dev
, stuff
->deviceSpec
, client
, DixManageAccess
);
6635 CHK_MASK_LEGAL(0x01, stuff
->change
, XkbXI_AllFeaturesMask
);
6637 rc
= _XkbSetDeviceInfoCheck(client
, dev
, stuff
);
6642 if (stuff
->deviceSpec
== XkbUseCoreKbd
||
6643 stuff
->deviceSpec
== XkbUseCorePtr
) {
6646 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
6647 if (((other
!= dev
) && !IsMaster(other
) &&
6648 GetMaster(other
, MASTER_KEYBOARD
) == dev
) &&
6649 ((stuff
->deviceSpec
== XkbUseCoreKbd
&& other
->key
) ||
6650 (stuff
->deviceSpec
== XkbUseCorePtr
&& other
->button
))) {
6651 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
6653 if (rc
== Success
) {
6654 rc
= _XkbSetDeviceInfoCheck(client
, other
, stuff
);
6662 /* checks done, apply */
6663 rc
= _XkbSetDeviceInfo(client
, dev
, stuff
);
6667 if (stuff
->deviceSpec
== XkbUseCoreKbd
||
6668 stuff
->deviceSpec
== XkbUseCorePtr
) {
6671 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
6672 if (((other
!= dev
) && !IsMaster(other
) &&
6673 GetMaster(other
, MASTER_KEYBOARD
) == dev
) &&
6674 ((stuff
->deviceSpec
== XkbUseCoreKbd
&& other
->key
) ||
6675 (stuff
->deviceSpec
== XkbUseCorePtr
&& other
->button
))) {
6676 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, other
,
6678 if (rc
== Success
) {
6679 rc
= _XkbSetDeviceInfo(client
, other
, stuff
);
6690 /***====================================================================***/
6693 ProcXkbSetDebuggingFlags(ClientPtr client
)
6695 CARD32 newFlags
, newCtrls
, extraLength
;
6696 xkbSetDebuggingFlagsReply rep
;
6699 REQUEST(xkbSetDebuggingFlagsReq
);
6700 REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq
);
6702 rc
= XaceHook(XACE_SERVER_ACCESS
, client
, DixDebugAccess
);
6706 newFlags
= xkbDebugFlags
& (~stuff
->affectFlags
);
6707 newFlags
|= (stuff
->flags
& stuff
->affectFlags
);
6708 newCtrls
= xkbDebugCtrls
& (~stuff
->affectCtrls
);
6709 newCtrls
|= (stuff
->ctrls
& stuff
->affectCtrls
);
6710 if (xkbDebugFlags
|| newFlags
|| stuff
->msgLength
) {
6711 ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",
6713 if (newCtrls
!= xkbDebugCtrls
)
6714 ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",
6717 extraLength
= (stuff
->length
<< 2) - sz_xkbSetDebuggingFlagsReq
;
6718 if (stuff
->msgLength
> 0) {
6721 if (extraLength
< XkbPaddedSize(stuff
->msgLength
)) {
6723 ("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n",
6724 stuff
->msgLength
, (long) extraLength
,
6725 XkbPaddedSize(stuff
->msgLength
));
6728 msg
= (char *) &stuff
[1];
6729 if (msg
[stuff
->msgLength
- 1] != '\0') {
6730 ErrorF("[xkb] XkbDebug: message not null-terminated\n");
6733 ErrorF("[xkb] XkbDebug: %s\n", msg
);
6735 xkbDebugFlags
= newFlags
;
6736 xkbDebugCtrls
= newCtrls
;
6738 rep
= (xkbSetDebuggingFlagsReply
) {
6740 .sequenceNumber
= client
->sequence
,
6742 .currentFlags
= newFlags
,
6743 .currentCtrls
= newCtrls
,
6744 .supportedFlags
= ~0,
6745 .supportedCtrls
= ~0
6747 if (client
->swapped
) {
6748 swaps(&rep
.sequenceNumber
);
6749 swapl(&rep
.currentFlags
);
6750 swapl(&rep
.currentCtrls
);
6751 swapl(&rep
.supportedFlags
);
6752 swapl(&rep
.supportedCtrls
);
6754 WriteToClient(client
, SIZEOF(xkbSetDebuggingFlagsReply
), &rep
);
6758 /***====================================================================***/
6761 ProcXkbDispatch(ClientPtr client
)
6764 switch (stuff
->data
) {
6765 case X_kbUseExtension
:
6766 return ProcXkbUseExtension(client
);
6767 case X_kbSelectEvents
:
6768 return ProcXkbSelectEvents(client
);
6770 return ProcXkbBell(client
);
6772 return ProcXkbGetState(client
);
6773 case X_kbLatchLockState
:
6774 return ProcXkbLatchLockState(client
);
6775 case X_kbGetControls
:
6776 return ProcXkbGetControls(client
);
6777 case X_kbSetControls
:
6778 return ProcXkbSetControls(client
);
6780 return ProcXkbGetMap(client
);
6782 return ProcXkbSetMap(client
);
6783 case X_kbGetCompatMap
:
6784 return ProcXkbGetCompatMap(client
);
6785 case X_kbSetCompatMap
:
6786 return ProcXkbSetCompatMap(client
);
6787 case X_kbGetIndicatorState
:
6788 return ProcXkbGetIndicatorState(client
);
6789 case X_kbGetIndicatorMap
:
6790 return ProcXkbGetIndicatorMap(client
);
6791 case X_kbSetIndicatorMap
:
6792 return ProcXkbSetIndicatorMap(client
);
6793 case X_kbGetNamedIndicator
:
6794 return ProcXkbGetNamedIndicator(client
);
6795 case X_kbSetNamedIndicator
:
6796 return ProcXkbSetNamedIndicator(client
);
6798 return ProcXkbGetNames(client
);
6800 return ProcXkbSetNames(client
);
6801 case X_kbGetGeometry
:
6802 return ProcXkbGetGeometry(client
);
6803 case X_kbSetGeometry
:
6804 return ProcXkbSetGeometry(client
);
6805 case X_kbPerClientFlags
:
6806 return ProcXkbPerClientFlags(client
);
6807 case X_kbListComponents
:
6808 return ProcXkbListComponents(client
);
6809 case X_kbGetKbdByName
:
6810 return ProcXkbGetKbdByName(client
);
6811 case X_kbGetDeviceInfo
:
6812 return ProcXkbGetDeviceInfo(client
);
6813 case X_kbSetDeviceInfo
:
6814 return ProcXkbSetDeviceInfo(client
);
6815 case X_kbSetDebuggingFlags
:
6816 return ProcXkbSetDebuggingFlags(client
);
6823 XkbClientGone(pointer data
, XID id
)
6825 DevicePtr pXDev
= (DevicePtr
) data
;
6827 if (!XkbRemoveResourceClient(pXDev
, id
)) {
6829 ("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n");
6835 XkbExtensionInit(void)
6837 ExtensionEntry
*extEntry
;
6839 RT_XKBCLIENT
= CreateNewResourceType(XkbClientGone
, "XkbClient");
6843 if (!XkbInitPrivates())
6846 if ((extEntry
= AddExtension(XkbName
, XkbNumberEvents
, XkbNumberErrors
,
6847 ProcXkbDispatch
, SProcXkbDispatch
,
6848 NULL
, StandardMinorOpcode
))) {
6849 XkbReqCode
= (unsigned char) extEntry
->base
;
6850 XkbEventBase
= (unsigned char) extEntry
->eventBase
;
6851 XkbErrorBase
= (unsigned char) extEntry
->errorBase
;
6852 XkbKeyboardErrorCode
= XkbErrorBase
+ XkbKeyboard
;