diff options
author | Sergey Udaltsov <svu@gnome.org> | 2004-11-02 23:23:50 +0000 |
---|---|---|
committer | Sergey Udaltsov <svu@gnome.org> | 2004-11-02 23:23:50 +0000 |
commit | 2ed6e54927603ae8c3fbbce81d8fdaf17366eccc (patch) | |
tree | 1dfca2d56e317ccbe993f72f4b4d538d2fc43af2 | |
parent | 4d431bbaae40a5a99988c4d8e7d5d33dc717710f (diff) | |
download | libxklavier-2ed6e54927603ae8c3fbbce81d8fdaf17366eccc.tar.gz |
added missing file
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | libxklavier/xklavier_evt_xkb.c | 187 |
2 files changed, 188 insertions, 0 deletions
@@ -8,6 +8,7 @@ libxklavier/xklavier_config_xkb.c, libxklavier/xklavier_dump.c, libxklavier/xklavier_evt.c, + libxklavier/xklavier_evt_xkb.c, libxklavier/xklavier_private.h, libxklavier/xklavier_private_xkb.h, libxklavier/xklavier_props.c, diff --git a/libxklavier/xklavier_evt_xkb.c b/libxklavier/xklavier_evt_xkb.c new file mode 100644 index 0000000..805b845 --- /dev/null +++ b/libxklavier/xklavier_evt_xkb.c @@ -0,0 +1,187 @@ +#include <time.h> + +#include <X11/Xatom.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xlibint.h> + +#include "xklavier_private.h" +#include "xklavier_private_xkb.h" + +#ifdef XKB_HEADERS_PRESENT +/** + * Some common functionality for Xkb handler + */ +static void _XklStdXkbHandler( int grp, XklStateChange changeType, unsigned inds, + Bool setInds ) +{ + Window focused, focusedApp; + XklState oldState; + int revert; + Bool haveState; + Bool setGroup = changeType == GROUP_CHANGED; + + XGetInputFocus( _xklDpy, &focused, &revert ); + + if( ( focused == None ) || ( focused == PointerRoot ) ) + { + XklDebug( 160, "Something with focus: " WINID_FORMAT "\n", focused ); + return; + } + + if( !_XklGetAppWindow( focused, &focusedApp ) ) + focusedApp = _xklCurClient; //what else can I do + + XklDebug( 150, "Focused window: " WINID_FORMAT ", '%s'\n", focusedApp, + _XklGetDebugWindowTitle( focusedApp ) ); + XklDebug( 150, "CurClient: " WINID_FORMAT ", '%s'\n", _xklCurClient, + _XklGetDebugWindowTitle( _xklCurClient ) ); + + if( focusedApp != _xklCurClient ) + { + if ( !_XklGetAppState( focusedApp, &oldState ) ) + { + _XklUpdateCurState( grp, inds, + "Updating the state from new focused window" ); + _XklAddAppWindow( focusedApp, ( Window ) NULL, False, &_xklCurState ); + } + else + { + grp = oldState.group; + inds = oldState.indicators; + } + _xklCurClient = focusedApp; + XklDebug( 160, "CurClient:changed to " WINID_FORMAT ", '%s'\n", + _xklCurClient, _XklGetDebugWindowTitle( _xklCurClient ) ); + } + // if the window already has this this state - we are just restoring it! + // (see the second parameter of stateCallback + haveState = _XklGetAppState( _xklCurClient, &oldState ); + + if( setGroup || haveState ) + { + _XklUpdateCurState( setGroup ? grp : oldState.group, + setInds ? inds : oldState.indicators, + "Restoring the state from the window" ); + } + + if( haveState ) + _XklTryCallStateCallback( changeType, &oldState ); + + _XklSaveAppState( _xklCurClient, &_xklCurState ); +} +#endif + +/** + * XKB event handler + */ +int _XklXkbEventHandler( XEvent *xev ) +{ +#ifdef XKB_HEADERS_PRESENT + int i; + unsigned bit; + unsigned inds; + XkbEvent *kev = (XkbEvent*)xev; + + if( xev->type != _xklXkbEventType ) + return 0; + + XklDebug( 150, "Xkb event detected\n" ); + + switch ( kev->any.xkb_type ) + { + case XkbStateNotify: +#define GROUP_CHANGE_MASK \ + ( XkbGroupStateMask | XkbGroupBaseMask | XkbGroupLatchMask | XkbGroupLockMask ) + + XklDebug( 150, + "XkbStateNotify detected, changes: %X/(mask %X), new group %d\n", + kev->state.changed, GROUP_CHANGE_MASK, + kev->state.locked_group ); + + if( kev->state.changed & GROUP_CHANGE_MASK ) + _XklStdXkbHandler( kev->state.locked_group, GROUP_CHANGED, 0, False ); + else + { + XklDebug( 200, + "This type of state notification is not regarding groups\n" ); + if ( kev->state.locked_group != _xklCurState.group ) + XklDebug( 0, + "ATTENTION! Currently cached group %d is not equal to the current group from the event: %d\n!", + _xklCurState.group, + kev->state.locked_group ); + } + + break; + + case XkbIndicatorStateNotify: + + XklDebug( 150, "XkbIndicatorStateNotify\n" ); + + inds = _xklCurState.indicators; + + ForPhysIndicators( i, bit ) if( kev->indicators.changed & bit ) + { + if( kev->indicators.state & bit ) + inds |= bit; + else + inds &= ~bit; + } + + _XklStdXkbHandler( 0, INDICATORS_CHANGED, inds, True ); + break; + + case XkbIndicatorMapNotify: + XklDebug( 150, "XkbIndicatorMapNotify\n" ); + _XklFreeAllInfo( ); + _XklLoadAllInfo( ); + break; + + case XkbControlsNotify: + XklDebug( 150, "XkbControlsNotify\n" ); + _XklFreeAllInfo( ); + _XklLoadAllInfo( ); + break; + + case XkbNamesNotify: + XklDebug( 150, "XkbNamesNotify\n" ); + _XklFreeAllInfo( ); + _XklLoadAllInfo( ); + break; + + case XkbNewKeyboardNotify: + XklDebug( 150, "XkbNewKeyboardNotify\n" ); + _XklFreeAllInfo( ); + _XklLoadAllInfo( ); + break; + + default: + XklDebug( 150, "Unknown xkb event %d\n", kev->any.xkb_type ); + return 0; + } + return 1; +#else + return 0; +#endif +} + +void _XklXkbSetIndicators( const XklState *windowState ) +{ +#ifdef XKB_HEADERS_PRESENT + int i; + unsigned bit; + + ForPhysIndicators( i, + bit ) if( _xklXkb->names->indicators[i] != None ) + { + Bool status; + status = _XklSetIndicator( i, + ( windowState->indicators & bit ) != 0 ); + XklDebug( 150, "Set indicator \"%s\"/%d to %d: %d\n", + _xklIndicatorNames[i], + _xklXkb->names->indicators[i], + windowState->indicators & bit, + status ); + } +#endif +} |