1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006 |
- /************************************************************
- Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ********************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <X11/X.h>
- #include <X11/Xproto.h>
- #include "misc.h"
- #include "inputstr.h"
- #include <X11/extensions/XI.h>
- #include <xkbsrv.h>
- #include "xkb.h"
- /***====================================================================***/
- /*
- * unsigned
- * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn)
- *
- * Given a keyboard and a set of state components that have changed,
- * this function returns the indicators on the default keyboard
- * feedback that might be affected. It also reports whether or not
- * any extension devices might be affected in check_devs_rtrn.
- */
- unsigned
- XkbIndicatorsToUpdate(DeviceIntPtr dev,
- unsigned long state_changes, Bool enable_changes)
- {
- register unsigned update = 0;
- XkbSrvLedInfoPtr sli;
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- if (!sli)
- return update;
- if (state_changes & (XkbModifierStateMask | XkbGroupStateMask))
- update |= sli->usesEffective;
- if (state_changes & (XkbModifierBaseMask | XkbGroupBaseMask))
- update |= sli->usesBase;
- if (state_changes & (XkbModifierLatchMask | XkbGroupLatchMask))
- update |= sli->usesLatched;
- if (state_changes & (XkbModifierLockMask | XkbGroupLockMask))
- update |= sli->usesLocked;
- if (state_changes & XkbCompatStateMask)
- update |= sli->usesCompat;
- if (enable_changes)
- update |= sli->usesControls;
- return update;
- }
- /***====================================================================***/
- /*
- * Bool
- *XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
- *
- * Some indicators "drive" the keyboard when their state is explicitly
- * changed, as described in section 9.2.1 of the XKB protocol spec.
- * This function updates the state and controls for the keyboard
- * specified by 'xkbi' to reflect any changes that are required
- * when the indicator described by 'map' is turned on or off. The
- * extent of the changes is reported in change, which must be defined.
- */
- static Bool
- XkbApplyLEDChangeToKeyboard(XkbSrvInfoPtr xkbi,
- XkbIndicatorMapPtr map,
- Bool on, XkbChangesPtr change)
- {
- Bool ctrlChange, stateChange;
- XkbStatePtr state;
- if ((map->flags & XkbIM_NoExplicit) ||
- ((map->flags & XkbIM_LEDDrivesKB) == 0))
- return FALSE;
- ctrlChange = stateChange = FALSE;
- if (map->ctrls) {
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- unsigned old;
- old = ctrls->enabled_ctrls;
- if (on)
- ctrls->enabled_ctrls |= map->ctrls;
- else
- ctrls->enabled_ctrls &= ~map->ctrls;
- if (old != ctrls->enabled_ctrls) {
- change->ctrls.changed_ctrls = XkbControlsEnabledMask;
- change->ctrls.enabled_ctrls_changes = old ^ ctrls->enabled_ctrls;
- ctrlChange = TRUE;
- }
- }
- state = &xkbi->state;
- if ((map->groups) && ((map->which_groups & (~XkbIM_UseBase)) != 0)) {
- register int i;
- register unsigned bit, match;
- if (on)
- match = (map->groups) & XkbAllGroupsMask;
- else
- match = (~map->groups) & XkbAllGroupsMask;
- if (map->which_groups & (XkbIM_UseLocked | XkbIM_UseEffective)) {
- for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
- if (bit & match)
- break;
- }
- if (map->which_groups & XkbIM_UseLatched)
- XkbLatchGroup(xkbi->device, 0); /* unlatch group */
- state->locked_group = i;
- stateChange = TRUE;
- }
- else if (map->which_groups & (XkbIM_UseLatched | XkbIM_UseEffective)) {
- for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
- if (bit & match)
- break;
- }
- state->locked_group = 0;
- XkbLatchGroup(xkbi->device, i);
- stateChange = TRUE;
- }
- }
- if ((map->mods.mask) && ((map->which_mods & (~XkbIM_UseBase)) != 0)) {
- if (map->which_mods & (XkbIM_UseLocked | XkbIM_UseEffective)) {
- register unsigned long old;
- old = state->locked_mods;
- if (on)
- state->locked_mods |= map->mods.mask;
- else
- state->locked_mods &= ~map->mods.mask;
- if (state->locked_mods != old)
- stateChange = TRUE;
- }
- if (map->which_mods & (XkbIM_UseLatched | XkbIM_UseEffective)) {
- register unsigned long newmods;
- newmods = state->latched_mods;
- if (on)
- newmods |= map->mods.mask;
- else
- newmods &= ~map->mods.mask;
- if (newmods != state->locked_mods) {
- newmods &= map->mods.mask;
- XkbLatchModifiers(xkbi->device, map->mods.mask, newmods);
- stateChange = TRUE;
- }
- }
- }
- return stateChange || ctrlChange;
- }
- /*
- * Bool
- * ComputeAutoState(map,state,ctrls)
- *
- * This function reports the effect of applying the specified
- * indicator map given the specified state and controls, as
- * described in section 9.2 of the XKB protocol specification.
- */
- static Bool
- ComputeAutoState(XkbIndicatorMapPtr map,
- XkbStatePtr state, XkbControlsPtr ctrls)
- {
- Bool on;
- CARD8 mods, group;
- on = FALSE;
- mods = group = 0;
- if (map->which_mods & XkbIM_UseAnyMods) {
- if (map->which_mods & XkbIM_UseBase)
- mods |= state->base_mods;
- if (map->which_mods & XkbIM_UseLatched)
- mods |= state->latched_mods;
- if (map->which_mods & XkbIM_UseLocked)
- mods |= state->locked_mods;
- if (map->which_mods & XkbIM_UseEffective)
- mods |= state->mods;
- if (map->which_mods & XkbIM_UseCompat)
- mods |= state->compat_state;
- on = ((map->mods.mask & mods) != 0);
- on = on || ((mods == 0) && (map->mods.mask == 0) &&
- (map->mods.vmods == 0));
- }
- if (map->which_groups & XkbIM_UseAnyGroup) {
- if (map->which_groups & XkbIM_UseBase)
- group |= (1L << state->base_group);
- if (map->which_groups & XkbIM_UseLatched)
- group |= (1L << state->latched_group);
- if (map->which_groups & XkbIM_UseLocked)
- group |= (1L << state->locked_group);
- if (map->which_groups & XkbIM_UseEffective)
- group |= (1L << state->group);
- on = on || (((map->groups & group) != 0) || (map->groups == 0));
- }
- if (map->ctrls)
- on = on || (ctrls->enabled_ctrls & map->ctrls);
- return on;
- }
- static void
- XkbUpdateLedAutoState(DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned maps_to_check,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes, XkbEventCausePtr cause)
- {
- DeviceIntPtr kbd;
- XkbStatePtr state;
- XkbControlsPtr ctrls;
- XkbChangesRec my_changes;
- xkbExtensionDeviceNotify my_ed;
- register unsigned i, bit, affected;
- register XkbIndicatorMapPtr map;
- unsigned oldState;
- if ((maps_to_check == 0) || (sli->maps == NULL) || (sli->mapsPresent == 0))
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd = dev;
- else
- kbd = inputInfo.keyboard;
- state = &kbd->key->xkbInfo->state;
- ctrls = kbd->key->xkbInfo->desc->ctrls;
- affected = maps_to_check;
- oldState = sli->effectiveState;
- sli->autoState &= ~affected;
- for (i = 0, bit = 1; (i < XkbNumIndicators) && (affected); i++, bit <<= 1) {
- if ((affected & bit) == 0)
- continue;
- affected &= ~bit;
- map = &sli->maps[i];
- if ((!(map->flags & XkbIM_NoAutomatic)) &&
- ComputeAutoState(map, state, ctrls))
- sli->autoState |= bit;
- }
- sli->effectiveState = (sli->autoState | sli->explicitState);
- affected = sli->effectiveState ^ oldState;
- if (affected == 0)
- return;
- if (ed == NULL) {
- ed = &my_ed;
- memset((char *) ed, 0, sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason & XkbXI_IndicatorsMask) &&
- ((ed->ledClass != sli->class) || (ed->ledID != sli->id))) {
- XkbFlushLedEvents(dev, kbd, sli, ed, changes, cause);
- }
- if ((kbd == dev) && (sli->flags & XkbSLI_IsDefault)) {
- if (changes == NULL) {
- changes = &my_changes;
- memset((char *) changes, 0, sizeof(XkbChangesRec));
- }
- changes->indicators.state_changes |= affected;
- }
- ed->reason |= XkbXI_IndicatorStateMask;
- ed->ledClass = sli->class;
- ed->ledID = sli->id;
- ed->ledsDefined = sli->namesPresent | sli->mapsPresent;
- ed->ledState = sli->effectiveState;
- ed->unsupported = 0;
- ed->supported = XkbXI_AllFeaturesMask;
- if (changes != &my_changes)
- changes = NULL;
- if (ed != &my_ed)
- ed = NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev, kbd, sli, ed, changes, cause);
- return;
- }
- static void
- XkbUpdateAllDeviceIndicators(XkbChangesPtr changes, XkbEventCausePtr cause)
- {
- DeviceIntPtr edev;
- XkbSrvLedInfoPtr sli;
- for (edev = inputInfo.devices; edev != NULL; edev = edev->next) {
- if (edev->kbdfeed) {
- KbdFeedbackPtr kf;
- for (kf = edev->kbdfeed; kf != NULL; kf = kf->next) {
- if ((kf->xkb_sli == NULL) || (kf->xkb_sli->maps == NULL))
- continue;
- sli = kf->xkb_sli;
- XkbUpdateLedAutoState(edev, sli, sli->mapsPresent, NULL,
- changes, cause);
- }
- }
- if (edev->leds) {
- LedFeedbackPtr lf;
- for (lf = edev->leds; lf != NULL; lf = lf->next) {
- if ((lf->xkb_sli == NULL) || (lf->xkb_sli->maps == NULL))
- continue;
- sli = lf->xkb_sli;
- XkbUpdateLedAutoState(edev, sli, sli->mapsPresent, NULL,
- changes, cause);
- }
- }
- }
- return;
- }
- /***====================================================================***/
- /*
- * void
- * XkbSetIndicators(dev,affect,values,cause)
- *
- * Attempts to change the indicators specified in 'affect' to the
- * states specified in 'values' for the default keyboard feedback
- * on the keyboard specified by 'dev.' Attempts to change indicator
- * state might be ignored or have no affect, depending on the XKB
- * indicator map for any affected indicators, as described in section
- * 9.2 of the XKB protocol specification.
- *
- * If 'changes' is non-NULL, this function notes any changes to the
- * keyboard state, controls, or indicator state that result from this
- * attempted change. If 'changes' is NULL, this function generates
- * XKB events to report any such changes to interested clients.
- *
- * If 'cause' is non-NULL, it specifies the reason for the change,
- * as reported in some XKB events. If it is NULL, this function
- * assumes that the change is the result of a core protocol
- * ChangeKeyboardMapping request.
- */
- void
- XkbSetIndicators(DeviceIntPtr dev,
- CARD32 affect, CARD32 values, XkbEventCausePtr cause)
- {
- XkbSrvLedInfoPtr sli;
- XkbChangesRec changes;
- xkbExtensionDeviceNotify ed;
- unsigned side_affected;
- memset((char *) &changes, 0, sizeof(XkbChangesRec));
- memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify));
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- sli->explicitState &= ~affect;
- sli->explicitState |= (affect & values);
- XkbApplyLedStateChanges(dev, sli, affect, &ed, &changes, cause);
- side_affected = 0;
- if (changes.state_changes != 0)
- side_affected |=
- XkbIndicatorsToUpdate(dev, changes.state_changes, FALSE);
- if (changes.ctrls.enabled_ctrls_changes)
- side_affected |= sli->usesControls;
- if (side_affected) {
- XkbUpdateLedAutoState(dev, sli, side_affected, &ed, &changes, cause);
- affect |= side_affected;
- }
- if (changes.state_changes || changes.ctrls.enabled_ctrls_changes)
- XkbUpdateAllDeviceIndicators(NULL, cause);
- XkbFlushLedEvents(dev, dev, sli, &ed, &changes, cause);
- return;
- }
- /***====================================================================***/
- /***====================================================================***/
- /*
- * void
- * XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
- *
- * Applies the indicator maps for any indicators specified in
- * 'update' from the default keyboard feedback on the device
- * specified by 'dev.'
- *
- * If 'changes' is NULL, this function generates and XKB events
- * required to report the necessary changes, otherwise it simply
- * notes the indicators with changed state.
- *
- * If 'check_edevs' is TRUE, this function also checks the indicator
- * maps for any open extension devices that have them, and updates
- * the state of any extension device indicators as necessary.
- */
- void
- XkbUpdateIndicators(DeviceIntPtr dev,
- register CARD32 update,
- Bool check_edevs,
- XkbChangesPtr changes, XkbEventCausePtr cause)
- {
- XkbSrvLedInfoPtr sli;
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- XkbUpdateLedAutoState(dev, sli, update, NULL, changes, cause);
- if (check_edevs)
- XkbUpdateAllDeviceIndicators(changes, cause);
- return;
- }
- /***====================================================================***/
- /***====================================================================***/
- /*
- * void
- * XkbCheckIndicatorMaps(dev,sli,which)
- *
- * Updates the 'indicator accelerators' for the indicators specified
- * by 'which' in the feedback specified by 'sli.' The indicator
- * accelerators are internal to the server and are used to simplify
- * and speed up the process of figuring out which indicators might
- * be affected by a particular change in keyboard state or controls.
- */
- void
- XkbCheckIndicatorMaps(DeviceIntPtr dev, XkbSrvLedInfoPtr sli, unsigned which)
- {
- register unsigned i, bit;
- XkbIndicatorMapPtr map;
- XkbDescPtr xkb;
- if ((sli->flags & XkbSLI_HasOwnState) == 0)
- return;
- sli->usesBase &= ~which;
- sli->usesLatched &= ~which;
- sli->usesLocked &= ~which;
- sli->usesEffective &= ~which;
- sli->usesCompat &= ~which;
- sli->usesControls &= ~which;
- sli->mapsPresent &= ~which;
- xkb = dev->key->xkbInfo->desc;
- for (i = 0, bit = 1, map = sli->maps; i < XkbNumIndicators;
- i++, bit <<= 1, map++) {
- if (which & bit) {
- CARD8 what;
- if (!map || !XkbIM_InUse(map))
- continue;
- sli->mapsPresent |= bit;
- what = (map->which_mods | map->which_groups);
- if (what & XkbIM_UseBase)
- sli->usesBase |= bit;
- if (what & XkbIM_UseLatched)
- sli->usesLatched |= bit;
- if (what & XkbIM_UseLocked)
- sli->usesLocked |= bit;
- if (what & XkbIM_UseEffective)
- sli->usesEffective |= bit;
- if (what & XkbIM_UseCompat)
- sli->usesCompat |= bit;
- if (map->ctrls)
- sli->usesControls |= bit;
- map->mods.mask = map->mods.real_mods;
- if (map->mods.vmods != 0) {
- map->mods.mask |= XkbMaskForVMask(xkb, map->mods.vmods);
- }
- }
- }
- sli->usedComponents = 0;
- if (sli->usesBase)
- sli->usedComponents |= XkbModifierBaseMask | XkbGroupBaseMask;
- if (sli->usesLatched)
- sli->usedComponents |= XkbModifierLatchMask | XkbGroupLatchMask;
- if (sli->usesLocked)
- sli->usedComponents |= XkbModifierLockMask | XkbGroupLockMask;
- if (sli->usesEffective)
- sli->usedComponents |= XkbModifierStateMask | XkbGroupStateMask;
- if (sli->usesCompat)
- sli->usedComponents |= XkbCompatStateMask;
- return;
- }
- /***====================================================================***/
- /*
- * XkbSrvLedInfoPtr
- * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
- *
- * Allocates an XkbSrvLedInfoPtr for the feedback specified by either
- * 'kf' or 'lf' on the keyboard specified by 'dev.'
- *
- * If 'needed_parts' is non-zero, this function makes sure that any
- * of the parts speicified therein are allocated.
- */
- XkbSrvLedInfoPtr
- XkbAllocSrvLedInfo(DeviceIntPtr dev,
- KbdFeedbackPtr kf, LedFeedbackPtr lf, unsigned needed_parts)
- {
- XkbSrvLedInfoPtr sli;
- Bool checkAccel;
- Bool checkNames;
- sli = NULL;
- checkAccel = checkNames = FALSE;
- if ((kf != NULL) && (kf->xkb_sli == NULL)) {
- kf->xkb_sli = sli = calloc(1, sizeof(XkbSrvLedInfoRec));
- if (sli == NULL)
- return NULL; /* ALLOCATION ERROR */
- if (dev->key && dev->key->xkbInfo)
- sli->flags = XkbSLI_HasOwnState;
- else
- sli->flags = 0;
- sli->class = KbdFeedbackClass;
- sli->id = kf->ctrl.id;
- sli->fb.kf = kf;
- sli->autoState = 0;
- sli->explicitState = kf->ctrl.leds;
- sli->effectiveState = kf->ctrl.leds;
- if ((kf == dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) {
- XkbDescPtr xkb;
- xkb = dev->key->xkbInfo->desc;
- sli->flags |= XkbSLI_IsDefault;
- sli->physIndicators = xkb->indicators->phys_indicators;
- sli->names = xkb->names->indicators;
- sli->maps = xkb->indicators->maps;
- checkNames = checkAccel = TRUE;
- }
- else {
- sli->physIndicators = XkbAllIndicatorsMask;
- sli->names = NULL;
- sli->maps = NULL;
- }
- }
- else if ((kf != NULL) && ((kf->xkb_sli->flags & XkbSLI_IsDefault) != 0)) {
- XkbDescPtr xkb;
- xkb = dev->key->xkbInfo->desc;
- sli = kf->xkb_sli;
- sli->physIndicators = xkb->indicators->phys_indicators;
- if (xkb->names->indicators != sli->names) {
- checkNames = TRUE;
- sli->names = xkb->names->indicators;
- }
- if (xkb->indicators->maps != sli->maps) {
- checkAccel = TRUE;
- sli->maps = xkb->indicators->maps;
- }
- }
- else if ((lf != NULL) && (lf->xkb_sli == NULL)) {
- lf->xkb_sli = sli = calloc(1, sizeof(XkbSrvLedInfoRec));
- if (sli == NULL)
- return NULL; /* ALLOCATION ERROR */
- if (dev->key && dev->key->xkbInfo)
- sli->flags = XkbSLI_HasOwnState;
- else
- sli->flags = 0;
- sli->class = LedFeedbackClass;
- sli->id = lf->ctrl.id;
- sli->fb.lf = lf;
- sli->physIndicators = lf->ctrl.led_mask;
- sli->autoState = 0;
- sli->explicitState = lf->ctrl.led_values;
- sli->effectiveState = lf->ctrl.led_values;
- sli->maps = NULL;
- sli->names = NULL;
- }
- else
- return NULL;
- if ((sli->names == NULL) && (needed_parts & XkbXI_IndicatorNamesMask))
- sli->names = calloc(XkbNumIndicators, sizeof(Atom));
- if ((sli->maps == NULL) && (needed_parts & XkbXI_IndicatorMapsMask))
- sli->maps = calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- if (checkNames) {
- register unsigned i, bit;
- sli->namesPresent = 0;
- for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
- if (sli->names[i] != None)
- sli->namesPresent |= bit;
- }
- }
- if (checkAccel)
- XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask);
- return sli;
- }
- void
- XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
- {
- if ((sli->flags & XkbSLI_IsDefault) == 0) {
- free(sli->maps);
- free(sli->names);
- }
- sli->maps = NULL;
- sli->names = NULL;
- free(sli);
- return;
- }
- /*
- * XkbSrvLedInfoPtr
- * XkbCopySrvLedInfo(dev,src,kf,lf)
- *
- * Takes the given XkbSrvLedInfoPtr and duplicates it. A deep copy is made,
- * thus the new copy behaves like the original one and can be freed with
- * XkbFreeSrvLedInfo.
- */
- XkbSrvLedInfoPtr
- XkbCopySrvLedInfo(DeviceIntPtr from,
- XkbSrvLedInfoPtr src, KbdFeedbackPtr kf, LedFeedbackPtr lf)
- {
- XkbSrvLedInfoPtr sli_new = NULL;
- if (!src)
- goto finish;
- sli_new = calloc(1, sizeof(XkbSrvLedInfoRec));
- if (!sli_new)
- goto finish;
- memcpy(sli_new, src, sizeof(XkbSrvLedInfoRec));
- if (sli_new->class == KbdFeedbackClass)
- sli_new->fb.kf = kf;
- else
- sli_new->fb.lf = lf;
- if (!(sli_new->flags & XkbSLI_IsDefault)) {
- sli_new->names = calloc(XkbNumIndicators, sizeof(Atom));
- sli_new->maps = calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- } /* else sli_new->names/maps is pointing to
- dev->key->xkbInfo->desc->names->indicators;
- dev->key->xkbInfo->desc->names->indicators; */
- finish:
- return sli_new;
- }
- /***====================================================================***/
- /*
- * XkbSrvLedInfoPtr
- * XkbFindSrvLedInfo(dev,class,id,needed_parts)
- *
- * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id'
- * on the device specified by 'dev.' If the class and id specify
- * a valid device feedback, this function returns the existing
- * feedback or allocates a new one.
- *
- */
- XkbSrvLedInfoPtr
- XkbFindSrvLedInfo(DeviceIntPtr dev,
- unsigned class, unsigned id, unsigned needed_parts)
- {
- XkbSrvLedInfoPtr sli;
- /* optimization to check for most common case */
- if (((class == XkbDfltXIClass) && (id == XkbDfltXIId)) && (dev->kbdfeed)) {
- if (dev->kbdfeed->xkb_sli == NULL) {
- dev->kbdfeed->xkb_sli =
- XkbAllocSrvLedInfo(dev, dev->kbdfeed, NULL, needed_parts);
- }
- return dev->kbdfeed->xkb_sli;
- }
- sli = NULL;
- if (class == XkbDfltXIClass) {
- if (dev->kbdfeed)
- class = KbdFeedbackClass;
- else if (dev->leds)
- class = LedFeedbackClass;
- else
- return NULL;
- }
- if (class == KbdFeedbackClass) {
- KbdFeedbackPtr kf;
- for (kf = dev->kbdfeed; kf != NULL; kf = kf->next) {
- if ((id == XkbDfltXIId) || (id == kf->ctrl.id)) {
- if (kf->xkb_sli == NULL)
- kf->xkb_sli =
- XkbAllocSrvLedInfo(dev, kf, NULL, needed_parts);
- sli = kf->xkb_sli;
- break;
- }
- }
- }
- else if (class == LedFeedbackClass) {
- LedFeedbackPtr lf;
- for (lf = dev->leds; lf != NULL; lf = lf->next) {
- if ((id == XkbDfltXIId) || (id == lf->ctrl.id)) {
- if (lf->xkb_sli == NULL)
- lf->xkb_sli =
- XkbAllocSrvLedInfo(dev, NULL, lf, needed_parts);
- sli = lf->xkb_sli;
- break;
- }
- }
- }
- if (sli) {
- if ((sli->names == NULL) && (needed_parts & XkbXI_IndicatorNamesMask))
- sli->names = calloc(XkbNumIndicators, sizeof(Atom));
- if ((sli->maps == NULL) && (needed_parts & XkbXI_IndicatorMapsMask))
- sli->maps = calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- }
- return sli;
- }
- /***====================================================================***/
- void
- XkbFlushLedEvents(DeviceIntPtr dev,
- DeviceIntPtr kbd,
- XkbSrvLedInfoPtr sli,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes, XkbEventCausePtr cause)
- {
- if (changes) {
- if (changes->indicators.state_changes)
- XkbDDXUpdateDeviceIndicators(dev, sli, sli->effectiveState);
- XkbSendNotification(kbd, changes, cause);
- memset((char *) changes, 0, sizeof(XkbChangesRec));
- if (XkbAX_NeedFeedback
- (kbd->key->xkbInfo->desc->ctrls, XkbAX_IndicatorFBMask)) {
- if (sli->effectiveState)
- /* it appears that the which parameter is not used */
- XkbDDXAccessXBeep(dev, _BEEP_LED_ON, XkbAccessXFeedbackMask);
- else
- XkbDDXAccessXBeep(dev, _BEEP_LED_OFF, XkbAccessXFeedbackMask);
- }
- }
- if (ed) {
- if (ed->reason) {
- if ((dev != kbd) && (ed->reason & XkbXI_IndicatorStateMask))
- XkbDDXUpdateDeviceIndicators(dev, sli, sli->effectiveState);
- XkbSendExtensionDeviceNotify(dev, cause->client, ed);
- }
- memset((char *) ed, 0, sizeof(XkbExtensionDeviceNotify));
- }
- return;
- }
- /***====================================================================***/
- void
- XkbApplyLedNameChanges(DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_names,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes, XkbEventCausePtr cause)
- {
- DeviceIntPtr kbd;
- XkbChangesRec my_changes;
- xkbExtensionDeviceNotify my_ed;
- if (changed_names == 0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd = dev;
- else
- kbd = inputInfo.keyboard;
- if (ed == NULL) {
- ed = &my_ed;
- memset((char *) ed, 0, sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason & XkbXI_IndicatorsMask) &&
- ((ed->ledClass != sli->class) || (ed->ledID != sli->id))) {
- XkbFlushLedEvents(dev, kbd, sli, ed, changes, cause);
- }
- if ((kbd == dev) && (sli->flags & XkbSLI_IsDefault)) {
- if (changes == NULL) {
- changes = &my_changes;
- memset((char *) changes, 0, sizeof(XkbChangesRec));
- }
- changes->names.changed |= XkbIndicatorNamesMask;
- changes->names.changed_indicators |= changed_names;
- }
- ed->reason |= XkbXI_IndicatorNamesMask;
- ed->ledClass = sli->class;
- ed->ledID = sli->id;
- ed->ledsDefined = sli->namesPresent | sli->mapsPresent;
- ed->ledState = sli->effectiveState;
- ed->unsupported = 0;
- ed->supported = XkbXI_AllFeaturesMask;
- if (changes != &my_changes)
- changes = NULL;
- if (ed != &my_ed)
- ed = NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev, kbd, sli, ed, changes, cause);
- return;
- }
- /***====================================================================***/
- /*
- * void
- * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause)
- *
- * Handles all of the secondary effects of the changes to the
- * feedback specified by 'sli' on the device specified by 'dev.'
- *
- * If 'changed_maps' specifies any indicators, this function generates
- * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify
- * events to report the changes, and recalculates the effective
- * state of each indicator with a changed map. If any indicators
- * change state, the server generates XkbExtensionDeviceNotify and
- * XkbIndicatorStateNotify events as appropriate.
- *
- * If 'changes' is non-NULL, this function updates it to reflect
- * any changes to the keyboard state or controls or to the 'core'
- * indicator names, maps, or state. If 'changes' is NULL, this
- * function generates XKB events as needed to report the changes.
- * If 'dev' is not a keyboard device, any changes are reported
- * for the core keyboard.
- *
- * The 'cause' specifies the reason for the event (key event or
- * request) for the change, as reported in some XKB events.
- */
- void
- XkbApplyLedMapChanges(DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_maps,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes, XkbEventCausePtr cause)
- {
- DeviceIntPtr kbd;
- XkbChangesRec my_changes;
- xkbExtensionDeviceNotify my_ed;
- if (changed_maps == 0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd = dev;
- else
- kbd = inputInfo.keyboard;
- if (ed == NULL) {
- ed = &my_ed;
- memset((char *) ed, 0, sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason & XkbXI_IndicatorsMask) &&
- ((ed->ledClass != sli->class) || (ed->ledID != sli->id))) {
- XkbFlushLedEvents(dev, kbd, sli, ed, changes, cause);
- }
- if ((kbd == dev) && (sli->flags & XkbSLI_IsDefault)) {
- if (changes == NULL) {
- changes = &my_changes;
- memset((char *) changes, 0, sizeof(XkbChangesRec));
- }
- changes->indicators.map_changes |= changed_maps;
- }
- XkbCheckIndicatorMaps(dev, sli, changed_maps);
- ed->reason |= XkbXI_IndicatorMapsMask;
- ed->ledClass = sli->class;
- ed->ledID = sli->id;
- ed->ledsDefined = sli->namesPresent | sli->mapsPresent;
- ed->ledState = sli->effectiveState;
- ed->unsupported = 0;
- ed->supported = XkbXI_AllFeaturesMask;
- XkbUpdateLedAutoState(dev, sli, changed_maps, ed, changes, cause);
- if (changes != &my_changes)
- changes = NULL;
- if (ed != &my_ed)
- ed = NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev, kbd, sli, ed, changes, cause);
- return;
- }
- /***====================================================================***/
- void
- XkbApplyLedStateChanges(DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_leds,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes, XkbEventCausePtr cause)
- {
- XkbSrvInfoPtr xkbi;
- DeviceIntPtr kbd;
- XkbChangesRec my_changes;
- xkbExtensionDeviceNotify my_ed;
- register unsigned i, bit, affected;
- XkbIndicatorMapPtr map;
- unsigned oldState;
- Bool kb_changed;
- if (changed_leds == 0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd = dev;
- else
- kbd = inputInfo.keyboard;
- xkbi = kbd->key->xkbInfo;
- if (changes == NULL) {
- changes = &my_changes;
- memset((char *) changes, 0, sizeof(XkbChangesRec));
- }
- kb_changed = FALSE;
- affected = changed_leds;
- oldState = sli->effectiveState;
- for (i = 0, bit = 1; (i < XkbNumIndicators) && (affected); i++, bit <<= 1) {
- if ((affected & bit) == 0)
- continue;
- affected &= ~bit;
- map = &sli->maps[i];
- if (map->flags & XkbIM_NoExplicit) {
- sli->explicitState &= ~bit;
- continue;
- }
- if (map->flags & XkbIM_LEDDrivesKB) {
- Bool on = ((sli->explicitState & bit) != 0);
- if (XkbApplyLEDChangeToKeyboard(xkbi, map, on, changes))
- kb_changed = TRUE;
- }
- }
- sli->effectiveState = (sli->autoState | sli->explicitState);
- affected = sli->effectiveState ^ oldState;
- if (ed == NULL) {
- ed = &my_ed;
- memset((char *) ed, 0, sizeof(xkbExtensionDeviceNotify));
- }
- else if (affected && (ed->reason & XkbXI_IndicatorsMask) &&
- ((ed->ledClass != sli->class) || (ed->ledID != sli->id))) {
- XkbFlushLedEvents(dev, kbd, sli, ed, changes, cause);
- }
- if ((kbd == dev) && (sli->flags & XkbSLI_IsDefault))
- changes->indicators.state_changes |= affected;
- if (affected) {
- ed->reason |= XkbXI_IndicatorStateMask;
- ed->ledClass = sli->class;
- ed->ledID = sli->id;
- ed->ledsDefined = sli->namesPresent | sli->mapsPresent;
- ed->ledState = sli->effectiveState;
- ed->unsupported = 0;
- ed->supported = XkbXI_AllFeaturesMask;
- }
- if (kb_changed) {
- XkbComputeDerivedState(kbd->key->xkbInfo);
- XkbUpdateLedAutoState(dev, sli, sli->mapsPresent, ed, changes, cause);
- }
- if (changes != &my_changes)
- changes = NULL;
- if (ed != &my_ed)
- ed = NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev, kbd, sli, ed, changes, cause);
- if (kb_changed)
- XkbUpdateAllDeviceIndicators(NULL, cause);
- return;
- }
|