summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Udaltsov <svu@gnome.org>2004-11-02 23:23:50 +0000
committerSergey Udaltsov <svu@gnome.org>2004-11-02 23:23:50 +0000
commit2ed6e54927603ae8c3fbbce81d8fdaf17366eccc (patch)
tree1dfca2d56e317ccbe993f72f4b4d538d2fc43af2
parent4d431bbaae40a5a99988c4d8e7d5d33dc717710f (diff)
downloadlibxklavier-2ed6e54927603ae8c3fbbce81d8fdaf17366eccc.tar.gz
added missing file
-rw-r--r--ChangeLog1
-rw-r--r--libxklavier/xklavier_evt_xkb.c187
2 files changed, 188 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 6b87a15..08a213e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
+}