xkbEvents.c revision 6747b715
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 905b261ecSmrgdocumentation, and that the name of Silicon Graphics not be 1005b261ecSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1205b261ecSmrgSilicon 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 1605b261ecSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1705b261ecSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1905b261ecSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2005b261ecSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2105b261ecSmrgDATA 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" 414642e01fSmrg#include "exevents.h" 4205b261ecSmrg#include <xkbsrv.h> 4305b261ecSmrg#include "xkb.h" 4405b261ecSmrg 4505b261ecSmrg/***====================================================================***/ 4605b261ecSmrg 476747b715Smrg/* 486747b715Smrg * This function sends out two kinds of notification: 496747b715Smrg * - Core mapping notify events sent to clients for whom kbd is the 506747b715Smrg * current core ('picked') keyboard _and_ have not explicitly 516747b715Smrg * selected for XKB mapping notify events; 526747b715Smrg * - Xi mapping events, sent unconditionally to all clients who have 536747b715Smrg * explicitly selected for them (including those who have explicitly 546747b715Smrg * selected for XKB mapping notify events!). 556747b715Smrg */ 566747b715Smrgstatic void 576747b715SmrgXkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed, 586747b715Smrg int first_key, int num_keys) 596747b715Smrg{ 606747b715Smrg int i; 616747b715Smrg int keymap_changed = 0; 626747b715Smrg int modmap_changed = 0; 636747b715Smrg xEvent core_mn; 646747b715Smrg deviceMappingNotify xi_mn; 656747b715Smrg CARD32 time = GetTimeInMillis(); 666747b715Smrg 676747b715Smrg if (xkb_event == XkbNewKeyboardNotify) { 686747b715Smrg if (changed & XkbNKN_KeycodesMask) { 696747b715Smrg keymap_changed = 1; 706747b715Smrg modmap_changed = 1; 716747b715Smrg } 726747b715Smrg } 736747b715Smrg else if (xkb_event == XkbMapNotify) { 746747b715Smrg if (changed & XkbKeySymsMask) 756747b715Smrg keymap_changed = 1; 766747b715Smrg if (changed & XkbModifierMapMask) 776747b715Smrg modmap_changed = 1; 786747b715Smrg } 796747b715Smrg if (!keymap_changed && !modmap_changed) 806747b715Smrg return; 816747b715Smrg 826747b715Smrg core_mn.u.u.type = MappingNotify; 836747b715Smrg xi_mn.type = DeviceMappingNotify; 846747b715Smrg xi_mn.deviceid = kbd->id; 856747b715Smrg xi_mn.time = time; 866747b715Smrg 876747b715Smrg /* 0 is serverClient. */ 886747b715Smrg for (i = 1; i < currentMaxClients; i++) { 896747b715Smrg if (!clients[i] || clients[i]->clientState != ClientStateRunning) 906747b715Smrg continue; 916747b715Smrg 926747b715Smrg /* Ignore clients which will have already received this. 936747b715Smrg * Inconsistent with themselves, but consistent with previous 946747b715Smrg * behaviour.*/ 956747b715Smrg if (xkb_event == XkbMapNotify && (clients[i]->mapNotifyMask & changed)) 966747b715Smrg continue; 976747b715Smrg if (xkb_event == XkbNewKeyboardNotify && 986747b715Smrg (clients[i]->xkbClientFlags & _XkbClientInitialized)) 996747b715Smrg continue; 1006747b715Smrg 1016747b715Smrg /* Don't send core events to clients who don't know about us. */ 1026747b715Smrg if (!XIShouldNotify(clients[i], kbd)) 1036747b715Smrg continue; 1046747b715Smrg 1056747b715Smrg if (keymap_changed) { 1066747b715Smrg core_mn.u.mappingNotify.request = MappingKeyboard; 1076747b715Smrg 1086747b715Smrg /* Clip the keycode range to what the client knows about, so it 1096747b715Smrg * doesn't freak out. */ 1106747b715Smrg if (first_key >= clients[i]->minKC) 1116747b715Smrg core_mn.u.mappingNotify.firstKeyCode = first_key; 1126747b715Smrg else 1136747b715Smrg core_mn.u.mappingNotify.firstKeyCode = clients[i]->minKC; 1146747b715Smrg if (first_key + num_keys - 1 <= clients[i]->maxKC) 1156747b715Smrg core_mn.u.mappingNotify.count = num_keys; 1166747b715Smrg else 1176747b715Smrg core_mn.u.mappingNotify.count = clients[i]->maxKC - 1186747b715Smrg clients[i]->minKC + 1; 1196747b715Smrg 1206747b715Smrg WriteEventsToClient(clients[i], 1, &core_mn); 1216747b715Smrg } 1226747b715Smrg if (modmap_changed) { 1236747b715Smrg core_mn.u.mappingNotify.request = MappingModifier; 1246747b715Smrg core_mn.u.mappingNotify.firstKeyCode = 0; 1256747b715Smrg core_mn.u.mappingNotify.count = 0; 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) { 1346747b715Smrg xi_mn.request = MappingKeyboard; 1356747b715Smrg xi_mn.firstKeyCode = first_key; 1366747b715Smrg xi_mn.count = num_keys; 1376747b715Smrg SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1386747b715Smrg 1); 1396747b715Smrg } 1406747b715Smrg if (modmap_changed) { 1416747b715Smrg xi_mn.request = MappingModifier; 1426747b715Smrg xi_mn.firstKeyCode = 0; 1436747b715Smrg xi_mn.count = 0; 1446747b715Smrg SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1456747b715Smrg 1); 1466747b715Smrg } 1476747b715Smrg} 1486747b715Smrg 1496747b715Smrg/***====================================================================***/ 1506747b715Smrg 15105b261ecSmrgvoid 15205b261ecSmrgXkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN) 1536747b715Smrg{ 1546747b715Smrg int i; 1556747b715Smrg Time time = GetTimeInMillis(); 1566747b715Smrg CARD16 changed = pNKN->changed; 15705b261ecSmrg 15805b261ecSmrg pNKN->type = XkbEventCode + XkbEventBase; 15905b261ecSmrg pNKN->xkbType = XkbNewKeyboardNotify; 16005b261ecSmrg 16105b261ecSmrg for (i=1; i<currentMaxClients; i++) { 1626747b715Smrg if (!clients[i] || clients[i]->clientState != ClientStateRunning) 1636747b715Smrg continue; 1646747b715Smrg 1656747b715Smrg if (!(clients[i]->newKeyboardNotifyMask & changed)) 1666747b715Smrg continue; 1676747b715Smrg 1686747b715Smrg if (!XIShouldNotify(clients[i], kbd)) 1696747b715Smrg continue; 1706747b715Smrg 1716747b715Smrg pNKN->sequenceNumber = clients[i]->sequence; 1726747b715Smrg pNKN->time = time; 1736747b715Smrg pNKN->changed = changed; 1746747b715Smrg if (clients[i]->swapped) { 1756747b715Smrg int n; 1766747b715Smrg swaps(&pNKN->sequenceNumber,n); 1776747b715Smrg swapl(&pNKN->time,n); 1786747b715Smrg swaps(&pNKN->changed,n); 1796747b715Smrg } 1806747b715Smrg WriteToClient(clients[i], sizeof(xEvent), pNKN); 18105b261ecSmrg 1826747b715Smrg if (changed & XkbNKN_KeycodesMask) { 1836747b715Smrg clients[i]->minKC = pNKN->minKeyCode; 1846747b715Smrg clients[i]->maxKC = pNKN->maxKeyCode; 1856747b715Smrg } 18605b261ecSmrg } 1876747b715Smrg 1886747b715Smrg XkbSendLegacyMapNotify(kbd, XkbNewKeyboardNotify, changed, pNKN->minKeyCode, 1896747b715Smrg pNKN->maxKeyCode - pNKN->minKeyCode + 1); 1906747b715Smrg 19105b261ecSmrg return; 19205b261ecSmrg} 19305b261ecSmrg 19405b261ecSmrg/***====================================================================***/ 19505b261ecSmrg 19605b261ecSmrgvoid 19705b261ecSmrgXkbSendStateNotify(DeviceIntPtr kbd,xkbStateNotify *pSN) 19805b261ecSmrg{ 19905b261ecSmrgXkbSrvInfoPtr xkbi; 20005b261ecSmrgXkbStatePtr state; 20105b261ecSmrgXkbInterestPtr interest; 20205b261ecSmrgTime time; 20305b261ecSmrgregister CARD16 changed,bState; 20405b261ecSmrg 20505b261ecSmrg interest = kbd->xkb_interest; 2064642e01fSmrg if (!interest || !kbd->key || !kbd->key->xkbInfo) 20705b261ecSmrg return; 20805b261ecSmrg xkbi = kbd->key->xkbInfo; 20905b261ecSmrg state= &xkbi->state; 21005b261ecSmrg 21105b261ecSmrg pSN->type = XkbEventCode + XkbEventBase; 21205b261ecSmrg pSN->xkbType = XkbStateNotify; 21305b261ecSmrg pSN->deviceID = kbd->id; 21405b261ecSmrg pSN->time = time = GetTimeInMillis(); 21505b261ecSmrg pSN->mods = state->mods; 21605b261ecSmrg pSN->baseMods = state->base_mods; 21705b261ecSmrg pSN->latchedMods = state->latched_mods; 21805b261ecSmrg pSN->lockedMods = state->locked_mods; 21905b261ecSmrg pSN->group = state->group; 22005b261ecSmrg pSN->baseGroup = state->base_group; 22105b261ecSmrg pSN->latchedGroup = state->latched_group; 22205b261ecSmrg pSN->lockedGroup = state->locked_group; 22305b261ecSmrg pSN->compatState = state->compat_state; 22405b261ecSmrg pSN->grabMods = state->grab_mods; 22505b261ecSmrg pSN->compatGrabMods = state->compat_grab_mods; 22605b261ecSmrg pSN->lookupMods = state->lookup_mods; 22705b261ecSmrg pSN->compatLookupMods = state->compat_lookup_mods; 22805b261ecSmrg pSN->ptrBtnState = state->ptr_buttons; 22905b261ecSmrg changed = pSN->changed; 23005b261ecSmrg bState= pSN->ptrBtnState; 23105b261ecSmrg 23205b261ecSmrg while (interest) { 23305b261ecSmrg if ((!interest->client->clientGone) && 23405b261ecSmrg (interest->client->requestVector != InitialVector) && 23505b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 2366747b715Smrg (interest->stateNotifyMask&changed) && 2376747b715Smrg XIShouldNotify(interest->client,kbd)) { 23805b261ecSmrg pSN->sequenceNumber = interest->client->sequence; 23905b261ecSmrg pSN->time = time; 24005b261ecSmrg pSN->changed = changed; 24105b261ecSmrg pSN->ptrBtnState = bState; 24205b261ecSmrg if ( interest->client->swapped ) { 24305b261ecSmrg register int n; 24405b261ecSmrg swaps(&pSN->sequenceNumber,n); 24505b261ecSmrg swapl(&pSN->time,n); 24605b261ecSmrg swaps(&pSN->changed,n); 24705b261ecSmrg swaps(&pSN->ptrBtnState,n); 24805b261ecSmrg } 24905b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)pSN); 25005b261ecSmrg } 25105b261ecSmrg interest= interest->next; 25205b261ecSmrg } 25305b261ecSmrg return; 25405b261ecSmrg} 25505b261ecSmrg 25605b261ecSmrg/***====================================================================***/ 25705b261ecSmrg 2586747b715Smrg/* 2596747b715Smrg * This function sends out XKB mapping notify events to clients which 2606747b715Smrg * have explicitly selected for them. Core and Xi events are handled by 2616747b715Smrg * XkbSendLegacyMapNotify. */ 26205b261ecSmrgvoid 2636747b715SmrgXkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify *pMN) 26405b261ecSmrg{ 2656747b715Smrg int i; 2666747b715Smrg CARD32 time = GetTimeInMillis(); 2676747b715Smrg CARD16 changed = pMN->changed; 2686747b715Smrg XkbSrvInfoPtr xkbi = kbd->key->xkbInfo; 2696747b715Smrg 2706747b715Smrg pMN->minKeyCode = xkbi->desc->min_key_code; 2716747b715Smrg pMN->maxKeyCode = xkbi->desc->max_key_code; 2726747b715Smrg pMN->type = XkbEventCode + XkbEventBase; 2736747b715Smrg pMN->xkbType = XkbMapNotify; 2746747b715Smrg pMN->deviceID = kbd->id; 2756747b715Smrg 2766747b715Smrg /* 0 is serverClient. */ 2776747b715Smrg for (i = 1; i < currentMaxClients; i++) { 2786747b715Smrg if (!clients[i] || clients[i]->clientState != ClientStateRunning) 2796747b715Smrg continue; 2806747b715Smrg 2816747b715Smrg if (!(clients[i]->mapNotifyMask & changed)) 2826747b715Smrg continue; 2836747b715Smrg 2846747b715Smrg if (!XIShouldNotify(clients[i], kbd)) 2856747b715Smrg continue; 2866747b715Smrg 2876747b715Smrg pMN->time = time; 2886747b715Smrg pMN->sequenceNumber = clients[i]->sequence; 2896747b715Smrg pMN->changed = changed; 2906747b715Smrg 2916747b715Smrg if (clients[i]->swapped) { 2926747b715Smrg int n; 2936747b715Smrg swaps(&pMN->sequenceNumber, n); 2946747b715Smrg swapl(&pMN->time, n); 2956747b715Smrg swaps(&pMN->changed, n); 2966747b715Smrg } 2976747b715Smrg WriteToClient(clients[i], sizeof(xEvent), pMN); 29805b261ecSmrg } 2996747b715Smrg 3006747b715Smrg XkbSendLegacyMapNotify(kbd, XkbMapNotify, changed, pMN->firstKeySym, 3016747b715Smrg pMN->nKeySyms); 30205b261ecSmrg} 30305b261ecSmrg 30405b261ecSmrgint 30505b261ecSmrgXkbComputeControlsNotify( DeviceIntPtr kbd, 30605b261ecSmrg XkbControlsPtr old, 30705b261ecSmrg XkbControlsPtr new, 30805b261ecSmrg xkbControlsNotify * pCN, 30905b261ecSmrg Bool forceCtrlProc) 31005b261ecSmrg{ 31105b261ecSmrgint i; 31205b261ecSmrgCARD32 changedControls; 31305b261ecSmrg 31405b261ecSmrg changedControls= 0; 31505b261ecSmrg 31605b261ecSmrg if (!kbd || !kbd->kbdfeed) 31705b261ecSmrg return 0; 31805b261ecSmrg 31905b261ecSmrg if (old->enabled_ctrls!=new->enabled_ctrls) 32005b261ecSmrg changedControls|= XkbControlsEnabledMask; 32105b261ecSmrg if ((old->repeat_delay!=new->repeat_delay)|| 32205b261ecSmrg (old->repeat_interval!=new->repeat_interval)) 32305b261ecSmrg changedControls|= XkbRepeatKeysMask; 32405b261ecSmrg for (i = 0; i < XkbPerKeyBitArraySize; i++) 32505b261ecSmrg if (old->per_key_repeat[i] != new->per_key_repeat[i]) 32605b261ecSmrg changedControls|= XkbPerKeyRepeatMask; 32705b261ecSmrg if (old->slow_keys_delay!=new->slow_keys_delay) 32805b261ecSmrg changedControls|= XkbSlowKeysMask; 32905b261ecSmrg if (old->debounce_delay!=new->debounce_delay) 33005b261ecSmrg changedControls|= XkbBounceKeysMask; 33105b261ecSmrg if ((old->mk_delay!=new->mk_delay)|| 33205b261ecSmrg (old->mk_interval!=new->mk_interval)|| 33305b261ecSmrg (old->mk_dflt_btn!=new->mk_dflt_btn)) 33405b261ecSmrg changedControls|= XkbMouseKeysMask; 33505b261ecSmrg if ((old->mk_time_to_max!=new->mk_time_to_max)|| 33605b261ecSmrg (old->mk_curve!=new->mk_curve)|| 33705b261ecSmrg (old->mk_max_speed!=new->mk_max_speed)) 33805b261ecSmrg changedControls|= XkbMouseKeysAccelMask; 33905b261ecSmrg if (old->ax_options!=new->ax_options) 34005b261ecSmrg changedControls|= XkbAccessXKeysMask; 34105b261ecSmrg if ((old->ax_options^new->ax_options) & XkbAX_SKOptionsMask) 34205b261ecSmrg changedControls|= XkbStickyKeysMask; 34305b261ecSmrg if ((old->ax_options^new->ax_options) & XkbAX_FBOptionsMask) 34405b261ecSmrg changedControls|= XkbAccessXFeedbackMask; 34505b261ecSmrg if ((old->ax_timeout!=new->ax_timeout)|| 34605b261ecSmrg (old->axt_ctrls_mask!=new->axt_ctrls_mask)|| 34705b261ecSmrg (old->axt_ctrls_values!=new->axt_ctrls_values)|| 34805b261ecSmrg (old->axt_opts_mask!=new->axt_opts_mask)|| 34905b261ecSmrg (old->axt_opts_values!= new->axt_opts_values)) { 35005b261ecSmrg changedControls|= XkbAccessXTimeoutMask; 35105b261ecSmrg } 35205b261ecSmrg if ((old->internal.mask!=new->internal.mask)|| 35305b261ecSmrg (old->internal.real_mods!=new->internal.real_mods)|| 35405b261ecSmrg (old->internal.vmods!=new->internal.vmods)) 35505b261ecSmrg changedControls|= XkbInternalModsMask; 35605b261ecSmrg if ((old->ignore_lock.mask!=new->ignore_lock.mask)|| 35705b261ecSmrg (old->ignore_lock.real_mods!=new->ignore_lock.real_mods)|| 35805b261ecSmrg (old->ignore_lock.vmods!=new->ignore_lock.vmods)) 35905b261ecSmrg changedControls|= XkbIgnoreLockModsMask; 36005b261ecSmrg 36105b261ecSmrg if (new->enabled_ctrls&XkbRepeatKeysMask) 36205b261ecSmrg kbd->kbdfeed->ctrl.autoRepeat=TRUE; 36305b261ecSmrg else kbd->kbdfeed->ctrl.autoRepeat=FALSE; 36405b261ecSmrg 36505b261ecSmrg if (kbd->kbdfeed && kbd->kbdfeed->CtrlProc && 36605b261ecSmrg (changedControls || forceCtrlProc)) 36705b261ecSmrg (*kbd->kbdfeed->CtrlProc)(kbd, &kbd->kbdfeed->ctrl); 36805b261ecSmrg 36905b261ecSmrg if ((!changedControls)&&(old->num_groups==new->num_groups)) 37005b261ecSmrg return 0; 37105b261ecSmrg 37205b261ecSmrg if (!kbd->xkb_interest) 37305b261ecSmrg return 0; 37405b261ecSmrg 37505b261ecSmrg pCN->changedControls = changedControls; 37605b261ecSmrg pCN->enabledControls = new->enabled_ctrls; 37705b261ecSmrg pCN->enabledControlChanges = (new->enabled_ctrls^old->enabled_ctrls); 37805b261ecSmrg pCN->numGroups = new->num_groups; 37905b261ecSmrg 38005b261ecSmrg return 1; 38105b261ecSmrg} 38205b261ecSmrg 38305b261ecSmrgvoid 38405b261ecSmrgXkbSendControlsNotify(DeviceIntPtr kbd,xkbControlsNotify *pCN) 38505b261ecSmrg{ 38605b261ecSmrgint initialized; 38705b261ecSmrgCARD32 changedControls, enabledControls, enabledChanges = 0; 38805b261ecSmrgXkbSrvInfoPtr xkbi; 38905b261ecSmrgXkbInterestPtr interest; 39005b261ecSmrgTime time = 0; 39105b261ecSmrg 39205b261ecSmrg interest = kbd->xkb_interest; 3934642e01fSmrg if (!interest || !kbd->key || !kbd->key->xkbInfo) 39405b261ecSmrg return; 39505b261ecSmrg xkbi = kbd->key->xkbInfo; 39605b261ecSmrg 39705b261ecSmrg initialized = 0; 39805b261ecSmrg enabledControls = xkbi->desc->ctrls->enabled_ctrls; 39905b261ecSmrg changedControls = pCN->changedControls; 40005b261ecSmrg pCN->numGroups= xkbi->desc->ctrls->num_groups; 40105b261ecSmrg while (interest) { 40205b261ecSmrg if ((!interest->client->clientGone) && 40305b261ecSmrg (interest->client->requestVector != InitialVector) && 40405b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 4056747b715Smrg (interest->ctrlsNotifyMask&changedControls) && 4066747b715Smrg XIShouldNotify(interest->client, kbd)) { 40705b261ecSmrg if (!initialized) { 40805b261ecSmrg pCN->type = XkbEventCode + XkbEventBase; 40905b261ecSmrg pCN->xkbType = XkbControlsNotify; 41005b261ecSmrg pCN->deviceID = kbd->id; 41105b261ecSmrg pCN->time = time = GetTimeInMillis(); 41205b261ecSmrg enabledChanges = pCN->enabledControlChanges; 41305b261ecSmrg initialized= 1; 41405b261ecSmrg } 41505b261ecSmrg pCN->changedControls = changedControls; 41605b261ecSmrg pCN->enabledControls = enabledControls; 41705b261ecSmrg pCN->enabledControlChanges = enabledChanges; 41805b261ecSmrg pCN->sequenceNumber = interest->client->sequence; 41905b261ecSmrg pCN->time = time; 42005b261ecSmrg if ( interest->client->swapped ) { 42105b261ecSmrg register int n; 42205b261ecSmrg swaps(&pCN->sequenceNumber,n); 42305b261ecSmrg swapl(&pCN->changedControls,n); 42405b261ecSmrg swapl(&pCN->enabledControls,n); 42505b261ecSmrg swapl(&pCN->enabledControlChanges,n); 42605b261ecSmrg swapl(&pCN->time,n); 42705b261ecSmrg } 42805b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)pCN); 42905b261ecSmrg } 43005b261ecSmrg interest= interest->next; 43105b261ecSmrg } 43205b261ecSmrg return; 43305b261ecSmrg} 43405b261ecSmrg 43505b261ecSmrgstatic void 43605b261ecSmrgXkbSendIndicatorNotify(DeviceIntPtr kbd,int xkbType,xkbIndicatorNotify *pEv) 43705b261ecSmrg{ 43805b261ecSmrgint initialized; 43905b261ecSmrgXkbInterestPtr interest; 44005b261ecSmrgTime time = 0; 44105b261ecSmrgCARD32 state,changed; 44205b261ecSmrg 44305b261ecSmrg interest = kbd->xkb_interest; 44405b261ecSmrg if (!interest) 44505b261ecSmrg return; 44605b261ecSmrg 44705b261ecSmrg initialized = 0; 44805b261ecSmrg state = pEv->state; 44905b261ecSmrg changed = pEv->changed; 45005b261ecSmrg while (interest) { 45105b261ecSmrg if ((!interest->client->clientGone) && 45205b261ecSmrg (interest->client->requestVector != InitialVector) && 45305b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 4546747b715Smrg XIShouldNotify(interest->client, kbd) && 45505b261ecSmrg (((xkbType==XkbIndicatorStateNotify)&& 45605b261ecSmrg (interest->iStateNotifyMask&changed))|| 45705b261ecSmrg ((xkbType==XkbIndicatorMapNotify)&& 45805b261ecSmrg (interest->iMapNotifyMask&changed)))) { 45905b261ecSmrg if (!initialized) { 46005b261ecSmrg pEv->type = XkbEventCode + XkbEventBase; 46105b261ecSmrg pEv->xkbType = xkbType; 46205b261ecSmrg pEv->deviceID = kbd->id; 46305b261ecSmrg pEv->time = time = GetTimeInMillis(); 46405b261ecSmrg initialized= 1; 46505b261ecSmrg } 46605b261ecSmrg pEv->sequenceNumber = interest->client->sequence; 46705b261ecSmrg pEv->time = time; 46805b261ecSmrg pEv->changed = changed; 46905b261ecSmrg pEv->state = state; 47005b261ecSmrg if ( interest->client->swapped ) { 47105b261ecSmrg register int n; 47205b261ecSmrg swaps(&pEv->sequenceNumber,n); 47305b261ecSmrg swapl(&pEv->time,n); 47405b261ecSmrg swapl(&pEv->changed,n); 47505b261ecSmrg swapl(&pEv->state,n); 47605b261ecSmrg } 47705b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 47805b261ecSmrg } 47905b261ecSmrg interest= interest->next; 48005b261ecSmrg } 48105b261ecSmrg return; 48205b261ecSmrg} 48305b261ecSmrg 48405b261ecSmrg 48505b261ecSmrgvoid 48605b261ecSmrgXkbHandleBell( BOOL force, 48705b261ecSmrg BOOL eventOnly, 48805b261ecSmrg DeviceIntPtr kbd, 48905b261ecSmrg CARD8 percent, 49005b261ecSmrg pointer pCtrl, 49105b261ecSmrg CARD8 class, 49205b261ecSmrg Atom name, 49305b261ecSmrg WindowPtr pWin, 49405b261ecSmrg ClientPtr pClient) 49505b261ecSmrg{ 49605b261ecSmrgxkbBellNotify bn; 49705b261ecSmrgint initialized; 49805b261ecSmrgXkbSrvInfoPtr xkbi; 49905b261ecSmrgXkbInterestPtr interest; 50005b261ecSmrgCARD8 id; 50105b261ecSmrgCARD16 pitch,duration; 50205b261ecSmrgTime time = 0; 50305b261ecSmrgXID winID = 0; 50405b261ecSmrg 5054642e01fSmrg if (!kbd->key || !kbd->key->xkbInfo) 5064642e01fSmrg return; 5074642e01fSmrg 50805b261ecSmrg xkbi = kbd->key->xkbInfo; 50905b261ecSmrg 51005b261ecSmrg if ((force||(xkbi->desc->ctrls->enabled_ctrls&XkbAudibleBellMask))&& 51105b261ecSmrg (!eventOnly)) { 51205b261ecSmrg if (kbd->kbdfeed->BellProc) 51305b261ecSmrg (*kbd->kbdfeed->BellProc)(percent,kbd,(pointer)pCtrl,class); 51405b261ecSmrg } 51505b261ecSmrg interest = kbd->xkb_interest; 51605b261ecSmrg if ((!interest)||(force)) 51705b261ecSmrg return; 51805b261ecSmrg 51905b261ecSmrg if ((class==0)||(class==KbdFeedbackClass)) { 52005b261ecSmrg KeybdCtrl *pKeyCtrl= (KeybdCtrl *)pCtrl; 52105b261ecSmrg id= pKeyCtrl->id; 52205b261ecSmrg pitch= pKeyCtrl->bell_pitch; 52305b261ecSmrg duration= pKeyCtrl->bell_duration; 52405b261ecSmrg } 52505b261ecSmrg else if (class==BellFeedbackClass) { 52605b261ecSmrg BellCtrl *pBellCtrl= (BellCtrl *)pCtrl; 52705b261ecSmrg id= pBellCtrl->id; 52805b261ecSmrg pitch= pBellCtrl->pitch; 52905b261ecSmrg duration= pBellCtrl->duration; 53005b261ecSmrg } 53105b261ecSmrg else return; 53205b261ecSmrg 53305b261ecSmrg initialized = 0; 53405b261ecSmrg while (interest) { 53505b261ecSmrg if ((!interest->client->clientGone) && 53605b261ecSmrg (interest->client->requestVector != InitialVector) && 53705b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 5386747b715Smrg (interest->bellNotifyMask) && 5396747b715Smrg XIShouldNotify(interest->client,kbd)) { 54005b261ecSmrg if (!initialized) { 54105b261ecSmrg time = GetTimeInMillis(); 54205b261ecSmrg bn.type = XkbEventCode + XkbEventBase; 54305b261ecSmrg bn.xkbType = XkbBellNotify; 54405b261ecSmrg bn.deviceID = kbd->id; 54505b261ecSmrg bn.bellClass = class; 54605b261ecSmrg bn.bellID = id; 54705b261ecSmrg bn.percent= percent; 54805b261ecSmrg bn.eventOnly = (eventOnly!=0); 54905b261ecSmrg winID= (pWin?pWin->drawable.id:None); 55005b261ecSmrg initialized= 1; 55105b261ecSmrg } 55205b261ecSmrg bn.sequenceNumber = interest->client->sequence; 55305b261ecSmrg bn.time = time; 55405b261ecSmrg bn.pitch = pitch; 55505b261ecSmrg bn.duration = duration; 55605b261ecSmrg bn.name = name; 55705b261ecSmrg bn.window= winID; 55805b261ecSmrg if ( interest->client->swapped ) { 55905b261ecSmrg register int n; 56005b261ecSmrg swaps(&bn.sequenceNumber,n); 56105b261ecSmrg swapl(&bn.time,n); 56205b261ecSmrg swaps(&bn.pitch,n); 56305b261ecSmrg swaps(&bn.duration,n); 56405b261ecSmrg swapl(&bn.name,n); 56505b261ecSmrg swapl(&bn.window,n); 56605b261ecSmrg } 56705b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)&bn); 56805b261ecSmrg } 56905b261ecSmrg interest= interest->next; 57005b261ecSmrg } 57105b261ecSmrg return; 57205b261ecSmrg} 57305b261ecSmrg 57405b261ecSmrgvoid 57505b261ecSmrgXkbSendAccessXNotify(DeviceIntPtr kbd,xkbAccessXNotify *pEv) 57605b261ecSmrg{ 57705b261ecSmrgint initialized; 57805b261ecSmrgXkbInterestPtr interest; 57905b261ecSmrgTime time = 0; 58005b261ecSmrgCARD16 sk_delay,db_delay; 58105b261ecSmrg 58205b261ecSmrg interest = kbd->xkb_interest; 58305b261ecSmrg if (!interest) 58405b261ecSmrg return; 58505b261ecSmrg 58605b261ecSmrg initialized = 0; 58705b261ecSmrg sk_delay= pEv->slowKeysDelay; 58805b261ecSmrg db_delay= pEv->debounceDelay; 58905b261ecSmrg while (interest) { 59005b261ecSmrg if ((!interest->client->clientGone) && 59105b261ecSmrg (interest->client->requestVector != InitialVector) && 59205b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 5936747b715Smrg (interest->accessXNotifyMask&(1<<pEv->detail)) && 5946747b715Smrg XIShouldNotify(interest->client, kbd)) { 59505b261ecSmrg if (!initialized) { 59605b261ecSmrg pEv->type = XkbEventCode + XkbEventBase; 59705b261ecSmrg pEv->xkbType = XkbAccessXNotify; 59805b261ecSmrg pEv->deviceID = kbd->id; 59905b261ecSmrg pEv->time = time = GetTimeInMillis(); 60005b261ecSmrg initialized= 1; 60105b261ecSmrg } 60205b261ecSmrg pEv->sequenceNumber = interest->client->sequence; 60305b261ecSmrg pEv->time = time; 60405b261ecSmrg pEv->slowKeysDelay = sk_delay; 60505b261ecSmrg pEv->debounceDelay = db_delay; 60605b261ecSmrg if ( interest->client->swapped ) { 60705b261ecSmrg register int n; 60805b261ecSmrg swaps(&pEv->sequenceNumber,n); 60905b261ecSmrg swapl(&pEv->time,n); 61005b261ecSmrg swaps(&pEv->slowKeysDelay,n); 61105b261ecSmrg swaps(&pEv->debounceDelay,n); 61205b261ecSmrg } 61305b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 61405b261ecSmrg } 61505b261ecSmrg interest= interest->next; 61605b261ecSmrg } 61705b261ecSmrg return; 61805b261ecSmrg} 61905b261ecSmrg 62005b261ecSmrgvoid 62105b261ecSmrgXkbSendNamesNotify(DeviceIntPtr kbd,xkbNamesNotify *pEv) 62205b261ecSmrg{ 62305b261ecSmrgint initialized; 62405b261ecSmrgXkbInterestPtr interest; 62505b261ecSmrgTime time = 0; 62605b261ecSmrgCARD16 changed,changedVirtualMods; 62705b261ecSmrgCARD32 changedIndicators; 62805b261ecSmrg 62905b261ecSmrg interest = kbd->xkb_interest; 63005b261ecSmrg if (!interest) 63105b261ecSmrg return; 63205b261ecSmrg 63305b261ecSmrg initialized = 0; 63405b261ecSmrg changed= pEv->changed; 63505b261ecSmrg changedIndicators= pEv->changedIndicators; 63605b261ecSmrg changedVirtualMods= pEv->changedVirtualMods; 63705b261ecSmrg while (interest) { 63805b261ecSmrg if ((!interest->client->clientGone) && 63905b261ecSmrg (interest->client->requestVector != InitialVector) && 64005b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 6416747b715Smrg (interest->namesNotifyMask&pEv->changed) && 6426747b715Smrg XIShouldNotify(interest->client, kbd)) { 64305b261ecSmrg if (!initialized) { 64405b261ecSmrg pEv->type = XkbEventCode + XkbEventBase; 64505b261ecSmrg pEv->xkbType = XkbNamesNotify; 64605b261ecSmrg pEv->deviceID = kbd->id; 64705b261ecSmrg pEv->time = time = GetTimeInMillis(); 64805b261ecSmrg initialized= 1; 64905b261ecSmrg } 65005b261ecSmrg pEv->sequenceNumber = interest->client->sequence; 65105b261ecSmrg pEv->time = time; 65205b261ecSmrg pEv->changed = changed; 65305b261ecSmrg pEv->changedIndicators = changedIndicators; 65405b261ecSmrg pEv->changedVirtualMods= changedVirtualMods; 65505b261ecSmrg if ( interest->client->swapped ) { 65605b261ecSmrg register int n; 65705b261ecSmrg swaps(&pEv->sequenceNumber,n); 65805b261ecSmrg swapl(&pEv->time,n); 65905b261ecSmrg swaps(&pEv->changed,n); 66005b261ecSmrg swapl(&pEv->changedIndicators,n); 66105b261ecSmrg swaps(&pEv->changedVirtualMods,n); 66205b261ecSmrg } 66305b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 66405b261ecSmrg } 66505b261ecSmrg interest= interest->next; 66605b261ecSmrg } 66705b261ecSmrg return; 66805b261ecSmrg} 66905b261ecSmrg 67005b261ecSmrgvoid 67105b261ecSmrgXkbSendCompatMapNotify(DeviceIntPtr kbd,xkbCompatMapNotify *pEv) 67205b261ecSmrg{ 67305b261ecSmrgint initialized; 67405b261ecSmrgXkbInterestPtr interest; 67505b261ecSmrgTime time = 0; 67605b261ecSmrgCARD16 firstSI = 0, nSI = 0, nTotalSI = 0; 67705b261ecSmrg 67805b261ecSmrg interest = kbd->xkb_interest; 67905b261ecSmrg if (!interest) 68005b261ecSmrg return; 68105b261ecSmrg 68205b261ecSmrg initialized = 0; 68305b261ecSmrg while (interest) { 68405b261ecSmrg if ((!interest->client->clientGone) && 68505b261ecSmrg (interest->client->requestVector != InitialVector) && 68605b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 6876747b715Smrg (interest->compatNotifyMask) && 6886747b715Smrg XIShouldNotify(interest->client, kbd)) { 68905b261ecSmrg if (!initialized) { 69005b261ecSmrg pEv->type = XkbEventCode + XkbEventBase; 69105b261ecSmrg pEv->xkbType = XkbCompatMapNotify; 69205b261ecSmrg pEv->deviceID = kbd->id; 69305b261ecSmrg pEv->time = time = GetTimeInMillis(); 69405b261ecSmrg firstSI= pEv->firstSI; 69505b261ecSmrg nSI= pEv->nSI; 69605b261ecSmrg nTotalSI= pEv->nTotalSI; 69705b261ecSmrg initialized= 1; 69805b261ecSmrg } 69905b261ecSmrg pEv->sequenceNumber = interest->client->sequence; 70005b261ecSmrg pEv->time = time; 70105b261ecSmrg pEv->firstSI = firstSI; 70205b261ecSmrg pEv->nSI = nSI; 70305b261ecSmrg pEv->nTotalSI = nTotalSI; 70405b261ecSmrg if ( interest->client->swapped ) { 70505b261ecSmrg register int n; 70605b261ecSmrg swaps(&pEv->sequenceNumber,n); 70705b261ecSmrg swapl(&pEv->time,n); 70805b261ecSmrg swaps(&pEv->firstSI,n); 70905b261ecSmrg swaps(&pEv->nSI,n); 71005b261ecSmrg swaps(&pEv->nTotalSI,n); 71105b261ecSmrg } 71205b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 71305b261ecSmrg } 71405b261ecSmrg interest= interest->next; 71505b261ecSmrg } 71605b261ecSmrg return; 71705b261ecSmrg} 71805b261ecSmrg 71905b261ecSmrgvoid 72005b261ecSmrgXkbSendActionMessage(DeviceIntPtr kbd,xkbActionMessage *pEv) 72105b261ecSmrg{ 72205b261ecSmrgint initialized; 72305b261ecSmrgXkbSrvInfoPtr xkbi; 72405b261ecSmrgXkbInterestPtr interest; 72505b261ecSmrgTime time = 0; 72605b261ecSmrg 72705b261ecSmrg interest = kbd->xkb_interest; 7284642e01fSmrg if (!interest || !kbd->key || !kbd->key->xkbInfo) 72905b261ecSmrg return; 73005b261ecSmrg 7314642e01fSmrg xkbi = kbd->key->xkbInfo; 7324642e01fSmrg 73305b261ecSmrg initialized = 0; 73405b261ecSmrg pEv->mods= xkbi->state.mods; 73505b261ecSmrg pEv->group= xkbi->state.group; 73605b261ecSmrg while (interest) { 73705b261ecSmrg if ((!interest->client->clientGone) && 73805b261ecSmrg (interest->client->requestVector != InitialVector) && 73905b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 7406747b715Smrg (interest->actionMessageMask) && 7416747b715Smrg XIShouldNotify(interest->client, kbd)) { 74205b261ecSmrg if (!initialized) { 74305b261ecSmrg pEv->type = XkbEventCode + XkbEventBase; 74405b261ecSmrg pEv->xkbType = XkbActionMessage; 74505b261ecSmrg pEv->deviceID = kbd->id; 74605b261ecSmrg pEv->sequenceNumber = interest->client->sequence; 74705b261ecSmrg pEv->time = time = GetTimeInMillis(); 74805b261ecSmrg initialized= 1; 74905b261ecSmrg } 75005b261ecSmrg pEv->sequenceNumber = interest->client->sequence; 75105b261ecSmrg pEv->time = time; 75205b261ecSmrg if ( interest->client->swapped ) { 75305b261ecSmrg register int n; 75405b261ecSmrg swaps(&pEv->sequenceNumber,n); 75505b261ecSmrg swapl(&pEv->time,n); 75605b261ecSmrg } 75705b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 75805b261ecSmrg } 75905b261ecSmrg interest= interest->next; 76005b261ecSmrg } 76105b261ecSmrg return; 76205b261ecSmrg} 76305b261ecSmrg 76405b261ecSmrgvoid 76505b261ecSmrgXkbSendExtensionDeviceNotify( DeviceIntPtr dev, 76605b261ecSmrg ClientPtr client, 76705b261ecSmrg xkbExtensionDeviceNotify * pEv) 76805b261ecSmrg{ 76905b261ecSmrgint initialized; 77005b261ecSmrgXkbInterestPtr interest; 77105b261ecSmrgTime time = 0; 77205b261ecSmrgCARD32 defined, state; 7736747b715SmrgCARD16 reason; 77405b261ecSmrg 77505b261ecSmrg interest = dev->xkb_interest; 77605b261ecSmrg if (!interest) 77705b261ecSmrg return; 77805b261ecSmrg 77905b261ecSmrg initialized = 0; 78005b261ecSmrg reason= pEv->reason; 78105b261ecSmrg defined= pEv->ledsDefined; 78205b261ecSmrg state= pEv->ledState; 78305b261ecSmrg while (interest) { 78405b261ecSmrg if ((!interest->client->clientGone) && 78505b261ecSmrg (interest->client->requestVector != InitialVector) && 78605b261ecSmrg (interest->client->xkbClientFlags&_XkbClientInitialized) && 7876747b715Smrg (interest->extDevNotifyMask&reason) && 7886747b715Smrg XIShouldNotify(interest->client, dev)) { 78905b261ecSmrg if (!initialized) { 79005b261ecSmrg pEv->type = XkbEventCode + XkbEventBase; 79105b261ecSmrg pEv->xkbType = XkbExtensionDeviceNotify; 79205b261ecSmrg pEv->deviceID = dev->id; 79305b261ecSmrg pEv->sequenceNumber = interest->client->sequence; 79405b261ecSmrg pEv->time = time = GetTimeInMillis(); 79505b261ecSmrg initialized= 1; 79605b261ecSmrg } 79705b261ecSmrg else { 79805b261ecSmrg pEv->sequenceNumber = interest->client->sequence; 79905b261ecSmrg pEv->time = time; 80005b261ecSmrg pEv->ledsDefined= defined; 80105b261ecSmrg pEv->ledState= state; 80205b261ecSmrg pEv->reason= reason; 8036747b715Smrg pEv->supported= XkbXI_AllFeaturesMask; 80405b261ecSmrg } 80505b261ecSmrg if ( interest->client->swapped ) { 80605b261ecSmrg register int n; 80705b261ecSmrg swaps(&pEv->sequenceNumber,n); 80805b261ecSmrg swapl(&pEv->time,n); 80905b261ecSmrg swapl(&pEv->ledsDefined,n); 81005b261ecSmrg swapl(&pEv->ledState,n); 81105b261ecSmrg swaps(&pEv->reason,n); 81205b261ecSmrg swaps(&pEv->supported,n); 81305b261ecSmrg } 81405b261ecSmrg WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 81505b261ecSmrg } 81605b261ecSmrg interest= interest->next; 81705b261ecSmrg } 81805b261ecSmrg return; 81905b261ecSmrg} 82005b261ecSmrg 82105b261ecSmrgvoid 82205b261ecSmrgXkbSendNotification( DeviceIntPtr kbd, 82305b261ecSmrg XkbChangesPtr pChanges, 82405b261ecSmrg XkbEventCausePtr cause) 82505b261ecSmrg{ 82605b261ecSmrgXkbSrvLedInfoPtr sli; 82705b261ecSmrg 82805b261ecSmrg sli= NULL; 82905b261ecSmrg if (pChanges->state_changes) { 83005b261ecSmrg xkbStateNotify sn; 83105b261ecSmrg sn.changed= pChanges->state_changes; 83205b261ecSmrg sn.keycode= cause->kc; 83305b261ecSmrg sn.eventType= cause->event; 83405b261ecSmrg sn.requestMajor= cause->mjr; 83505b261ecSmrg sn.requestMinor= cause->mnr; 83605b261ecSmrg XkbSendStateNotify(kbd,&sn); 83705b261ecSmrg } 83805b261ecSmrg if (pChanges->map.changed) { 83905b261ecSmrg xkbMapNotify mn; 8406747b715Smrg memset(&mn, 0, sizeof(xkbMapNotify)); 84105b261ecSmrg mn.changed= pChanges->map.changed; 84205b261ecSmrg mn.firstType= pChanges->map.first_type; 84305b261ecSmrg mn.nTypes= pChanges->map.num_types; 84405b261ecSmrg mn.firstKeySym= pChanges->map.first_key_sym; 84505b261ecSmrg mn.nKeySyms= pChanges->map.num_key_syms; 84605b261ecSmrg mn.firstKeyAct= pChanges->map.first_key_act; 84705b261ecSmrg mn.nKeyActs= pChanges->map.num_key_acts; 84805b261ecSmrg mn.firstKeyBehavior= pChanges->map.first_key_behavior; 84905b261ecSmrg mn.nKeyBehaviors= pChanges->map.num_key_behaviors; 85005b261ecSmrg mn.virtualMods= pChanges->map.vmods; 85105b261ecSmrg mn.firstKeyExplicit= pChanges->map.first_key_explicit; 85205b261ecSmrg mn.nKeyExplicit= pChanges->map.num_key_explicit; 85305b261ecSmrg mn.firstModMapKey= pChanges->map.first_modmap_key; 85405b261ecSmrg mn.nModMapKeys= pChanges->map.num_modmap_keys; 85505b261ecSmrg mn.firstVModMapKey= pChanges->map.first_vmodmap_key; 85605b261ecSmrg mn.nVModMapKeys= pChanges->map.num_vmodmap_keys; 85705b261ecSmrg XkbSendMapNotify(kbd,&mn); 85805b261ecSmrg } 85905b261ecSmrg if ((pChanges->ctrls.changed_ctrls)|| 86005b261ecSmrg (pChanges->ctrls.enabled_ctrls_changes)) { 86105b261ecSmrg xkbControlsNotify cn; 8626747b715Smrg memset(&cn, 0, sizeof(xkbControlsNotify)); 86305b261ecSmrg cn.changedControls= pChanges->ctrls.changed_ctrls; 86405b261ecSmrg cn.enabledControlChanges= pChanges->ctrls.enabled_ctrls_changes; 86505b261ecSmrg cn.keycode= cause->kc; 86605b261ecSmrg cn.eventType= cause->event; 86705b261ecSmrg cn.requestMajor= cause->mjr; 86805b261ecSmrg cn.requestMinor= cause->mnr; 86905b261ecSmrg XkbSendControlsNotify(kbd,&cn); 87005b261ecSmrg } 87105b261ecSmrg if (pChanges->indicators.map_changes) { 87205b261ecSmrg xkbIndicatorNotify in; 87305b261ecSmrg if (sli==NULL) 87405b261ecSmrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 8756747b715Smrg memset(&in, 0, sizeof(xkbIndicatorNotify)); 87605b261ecSmrg in.state= sli->effectiveState; 87705b261ecSmrg in.changed= pChanges->indicators.map_changes; 87805b261ecSmrg XkbSendIndicatorNotify(kbd,XkbIndicatorMapNotify,&in); 87905b261ecSmrg } 88005b261ecSmrg if (pChanges->indicators.state_changes) { 88105b261ecSmrg xkbIndicatorNotify in; 88205b261ecSmrg if (sli==NULL) 88305b261ecSmrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 8846747b715Smrg memset(&in, 0, sizeof(xkbIndicatorNotify)); 88505b261ecSmrg in.state= sli->effectiveState; 88605b261ecSmrg in.changed= pChanges->indicators.state_changes; 88705b261ecSmrg XkbSendIndicatorNotify(kbd,XkbIndicatorStateNotify,&in); 88805b261ecSmrg } 88905b261ecSmrg if (pChanges->names.changed) { 89005b261ecSmrg xkbNamesNotify nn; 8916747b715Smrg memset(&nn, 0, sizeof(xkbNamesNotify)); 89205b261ecSmrg nn.changed= pChanges->names.changed; 89305b261ecSmrg nn.firstType= pChanges->names.first_type; 89405b261ecSmrg nn.nTypes= pChanges->names.num_types; 89505b261ecSmrg nn.firstLevelName= pChanges->names.first_lvl; 89605b261ecSmrg nn.nLevelNames= pChanges->names.num_lvls; 89705b261ecSmrg nn.nRadioGroups= pChanges->names.num_rg; 89805b261ecSmrg nn.changedVirtualMods= pChanges->names.changed_vmods; 89905b261ecSmrg nn.changedIndicators= pChanges->names.changed_indicators; 90005b261ecSmrg XkbSendNamesNotify(kbd,&nn); 90105b261ecSmrg } 90205b261ecSmrg if ((pChanges->compat.changed_groups)||(pChanges->compat.num_si>0)) { 90305b261ecSmrg xkbCompatMapNotify cmn; 9046747b715Smrg memset(&cmn, 0, sizeof(xkbCompatMapNotify)); 90505b261ecSmrg cmn.changedGroups= pChanges->compat.changed_groups; 90605b261ecSmrg cmn.firstSI= pChanges->compat.first_si; 90705b261ecSmrg cmn.nSI= pChanges->compat.num_si; 90805b261ecSmrg cmn.nTotalSI= kbd->key->xkbInfo->desc->compat->num_si; 90905b261ecSmrg XkbSendCompatMapNotify(kbd,&cmn); 91005b261ecSmrg } 91105b261ecSmrg return; 91205b261ecSmrg} 91305b261ecSmrg 91405b261ecSmrg/***====================================================================***/ 91505b261ecSmrg 9166747b715Smrgvoid 9176747b715SmrgXkbFilterEvents(ClientPtr client,int nEvents,xEvent *xE) 91805b261ecSmrg{ 9196747b715Smrg DeviceIntPtr dev = NULL; 9206747b715Smrg XkbSrvInfoPtr xkbi; 9216747b715Smrg CARD8 type = xE[0].u.u.type; 92205b261ecSmrg 9234642e01fSmrg if (xE->u.u.type & EXTENSION_EVENT_BASE) 9246747b715Smrg dev = XIGetDevice(xE); 9254642e01fSmrg 9266747b715Smrg if (!dev) 9276747b715Smrg dev = PickKeyboard(client); 9284642e01fSmrg 9296747b715Smrg if (!dev->key) 9306747b715Smrg return; 9314642e01fSmrg 9326747b715Smrg xkbi = dev->key->xkbInfo; 93305b261ecSmrg 9346747b715Smrg if (client->xkbClientFlags & _XkbClientInitialized) { 9356747b715Smrg if ((xkbDebugFlags&0x10)&& 9366747b715Smrg (type == KeyPress || type == KeyRelease || 9376747b715Smrg type == DeviceKeyPress || type == DeviceKeyRelease)) 9386747b715Smrg DebugF("[xkb] XkbFilterWriteEvents (XKB client): state 0x%04x\n", 9396747b715Smrg xE[0].u.keyButtonPointer.state); 9406747b715Smrg 9416747b715Smrg if (dev->deviceGrab.grab != NullGrab && dev->deviceGrab.fromPassiveGrab && 9426747b715Smrg (type == KeyPress || type == KeyRelease || 9436747b715Smrg type == DeviceKeyPress || type == DeviceKeyRelease)) { 9446747b715Smrg unsigned int state, flags; 9456747b715Smrg 9466747b715Smrg flags = client->xkbClientFlags; 9476747b715Smrg state = xkbi->state.compat_grab_mods; 94805b261ecSmrg if (flags & XkbPCF_GrabsUseXKBStateMask) { 94905b261ecSmrg int group; 9506747b715Smrg if (flags & XkbPCF_LookupStateWhenGrabbed) { 9516747b715Smrg group = xkbi->state.group; 9526747b715Smrg state = xkbi->state.lookup_mods; 95305b261ecSmrg } 95405b261ecSmrg else { 9556747b715Smrg state = xkbi->state.grab_mods; 9566747b715Smrg group = xkbi->state.base_group + xkbi->state.latched_group; 9576747b715Smrg if (group < 0 || group >= xkbi->desc->ctrls->num_groups) 9586747b715Smrg group = XkbAdjustGroup(group, xkbi->desc->ctrls); 95905b261ecSmrg } 96005b261ecSmrg state = XkbBuildCoreState(state, group); 96105b261ecSmrg } 9626747b715Smrg else if (flags & XkbPCF_LookupStateWhenGrabbed) { 9636747b715Smrg state = xkbi->state.compat_lookup_mods; 9646747b715Smrg } 9656747b715Smrg xE[0].u.keyButtonPointer.state = state; 96605b261ecSmrg } 96705b261ecSmrg } 96805b261ecSmrg else { 9696747b715Smrg if ((xkbDebugFlags & 0x4) && 9706747b715Smrg (xE[0].u.u.type == KeyPress || xE[0].u.u.type==KeyRelease || 9716747b715Smrg xE[0].u.u.type == DeviceKeyPress || 9726747b715Smrg xE[0].u.u.type == DeviceKeyRelease)) { 9736747b715Smrg DebugF("[xkb] XKbFilterWriteEvents (non-XKB):\n"); 9746747b715Smrg DebugF("[xkb] event= 0x%04x\n",xE[0].u.keyButtonPointer.state); 9756747b715Smrg DebugF("[xkb] lookup= 0x%02x, grab= 0x%02x\n", 9766747b715Smrg xkbi->state.lookup_mods, xkbi->state.grab_mods); 9776747b715Smrg DebugF("[xkb] compat lookup= 0x%02x, grab= 0x%02x\n", 9786747b715Smrg xkbi->state.compat_lookup_mods, xkbi->state.compat_grab_mods); 9796747b715Smrg } 9806747b715Smrg if (type >= KeyPress && type <= MotionNotify) { 9816747b715Smrg CARD16 old, new; 98205b261ecSmrg 9836747b715Smrg old = xE[0].u.keyButtonPointer.state & ~0x1f00; 9846747b715Smrg new = xE[0].u.keyButtonPointer.state & 0x1F00; 98505b261ecSmrg 9866747b715Smrg if (old == XkbStateFieldFromRec(&xkbi->state)) 9876747b715Smrg new |= xkbi->state.compat_lookup_mods; 9886747b715Smrg else 9896747b715Smrg new |= xkbi->state.compat_grab_mods; 9906747b715Smrg xE[0].u.keyButtonPointer.state = new; 99105b261ecSmrg } 9926747b715Smrg else if (type == EnterNotify || type == LeaveNotify) { 9936747b715Smrg xE[0].u.enterLeave.state &= 0x1F00; 9946747b715Smrg xE[0].u.enterLeave.state |= xkbi->state.compat_grab_mods; 9956747b715Smrg } 9966747b715Smrg else if (type >= DeviceKeyPress && type <= DeviceMotionNotify) { 9976747b715Smrg CARD16 old, new; 9986747b715Smrg deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer*) &xE[0]; 9996747b715Smrg 10006747b715Smrg old = kbp->state & ~0x1F00; 10016747b715Smrg new = kbp->state & 0x1F00; 10026747b715Smrg if (old == XkbStateFieldFromRec(&xkbi->state)) 10036747b715Smrg new |= xkbi->state.compat_lookup_mods; 10046747b715Smrg else 10056747b715Smrg new |= xkbi->state.compat_grab_mods; 10066747b715Smrg kbp->state = new; 10076747b715Smrg } 100805b261ecSmrg } 100905b261ecSmrg} 101005b261ecSmrg 101105b261ecSmrg/***====================================================================***/ 101205b261ecSmrg 10136747b715SmrgXkbInterestPtr 101405b261ecSmrgXkbFindClientResource(DevicePtr inDev,ClientPtr client) 101505b261ecSmrg{ 101605b261ecSmrgDeviceIntPtr dev = (DeviceIntPtr)inDev; 101705b261ecSmrgXkbInterestPtr interest; 101805b261ecSmrg 101905b261ecSmrg if ( dev->xkb_interest ) { 102005b261ecSmrg interest = dev->xkb_interest; 102105b261ecSmrg while (interest){ 102205b261ecSmrg if (interest->client==client) { 102305b261ecSmrg return interest; 102405b261ecSmrg } 102505b261ecSmrg interest = interest->next; 102605b261ecSmrg } 102705b261ecSmrg } 102805b261ecSmrg return NULL; 102905b261ecSmrg} 103005b261ecSmrg 10316747b715SmrgXkbInterestPtr 103205b261ecSmrgXkbAddClientResource(DevicePtr inDev,ClientPtr client,XID id) 103305b261ecSmrg{ 103405b261ecSmrgDeviceIntPtr dev = (DeviceIntPtr)inDev; 103505b261ecSmrgXkbInterestPtr interest; 103605b261ecSmrg 103705b261ecSmrg interest = dev->xkb_interest; 103805b261ecSmrg while (interest) { 103905b261ecSmrg if (interest->client==client) 104005b261ecSmrg return ((interest->resource==id)?interest:NULL); 104105b261ecSmrg interest = interest->next; 104205b261ecSmrg } 10436747b715Smrg interest = calloc(1, sizeof(XkbInterestRec)); 104405b261ecSmrg if (interest) { 104505b261ecSmrg interest->dev = dev; 104605b261ecSmrg interest->client = client; 104705b261ecSmrg interest->resource = id; 104805b261ecSmrg interest->stateNotifyMask= 0; 104905b261ecSmrg interest->ctrlsNotifyMask= 0; 105005b261ecSmrg interest->namesNotifyMask= 0; 105105b261ecSmrg interest->compatNotifyMask= 0; 105205b261ecSmrg interest->bellNotifyMask= FALSE; 105305b261ecSmrg interest->accessXNotifyMask= 0; 105405b261ecSmrg interest->iStateNotifyMask= 0; 105505b261ecSmrg interest->iMapNotifyMask= 0; 105605b261ecSmrg interest->altSymsNotifyMask= 0; 105705b261ecSmrg interest->next = dev->xkb_interest; 105805b261ecSmrg dev->xkb_interest= interest; 105905b261ecSmrg return interest; 106005b261ecSmrg } 106105b261ecSmrg return NULL; 106205b261ecSmrg} 106305b261ecSmrg 106405b261ecSmrgint 106505b261ecSmrgXkbRemoveResourceClient(DevicePtr inDev,XID id) 106605b261ecSmrg{ 106705b261ecSmrgXkbSrvInfoPtr xkbi; 106805b261ecSmrgDeviceIntPtr dev = (DeviceIntPtr)inDev; 106905b261ecSmrgXkbInterestPtr interest; 107005b261ecSmrgBool found; 107105b261ecSmrgunsigned long autoCtrls,autoValues; 107205b261ecSmrgClientPtr client = NULL; 107305b261ecSmrg 10746747b715Smrg found= FALSE; 10754642e01fSmrg 10764642e01fSmrg if (!dev->key || !dev->key->xkbInfo) 10774642e01fSmrg return found; 10784642e01fSmrg 107905b261ecSmrg autoCtrls= autoValues= 0; 108005b261ecSmrg if ( dev->xkb_interest ) { 108105b261ecSmrg interest = dev->xkb_interest; 108205b261ecSmrg if (interest && (interest->resource==id)){ 108305b261ecSmrg dev->xkb_interest = interest->next; 108405b261ecSmrg autoCtrls= interest->autoCtrls; 108505b261ecSmrg autoValues= interest->autoCtrlValues; 108605b261ecSmrg client= interest->client; 10876747b715Smrg free(interest); 10886747b715Smrg found= TRUE; 108905b261ecSmrg } 109005b261ecSmrg while ((!found)&&(interest->next)) { 109105b261ecSmrg if (interest->next->resource==id) { 109205b261ecSmrg XkbInterestPtr victim = interest->next; 109305b261ecSmrg interest->next = victim->next; 109405b261ecSmrg autoCtrls= victim->autoCtrls; 109505b261ecSmrg autoValues= victim->autoCtrlValues; 109605b261ecSmrg client= victim->client; 10976747b715Smrg free(victim); 10986747b715Smrg found= TRUE; 109905b261ecSmrg } 110005b261ecSmrg interest = interest->next; 110105b261ecSmrg } 110205b261ecSmrg } 110305b261ecSmrg if (found && autoCtrls && dev->key && dev->key->xkbInfo ) { 110405b261ecSmrg XkbEventCauseRec cause; 110505b261ecSmrg 110605b261ecSmrg xkbi= dev->key->xkbInfo; 110705b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client); 110805b261ecSmrg XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause); 110905b261ecSmrg } 111005b261ecSmrg return found; 111105b261ecSmrg} 1112