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>
34 #include <X11/keysym.h>
35 #include <X11/extensions/XI.h>
36 #include <X11/extensions/XIproto.h>
39 #include "exglobals.h"
40 #include "windowstr.h"
45 /***====================================================================***/
48 * This function sends out two kinds of notification:
49 * - Core mapping notify events sent to clients for whom kbd is the
50 * current core ('picked') keyboard _and_ have not explicitly
51 * selected for XKB mapping notify events;
52 * - Xi mapping events, sent unconditionally to all clients who have
53 * explicitly selected for them (including those who have explicitly
54 * selected for XKB mapping notify events!).
57 XkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed,
58 int first_key, int num_keys)
61 int keymap_changed = 0;
62 int modmap_changed = 0;
64 deviceMappingNotify xi_mn;
65 CARD32 time = GetTimeInMillis();
67 if (xkb_event == XkbNewKeyboardNotify) {
68 if (changed & XkbNKN_KeycodesMask) {
73 else if (xkb_event == XkbMapNotify) {
74 if (changed & XkbKeySymsMask)
76 if (changed & XkbModifierMapMask)
79 if (!keymap_changed && !modmap_changed)
82 core_mn.u.u.type = MappingNotify;
83 xi_mn.type = DeviceMappingNotify;
84 xi_mn.deviceid = kbd->id;
87 /* 0 is serverClient. */
88 for (i = 1; i < currentMaxClients; i++) {
89 if (!clients[i] || clients[i]->clientState != ClientStateRunning)
92 /* Ignore clients which will have already received this.
93 * Inconsistent with themselves, but consistent with previous
95 if (xkb_event == XkbMapNotify && (clients[i]->mapNotifyMask & changed))
97 if (xkb_event == XkbNewKeyboardNotify &&
98 (clients[i]->xkbClientFlags & _XkbClientInitialized))
101 /* Don't send core events to clients who don't know about us. */
102 if (!XIShouldNotify(clients[i], kbd))
105 if (keymap_changed) {
106 core_mn.u.mappingNotify.request = MappingKeyboard;
108 /* Clip the keycode range to what the client knows about, so it
109 * doesn't freak out. */
110 if (first_key >= clients[i]->minKC)
111 core_mn.u.mappingNotify.firstKeyCode = first_key;
113 core_mn.u.mappingNotify.firstKeyCode = clients[i]->minKC;
114 if (first_key + num_keys - 1 <= clients[i]->maxKC)
115 core_mn.u.mappingNotify.count = num_keys;
117 core_mn.u.mappingNotify.count = clients[i]->maxKC -
118 clients[i]->minKC + 1;
120 WriteEventsToClient(clients[i], 1, &core_mn);
122 if (modmap_changed) {
123 core_mn.u.mappingNotify.request = MappingModifier;
124 core_mn.u.mappingNotify.firstKeyCode = 0;
125 core_mn.u.mappingNotify.count = 0;
126 WriteEventsToClient(clients[i], 1, &core_mn);
130 /* Hmm, maybe we can accidentally generate Xi events for core devices
131 * here? Clients might be upset, but that seems better than the
132 * alternative of stale keymaps. -ds */
133 if (keymap_changed) {
134 xi_mn.request = MappingKeyboard;
135 xi_mn.firstKeyCode = first_key;
136 xi_mn.count = num_keys;
137 SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn,
140 if (modmap_changed) {
141 xi_mn.request = MappingModifier;
142 xi_mn.firstKeyCode = 0;
144 SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn,
149 /***====================================================================***/
152 XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN)
155 Time time = GetTimeInMillis();
156 CARD16 changed = pNKN->changed;
158 pNKN->type = XkbEventCode + XkbEventBase;
159 pNKN->xkbType = XkbNewKeyboardNotify;
161 for (i=1; i<currentMaxClients; i++) {
162 if (!clients[i] || clients[i]->clientState != ClientStateRunning)
165 if (!(clients[i]->newKeyboardNotifyMask & changed))
168 if (!XIShouldNotify(clients[i], kbd))
171 pNKN->sequenceNumber = clients[i]->sequence;
173 pNKN->changed = changed;
174 if (clients[i]->swapped) {
176 swaps(&pNKN->sequenceNumber,n);
177 swapl(&pNKN->time,n);
178 swaps(&pNKN->changed,n);
180 WriteToClient(clients[i], sizeof(xEvent), pNKN);
182 if (changed & XkbNKN_KeycodesMask) {
183 clients[i]->minKC = pNKN->minKeyCode;
184 clients[i]->maxKC = pNKN->maxKeyCode;
188 XkbSendLegacyMapNotify(kbd, XkbNewKeyboardNotify, changed, pNKN->minKeyCode,
189 pNKN->maxKeyCode - pNKN->minKeyCode + 1);
194 /***====================================================================***/
197 XkbSendStateNotify(DeviceIntPtr kbd,xkbStateNotify *pSN)
201 XkbInterestPtr interest;
203 register CARD16 changed,bState;
205 interest = kbd->xkb_interest;
206 if (!interest || !kbd->key || !kbd->key->xkbInfo)
208 xkbi = kbd->key->xkbInfo;
211 pSN->type = XkbEventCode + XkbEventBase;
212 pSN->xkbType = XkbStateNotify;
213 pSN->deviceID = kbd->id;
214 pSN->time = time = GetTimeInMillis();
215 pSN->mods = state->mods;
216 pSN->baseMods = state->base_mods;
217 pSN->latchedMods = state->latched_mods;
218 pSN->lockedMods = state->locked_mods;
219 pSN->group = state->group;
220 pSN->baseGroup = state->base_group;
221 pSN->latchedGroup = state->latched_group;
222 pSN->lockedGroup = state->locked_group;
223 pSN->compatState = state->compat_state;
224 pSN->grabMods = state->grab_mods;
225 pSN->compatGrabMods = state->compat_grab_mods;
226 pSN->lookupMods = state->lookup_mods;
227 pSN->compatLookupMods = state->compat_lookup_mods;
228 pSN->ptrBtnState = state->ptr_buttons;
229 changed = pSN->changed;
230 bState= pSN->ptrBtnState;
233 if ((!interest->client->clientGone) &&
234 (interest->client->requestVector != InitialVector) &&
235 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
236 (interest->stateNotifyMask&changed) &&
237 XIShouldNotify(interest->client,kbd)) {
238 pSN->sequenceNumber = interest->client->sequence;
240 pSN->changed = changed;
241 pSN->ptrBtnState = bState;
242 if ( interest->client->swapped ) {
244 swaps(&pSN->sequenceNumber,n);
246 swaps(&pSN->changed,n);
247 swaps(&pSN->ptrBtnState,n);
249 WriteToClient(interest->client, sizeof(xEvent), (char *)pSN);
251 interest= interest->next;
256 /***====================================================================***/
259 * This function sends out XKB mapping notify events to clients which
260 * have explicitly selected for them. Core and Xi events are handled by
261 * XkbSendLegacyMapNotify. */
263 XkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify *pMN)
266 CARD32 time = GetTimeInMillis();
267 CARD16 changed = pMN->changed;
268 XkbSrvInfoPtr xkbi = kbd->key->xkbInfo;
270 pMN->minKeyCode = xkbi->desc->min_key_code;
271 pMN->maxKeyCode = xkbi->desc->max_key_code;
272 pMN->type = XkbEventCode + XkbEventBase;
273 pMN->xkbType = XkbMapNotify;
274 pMN->deviceID = kbd->id;
276 /* 0 is serverClient. */
277 for (i = 1; i < currentMaxClients; i++) {
278 if (!clients[i] || clients[i]->clientState != ClientStateRunning)
281 if (!(clients[i]->mapNotifyMask & changed))
284 if (!XIShouldNotify(clients[i], kbd))
288 pMN->sequenceNumber = clients[i]->sequence;
289 pMN->changed = changed;
291 if (clients[i]->swapped) {
293 swaps(&pMN->sequenceNumber, n);
294 swapl(&pMN->time, n);
295 swaps(&pMN->changed, n);
297 WriteToClient(clients[i], sizeof(xEvent), pMN);
300 XkbSendLegacyMapNotify(kbd, XkbMapNotify, changed, pMN->firstKeySym,
305 XkbComputeControlsNotify( DeviceIntPtr kbd,
308 xkbControlsNotify * pCN,
312 CARD32 changedControls;
316 if (!kbd || !kbd->kbdfeed)
319 if (old->enabled_ctrls!=new->enabled_ctrls)
320 changedControls|= XkbControlsEnabledMask;
321 if ((old->repeat_delay!=new->repeat_delay)||
322 (old->repeat_interval!=new->repeat_interval))
323 changedControls|= XkbRepeatKeysMask;
324 for (i = 0; i < XkbPerKeyBitArraySize; i++)
325 if (old->per_key_repeat[i] != new->per_key_repeat[i])
326 changedControls|= XkbPerKeyRepeatMask;
327 if (old->slow_keys_delay!=new->slow_keys_delay)
328 changedControls|= XkbSlowKeysMask;
329 if (old->debounce_delay!=new->debounce_delay)
330 changedControls|= XkbBounceKeysMask;
331 if ((old->mk_delay!=new->mk_delay)||
332 (old->mk_interval!=new->mk_interval)||
333 (old->mk_dflt_btn!=new->mk_dflt_btn))
334 changedControls|= XkbMouseKeysMask;
335 if ((old->mk_time_to_max!=new->mk_time_to_max)||
336 (old->mk_curve!=new->mk_curve)||
337 (old->mk_max_speed!=new->mk_max_speed))
338 changedControls|= XkbMouseKeysAccelMask;
339 if (old->ax_options!=new->ax_options)
340 changedControls|= XkbAccessXKeysMask;
341 if ((old->ax_options^new->ax_options) & XkbAX_SKOptionsMask)
342 changedControls|= XkbStickyKeysMask;
343 if ((old->ax_options^new->ax_options) & XkbAX_FBOptionsMask)
344 changedControls|= XkbAccessXFeedbackMask;
345 if ((old->ax_timeout!=new->ax_timeout)||
346 (old->axt_ctrls_mask!=new->axt_ctrls_mask)||
347 (old->axt_ctrls_values!=new->axt_ctrls_values)||
348 (old->axt_opts_mask!=new->axt_opts_mask)||
349 (old->axt_opts_values!= new->axt_opts_values)) {
350 changedControls|= XkbAccessXTimeoutMask;
352 if ((old->internal.mask!=new->internal.mask)||
353 (old->internal.real_mods!=new->internal.real_mods)||
354 (old->internal.vmods!=new->internal.vmods))
355 changedControls|= XkbInternalModsMask;
356 if ((old->ignore_lock.mask!=new->ignore_lock.mask)||
357 (old->ignore_lock.real_mods!=new->ignore_lock.real_mods)||
358 (old->ignore_lock.vmods!=new->ignore_lock.vmods))
359 changedControls|= XkbIgnoreLockModsMask;
361 if (new->enabled_ctrls&XkbRepeatKeysMask)
362 kbd->kbdfeed->ctrl.autoRepeat=TRUE;
363 else kbd->kbdfeed->ctrl.autoRepeat=FALSE;
365 if (kbd->kbdfeed && kbd->kbdfeed->CtrlProc &&
366 (changedControls || forceCtrlProc))
367 (*kbd->kbdfeed->CtrlProc)(kbd, &kbd->kbdfeed->ctrl);
369 if ((!changedControls)&&(old->num_groups==new->num_groups))
372 if (!kbd->xkb_interest)
375 pCN->changedControls = changedControls;
376 pCN->enabledControls = new->enabled_ctrls;
377 pCN->enabledControlChanges = (new->enabled_ctrls^old->enabled_ctrls);
378 pCN->numGroups = new->num_groups;
384 XkbSendControlsNotify(DeviceIntPtr kbd,xkbControlsNotify *pCN)
387 CARD32 changedControls, enabledControls, enabledChanges = 0;
389 XkbInterestPtr interest;
392 interest = kbd->xkb_interest;
393 if (!interest || !kbd->key || !kbd->key->xkbInfo)
395 xkbi = kbd->key->xkbInfo;
398 enabledControls = xkbi->desc->ctrls->enabled_ctrls;
399 changedControls = pCN->changedControls;
400 pCN->numGroups= xkbi->desc->ctrls->num_groups;
402 if ((!interest->client->clientGone) &&
403 (interest->client->requestVector != InitialVector) &&
404 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
405 (interest->ctrlsNotifyMask&changedControls) &&
406 XIShouldNotify(interest->client, kbd)) {
408 pCN->type = XkbEventCode + XkbEventBase;
409 pCN->xkbType = XkbControlsNotify;
410 pCN->deviceID = kbd->id;
411 pCN->time = time = GetTimeInMillis();
412 enabledChanges = pCN->enabledControlChanges;
415 pCN->changedControls = changedControls;
416 pCN->enabledControls = enabledControls;
417 pCN->enabledControlChanges = enabledChanges;
418 pCN->sequenceNumber = interest->client->sequence;
420 if ( interest->client->swapped ) {
422 swaps(&pCN->sequenceNumber,n);
423 swapl(&pCN->changedControls,n);
424 swapl(&pCN->enabledControls,n);
425 swapl(&pCN->enabledControlChanges,n);
428 WriteToClient(interest->client, sizeof(xEvent), (char *)pCN);
430 interest= interest->next;
436 XkbSendIndicatorNotify(DeviceIntPtr kbd,int xkbType,xkbIndicatorNotify *pEv)
439 XkbInterestPtr interest;
441 CARD32 state,changed;
443 interest = kbd->xkb_interest;
449 changed = pEv->changed;
451 if ((!interest->client->clientGone) &&
452 (interest->client->requestVector != InitialVector) &&
453 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
454 XIShouldNotify(interest->client, kbd) &&
455 (((xkbType==XkbIndicatorStateNotify)&&
456 (interest->iStateNotifyMask&changed))||
457 ((xkbType==XkbIndicatorMapNotify)&&
458 (interest->iMapNotifyMask&changed)))) {
460 pEv->type = XkbEventCode + XkbEventBase;
461 pEv->xkbType = xkbType;
462 pEv->deviceID = kbd->id;
463 pEv->time = time = GetTimeInMillis();
466 pEv->sequenceNumber = interest->client->sequence;
468 pEv->changed = changed;
470 if ( interest->client->swapped ) {
472 swaps(&pEv->sequenceNumber,n);
474 swapl(&pEv->changed,n);
475 swapl(&pEv->state,n);
477 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
479 interest= interest->next;
486 XkbHandleBell( BOOL force,
499 XkbInterestPtr interest;
501 CARD16 pitch,duration;
505 if (!kbd->key || !kbd->key->xkbInfo)
508 xkbi = kbd->key->xkbInfo;
510 if ((force||(xkbi->desc->ctrls->enabled_ctrls&XkbAudibleBellMask))&&
512 if (kbd->kbdfeed->BellProc)
513 (*kbd->kbdfeed->BellProc)(percent,kbd,(pointer)pCtrl,class);
515 interest = kbd->xkb_interest;
516 if ((!interest)||(force))
519 if ((class==0)||(class==KbdFeedbackClass)) {
520 KeybdCtrl *pKeyCtrl= (KeybdCtrl *)pCtrl;
522 pitch= pKeyCtrl->bell_pitch;
523 duration= pKeyCtrl->bell_duration;
525 else if (class==BellFeedbackClass) {
526 BellCtrl *pBellCtrl= (BellCtrl *)pCtrl;
528 pitch= pBellCtrl->pitch;
529 duration= pBellCtrl->duration;
535 if ((!interest->client->clientGone) &&
536 (interest->client->requestVector != InitialVector) &&
537 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
538 (interest->bellNotifyMask) &&
539 XIShouldNotify(interest->client,kbd)) {
541 time = GetTimeInMillis();
542 bn.type = XkbEventCode + XkbEventBase;
543 bn.xkbType = XkbBellNotify;
544 bn.deviceID = kbd->id;
545 bn.bellClass = class;
548 bn.eventOnly = (eventOnly!=0);
549 winID= (pWin?pWin->drawable.id:None);
552 bn.sequenceNumber = interest->client->sequence;
555 bn.duration = duration;
558 if ( interest->client->swapped ) {
560 swaps(&bn.sequenceNumber,n);
563 swaps(&bn.duration,n);
567 WriteToClient(interest->client, sizeof(xEvent), (char *)&bn);
569 interest= interest->next;
575 XkbSendAccessXNotify(DeviceIntPtr kbd,xkbAccessXNotify *pEv)
578 XkbInterestPtr interest;
580 CARD16 sk_delay,db_delay;
582 interest = kbd->xkb_interest;
587 sk_delay= pEv->slowKeysDelay;
588 db_delay= pEv->debounceDelay;
590 if ((!interest->client->clientGone) &&
591 (interest->client->requestVector != InitialVector) &&
592 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
593 (interest->accessXNotifyMask&(1<<pEv->detail)) &&
594 XIShouldNotify(interest->client, kbd)) {
596 pEv->type = XkbEventCode + XkbEventBase;
597 pEv->xkbType = XkbAccessXNotify;
598 pEv->deviceID = kbd->id;
599 pEv->time = time = GetTimeInMillis();
602 pEv->sequenceNumber = interest->client->sequence;
604 pEv->slowKeysDelay = sk_delay;
605 pEv->debounceDelay = db_delay;
606 if ( interest->client->swapped ) {
608 swaps(&pEv->sequenceNumber,n);
610 swaps(&pEv->slowKeysDelay,n);
611 swaps(&pEv->debounceDelay,n);
613 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
615 interest= interest->next;
621 XkbSendNamesNotify(DeviceIntPtr kbd,xkbNamesNotify *pEv)
624 XkbInterestPtr interest;
626 CARD16 changed,changedVirtualMods;
627 CARD32 changedIndicators;
629 interest = kbd->xkb_interest;
634 changed= pEv->changed;
635 changedIndicators= pEv->changedIndicators;
636 changedVirtualMods= pEv->changedVirtualMods;
638 if ((!interest->client->clientGone) &&
639 (interest->client->requestVector != InitialVector) &&
640 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
641 (interest->namesNotifyMask&pEv->changed) &&
642 XIShouldNotify(interest->client, kbd)) {
644 pEv->type = XkbEventCode + XkbEventBase;
645 pEv->xkbType = XkbNamesNotify;
646 pEv->deviceID = kbd->id;
647 pEv->time = time = GetTimeInMillis();
650 pEv->sequenceNumber = interest->client->sequence;
652 pEv->changed = changed;
653 pEv->changedIndicators = changedIndicators;
654 pEv->changedVirtualMods= changedVirtualMods;
655 if ( interest->client->swapped ) {
657 swaps(&pEv->sequenceNumber,n);
659 swaps(&pEv->changed,n);
660 swapl(&pEv->changedIndicators,n);
661 swaps(&pEv->changedVirtualMods,n);
663 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
665 interest= interest->next;
671 XkbSendCompatMapNotify(DeviceIntPtr kbd,xkbCompatMapNotify *pEv)
674 XkbInterestPtr interest;
676 CARD16 firstSI = 0, nSI = 0, nTotalSI = 0;
678 interest = kbd->xkb_interest;
684 if ((!interest->client->clientGone) &&
685 (interest->client->requestVector != InitialVector) &&
686 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
687 (interest->compatNotifyMask) &&
688 XIShouldNotify(interest->client, kbd)) {
690 pEv->type = XkbEventCode + XkbEventBase;
691 pEv->xkbType = XkbCompatMapNotify;
692 pEv->deviceID = kbd->id;
693 pEv->time = time = GetTimeInMillis();
694 firstSI= pEv->firstSI;
696 nTotalSI= pEv->nTotalSI;
699 pEv->sequenceNumber = interest->client->sequence;
701 pEv->firstSI = firstSI;
703 pEv->nTotalSI = nTotalSI;
704 if ( interest->client->swapped ) {
706 swaps(&pEv->sequenceNumber,n);
708 swaps(&pEv->firstSI,n);
710 swaps(&pEv->nTotalSI,n);
712 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
714 interest= interest->next;
720 XkbSendActionMessage(DeviceIntPtr kbd,xkbActionMessage *pEv)
724 XkbInterestPtr interest;
727 interest = kbd->xkb_interest;
728 if (!interest || !kbd->key || !kbd->key->xkbInfo)
731 xkbi = kbd->key->xkbInfo;
734 pEv->mods= xkbi->state.mods;
735 pEv->group= xkbi->state.group;
737 if ((!interest->client->clientGone) &&
738 (interest->client->requestVector != InitialVector) &&
739 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
740 (interest->actionMessageMask) &&
741 XIShouldNotify(interest->client, kbd)) {
743 pEv->type = XkbEventCode + XkbEventBase;
744 pEv->xkbType = XkbActionMessage;
745 pEv->deviceID = kbd->id;
746 pEv->sequenceNumber = interest->client->sequence;
747 pEv->time = time = GetTimeInMillis();
750 pEv->sequenceNumber = interest->client->sequence;
752 if ( interest->client->swapped ) {
754 swaps(&pEv->sequenceNumber,n);
757 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
759 interest= interest->next;
765 XkbSendExtensionDeviceNotify( DeviceIntPtr dev,
767 xkbExtensionDeviceNotify * pEv)
770 XkbInterestPtr interest;
772 CARD32 defined, state;
775 interest = dev->xkb_interest;
781 defined= pEv->ledsDefined;
782 state= pEv->ledState;
784 if ((!interest->client->clientGone) &&
785 (interest->client->requestVector != InitialVector) &&
786 (interest->client->xkbClientFlags&_XkbClientInitialized) &&
787 (interest->extDevNotifyMask&reason) &&
788 XIShouldNotify(interest->client, dev)) {
790 pEv->type = XkbEventCode + XkbEventBase;
791 pEv->xkbType = XkbExtensionDeviceNotify;
792 pEv->deviceID = dev->id;
793 pEv->sequenceNumber = interest->client->sequence;
794 pEv->time = time = GetTimeInMillis();
798 pEv->sequenceNumber = interest->client->sequence;
800 pEv->ledsDefined= defined;
801 pEv->ledState= state;
803 pEv->supported= XkbXI_AllFeaturesMask;
805 if ( interest->client->swapped ) {
807 swaps(&pEv->sequenceNumber,n);
809 swapl(&pEv->ledsDefined,n);
810 swapl(&pEv->ledState,n);
811 swaps(&pEv->reason,n);
812 swaps(&pEv->supported,n);
814 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
816 interest= interest->next;
822 XkbSendNotification( DeviceIntPtr kbd,
823 XkbChangesPtr pChanges,
824 XkbEventCausePtr cause)
826 XkbSrvLedInfoPtr sli;
829 if (pChanges->state_changes) {
831 sn.changed= pChanges->state_changes;
832 sn.keycode= cause->kc;
833 sn.eventType= cause->event;
834 sn.requestMajor= cause->mjr;
835 sn.requestMinor= cause->mnr;
836 XkbSendStateNotify(kbd,&sn);
838 if (pChanges->map.changed) {
840 memset(&mn, 0, sizeof(xkbMapNotify));
841 mn.changed= pChanges->map.changed;
842 mn.firstType= pChanges->map.first_type;
843 mn.nTypes= pChanges->map.num_types;
844 mn.firstKeySym= pChanges->map.first_key_sym;
845 mn.nKeySyms= pChanges->map.num_key_syms;
846 mn.firstKeyAct= pChanges->map.first_key_act;
847 mn.nKeyActs= pChanges->map.num_key_acts;
848 mn.firstKeyBehavior= pChanges->map.first_key_behavior;
849 mn.nKeyBehaviors= pChanges->map.num_key_behaviors;
850 mn.virtualMods= pChanges->map.vmods;
851 mn.firstKeyExplicit= pChanges->map.first_key_explicit;
852 mn.nKeyExplicit= pChanges->map.num_key_explicit;
853 mn.firstModMapKey= pChanges->map.first_modmap_key;
854 mn.nModMapKeys= pChanges->map.num_modmap_keys;
855 mn.firstVModMapKey= pChanges->map.first_vmodmap_key;
856 mn.nVModMapKeys= pChanges->map.num_vmodmap_keys;
857 XkbSendMapNotify(kbd,&mn);
859 if ((pChanges->ctrls.changed_ctrls)||
860 (pChanges->ctrls.enabled_ctrls_changes)) {
861 xkbControlsNotify cn;
862 memset(&cn, 0, sizeof(xkbControlsNotify));
863 cn.changedControls= pChanges->ctrls.changed_ctrls;
864 cn.enabledControlChanges= pChanges->ctrls.enabled_ctrls_changes;
865 cn.keycode= cause->kc;
866 cn.eventType= cause->event;
867 cn.requestMajor= cause->mjr;
868 cn.requestMinor= cause->mnr;
869 XkbSendControlsNotify(kbd,&cn);
871 if (pChanges->indicators.map_changes) {
872 xkbIndicatorNotify in;
874 sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
875 memset(&in, 0, sizeof(xkbIndicatorNotify));
876 in.state= sli->effectiveState;
877 in.changed= pChanges->indicators.map_changes;
878 XkbSendIndicatorNotify(kbd,XkbIndicatorMapNotify,&in);
880 if (pChanges->indicators.state_changes) {
881 xkbIndicatorNotify in;
883 sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
884 memset(&in, 0, sizeof(xkbIndicatorNotify));
885 in.state= sli->effectiveState;
886 in.changed= pChanges->indicators.state_changes;
887 XkbSendIndicatorNotify(kbd,XkbIndicatorStateNotify,&in);
889 if (pChanges->names.changed) {
891 memset(&nn, 0, sizeof(xkbNamesNotify));
892 nn.changed= pChanges->names.changed;
893 nn.firstType= pChanges->names.first_type;
894 nn.nTypes= pChanges->names.num_types;
895 nn.firstLevelName= pChanges->names.first_lvl;
896 nn.nLevelNames= pChanges->names.num_lvls;
897 nn.nRadioGroups= pChanges->names.num_rg;
898 nn.changedVirtualMods= pChanges->names.changed_vmods;
899 nn.changedIndicators= pChanges->names.changed_indicators;
900 XkbSendNamesNotify(kbd,&nn);
902 if ((pChanges->compat.changed_groups)||(pChanges->compat.num_si>0)) {
903 xkbCompatMapNotify cmn;
904 memset(&cmn, 0, sizeof(xkbCompatMapNotify));
905 cmn.changedGroups= pChanges->compat.changed_groups;
906 cmn.firstSI= pChanges->compat.first_si;
907 cmn.nSI= pChanges->compat.num_si;
908 cmn.nTotalSI= kbd->key->xkbInfo->desc->compat->num_si;
909 XkbSendCompatMapNotify(kbd,&cmn);
914 /***====================================================================***/
917 XkbFilterEvents(ClientPtr client,int nEvents,xEvent *xE)
919 DeviceIntPtr dev = NULL;
921 CARD8 type = xE[0].u.u.type;
923 if (xE->u.u.type & EXTENSION_EVENT_BASE)
924 dev = XIGetDevice(xE);
927 dev = PickKeyboard(client);
932 xkbi = dev->key->xkbInfo;
934 if (client->xkbClientFlags & _XkbClientInitialized) {
935 if ((xkbDebugFlags&0x10)&&
936 (type == KeyPress || type == KeyRelease ||
937 type == DeviceKeyPress || type == DeviceKeyRelease))
938 DebugF("[xkb] XkbFilterWriteEvents (XKB client): state 0x%04x\n",
939 xE[0].u.keyButtonPointer.state);
941 if (dev->deviceGrab.grab != NullGrab && dev->deviceGrab.fromPassiveGrab &&
942 (type == KeyPress || type == KeyRelease ||
943 type == DeviceKeyPress || type == DeviceKeyRelease)) {
944 unsigned int state, flags;
946 flags = client->xkbClientFlags;
947 state = xkbi->state.compat_grab_mods;
948 if (flags & XkbPCF_GrabsUseXKBStateMask) {
950 if (flags & XkbPCF_LookupStateWhenGrabbed) {
951 group = xkbi->state.group;
952 state = xkbi->state.lookup_mods;
955 state = xkbi->state.grab_mods;
956 group = xkbi->state.base_group + xkbi->state.latched_group;
957 if (group < 0 || group >= xkbi->desc->ctrls->num_groups)
958 group = XkbAdjustGroup(group, xkbi->desc->ctrls);
960 state = XkbBuildCoreState(state, group);
962 else if (flags & XkbPCF_LookupStateWhenGrabbed) {
963 state = xkbi->state.compat_lookup_mods;
965 xE[0].u.keyButtonPointer.state = state;
969 if ((xkbDebugFlags & 0x4) &&
970 (xE[0].u.u.type == KeyPress || xE[0].u.u.type==KeyRelease ||
971 xE[0].u.u.type == DeviceKeyPress ||
972 xE[0].u.u.type == DeviceKeyRelease)) {
973 DebugF("[xkb] XKbFilterWriteEvents (non-XKB):\n");
974 DebugF("[xkb] event= 0x%04x\n",xE[0].u.keyButtonPointer.state);
975 DebugF("[xkb] lookup= 0x%02x, grab= 0x%02x\n",
976 xkbi->state.lookup_mods, xkbi->state.grab_mods);
977 DebugF("[xkb] compat lookup= 0x%02x, grab= 0x%02x\n",
978 xkbi->state.compat_lookup_mods, xkbi->state.compat_grab_mods);
980 if (type >= KeyPress && type <= MotionNotify) {
983 old = xE[0].u.keyButtonPointer.state & ~0x1f00;
984 new = xE[0].u.keyButtonPointer.state & 0x1F00;
986 if (old == XkbStateFieldFromRec(&xkbi->state))
987 new |= xkbi->state.compat_lookup_mods;
989 new |= xkbi->state.compat_grab_mods;
990 xE[0].u.keyButtonPointer.state = new;
992 else if (type == EnterNotify || type == LeaveNotify) {
993 xE[0].u.enterLeave.state &= 0x1F00;
994 xE[0].u.enterLeave.state |= xkbi->state.compat_grab_mods;
996 else if (type >= DeviceKeyPress && type <= DeviceMotionNotify) {
998 deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer*) &xE[0];
1000 old = kbp->state & ~0x1F00;
1001 new = kbp->state & 0x1F00;
1002 if (old == XkbStateFieldFromRec(&xkbi->state))
1003 new |= xkbi->state.compat_lookup_mods;
1005 new |= xkbi->state.compat_grab_mods;
1011 /***====================================================================***/
1014 XkbFindClientResource(DevicePtr inDev,ClientPtr client)
1016 DeviceIntPtr dev = (DeviceIntPtr)inDev;
1017 XkbInterestPtr interest;
1019 if ( dev->xkb_interest ) {
1020 interest = dev->xkb_interest;
1022 if (interest->client==client) {
1025 interest = interest->next;
1032 XkbAddClientResource(DevicePtr inDev,ClientPtr client,XID id)
1034 DeviceIntPtr dev = (DeviceIntPtr)inDev;
1035 XkbInterestPtr interest;
1037 interest = dev->xkb_interest;
1039 if (interest->client==client)
1040 return ((interest->resource==id)?interest:NULL);
1041 interest = interest->next;
1043 interest = calloc(1, sizeof(XkbInterestRec));
1045 interest->dev = dev;
1046 interest->client = client;
1047 interest->resource = id;
1048 interest->stateNotifyMask= 0;
1049 interest->ctrlsNotifyMask= 0;
1050 interest->namesNotifyMask= 0;
1051 interest->compatNotifyMask= 0;
1052 interest->bellNotifyMask= FALSE;
1053 interest->accessXNotifyMask= 0;
1054 interest->iStateNotifyMask= 0;
1055 interest->iMapNotifyMask= 0;
1056 interest->altSymsNotifyMask= 0;
1057 interest->next = dev->xkb_interest;
1058 dev->xkb_interest= interest;
1065 XkbRemoveResourceClient(DevicePtr inDev,XID id)
1068 DeviceIntPtr dev = (DeviceIntPtr)inDev;
1069 XkbInterestPtr interest;
1071 unsigned long autoCtrls,autoValues;
1072 ClientPtr client = NULL;
1076 if (!dev->key || !dev->key->xkbInfo)
1079 autoCtrls= autoValues= 0;
1080 if ( dev->xkb_interest ) {
1081 interest = dev->xkb_interest;
1082 if (interest && (interest->resource==id)){
1083 dev->xkb_interest = interest->next;
1084 autoCtrls= interest->autoCtrls;
1085 autoValues= interest->autoCtrlValues;
1086 client= interest->client;
1090 while ((!found)&&(interest->next)) {
1091 if (interest->next->resource==id) {
1092 XkbInterestPtr victim = interest->next;
1093 interest->next = victim->next;
1094 autoCtrls= victim->autoCtrls;
1095 autoValues= victim->autoCtrlValues;
1096 client= victim->client;
1100 interest = interest->next;
1103 if (found && autoCtrls && dev->key && dev->key->xkbInfo ) {
1104 XkbEventCauseRec cause;
1106 xkbi= dev->key->xkbInfo;
1107 XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client);
1108 XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause);