105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 935c4bbdfSmrgdocumentation, and that the name of Silicon Graphics not be 1035c4bbdfSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1235c4bbdfSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1635c4bbdfSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1735c4bbdfSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1935c4bbdfSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2035c4bbdfSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2135c4bbdfSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#include <stdio.h> 3205b261ecSmrg#include <X11/X.h> 3305b261ecSmrg#include <X11/Xproto.h> 3405b261ecSmrg#include <X11/keysym.h> 3505b261ecSmrg#include <X11/extensions/XI.h> 3605b261ecSmrg#include <X11/extensions/XIproto.h> 3705b261ecSmrg#include "inputstr.h" 386747b715Smrg#include "exevents.h" 396747b715Smrg#include "exglobals.h" 4005b261ecSmrg#include "windowstr.h" 4105b261ecSmrg#include <xkbsrv.h> 4205b261ecSmrg#include "xkb.h" 4305b261ecSmrg 4405b261ecSmrg/***====================================================================***/ 4505b261ecSmrg 466747b715Smrg/* 476747b715Smrg * This function sends out two kinds of notification: 486747b715Smrg * - Core mapping notify events sent to clients for whom kbd is the 496747b715Smrg * current core ('picked') keyboard _and_ have not explicitly 506747b715Smrg * selected for XKB mapping notify events; 516747b715Smrg * - Xi mapping events, sent unconditionally to all clients who have 526747b715Smrg * explicitly selected for them (including those who have explicitly 536747b715Smrg * selected for XKB mapping notify events!). 546747b715Smrg */ 556747b715Smrgstatic void 566747b715SmrgXkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed, 576747b715Smrg int first_key, int num_keys) 586747b715Smrg{ 596747b715Smrg int i; 606747b715Smrg int keymap_changed = 0; 616747b715Smrg int modmap_changed = 0; 626747b715Smrg CARD32 time = GetTimeInMillis(); 636747b715Smrg 646747b715Smrg if (xkb_event == XkbNewKeyboardNotify) { 656747b715Smrg if (changed & XkbNKN_KeycodesMask) { 666747b715Smrg keymap_changed = 1; 676747b715Smrg modmap_changed = 1; 686747b715Smrg } 696747b715Smrg } 706747b715Smrg else if (xkb_event == XkbMapNotify) { 716747b715Smrg if (changed & XkbKeySymsMask) 726747b715Smrg keymap_changed = 1; 736747b715Smrg if (changed & XkbModifierMapMask) 746747b715Smrg modmap_changed = 1; 756747b715Smrg } 766747b715Smrg if (!keymap_changed && !modmap_changed) 776747b715Smrg return; 786747b715Smrg 796747b715Smrg /* 0 is serverClient. */ 806747b715Smrg for (i = 1; i < currentMaxClients; i++) { 816747b715Smrg if (!clients[i] || clients[i]->clientState != ClientStateRunning) 826747b715Smrg continue; 836747b715Smrg 8435c4bbdfSmrg /* XKB allows clients to restrict the MappingNotify events sent to 8535c4bbdfSmrg * them. This was broken for three years. Sorry. */ 8635c4bbdfSmrg if (xkb_event == XkbMapNotify && 8735c4bbdfSmrg (clients[i]->xkbClientFlags & _XkbClientInitialized) && 8835c4bbdfSmrg !(clients[i]->mapNotifyMask & changed)) 896747b715Smrg continue; 9035c4bbdfSmrg /* Emulate previous server behaviour: any client which has activated 9135c4bbdfSmrg * XKB will not receive core events emulated from a NewKeyboardNotify 9235c4bbdfSmrg * at all. */ 936747b715Smrg if (xkb_event == XkbNewKeyboardNotify && 946747b715Smrg (clients[i]->xkbClientFlags & _XkbClientInitialized)) 956747b715Smrg continue; 966747b715Smrg 976747b715Smrg /* Don't send core events to clients who don't know about us. */ 986747b715Smrg if (!XIShouldNotify(clients[i], kbd)) 996747b715Smrg continue; 1006747b715Smrg 1016747b715Smrg if (keymap_changed) { 10235c4bbdfSmrg xEvent core_mn = { .u.u.type = MappingNotify }; 1036747b715Smrg core_mn.u.mappingNotify.request = MappingKeyboard; 1046747b715Smrg 1056747b715Smrg /* Clip the keycode range to what the client knows about, so it 1066747b715Smrg * doesn't freak out. */ 1076747b715Smrg if (first_key >= clients[i]->minKC) 1086747b715Smrg core_mn.u.mappingNotify.firstKeyCode = first_key; 1096747b715Smrg else 1106747b715Smrg core_mn.u.mappingNotify.firstKeyCode = clients[i]->minKC; 1116747b715Smrg if (first_key + num_keys - 1 <= clients[i]->maxKC) 1126747b715Smrg core_mn.u.mappingNotify.count = num_keys; 1136747b715Smrg else 1146747b715Smrg core_mn.u.mappingNotify.count = clients[i]->maxKC - 11535c4bbdfSmrg clients[i]->minKC + 1; 1166747b715Smrg 1176747b715Smrg WriteEventsToClient(clients[i], 1, &core_mn); 1186747b715Smrg } 1196747b715Smrg if (modmap_changed) { 12035c4bbdfSmrg xEvent core_mn = { 12135c4bbdfSmrg .u.mappingNotify.request = MappingModifier, 12235c4bbdfSmrg .u.mappingNotify.firstKeyCode = 0, 12335c4bbdfSmrg .u.mappingNotify.count = 0 12435c4bbdfSmrg }; 12535c4bbdfSmrg core_mn.u.u.type = MappingNotify; 1266747b715Smrg WriteEventsToClient(clients[i], 1, &core_mn); 1276747b715Smrg } 1286747b715Smrg } 1296747b715Smrg 1306747b715Smrg /* Hmm, maybe we can accidentally generate Xi events for core devices 1316747b715Smrg * here? Clients might be upset, but that seems better than the 1326747b715Smrg * alternative of stale keymaps. -ds */ 1336747b715Smrg if (keymap_changed) { 13435c4bbdfSmrg deviceMappingNotify xi_mn = { 13535c4bbdfSmrg .type = DeviceMappingNotify, 13635c4bbdfSmrg .deviceid = kbd->id, 13735c4bbdfSmrg .request = MappingKeyboard, 13835c4bbdfSmrg .firstKeyCode = first_key, 13935c4bbdfSmrg .count = num_keys, 14035c4bbdfSmrg .time = time 14135c4bbdfSmrg }; 1426747b715Smrg SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1436747b715Smrg 1); 1446747b715Smrg } 1456747b715Smrg if (modmap_changed) { 14635c4bbdfSmrg deviceMappingNotify xi_mn = { 14735c4bbdfSmrg .type = DeviceMappingNotify, 14835c4bbdfSmrg .deviceid = kbd->id, 14935c4bbdfSmrg .request = MappingModifier, 15035c4bbdfSmrg .firstKeyCode = 0, 15135c4bbdfSmrg .count = 0, 15235c4bbdfSmrg .time = time 15335c4bbdfSmrg }; 1546747b715Smrg SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1556747b715Smrg 1); 1566747b715Smrg } 1576747b715Smrg} 1586747b715Smrg 1596747b715Smrg/***====================================================================***/ 1606747b715Smrg 16105b261ecSmrgvoid 16235c4bbdfSmrgXkbSendNewKeyboardNotify(DeviceIntPtr kbd, xkbNewKeyboardNotify * pNKN) 1636747b715Smrg{ 1646747b715Smrg int i; 1656747b715Smrg Time time = GetTimeInMillis(); 1666747b715Smrg CARD16 changed = pNKN->changed; 16705b261ecSmrg 16805b261ecSmrg pNKN->type = XkbEventCode + XkbEventBase; 16905b261ecSmrg pNKN->xkbType = XkbNewKeyboardNotify; 17005b261ecSmrg 17135c4bbdfSmrg for (i = 1; i < currentMaxClients; i++) { 1726747b715Smrg if (!clients[i] || clients[i]->clientState != ClientStateRunning) 1736747b715Smrg continue; 1746747b715Smrg 1756747b715Smrg if (!(clients[i]->newKeyboardNotifyMask & changed)) 1766747b715Smrg continue; 1776747b715Smrg 1786747b715Smrg pNKN->sequenceNumber = clients[i]->sequence; 1796747b715Smrg pNKN->time = time; 1806747b715Smrg pNKN->changed = changed; 1816747b715Smrg if (clients[i]->swapped) { 18235c4bbdfSmrg swaps(&pNKN->sequenceNumber); 18335c4bbdfSmrg swapl(&pNKN->time); 18435c4bbdfSmrg swaps(&pNKN->changed); 1856747b715Smrg } 1866747b715Smrg WriteToClient(clients[i], sizeof(xEvent), pNKN); 18705b261ecSmrg 1886747b715Smrg if (changed & XkbNKN_KeycodesMask) { 1896747b715Smrg clients[i]->minKC = pNKN->minKeyCode; 1906747b715Smrg clients[i]->maxKC = pNKN->maxKeyCode; 1916747b715Smrg } 19205b261ecSmrg } 1936747b715Smrg 1946747b715Smrg XkbSendLegacyMapNotify(kbd, XkbNewKeyboardNotify, changed, pNKN->minKeyCode, 1956747b715Smrg pNKN->maxKeyCode - pNKN->minKeyCode + 1); 1966747b715Smrg 19705b261ecSmrg return; 19805b261ecSmrg} 19905b261ecSmrg 20005b261ecSmrg/***====================================================================***/ 20105b261ecSmrg 20205b261ecSmrgvoid 20335c4bbdfSmrgXkbSendStateNotify(DeviceIntPtr kbd, xkbStateNotify * pSN) 20405b261ecSmrg{ 20535c4bbdfSmrg XkbSrvInfoPtr xkbi; 20635c4bbdfSmrg XkbStatePtr state; 20735c4bbdfSmrg XkbInterestPtr interest; 20835c4bbdfSmrg Time time; 20935c4bbdfSmrg register CARD16 changed, bState; 21005b261ecSmrg 21105b261ecSmrg interest = kbd->xkb_interest; 2124642e01fSmrg if (!interest || !kbd->key || !kbd->key->xkbInfo) 21335c4bbdfSmrg return; 21405b261ecSmrg xkbi = kbd->key->xkbInfo; 21535c4bbdfSmrg state = &xkbi->state; 21605b261ecSmrg 21705b261ecSmrg pSN->type = XkbEventCode + XkbEventBase; 21805b261ecSmrg pSN->xkbType = XkbStateNotify; 21905b261ecSmrg pSN->deviceID = kbd->id; 22005b261ecSmrg pSN->time = time = GetTimeInMillis(); 22105b261ecSmrg pSN->mods = state->mods; 22205b261ecSmrg pSN->baseMods = state->base_mods; 22305b261ecSmrg pSN->latchedMods = state->latched_mods; 22405b261ecSmrg pSN->lockedMods = state->locked_mods; 22505b261ecSmrg pSN->group = state->group; 22605b261ecSmrg pSN->baseGroup = state->base_group; 22705b261ecSmrg pSN->latchedGroup = state->latched_group; 22805b261ecSmrg pSN->lockedGroup = state->locked_group; 22905b261ecSmrg pSN->compatState = state->compat_state; 23005b261ecSmrg pSN->grabMods = state->grab_mods; 23105b261ecSmrg pSN->compatGrabMods = state->compat_grab_mods; 23205b261ecSmrg pSN->lookupMods = state->lookup_mods; 23305b261ecSmrg pSN->compatLookupMods = state->compat_lookup_mods; 23405b261ecSmrg pSN->ptrBtnState = state->ptr_buttons; 23505b261ecSmrg changed = pSN->changed; 23635c4bbdfSmrg bState = pSN->ptrBtnState; 23705b261ecSmrg 23805b261ecSmrg while (interest) { 23935c4bbdfSmrg if ((!interest->client->clientGone) && 24035c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 24135c4bbdfSmrg (interest->stateNotifyMask & changed)) { 24235c4bbdfSmrg pSN->sequenceNumber = interest->client->sequence; 24335c4bbdfSmrg pSN->time = time; 24435c4bbdfSmrg pSN->changed = changed; 24535c4bbdfSmrg pSN->ptrBtnState = bState; 24635c4bbdfSmrg if (interest->client->swapped) { 24735c4bbdfSmrg swaps(&pSN->sequenceNumber); 24835c4bbdfSmrg swapl(&pSN->time); 24935c4bbdfSmrg swaps(&pSN->changed); 25035c4bbdfSmrg swaps(&pSN->ptrBtnState); 25135c4bbdfSmrg } 25235c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), pSN); 25335c4bbdfSmrg } 25435c4bbdfSmrg interest = interest->next; 25505b261ecSmrg } 25605b261ecSmrg return; 25705b261ecSmrg} 25805b261ecSmrg 25905b261ecSmrg/***====================================================================***/ 26005b261ecSmrg 2616747b715Smrg/* 2626747b715Smrg * This function sends out XKB mapping notify events to clients which 2636747b715Smrg * have explicitly selected for them. Core and Xi events are handled by 2646747b715Smrg * XkbSendLegacyMapNotify. */ 26505b261ecSmrgvoid 26635c4bbdfSmrgXkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify * pMN) 26705b261ecSmrg{ 2686747b715Smrg int i; 2696747b715Smrg CARD32 time = GetTimeInMillis(); 2706747b715Smrg CARD16 changed = pMN->changed; 2716747b715Smrg XkbSrvInfoPtr xkbi = kbd->key->xkbInfo; 2726747b715Smrg 2736747b715Smrg pMN->minKeyCode = xkbi->desc->min_key_code; 2746747b715Smrg pMN->maxKeyCode = xkbi->desc->max_key_code; 2756747b715Smrg pMN->type = XkbEventCode + XkbEventBase; 2766747b715Smrg pMN->xkbType = XkbMapNotify; 2776747b715Smrg pMN->deviceID = kbd->id; 2786747b715Smrg 2796747b715Smrg /* 0 is serverClient. */ 2806747b715Smrg for (i = 1; i < currentMaxClients; i++) { 2816747b715Smrg if (!clients[i] || clients[i]->clientState != ClientStateRunning) 2826747b715Smrg continue; 2836747b715Smrg 2846747b715Smrg if (!(clients[i]->mapNotifyMask & changed)) 2856747b715Smrg continue; 2866747b715Smrg 2876747b715Smrg pMN->time = time; 2886747b715Smrg pMN->sequenceNumber = clients[i]->sequence; 2896747b715Smrg pMN->changed = changed; 2906747b715Smrg 2916747b715Smrg if (clients[i]->swapped) { 29235c4bbdfSmrg swaps(&pMN->sequenceNumber); 29335c4bbdfSmrg swapl(&pMN->time); 29435c4bbdfSmrg swaps(&pMN->changed); 2956747b715Smrg } 2966747b715Smrg WriteToClient(clients[i], sizeof(xEvent), pMN); 29705b261ecSmrg } 2986747b715Smrg 2996747b715Smrg XkbSendLegacyMapNotify(kbd, XkbMapNotify, changed, pMN->firstKeySym, 3006747b715Smrg pMN->nKeySyms); 30105b261ecSmrg} 30205b261ecSmrg 30305b261ecSmrgint 30435c4bbdfSmrgXkbComputeControlsNotify(DeviceIntPtr kbd, 30535c4bbdfSmrg XkbControlsPtr old, 30635c4bbdfSmrg XkbControlsPtr new, 30735c4bbdfSmrg xkbControlsNotify * pCN, Bool forceCtrlProc) 30805b261ecSmrg{ 30935c4bbdfSmrg int i; 31035c4bbdfSmrg CARD32 changedControls; 31105b261ecSmrg 31235c4bbdfSmrg changedControls = 0; 31305b261ecSmrg 31405b261ecSmrg if (!kbd || !kbd->kbdfeed) 31505b261ecSmrg return 0; 31635c4bbdfSmrg 31735c4bbdfSmrg if (old->enabled_ctrls != new->enabled_ctrls) 31835c4bbdfSmrg changedControls |= XkbControlsEnabledMask; 31935c4bbdfSmrg if ((old->repeat_delay != new->repeat_delay) || 32035c4bbdfSmrg (old->repeat_interval != new->repeat_interval)) 32135c4bbdfSmrg changedControls |= XkbRepeatKeysMask; 32205b261ecSmrg for (i = 0; i < XkbPerKeyBitArraySize; i++) 32335c4bbdfSmrg if (old->per_key_repeat[i] != new->per_key_repeat[i]) 32435c4bbdfSmrg changedControls |= XkbPerKeyRepeatMask; 32535c4bbdfSmrg if (old->slow_keys_delay != new->slow_keys_delay) 32635c4bbdfSmrg changedControls |= XkbSlowKeysMask; 32735c4bbdfSmrg if (old->debounce_delay != new->debounce_delay) 32835c4bbdfSmrg changedControls |= XkbBounceKeysMask; 32935c4bbdfSmrg if ((old->mk_delay != new->mk_delay) || 33035c4bbdfSmrg (old->mk_interval != new->mk_interval) || 33135c4bbdfSmrg (old->mk_dflt_btn != new->mk_dflt_btn)) 33235c4bbdfSmrg changedControls |= XkbMouseKeysMask; 33335c4bbdfSmrg if ((old->mk_time_to_max != new->mk_time_to_max) || 33435c4bbdfSmrg (old->mk_curve != new->mk_curve) || 33535c4bbdfSmrg (old->mk_max_speed != new->mk_max_speed)) 33635c4bbdfSmrg changedControls |= XkbMouseKeysAccelMask; 33735c4bbdfSmrg if (old->ax_options != new->ax_options) 33835c4bbdfSmrg changedControls |= XkbAccessXKeysMask; 33935c4bbdfSmrg if ((old->ax_options ^ new->ax_options) & XkbAX_SKOptionsMask) 34035c4bbdfSmrg changedControls |= XkbStickyKeysMask; 34135c4bbdfSmrg if ((old->ax_options ^ new->ax_options) & XkbAX_FBOptionsMask) 34235c4bbdfSmrg changedControls |= XkbAccessXFeedbackMask; 34335c4bbdfSmrg if ((old->ax_timeout != new->ax_timeout) || 34435c4bbdfSmrg (old->axt_ctrls_mask != new->axt_ctrls_mask) || 34535c4bbdfSmrg (old->axt_ctrls_values != new->axt_ctrls_values) || 34635c4bbdfSmrg (old->axt_opts_mask != new->axt_opts_mask) || 34735c4bbdfSmrg (old->axt_opts_values != new->axt_opts_values)) { 34835c4bbdfSmrg changedControls |= XkbAccessXTimeoutMask; 34905b261ecSmrg } 35035c4bbdfSmrg if ((old->internal.mask != new->internal.mask) || 35135c4bbdfSmrg (old->internal.real_mods != new->internal.real_mods) || 35235c4bbdfSmrg (old->internal.vmods != new->internal.vmods)) 35335c4bbdfSmrg changedControls |= XkbInternalModsMask; 35435c4bbdfSmrg if ((old->ignore_lock.mask != new->ignore_lock.mask) || 35535c4bbdfSmrg (old->ignore_lock.real_mods != new->ignore_lock.real_mods) || 35635c4bbdfSmrg (old->ignore_lock.vmods != new->ignore_lock.vmods)) 35735c4bbdfSmrg changedControls |= XkbIgnoreLockModsMask; 35835c4bbdfSmrg 35935c4bbdfSmrg if (new->enabled_ctrls & XkbRepeatKeysMask) 36035c4bbdfSmrg kbd->kbdfeed->ctrl.autoRepeat = TRUE; 36135c4bbdfSmrg else 36235c4bbdfSmrg kbd->kbdfeed->ctrl.autoRepeat = FALSE; 36305b261ecSmrg 36405b261ecSmrg if (kbd->kbdfeed && kbd->kbdfeed->CtrlProc && 36535c4bbdfSmrg (changedControls || forceCtrlProc)) 36635c4bbdfSmrg (*kbd->kbdfeed->CtrlProc) (kbd, &kbd->kbdfeed->ctrl); 36705b261ecSmrg 36835c4bbdfSmrg if ((!changedControls) && (old->num_groups == new->num_groups)) 36935c4bbdfSmrg return 0; 37005b261ecSmrg 37105b261ecSmrg if (!kbd->xkb_interest) 37235c4bbdfSmrg return 0; 37305b261ecSmrg 37405b261ecSmrg pCN->changedControls = changedControls; 37505b261ecSmrg pCN->enabledControls = new->enabled_ctrls; 37635c4bbdfSmrg pCN->enabledControlChanges = (new->enabled_ctrls ^ old->enabled_ctrls); 37705b261ecSmrg pCN->numGroups = new->num_groups; 37805b261ecSmrg 37905b261ecSmrg return 1; 38005b261ecSmrg} 38105b261ecSmrg 38205b261ecSmrgvoid 38335c4bbdfSmrgXkbSendControlsNotify(DeviceIntPtr kbd, xkbControlsNotify * pCN) 38405b261ecSmrg{ 38535c4bbdfSmrg int initialized; 38635c4bbdfSmrg CARD32 changedControls, enabledControls, enabledChanges = 0; 38735c4bbdfSmrg XkbSrvInfoPtr xkbi; 38835c4bbdfSmrg XkbInterestPtr interest; 38935c4bbdfSmrg Time time = 0; 39005b261ecSmrg 39105b261ecSmrg interest = kbd->xkb_interest; 3924642e01fSmrg if (!interest || !kbd->key || !kbd->key->xkbInfo) 39335c4bbdfSmrg return; 39405b261ecSmrg xkbi = kbd->key->xkbInfo; 39535c4bbdfSmrg 39605b261ecSmrg initialized = 0; 39705b261ecSmrg enabledControls = xkbi->desc->ctrls->enabled_ctrls; 39805b261ecSmrg changedControls = pCN->changedControls; 39935c4bbdfSmrg pCN->numGroups = xkbi->desc->ctrls->num_groups; 40005b261ecSmrg while (interest) { 40135c4bbdfSmrg if ((!interest->client->clientGone) && 40235c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 40335c4bbdfSmrg (interest->ctrlsNotifyMask & changedControls)) { 40435c4bbdfSmrg if (!initialized) { 40535c4bbdfSmrg pCN->type = XkbEventCode + XkbEventBase; 40635c4bbdfSmrg pCN->xkbType = XkbControlsNotify; 40735c4bbdfSmrg pCN->deviceID = kbd->id; 40835c4bbdfSmrg pCN->time = time = GetTimeInMillis(); 40935c4bbdfSmrg enabledChanges = pCN->enabledControlChanges; 41035c4bbdfSmrg initialized = 1; 41135c4bbdfSmrg } 41235c4bbdfSmrg pCN->changedControls = changedControls; 41335c4bbdfSmrg pCN->enabledControls = enabledControls; 41435c4bbdfSmrg pCN->enabledControlChanges = enabledChanges; 41535c4bbdfSmrg pCN->sequenceNumber = interest->client->sequence; 41635c4bbdfSmrg pCN->time = time; 41735c4bbdfSmrg if (interest->client->swapped) { 41835c4bbdfSmrg swaps(&pCN->sequenceNumber); 41935c4bbdfSmrg swapl(&pCN->changedControls); 42035c4bbdfSmrg swapl(&pCN->enabledControls); 42135c4bbdfSmrg swapl(&pCN->enabledControlChanges); 42235c4bbdfSmrg swapl(&pCN->time); 42335c4bbdfSmrg } 42435c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), pCN); 42535c4bbdfSmrg } 42635c4bbdfSmrg interest = interest->next; 42705b261ecSmrg } 42805b261ecSmrg return; 42905b261ecSmrg} 43005b261ecSmrg 43105b261ecSmrgstatic void 43235c4bbdfSmrgXkbSendIndicatorNotify(DeviceIntPtr kbd, int xkbType, xkbIndicatorNotify * pEv) 43305b261ecSmrg{ 43435c4bbdfSmrg int initialized; 43535c4bbdfSmrg XkbInterestPtr interest; 43635c4bbdfSmrg Time time = 0; 43735c4bbdfSmrg CARD32 state, changed; 43805b261ecSmrg 43905b261ecSmrg interest = kbd->xkb_interest; 44005b261ecSmrg if (!interest) 44135c4bbdfSmrg return; 44235c4bbdfSmrg 44305b261ecSmrg initialized = 0; 44405b261ecSmrg state = pEv->state; 44505b261ecSmrg changed = pEv->changed; 44605b261ecSmrg while (interest) { 44735c4bbdfSmrg if ((!interest->client->clientGone) && 44835c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 44935c4bbdfSmrg (((xkbType == XkbIndicatorStateNotify) && 45035c4bbdfSmrg (interest->iStateNotifyMask & changed)) || 45135c4bbdfSmrg ((xkbType == XkbIndicatorMapNotify) && 45235c4bbdfSmrg (interest->iMapNotifyMask & changed)))) { 45335c4bbdfSmrg if (!initialized) { 45435c4bbdfSmrg pEv->type = XkbEventCode + XkbEventBase; 45535c4bbdfSmrg pEv->xkbType = xkbType; 45635c4bbdfSmrg pEv->deviceID = kbd->id; 45735c4bbdfSmrg pEv->time = time = GetTimeInMillis(); 45835c4bbdfSmrg initialized = 1; 45935c4bbdfSmrg } 46035c4bbdfSmrg pEv->sequenceNumber = interest->client->sequence; 46135c4bbdfSmrg pEv->time = time; 46235c4bbdfSmrg pEv->changed = changed; 46335c4bbdfSmrg pEv->state = state; 46435c4bbdfSmrg if (interest->client->swapped) { 46535c4bbdfSmrg swaps(&pEv->sequenceNumber); 46635c4bbdfSmrg swapl(&pEv->time); 46735c4bbdfSmrg swapl(&pEv->changed); 46835c4bbdfSmrg swapl(&pEv->state); 46935c4bbdfSmrg } 47035c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), pEv); 47135c4bbdfSmrg } 47235c4bbdfSmrg interest = interest->next; 47305b261ecSmrg } 47405b261ecSmrg return; 47505b261ecSmrg} 47605b261ecSmrg 47705b261ecSmrgvoid 47835c4bbdfSmrgXkbHandleBell(BOOL force, 47935c4bbdfSmrg BOOL eventOnly, 48035c4bbdfSmrg DeviceIntPtr kbd, 48135c4bbdfSmrg CARD8 percent, 48235c4bbdfSmrg void *pCtrl, 48335c4bbdfSmrg CARD8 class, Atom name, WindowPtr pWin, ClientPtr pClient) 48405b261ecSmrg{ 48535c4bbdfSmrg xkbBellNotify bn; 48635c4bbdfSmrg int initialized; 48735c4bbdfSmrg XkbSrvInfoPtr xkbi; 48835c4bbdfSmrg XkbInterestPtr interest; 48935c4bbdfSmrg CARD8 id; 49035c4bbdfSmrg CARD16 pitch, duration; 49135c4bbdfSmrg Time time = 0; 49235c4bbdfSmrg XID winID = 0; 49305b261ecSmrg 4944642e01fSmrg if (!kbd->key || !kbd->key->xkbInfo) 4954642e01fSmrg return; 4964642e01fSmrg 49705b261ecSmrg xkbi = kbd->key->xkbInfo; 49805b261ecSmrg 49935c4bbdfSmrg if ((force || (xkbi->desc->ctrls->enabled_ctrls & XkbAudibleBellMask)) && 50035c4bbdfSmrg (!eventOnly)) { 50105b261ecSmrg if (kbd->kbdfeed->BellProc) 50235c4bbdfSmrg (*kbd->kbdfeed->BellProc) (percent, kbd, (void *) pCtrl, class); 50305b261ecSmrg } 50405b261ecSmrg interest = kbd->xkb_interest; 50535c4bbdfSmrg if ((!interest) || (force)) 50635c4bbdfSmrg return; 50735c4bbdfSmrg 50835c4bbdfSmrg if (class == KbdFeedbackClass) { 50935c4bbdfSmrg KeybdCtrl *pKeyCtrl = (KeybdCtrl *) pCtrl; 51035c4bbdfSmrg 51135c4bbdfSmrg id = pKeyCtrl->id; 51235c4bbdfSmrg pitch = pKeyCtrl->bell_pitch; 51335c4bbdfSmrg duration = pKeyCtrl->bell_duration; 51405b261ecSmrg } 51535c4bbdfSmrg else if (class == BellFeedbackClass) { 51635c4bbdfSmrg BellCtrl *pBellCtrl = (BellCtrl *) pCtrl; 51735c4bbdfSmrg 51835c4bbdfSmrg id = pBellCtrl->id; 51935c4bbdfSmrg pitch = pBellCtrl->pitch; 52035c4bbdfSmrg duration = pBellCtrl->duration; 52105b261ecSmrg } 52235c4bbdfSmrg else 52335c4bbdfSmrg return; 52435c4bbdfSmrg 52505b261ecSmrg initialized = 0; 52605b261ecSmrg while (interest) { 52735c4bbdfSmrg if ((!interest->client->clientGone) && 52835c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 52935c4bbdfSmrg (interest->bellNotifyMask)) { 53035c4bbdfSmrg if (!initialized) { 53135c4bbdfSmrg time = GetTimeInMillis(); 53235c4bbdfSmrg bn.type = XkbEventCode + XkbEventBase; 53335c4bbdfSmrg bn.xkbType = XkbBellNotify; 53435c4bbdfSmrg bn.deviceID = kbd->id; 53535c4bbdfSmrg bn.bellClass = class; 53635c4bbdfSmrg bn.bellID = id; 53735c4bbdfSmrg bn.percent = percent; 53835c4bbdfSmrg bn.eventOnly = (eventOnly != 0); 53935c4bbdfSmrg winID = (pWin ? pWin->drawable.id : None); 54035c4bbdfSmrg initialized = 1; 54135c4bbdfSmrg } 54235c4bbdfSmrg bn.sequenceNumber = interest->client->sequence; 54335c4bbdfSmrg bn.time = time; 54435c4bbdfSmrg bn.pitch = pitch; 54535c4bbdfSmrg bn.duration = duration; 54635c4bbdfSmrg bn.name = name; 54735c4bbdfSmrg bn.window = winID; 54835c4bbdfSmrg if (interest->client->swapped) { 54935c4bbdfSmrg swaps(&bn.sequenceNumber); 55035c4bbdfSmrg swapl(&bn.time); 55135c4bbdfSmrg swaps(&bn.pitch); 55235c4bbdfSmrg swaps(&bn.duration); 55335c4bbdfSmrg swapl(&bn.name); 55435c4bbdfSmrg swapl(&bn.window); 55535c4bbdfSmrg } 55635c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), &bn); 55735c4bbdfSmrg } 55835c4bbdfSmrg interest = interest->next; 55905b261ecSmrg } 56005b261ecSmrg return; 56105b261ecSmrg} 56205b261ecSmrg 56305b261ecSmrgvoid 56435c4bbdfSmrgXkbSendAccessXNotify(DeviceIntPtr kbd, xkbAccessXNotify * pEv) 56505b261ecSmrg{ 56635c4bbdfSmrg int initialized; 56735c4bbdfSmrg XkbInterestPtr interest; 56835c4bbdfSmrg Time time = 0; 56935c4bbdfSmrg CARD16 sk_delay, db_delay; 57005b261ecSmrg 57105b261ecSmrg interest = kbd->xkb_interest; 57205b261ecSmrg if (!interest) 57335c4bbdfSmrg return; 57435c4bbdfSmrg 57505b261ecSmrg initialized = 0; 57635c4bbdfSmrg sk_delay = pEv->slowKeysDelay; 57735c4bbdfSmrg db_delay = pEv->debounceDelay; 57805b261ecSmrg while (interest) { 57935c4bbdfSmrg if ((!interest->client->clientGone) && 58035c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 58135c4bbdfSmrg (interest->accessXNotifyMask & (1 << pEv->detail))) { 58235c4bbdfSmrg if (!initialized) { 58335c4bbdfSmrg pEv->type = XkbEventCode + XkbEventBase; 58435c4bbdfSmrg pEv->xkbType = XkbAccessXNotify; 58535c4bbdfSmrg pEv->deviceID = kbd->id; 58635c4bbdfSmrg pEv->time = time = GetTimeInMillis(); 58735c4bbdfSmrg initialized = 1; 58835c4bbdfSmrg } 58935c4bbdfSmrg pEv->sequenceNumber = interest->client->sequence; 59035c4bbdfSmrg pEv->time = time; 59135c4bbdfSmrg pEv->slowKeysDelay = sk_delay; 59235c4bbdfSmrg pEv->debounceDelay = db_delay; 59335c4bbdfSmrg if (interest->client->swapped) { 59435c4bbdfSmrg swaps(&pEv->sequenceNumber); 59535c4bbdfSmrg swapl(&pEv->time); 59635c4bbdfSmrg swaps(&pEv->slowKeysDelay); 59735c4bbdfSmrg swaps(&pEv->debounceDelay); 59835c4bbdfSmrg } 59935c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), pEv); 60035c4bbdfSmrg } 60135c4bbdfSmrg interest = interest->next; 60205b261ecSmrg } 60305b261ecSmrg return; 60405b261ecSmrg} 60505b261ecSmrg 60605b261ecSmrgvoid 60735c4bbdfSmrgXkbSendNamesNotify(DeviceIntPtr kbd, xkbNamesNotify * pEv) 60805b261ecSmrg{ 60935c4bbdfSmrg int initialized; 61035c4bbdfSmrg XkbInterestPtr interest; 61135c4bbdfSmrg Time time = 0; 61235c4bbdfSmrg CARD16 changed, changedVirtualMods; 61335c4bbdfSmrg CARD32 changedIndicators; 61405b261ecSmrg 61505b261ecSmrg interest = kbd->xkb_interest; 61605b261ecSmrg if (!interest) 61735c4bbdfSmrg return; 61835c4bbdfSmrg 61905b261ecSmrg initialized = 0; 62035c4bbdfSmrg changed = pEv->changed; 62135c4bbdfSmrg changedIndicators = pEv->changedIndicators; 62235c4bbdfSmrg changedVirtualMods = pEv->changedVirtualMods; 62305b261ecSmrg while (interest) { 62435c4bbdfSmrg if ((!interest->client->clientGone) && 62535c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 62635c4bbdfSmrg (interest->namesNotifyMask & pEv->changed)) { 62735c4bbdfSmrg if (!initialized) { 62835c4bbdfSmrg pEv->type = XkbEventCode + XkbEventBase; 62935c4bbdfSmrg pEv->xkbType = XkbNamesNotify; 63035c4bbdfSmrg pEv->deviceID = kbd->id; 63135c4bbdfSmrg pEv->time = time = GetTimeInMillis(); 63235c4bbdfSmrg initialized = 1; 63335c4bbdfSmrg } 63435c4bbdfSmrg pEv->sequenceNumber = interest->client->sequence; 63535c4bbdfSmrg pEv->time = time; 63635c4bbdfSmrg pEv->changed = changed; 63735c4bbdfSmrg pEv->changedIndicators = changedIndicators; 63835c4bbdfSmrg pEv->changedVirtualMods = changedVirtualMods; 63935c4bbdfSmrg if (interest->client->swapped) { 64035c4bbdfSmrg swaps(&pEv->sequenceNumber); 64135c4bbdfSmrg swapl(&pEv->time); 64235c4bbdfSmrg swaps(&pEv->changed); 64335c4bbdfSmrg swapl(&pEv->changedIndicators); 64435c4bbdfSmrg swaps(&pEv->changedVirtualMods); 64535c4bbdfSmrg } 64635c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), pEv); 64735c4bbdfSmrg } 64835c4bbdfSmrg interest = interest->next; 64905b261ecSmrg } 65005b261ecSmrg return; 65105b261ecSmrg} 65205b261ecSmrg 65305b261ecSmrgvoid 65435c4bbdfSmrgXkbSendCompatMapNotify(DeviceIntPtr kbd, xkbCompatMapNotify * pEv) 65505b261ecSmrg{ 65635c4bbdfSmrg int initialized; 65735c4bbdfSmrg XkbInterestPtr interest; 65835c4bbdfSmrg Time time = 0; 65935c4bbdfSmrg CARD16 firstSI = 0, nSI = 0, nTotalSI = 0; 66005b261ecSmrg 66105b261ecSmrg interest = kbd->xkb_interest; 66205b261ecSmrg if (!interest) 66335c4bbdfSmrg return; 66435c4bbdfSmrg 66505b261ecSmrg initialized = 0; 66605b261ecSmrg while (interest) { 66735c4bbdfSmrg if ((!interest->client->clientGone) && 66835c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 66935c4bbdfSmrg (interest->compatNotifyMask)) { 67035c4bbdfSmrg if (!initialized) { 67135c4bbdfSmrg pEv->type = XkbEventCode + XkbEventBase; 67235c4bbdfSmrg pEv->xkbType = XkbCompatMapNotify; 67335c4bbdfSmrg pEv->deviceID = kbd->id; 67435c4bbdfSmrg pEv->time = time = GetTimeInMillis(); 67535c4bbdfSmrg firstSI = pEv->firstSI; 67635c4bbdfSmrg nSI = pEv->nSI; 67735c4bbdfSmrg nTotalSI = pEv->nTotalSI; 67835c4bbdfSmrg initialized = 1; 67935c4bbdfSmrg } 68035c4bbdfSmrg pEv->sequenceNumber = interest->client->sequence; 68135c4bbdfSmrg pEv->time = time; 68235c4bbdfSmrg pEv->firstSI = firstSI; 68335c4bbdfSmrg pEv->nSI = nSI; 68435c4bbdfSmrg pEv->nTotalSI = nTotalSI; 68535c4bbdfSmrg if (interest->client->swapped) { 68635c4bbdfSmrg swaps(&pEv->sequenceNumber); 68735c4bbdfSmrg swapl(&pEv->time); 68835c4bbdfSmrg swaps(&pEv->firstSI); 68935c4bbdfSmrg swaps(&pEv->nSI); 69035c4bbdfSmrg swaps(&pEv->nTotalSI); 69135c4bbdfSmrg } 69235c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), pEv); 69335c4bbdfSmrg } 69435c4bbdfSmrg interest = interest->next; 69505b261ecSmrg } 69605b261ecSmrg return; 69705b261ecSmrg} 69805b261ecSmrg 69905b261ecSmrgvoid 70035c4bbdfSmrgXkbSendActionMessage(DeviceIntPtr kbd, xkbActionMessage * pEv) 70105b261ecSmrg{ 70235c4bbdfSmrg int initialized; 70335c4bbdfSmrg XkbSrvInfoPtr xkbi; 70435c4bbdfSmrg XkbInterestPtr interest; 70535c4bbdfSmrg Time time = 0; 70605b261ecSmrg 70705b261ecSmrg interest = kbd->xkb_interest; 7084642e01fSmrg if (!interest || !kbd->key || !kbd->key->xkbInfo) 70935c4bbdfSmrg return; 71035c4bbdfSmrg 7114642e01fSmrg xkbi = kbd->key->xkbInfo; 7124642e01fSmrg 71305b261ecSmrg initialized = 0; 71435c4bbdfSmrg pEv->mods = xkbi->state.mods; 71535c4bbdfSmrg pEv->group = xkbi->state.group; 71605b261ecSmrg while (interest) { 71735c4bbdfSmrg if ((!interest->client->clientGone) && 71835c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 71935c4bbdfSmrg (interest->actionMessageMask)) { 72035c4bbdfSmrg if (!initialized) { 72135c4bbdfSmrg pEv->type = XkbEventCode + XkbEventBase; 72235c4bbdfSmrg pEv->xkbType = XkbActionMessage; 72335c4bbdfSmrg pEv->deviceID = kbd->id; 72435c4bbdfSmrg pEv->sequenceNumber = interest->client->sequence; 72535c4bbdfSmrg pEv->time = time = GetTimeInMillis(); 72635c4bbdfSmrg initialized = 1; 72735c4bbdfSmrg } 72835c4bbdfSmrg pEv->sequenceNumber = interest->client->sequence; 72935c4bbdfSmrg pEv->time = time; 73035c4bbdfSmrg if (interest->client->swapped) { 73135c4bbdfSmrg swaps(&pEv->sequenceNumber); 73235c4bbdfSmrg swapl(&pEv->time); 73335c4bbdfSmrg } 73435c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), pEv); 73535c4bbdfSmrg } 73635c4bbdfSmrg interest = interest->next; 73705b261ecSmrg } 73805b261ecSmrg return; 73905b261ecSmrg} 74005b261ecSmrg 74105b261ecSmrgvoid 74235c4bbdfSmrgXkbSendExtensionDeviceNotify(DeviceIntPtr dev, 74335c4bbdfSmrg ClientPtr client, xkbExtensionDeviceNotify * pEv) 74405b261ecSmrg{ 74535c4bbdfSmrg int initialized; 74635c4bbdfSmrg XkbInterestPtr interest; 74735c4bbdfSmrg Time time = 0; 74835c4bbdfSmrg CARD32 defined, state; 74935c4bbdfSmrg CARD16 reason; 75005b261ecSmrg 75105b261ecSmrg interest = dev->xkb_interest; 75205b261ecSmrg if (!interest) 75335c4bbdfSmrg return; 75435c4bbdfSmrg 75505b261ecSmrg initialized = 0; 75635c4bbdfSmrg reason = pEv->reason; 75735c4bbdfSmrg defined = pEv->ledsDefined; 75835c4bbdfSmrg state = pEv->ledState; 75905b261ecSmrg while (interest) { 76035c4bbdfSmrg if ((!interest->client->clientGone) && 76135c4bbdfSmrg (interest->client->xkbClientFlags & _XkbClientInitialized) && 76235c4bbdfSmrg (interest->extDevNotifyMask & reason)) { 76335c4bbdfSmrg if (!initialized) { 76435c4bbdfSmrg pEv->type = XkbEventCode + XkbEventBase; 76535c4bbdfSmrg pEv->xkbType = XkbExtensionDeviceNotify; 76635c4bbdfSmrg pEv->deviceID = dev->id; 76735c4bbdfSmrg pEv->sequenceNumber = interest->client->sequence; 76835c4bbdfSmrg pEv->time = time = GetTimeInMillis(); 76935c4bbdfSmrg initialized = 1; 77035c4bbdfSmrg } 77135c4bbdfSmrg else { 77235c4bbdfSmrg pEv->sequenceNumber = interest->client->sequence; 77335c4bbdfSmrg pEv->time = time; 77435c4bbdfSmrg pEv->ledsDefined = defined; 77535c4bbdfSmrg pEv->ledState = state; 77635c4bbdfSmrg pEv->reason = reason; 77735c4bbdfSmrg pEv->supported = XkbXI_AllFeaturesMask; 77835c4bbdfSmrg } 77935c4bbdfSmrg if (interest->client->swapped) { 78035c4bbdfSmrg swaps(&pEv->sequenceNumber); 78135c4bbdfSmrg swapl(&pEv->time); 78235c4bbdfSmrg swapl(&pEv->ledsDefined); 78335c4bbdfSmrg swapl(&pEv->ledState); 78435c4bbdfSmrg swaps(&pEv->reason); 78535c4bbdfSmrg swaps(&pEv->supported); 78635c4bbdfSmrg } 78735c4bbdfSmrg WriteToClient(interest->client, sizeof(xEvent), pEv); 78835c4bbdfSmrg } 78935c4bbdfSmrg interest = interest->next; 79005b261ecSmrg } 79105b261ecSmrg return; 79205b261ecSmrg} 79305b261ecSmrg 79405b261ecSmrgvoid 79535c4bbdfSmrgXkbSendNotification(DeviceIntPtr kbd, 79635c4bbdfSmrg XkbChangesPtr pChanges, XkbEventCausePtr cause) 79705b261ecSmrg{ 79835c4bbdfSmrg XkbSrvLedInfoPtr sli; 79905b261ecSmrg 80035c4bbdfSmrg sli = NULL; 80105b261ecSmrg if (pChanges->state_changes) { 80235c4bbdfSmrg xkbStateNotify sn; 80335c4bbdfSmrg 80435c4bbdfSmrg sn.changed = pChanges->state_changes; 80535c4bbdfSmrg sn.keycode = cause->kc; 80635c4bbdfSmrg sn.eventType = cause->event; 80735c4bbdfSmrg sn.requestMajor = cause->mjr; 80835c4bbdfSmrg sn.requestMinor = cause->mnr; 80935c4bbdfSmrg XkbSendStateNotify(kbd, &sn); 81005b261ecSmrg } 81105b261ecSmrg if (pChanges->map.changed) { 81235c4bbdfSmrg xkbMapNotify mn; 81335c4bbdfSmrg 81435c4bbdfSmrg memset(&mn, 0, sizeof(xkbMapNotify)); 81535c4bbdfSmrg mn.changed = pChanges->map.changed; 81635c4bbdfSmrg mn.firstType = pChanges->map.first_type; 81735c4bbdfSmrg mn.nTypes = pChanges->map.num_types; 81835c4bbdfSmrg mn.firstKeySym = pChanges->map.first_key_sym; 81935c4bbdfSmrg mn.nKeySyms = pChanges->map.num_key_syms; 82035c4bbdfSmrg mn.firstKeyAct = pChanges->map.first_key_act; 82135c4bbdfSmrg mn.nKeyActs = pChanges->map.num_key_acts; 82235c4bbdfSmrg mn.firstKeyBehavior = pChanges->map.first_key_behavior; 82335c4bbdfSmrg mn.nKeyBehaviors = pChanges->map.num_key_behaviors; 82435c4bbdfSmrg mn.virtualMods = pChanges->map.vmods; 82535c4bbdfSmrg mn.firstKeyExplicit = pChanges->map.first_key_explicit; 82635c4bbdfSmrg mn.nKeyExplicit = pChanges->map.num_key_explicit; 82735c4bbdfSmrg mn.firstModMapKey = pChanges->map.first_modmap_key; 82835c4bbdfSmrg mn.nModMapKeys = pChanges->map.num_modmap_keys; 82935c4bbdfSmrg mn.firstVModMapKey = pChanges->map.first_vmodmap_key; 83035c4bbdfSmrg mn.nVModMapKeys = pChanges->map.num_vmodmap_keys; 83135c4bbdfSmrg XkbSendMapNotify(kbd, &mn); 83205b261ecSmrg } 83335c4bbdfSmrg if ((pChanges->ctrls.changed_ctrls) || 83435c4bbdfSmrg (pChanges->ctrls.enabled_ctrls_changes)) { 83535c4bbdfSmrg xkbControlsNotify cn; 83635c4bbdfSmrg 83735c4bbdfSmrg memset(&cn, 0, sizeof(xkbControlsNotify)); 83835c4bbdfSmrg cn.changedControls = pChanges->ctrls.changed_ctrls; 83935c4bbdfSmrg cn.enabledControlChanges = pChanges->ctrls.enabled_ctrls_changes; 84035c4bbdfSmrg cn.keycode = cause->kc; 84135c4bbdfSmrg cn.eventType = cause->event; 84235c4bbdfSmrg cn.requestMajor = cause->mjr; 84335c4bbdfSmrg cn.requestMinor = cause->mnr; 84435c4bbdfSmrg XkbSendControlsNotify(kbd, &cn); 84505b261ecSmrg } 84605b261ecSmrg if (pChanges->indicators.map_changes) { 84735c4bbdfSmrg xkbIndicatorNotify in; 84835c4bbdfSmrg 84935c4bbdfSmrg if (sli == NULL) 85035c4bbdfSmrg sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0); 85135c4bbdfSmrg memset(&in, 0, sizeof(xkbIndicatorNotify)); 85235c4bbdfSmrg in.state = sli->effectiveState; 85335c4bbdfSmrg in.changed = pChanges->indicators.map_changes; 85435c4bbdfSmrg XkbSendIndicatorNotify(kbd, XkbIndicatorMapNotify, &in); 85505b261ecSmrg } 85605b261ecSmrg if (pChanges->indicators.state_changes) { 85735c4bbdfSmrg xkbIndicatorNotify in; 85835c4bbdfSmrg 85935c4bbdfSmrg if (sli == NULL) 86035c4bbdfSmrg sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0); 86135c4bbdfSmrg memset(&in, 0, sizeof(xkbIndicatorNotify)); 86235c4bbdfSmrg in.state = sli->effectiveState; 86335c4bbdfSmrg in.changed = pChanges->indicators.state_changes; 86435c4bbdfSmrg XkbSendIndicatorNotify(kbd, XkbIndicatorStateNotify, &in); 86505b261ecSmrg } 86605b261ecSmrg if (pChanges->names.changed) { 86735c4bbdfSmrg xkbNamesNotify nn; 86835c4bbdfSmrg 86935c4bbdfSmrg memset(&nn, 0, sizeof(xkbNamesNotify)); 87035c4bbdfSmrg nn.changed = pChanges->names.changed; 87135c4bbdfSmrg nn.firstType = pChanges->names.first_type; 87235c4bbdfSmrg nn.nTypes = pChanges->names.num_types; 87335c4bbdfSmrg nn.firstLevelName = pChanges->names.first_lvl; 87435c4bbdfSmrg nn.nLevelNames = pChanges->names.num_lvls; 87535c4bbdfSmrg nn.nRadioGroups = pChanges->names.num_rg; 87635c4bbdfSmrg nn.changedVirtualMods = pChanges->names.changed_vmods; 87735c4bbdfSmrg nn.changedIndicators = pChanges->names.changed_indicators; 87835c4bbdfSmrg XkbSendNamesNotify(kbd, &nn); 87905b261ecSmrg } 88035c4bbdfSmrg if ((pChanges->compat.changed_groups) || (pChanges->compat.num_si > 0)) { 88135c4bbdfSmrg xkbCompatMapNotify cmn; 88235c4bbdfSmrg 88335c4bbdfSmrg memset(&cmn, 0, sizeof(xkbCompatMapNotify)); 88435c4bbdfSmrg cmn.changedGroups = pChanges->compat.changed_groups; 88535c4bbdfSmrg cmn.firstSI = pChanges->compat.first_si; 88635c4bbdfSmrg cmn.nSI = pChanges->compat.num_si; 88735c4bbdfSmrg cmn.nTotalSI = kbd->key->xkbInfo->desc->compat->num_si; 88835c4bbdfSmrg XkbSendCompatMapNotify(kbd, &cmn); 88905b261ecSmrg } 89005b261ecSmrg return; 89105b261ecSmrg} 89205b261ecSmrg 89305b261ecSmrg/***====================================================================***/ 89405b261ecSmrg 8956747b715Smrgvoid 89635c4bbdfSmrgXkbFilterEvents(ClientPtr client, int nEvents, xEvent *xE) 89705b261ecSmrg{ 8986747b715Smrg DeviceIntPtr dev = NULL; 8996747b715Smrg XkbSrvInfoPtr xkbi; 9006747b715Smrg CARD8 type = xE[0].u.u.type; 90105b261ecSmrg 9024642e01fSmrg if (xE->u.u.type & EXTENSION_EVENT_BASE) 9036747b715Smrg dev = XIGetDevice(xE); 9044642e01fSmrg 9056747b715Smrg if (!dev) 9066747b715Smrg dev = PickKeyboard(client); 9074642e01fSmrg 9086747b715Smrg if (!dev->key) 9096747b715Smrg return; 9104642e01fSmrg 9116747b715Smrg xkbi = dev->key->xkbInfo; 91205b261ecSmrg 9136747b715Smrg if (client->xkbClientFlags & _XkbClientInitialized) { 91435c4bbdfSmrg if ((xkbDebugFlags & 0x10) && 9156747b715Smrg (type == KeyPress || type == KeyRelease || 9166747b715Smrg type == DeviceKeyPress || type == DeviceKeyRelease)) 91735c4bbdfSmrg DebugF("[xkb] XkbFilterWriteEvents (XKB client): state 0x%04x\n", 9186747b715Smrg xE[0].u.keyButtonPointer.state); 9196747b715Smrg 92035c4bbdfSmrg if (dev->deviceGrab.grab != NullGrab && dev->deviceGrab.fromPassiveGrab 92135c4bbdfSmrg && (type == KeyPress || type == KeyRelease || type == DeviceKeyPress 92235c4bbdfSmrg || type == DeviceKeyRelease)) { 92335c4bbdfSmrg unsigned int state, flags; 92435c4bbdfSmrg 92535c4bbdfSmrg flags = client->xkbClientFlags; 92635c4bbdfSmrg state = xkbi->state.compat_grab_mods; 92735c4bbdfSmrg if (flags & XkbPCF_GrabsUseXKBStateMask) { 92835c4bbdfSmrg int group; 92935c4bbdfSmrg 93035c4bbdfSmrg if (flags & XkbPCF_LookupStateWhenGrabbed) { 93135c4bbdfSmrg group = xkbi->state.group; 93235c4bbdfSmrg state = xkbi->state.lookup_mods; 93335c4bbdfSmrg } 93435c4bbdfSmrg else { 93535c4bbdfSmrg state = xkbi->state.grab_mods; 93635c4bbdfSmrg group = xkbi->state.base_group + xkbi->state.latched_group; 93735c4bbdfSmrg if (group < 0 || group >= xkbi->desc->ctrls->num_groups) 93835c4bbdfSmrg group = XkbAdjustGroup(group, xkbi->desc->ctrls); 93935c4bbdfSmrg } 94035c4bbdfSmrg state = XkbBuildCoreState(state, group); 94135c4bbdfSmrg } 94235c4bbdfSmrg else if (flags & XkbPCF_LookupStateWhenGrabbed) { 94335c4bbdfSmrg state = xkbi->state.compat_lookup_mods; 9446747b715Smrg } 94535c4bbdfSmrg xE[0].u.keyButtonPointer.state = state; 94635c4bbdfSmrg } 94705b261ecSmrg } 94805b261ecSmrg else { 9496747b715Smrg if ((xkbDebugFlags & 0x4) && 95035c4bbdfSmrg (xE[0].u.u.type == KeyPress || xE[0].u.u.type == KeyRelease || 9516747b715Smrg xE[0].u.u.type == DeviceKeyPress || 9526747b715Smrg xE[0].u.u.type == DeviceKeyRelease)) { 95335c4bbdfSmrg DebugF("[xkb] XKbFilterWriteEvents (non-XKB):\n"); 95435c4bbdfSmrg DebugF("[xkb] event= 0x%04x\n", xE[0].u.keyButtonPointer.state); 95535c4bbdfSmrg DebugF("[xkb] lookup= 0x%02x, grab= 0x%02x\n", 9566747b715Smrg xkbi->state.lookup_mods, xkbi->state.grab_mods); 95735c4bbdfSmrg DebugF("[xkb] compat lookup= 0x%02x, grab= 0x%02x\n", 95835c4bbdfSmrg xkbi->state.compat_lookup_mods, 95935c4bbdfSmrg xkbi->state.compat_grab_mods); 96035c4bbdfSmrg } 96135c4bbdfSmrg if (type >= KeyPress && type <= MotionNotify) { 96235c4bbdfSmrg CARD16 old, new; 96335c4bbdfSmrg 96435c4bbdfSmrg old = xE[0].u.keyButtonPointer.state & ~0x1f00; 96535c4bbdfSmrg new = xE[0].u.keyButtonPointer.state & 0x1F00; 96635c4bbdfSmrg 96735c4bbdfSmrg if (old == XkbStateFieldFromRec(&xkbi->state)) 96835c4bbdfSmrg new |= xkbi->state.compat_lookup_mods; 96935c4bbdfSmrg else 9706747b715Smrg new |= xkbi->state.compat_grab_mods; 97135c4bbdfSmrg xE[0].u.keyButtonPointer.state = new; 97235c4bbdfSmrg } 97335c4bbdfSmrg else if (type == EnterNotify || type == LeaveNotify) { 97435c4bbdfSmrg xE[0].u.enterLeave.state &= 0x1F00; 97535c4bbdfSmrg xE[0].u.enterLeave.state |= xkbi->state.compat_grab_mods; 97635c4bbdfSmrg } 9776747b715Smrg else if (type >= DeviceKeyPress && type <= DeviceMotionNotify) { 9786747b715Smrg CARD16 old, new; 97935c4bbdfSmrg deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) &xE[0]; 9806747b715Smrg 9816747b715Smrg old = kbp->state & ~0x1F00; 9826747b715Smrg new = kbp->state & 0x1F00; 98335c4bbdfSmrg if (old == XkbStateFieldFromRec(&xkbi->state)) 98435c4bbdfSmrg new |= xkbi->state.compat_lookup_mods; 98535c4bbdfSmrg else 9866747b715Smrg new |= xkbi->state.compat_grab_mods; 9876747b715Smrg kbp->state = new; 9886747b715Smrg } 98905b261ecSmrg } 99005b261ecSmrg} 99105b261ecSmrg 99205b261ecSmrg/***====================================================================***/ 99305b261ecSmrg 9946747b715SmrgXkbInterestPtr 99535c4bbdfSmrgXkbFindClientResource(DevicePtr inDev, ClientPtr client) 99605b261ecSmrg{ 99735c4bbdfSmrg DeviceIntPtr dev = (DeviceIntPtr) inDev; 99835c4bbdfSmrg XkbInterestPtr interest; 99935c4bbdfSmrg 100035c4bbdfSmrg if (dev->xkb_interest) { 100135c4bbdfSmrg interest = dev->xkb_interest; 100235c4bbdfSmrg while (interest) { 100335c4bbdfSmrg if (interest->client == client) { 100435c4bbdfSmrg return interest; 100535c4bbdfSmrg } 100635c4bbdfSmrg interest = interest->next; 100735c4bbdfSmrg } 100805b261ecSmrg } 100905b261ecSmrg return NULL; 101005b261ecSmrg} 101105b261ecSmrg 10126747b715SmrgXkbInterestPtr 101335c4bbdfSmrgXkbAddClientResource(DevicePtr inDev, ClientPtr client, XID id) 101405b261ecSmrg{ 101535c4bbdfSmrg DeviceIntPtr dev = (DeviceIntPtr) inDev; 101635c4bbdfSmrg XkbInterestPtr interest; 101705b261ecSmrg 101805b261ecSmrg interest = dev->xkb_interest; 101905b261ecSmrg while (interest) { 102035c4bbdfSmrg if (interest->client == client) 102135c4bbdfSmrg return ((interest->resource == id) ? interest : NULL); 102235c4bbdfSmrg interest = interest->next; 102305b261ecSmrg } 10246747b715Smrg interest = calloc(1, sizeof(XkbInterestRec)); 102505b261ecSmrg if (interest) { 102635c4bbdfSmrg interest->dev = dev; 102735c4bbdfSmrg interest->client = client; 102835c4bbdfSmrg interest->resource = id; 102935c4bbdfSmrg interest->next = dev->xkb_interest; 103035c4bbdfSmrg dev->xkb_interest = interest; 103135c4bbdfSmrg return interest; 103205b261ecSmrg } 103305b261ecSmrg return NULL; 103405b261ecSmrg} 103505b261ecSmrg 103605b261ecSmrgint 103735c4bbdfSmrgXkbRemoveResourceClient(DevicePtr inDev, XID id) 103805b261ecSmrg{ 103935c4bbdfSmrg XkbSrvInfoPtr xkbi; 104035c4bbdfSmrg DeviceIntPtr dev = (DeviceIntPtr) inDev; 104135c4bbdfSmrg XkbInterestPtr interest; 104235c4bbdfSmrg Bool found; 104335c4bbdfSmrg unsigned long autoCtrls, autoValues; 104435c4bbdfSmrg ClientPtr client = NULL; 104505b261ecSmrg 104635c4bbdfSmrg found = FALSE; 10474642e01fSmrg 10484642e01fSmrg if (!dev->key || !dev->key->xkbInfo) 10494642e01fSmrg return found; 10504642e01fSmrg 105135c4bbdfSmrg autoCtrls = autoValues = 0; 105235c4bbdfSmrg if (dev->xkb_interest) { 105335c4bbdfSmrg interest = dev->xkb_interest; 105435c4bbdfSmrg if (interest && (interest->resource == id)) { 105535c4bbdfSmrg dev->xkb_interest = interest->next; 105635c4bbdfSmrg autoCtrls = interest->autoCtrls; 105735c4bbdfSmrg autoValues = interest->autoCtrlValues; 105835c4bbdfSmrg client = interest->client; 105935c4bbdfSmrg free(interest); 106035c4bbdfSmrg found = TRUE; 106135c4bbdfSmrg } 106235c4bbdfSmrg while ((!found) && (interest->next)) { 106335c4bbdfSmrg if (interest->next->resource == id) { 106435c4bbdfSmrg XkbInterestPtr victim = interest->next; 106535c4bbdfSmrg 106635c4bbdfSmrg interest->next = victim->next; 106735c4bbdfSmrg autoCtrls = victim->autoCtrls; 106835c4bbdfSmrg autoValues = victim->autoCtrlValues; 106935c4bbdfSmrg client = victim->client; 107035c4bbdfSmrg free(victim); 107135c4bbdfSmrg found = TRUE; 107235c4bbdfSmrg } 107335c4bbdfSmrg interest = interest->next; 107435c4bbdfSmrg } 107505b261ecSmrg } 107635c4bbdfSmrg if (found && autoCtrls && dev->key && dev->key->xkbInfo) { 107735c4bbdfSmrg XkbEventCauseRec cause; 107805b261ecSmrg 107935c4bbdfSmrg xkbi = dev->key->xkbInfo; 108035c4bbdfSmrg XkbSetCauseXkbReq(&cause, X_kbPerClientFlags, client); 108135c4bbdfSmrg XkbEnableDisableControls(xkbi, autoCtrls, autoValues, NULL, &cause); 108205b261ecSmrg } 108305b261ecSmrg return found; 108405b261ecSmrg} 1085