summaryrefslogtreecommitdiff
path: root/libxklavier/xklavier_xkb.c
diff options
context:
space:
mode:
authorSergey Udaltsov <svu@gnome.org>2006-03-12 04:20:01 +0000
committerSergey Udaltsov <svu@gnome.org>2006-03-12 04:20:01 +0000
commit2c88cc80147b72eba939d6358939ef59d403c34e (patch)
treeb6b145f6d50e1f4bba8145bef5963aee8a5f3180 /libxklavier/xklavier_xkb.c
parentd7bc98fb5f9d55c37a08ceeedbc87cb70ee6f133 (diff)
downloadlibxklavier-2c88cc80147b72eba939d6358939ef59d403c34e.tar.gz
branching 2.x, merging GLIBing to HEAD
Diffstat (limited to 'libxklavier/xklavier_xkb.c')
-rw-r--r--libxklavier/xklavier_xkb.c936
1 files changed, 501 insertions, 435 deletions
diff --git a/libxklavier/xklavier_xkb.c b/libxklavier/xklavier_xkb.c
index c2b3e60..ebb473a 100644
--- a/libxklavier/xklavier_xkb.c
+++ b/libxklavier/xklavier_xkb.c
@@ -4,31 +4,25 @@
#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
-XkbDescPtr _xklXkb;
-static XkbDescPtr precachedXkb = NULL;
-
-char *_xklIndicatorNames[XkbNumIndicators];
-
-int _xklXkbEventType, _xklXkbError;
-
-static char *groupNames[XkbNumKbdGroups];
-
-const char **_XklXkbGetGroupNames( void )
+const gchar **
+xkl_xkb_get_groups_names(XklEngine * engine)
{
- return ( const char ** ) groupNames;
+ return (const gchar **) xkl_engine_backend(engine, XklXkb,
+ group_names);
}
-int _XklXkbPauseListen( void )
+gint
+xkl_xkb_pause_listen(XklEngine * engine)
{
- XkbSelectEvents( _xklDpy, XkbUseCoreKbd, XkbAllEventsMask, 0 );
-/* XkbSelectEventDetails( _xklDpy,
+ XkbSelectEvents(xkl_engine_get_display(engine), XkbUseCoreKbd,
+ XkbAllEventsMask, 0);
+/* XkbSelectEventDetails( xkl_display,
XkbUseCoreKbd,
XkbStateNotify,
0,
@@ -36,12 +30,13 @@ int _XklXkbPauseListen( void )
!!_XklSelectInput( _xklRootWindow, 0 );
*/
- return 0;
+ return 0;
}
-int _XklXkbResumeListen( void )
+gint
+xkl_xkb_resume_listen(XklEngine * engine)
{
- /* What events we want */
+ /* What events we want */
#define XKB_EVT_MASK \
(XkbStateNotifyMask| \
XkbNamesNotifyMask| \
@@ -50,35 +45,43 @@ int _XklXkbResumeListen( void )
XkbIndicatorMapNotifyMask| \
XkbNewKeyboardNotifyMask)
- XkbSelectEvents( _xklDpy, XkbUseCoreKbd, XKB_EVT_MASK, XKB_EVT_MASK );
+ Display *display = xkl_engine_get_display(engine);
+ XkbSelectEvents(display, XkbUseCoreKbd, XKB_EVT_MASK,
+ XKB_EVT_MASK);
#define XKB_STATE_EVT_DTL_MASK \
(XkbGroupStateMask)
- XkbSelectEventDetails( _xklDpy,
- XkbUseCoreKbd,
- XkbStateNotify,
- XKB_STATE_EVT_DTL_MASK, XKB_STATE_EVT_DTL_MASK );
+ XkbSelectEventDetails(display,
+ XkbUseCoreKbd,
+ XkbStateNotify,
+ XKB_STATE_EVT_DTL_MASK,
+ XKB_STATE_EVT_DTL_MASK);
#define XKB_NAMES_EVT_DTL_MASK \
(XkbGroupNamesMask|XkbIndicatorNamesMask)
- XkbSelectEventDetails( _xklDpy,
- XkbUseCoreKbd,
- XkbNamesNotify,
- XKB_NAMES_EVT_DTL_MASK, XKB_NAMES_EVT_DTL_MASK );
- return 0;
+ XkbSelectEventDetails(display,
+ XkbUseCoreKbd,
+ XkbNamesNotify,
+ XKB_NAMES_EVT_DTL_MASK,
+ XKB_NAMES_EVT_DTL_MASK);
+ return 0;
}
-unsigned _XklXkbGetMaxNumGroups( void )
+guint
+xkl_xkb_get_max_num_groups(XklEngine * engine)
{
- return xklVTable->features & XKLF_MULTIPLE_LAYOUTS_SUPPORTED ?
- XkbNumKbdGroups : 1;
+ return xkl_engine_priv(engine,
+ features) & XKLF_MULTIPLE_LAYOUTS_SUPPORTED
+ ? XkbNumKbdGroups : 1;
}
-unsigned _XklXkbGetNumGroups( void )
+guint
+xkl_xkb_get_num_groups(XklEngine * engine)
{
- return _xklXkb->ctrls->num_groups;
+ return xkl_engine_backend(engine, XklXkb,
+ cached_desc)->ctrls->num_groups;
}
#define KBD_MASK \
@@ -88,448 +91,511 @@ unsigned _XklXkbGetNumGroups( void )
#define NAMES_MASK \
( XkbGroupNamesMask | XkbIndicatorNamesMask )
-void _XklXkbFreeAllInfo( void )
+void
+xkl_xkb_free_all_info(XklEngine * engine)
{
- int i;
- char **pi = _xklIndicatorNames;
- for( i = 0; i < XkbNumIndicators; i++, pi++ )
- {
- /* only free non-empty ones */
- if( *pi && **pi )
- XFree( *pi );
- }
- if( _xklXkb != NULL )
- {
- int i;
- char **groupName = groupNames;
- for( i = _xklXkb->ctrls->num_groups; --i >= 0; groupName++ )
- if( *groupName )
- {
- XFree( *groupName );
- *groupName = NULL;
- }
- XkbFreeKeyboard( _xklXkb, XkbAllComponentsMask, True );
- _xklXkb = NULL;
- }
-
- /* just in case - never actually happens...*/
- if( precachedXkb != NULL )
- {
- XkbFreeKeyboard( precachedXkb, XkbAllComponentsMask, True );
- precachedXkb = NULL;
- }
+ gint i;
+ gchar **pi = xkl_engine_backend(engine, XklXkb, indicator_names);
+ for (i = 0; i < XkbNumIndicators; i++, pi++) {
+ /* only free non-empty ones */
+ if (*pi && **pi)
+ XFree(*pi);
+ }
+ XkbDescPtr desc = xkl_engine_backend(engine, XklXkb, cached_desc);
+ if (desc != NULL) {
+ int i;
+ char **group_name =
+ xkl_engine_backend(engine, XklXkb, group_names);
+ for (i = desc->ctrls->num_groups; --i >= 0; group_name++)
+ if (*group_name) {
+ XFree(*group_name);
+ *group_name = NULL;
+ }
+ XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
+ xkl_engine_backend(engine, XklXkb, cached_desc) = NULL;
+ }
+
+ /* just in case - never actually happens... */
+ desc = xkl_engine_backend(engine, XklXkb, actual_desc);
+ if (desc != NULL) {
+ XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
+ xkl_engine_backend(engine, XklXkb, actual_desc) = NULL;
+ }
}
-static Bool _XklXkbLoadPrecachedXkb( void )
+static gboolean
+xkl_xkb_load_actual_desc(XklEngine * engine)
{
- Bool rv = False;
- Status status;
-
- precachedXkb = XkbGetMap( _xklDpy, KBD_MASK, XkbUseCoreKbd );
- if( precachedXkb != NULL )
- {
- rv = Success == ( status = XkbGetControls( _xklDpy, CTRLS_MASK, precachedXkb ) ) &&
- Success == ( status = XkbGetNames( _xklDpy, NAMES_MASK, precachedXkb ) ) &&
- Success == ( status = XkbGetIndicatorMap( _xklDpy, XkbAllIndicatorsMask, precachedXkb ) );
- if( !rv )
- {
- _xklLastErrorMsg = "Could not load controls/names/indicators";
- XklDebug( 0, "%s: %d\n", _xklLastErrorMsg, status );
- XkbFreeKeyboard( precachedXkb, XkbAllComponentsMask, True );
-
- }
- }
- return rv;
+ gboolean rv = FALSE;
+ Status status;
+
+ Display *display = xkl_engine_get_display(engine);
+ XkbDescPtr desc = XkbGetMap(display, KBD_MASK, XkbUseCoreKbd);
+ xkl_engine_backend(engine, XklXkb, actual_desc) = desc;
+ if (desc != NULL) {
+ rv = Success == (status = XkbGetControls(display,
+ CTRLS_MASK,
+ desc)) &&
+ Success == (status = XkbGetNames(display,
+ NAMES_MASK,
+ desc)) &&
+ Success == (status = XkbGetIndicatorMap(display,
+ XkbAllIndicatorsMask,
+ desc));
+ if (!rv) {
+ xkl_last_error_message =
+ "Could not load controls/names/indicators";
+ xkl_debug(0, "%s: %d\n",
+ xkl_last_error_message, status);
+ XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
+ xkl_engine_backend(engine, XklXkb, actual_desc) =
+ NULL;
+ }
+ }
+ return rv;
}
-Bool _XklXkbIfCachedInfoEqualsActual( void )
+gboolean
+xkl_xkb_if_cached_info_equals_actual(XklEngine * engine)
{
- int i;
- Atom *pa1, *pa2;
- Bool rv = False;
-
- if( _XklXkbLoadPrecachedXkb() )
- {
- /* First, compare the number of groups */
- if( _xklXkb->ctrls->num_groups == precachedXkb->ctrls->num_groups )
- {
- /* Then, compare group names, just atoms */
- pa1 = _xklXkb->names->groups;
- pa2 = precachedXkb->names->groups;
- for( i = _xklXkb->ctrls->num_groups; --i >= 0; pa1++, pa2++ )
- if( *pa1 != *pa2 )
- break;
-
- /* Then, compare indicator names, just atoms */
- if( i < 0 )
- {
- pa1 = _xklXkb->names->indicators;
- pa2 = precachedXkb->names->indicators;
- for( i = XkbNumIndicators; --i >= 0; pa1++, pa2++ )
- if( *pa1 != *pa2 )
- break;
- rv = i < 0;
- }
- }
- /**
+ gint i;
+ Atom *pa1, *pa2;
+ gboolean rv = FALSE;
+
+ if (xkl_xkb_load_actual_desc(engine)) {
+ /* First, compare the number of groups */
+ XkbDescPtr cached =
+ xkl_engine_backend(engine, XklXkb, cached_desc);
+ XkbDescPtr actual =
+ xkl_engine_backend(engine, XklXkb, actual_desc);
+
+ if (cached->ctrls->num_groups == actual->ctrls->num_groups) {
+ /* Then, compare group names, just atoms */
+ pa1 = cached->names->groups;
+ pa2 = actual->names->groups;
+ for (i = cached->ctrls->num_groups; --i >= 0;
+ pa1++, pa2++)
+ if (*pa1 != *pa2)
+ break;
+
+ /* Then, compare indicator names, just atoms */
+ if (i < 0) {
+ pa1 = cached->names->indicators;
+ pa2 = actual->names->indicators;
+ for (i = XkbNumIndicators; --i >= 0;
+ pa1++, pa2++)
+ if (*pa1 != *pa2)
+ break;
+ rv = i < 0;
+ }
+ }
+ /*
* in case of failure, reuse in _XklXkbLoadAllInfo
* in case of success - free it
*/
- if( rv )
- {
- XkbFreeKeyboard( precachedXkb, XkbAllComponentsMask, True );
- precachedXkb = NULL;
- }
- } else
- {
- XklDebug( 0, "Could not load the XkbDescPtr for comparison\n" );
- }
- return rv;
+ if (rv) {
+ XkbFreeKeyboard(actual,
+ XkbAllComponentsMask, True);
+ xkl_engine_backend(engine, XklXkb, actual_desc) =
+ NULL;
+ }
+ } else {
+ xkl_debug(0,
+ "Could not load the XkbDescPtr for comparison\n");
+ }
+ return rv;
}
-/**
+/*
* Load some XKB parameters
*/
-Bool _XklXkbLoadAllInfo( void )
+gboolean
+xkl_xkb_load_all_info(XklEngine * engine)
{
- int i;
- Atom *pa;
- char **groupName;
- char **pi = _xklIndicatorNames;
-
- if ( precachedXkb == NULL )
- if ( !_XklXkbLoadPrecachedXkb() )
- {
- _xklLastErrorMsg = "Could not load keyboard";
- return False;
- }
-
- /* take it from the cache (in most cases LoadAll is called from ResetAll which in turn ...)*/
- _xklXkb = precachedXkb;
- precachedXkb = NULL;
-
- /* First, output the number of the groups */
- XklDebug( 200, "found %d groups\n", _xklXkb->ctrls->num_groups );
-
- /* Then, cache (and output) the names of the groups */
- pa = _xklXkb->names->groups;
- groupName = groupNames;
- for( i = _xklXkb->ctrls->num_groups; --i >= 0; pa++, groupName++ )
- {
- *groupName = XGetAtomName( _xklDpy,
- *pa == None ?
- XInternAtom( _xklDpy, "-", False ) : *pa );
- XklDebug( 200, "group %d has name [%s]\n", i, *groupName );
- }
-
- _xklLastErrorCode =
- XkbGetIndicatorMap( _xklDpy, XkbAllIndicatorsMask, _xklXkb );
-
- if( _xklLastErrorCode != Success )
- {
- _xklLastErrorMsg = "Could not load indicator map";
- return False;
- }
-
- /* Then, cache (and output) the names of the indicators */
- pa = _xklXkb->names->indicators;
- for( i = XkbNumIndicators; --i >= 0; pi++, pa++ )
- {
- Atom a = *pa;
- if( a != None )
- *pi = XGetAtomName( _xklDpy, a );
- else
- *pi = "";
-
- XklDebug( 200, "Indicator[%d] is %s\n", i, *pi );
- }
-
- XklDebug( 200, "Real indicators are %X\n",
- _xklXkb->indicators->phys_indicators );
-
- if( _xklConfigCallback != NULL )
- ( *_xklConfigCallback ) ( _xklConfigCallbackData );
- return True;
+ gint i;
+ Atom *pa;
+ gchar **group_name;
+ gchar **pi = xkl_engine_backend(engine, XklXkb, indicator_names);
+ Display *display = xkl_engine_get_display(engine);
+ XkbDescPtr actual =
+ xkl_engine_backend(engine, XklXkb, actual_desc);
+
+ if (actual == NULL)
+ if (!xkl_xkb_load_actual_desc(engine)) {
+ xkl_last_error_message = "Could not load keyboard";
+ return FALSE;
+ }
+
+ /* take it from the cache (in most cases LoadAll is called from ResetAll which in turn ...) */
+ XkbDescPtr cached = actual =
+ xkl_engine_backend(engine, XklXkb, actual_desc);
+ xkl_engine_backend(engine, XklXkb, cached_desc) =
+ xkl_engine_backend(engine, XklXkb, actual_desc);
+ xkl_engine_backend(engine, XklXkb, actual_desc) = NULL;
+
+ /* First, output the number of the groups */
+ xkl_debug(200, "found %d groups\n", cached->ctrls->num_groups);
+
+ /* Then, cache (and output) the names of the groups */
+ pa = cached->names->groups;
+ group_name = xkl_engine_backend(engine, XklXkb, group_names);
+ for (i = cached->ctrls->num_groups; --i >= 0; pa++, group_name++) {
+ *group_name =
+ XGetAtomName(display,
+ *pa == None ? XInternAtom(display,
+ "-",
+ False) : *pa);
+ xkl_debug(200, "Group %d has name [%s]\n", i, *group_name);
+ }
+
+ xkl_engine_priv(engine, last_error_code) =
+ XkbGetIndicatorMap(display, XkbAllIndicatorsMask, cached);
+
+ if (xkl_engine_priv(engine, last_error_code) != Success) {
+ xkl_last_error_message = "Could not load indicator map";
+ return FALSE;
+ }
+
+ /* Then, cache (and output) the names of the indicators */
+ pa = cached->names->indicators;
+ for (i = XkbNumIndicators; --i >= 0; pi++, pa++) {
+ Atom a = *pa;
+ if (a != None)
+ *pi = XGetAtomName(display, a);
+ else
+ *pi = "";
+
+ xkl_debug(200, "Indicator[%d] is %s\n", i, *pi);
+ }
+
+ xkl_debug(200, "Real indicators are %X\n",
+ cached->indicators->phys_indicators);
+
+ g_signal_emit_by_name(engine, "X-config-changed");
+
+ return TRUE;
}
-void _XklXkbLockGroup( int group )
+void
+xkl_xkb_lock_group(XklEngine * engine, gint group)
{
- XklDebug( 100, "Posted request for change the group to %d ##\n", group );
- XkbLockGroup( _xklDpy, XkbUseCoreKbd, group );
- XSync( _xklDpy, False );
+ Display *display = xkl_engine_get_display(engine);
+ xkl_debug(100, "Posted request for change the group to %d ##\n",
+ group);
+ XkbLockGroup(display, XkbUseCoreKbd, group);
+ XSync(display, False);
}
-/**
+/*
* Updates current internal state from X state
*/
-void _XklXkbGetRealState( XklState * curState_return )
+void
+xkl_xkb_get_server_state(XklEngine * engine, XklState * current_state_out)
{
- XkbStateRec state;
-
- curState_return->group = 0;
- if( Success == XkbGetState( _xklDpy, XkbUseCoreKbd, &state ) )
- curState_return->group = state.locked_group;
-
- if( Success ==
- XkbGetIndicatorState( _xklDpy, XkbUseCoreKbd,
- &curState_return->indicators ) )
- curState_return->indicators &= _xklXkb->indicators->phys_indicators;
- else
- curState_return->indicators = 0;
+ XkbStateRec state;
+ Display *display = xkl_engine_get_display(engine);
+
+ current_state_out->group = 0;
+ if (Success == XkbGetState(display, XkbUseCoreKbd, &state))
+ current_state_out->group = state.locked_group;
+
+ if (Success ==
+ XkbGetIndicatorState(display, XkbUseCoreKbd,
+ &current_state_out->indicators))
+ current_state_out->indicators &=
+ xkl_engine_backend(engine, XklXkb,
+ cached_desc)->indicators->
+ phys_indicators;
+ else
+ current_state_out->indicators = 0;
}
/*
* Actually taken from mxkbledpanel, valueChangedProc
*/
-Bool _XklSetIndicator( int indicatorNum, Bool set )
+gboolean
+xkl_xkb_set_indicator(XklEngine * engine, gint indicator_num, gboolean set)
{
- XkbIndicatorMapPtr map;
-
- map = _xklXkb->indicators->maps + indicatorNum;
-
- /* The 'flags' field tells whether this indicator is automatic
- * (XkbIM_NoExplicit - 0x80), explicit (XkbIM_NoAutomatic - 0x40),
- * or neither (both - 0xC0).
- *
- * If NoAutomatic is set, the server ignores the rest of the
- * fields in the indicator map (i.e. it disables automatic control
- * of the LED). If NoExplicit is set, the server prevents clients
- * from explicitly changing the value of the LED (using the core
- * protocol *or* XKB). If NoAutomatic *and* NoExplicit are set,
- * the LED cannot be changed (unless you change the map first).
- * If neither NoAutomatic nor NoExplicit are set, the server will
- * change the LED according to the indicator map, but clients can
- * override that (until the next automatic change) using the core
- * protocol or XKB.
- */
- switch ( map->flags & ( XkbIM_NoExplicit | XkbIM_NoAutomatic ) )
- {
- case XkbIM_NoExplicit | XkbIM_NoAutomatic:
- {
- /* Can do nothing. Just ignore the indicator */
- return True;
- }
-
- case XkbIM_NoAutomatic:
- {
- if( _xklXkb->names->indicators[indicatorNum] != None )
- XkbSetNamedIndicator( _xklDpy, XkbUseCoreKbd,
- _xklXkb->names->indicators[indicatorNum], set,
- False, NULL );
- else
- {
- XKeyboardControl xkc;
- xkc.led = indicatorNum;
- xkc.led_mode = set ? LedModeOn : LedModeOff;
- XChangeKeyboardControl( _xklDpy, KBLed | KBLedMode, &xkc );
- XSync( _xklDpy, 0 );
- }
-
- return True;
- }
-
- case XkbIM_NoExplicit:
- break;
- }
-
- /* The 'ctrls' field tells what controls tell this indicator to
- * to turn on: RepeatKeys (0x1), SlowKeys (0x2), BounceKeys (0x4),
- * StickyKeys (0x8), MouseKeys (0x10), AccessXKeys (0x20),
- * TimeOut (0x40), Feedback (0x80), ToggleKeys (0x100),
- * Overlay1 (0x200), Overlay2 (0x400), GroupsWrap (0x800),
- * InternalMods (0x1000), IgnoreLockMods (0x2000),
- * PerKeyRepeat (0x3000), or ControlsEnabled (0x4000)
- */
- if( map->ctrls )
- {
- unsigned long which = map->ctrls;
-
- XkbGetControls( _xklDpy, XkbAllControlsMask, _xklXkb );
- if( set )
- _xklXkb->ctrls->enabled_ctrls |= which;
- else
- _xklXkb->ctrls->enabled_ctrls &= ~which;
- XkbSetControls( _xklDpy, which | XkbControlsEnabledMask, _xklXkb );
- }
-
- /* The 'which_groups' field tells when this indicator turns on
- * for the 'groups' field: base (0x1), latched (0x2), locked (0x4),
- * or effective (0x8).
- */
- if( map->groups )
- {
- int i;
- unsigned int group = 1;
-
- /* Turning on a group indicator is kind of tricky. For
- * now, we will just Latch or Lock the first group we find
- * if that is what this indicator does. Otherwise, we're
- * just going to punt and get out of here.
- */
- if( set )
- {
- for( i = XkbNumKbdGroups; --i >= 0; )
- if( ( 1 << i ) & map->groups )
- {
- group = i;
- break;
- }
- if( map->which_groups & ( XkbIM_UseLocked | XkbIM_UseEffective ) )
- {
- /* Important: Groups should be ignored here - because they are handled separately! */
- /* XklLockGroup( group ); */
- } else if( map->which_groups & XkbIM_UseLatched )
- XkbLatchGroup( _xklDpy, XkbUseCoreKbd, group );
- else
- {
- /* Can do nothing. Just ignore the indicator */
- return True;
- }
- } else
- /* Turning off a group indicator will mean that we just
- * Lock the first group that this indicator doesn't watch.
- */
- {
- for( i = XkbNumKbdGroups; --i >= 0; )
- if( !( ( 1 << i ) & map->groups ) )
- {
- group = i;
- break;
- }
- XklLockGroup( group );
- }
- }
-
- /* The 'which_mods' field tells when this indicator turns on
- * for the modifiers: base (0x1), latched (0x2), locked (0x4),
- * or effective (0x8).
- *
- * The 'real_mods' field tells whether this turns on when one of
- * the real X modifiers is set: Shift (0x1), Lock (0x2), Control (0x4),
- * Mod1 (0x8), Mod2 (0x10), Mod3 (0x20), Mod4 (0x40), or Mod5 (0x80).
- *
- * The 'virtual_mods' field tells whether this turns on when one of
- * the virtual modifiers is set.
- *
- * The 'mask' field tells what real X modifiers the virtual_modifiers
- * map to?
- */
- if( map->mods.real_mods || map->mods.mask )
- {
- unsigned int affect, mods;
-
- affect = ( map->mods.real_mods | map->mods.mask );
-
- mods = set ? affect : 0;
-
- if( map->which_mods & ( XkbIM_UseLocked | XkbIM_UseEffective ) )
- XkbLockModifiers( _xklDpy, XkbUseCoreKbd, affect, mods );
- else if( map->which_mods & XkbIM_UseLatched )
- XkbLatchModifiers( _xklDpy, XkbUseCoreKbd, affect, mods );
- else
- {
- return True;
- }
- }
- return True;
+ XkbIndicatorMapPtr map;
+ Display *display = xkl_engine_get_display(engine);
+ XkbDescPtr cached =
+ xkl_engine_backend(engine, XklXkb, cached_desc);
+
+ map = cached->indicators->maps + indicator_num;
+
+ /* The 'flags' field tells whether this indicator is automatic
+ * (XkbIM_NoExplicit - 0x80), explicit (XkbIM_NoAutomatic - 0x40),
+ * or neither (both - 0xC0).
+ *
+ * If NoAutomatic is set, the server ignores the rest of the
+ * fields in the indicator map (i.e. it disables automatic control
+ * of the LED). If NoExplicit is set, the server prevents clients
+ * from explicitly changing the value of the LED (using the core
+ * protocol *or* XKB). If NoAutomatic *and* NoExplicit are set,
+ * the LED cannot be changed (unless you change the map first).
+ * If neither NoAutomatic nor NoExplicit are set, the server will
+ * change the LED according to the indicator map, but clients can
+ * override that (until the next automatic change) using the core
+ * protocol or XKB.
+ */
+ switch (map->flags & (XkbIM_NoExplicit | XkbIM_NoAutomatic)) {
+ case XkbIM_NoExplicit | XkbIM_NoAutomatic:
+ {
+ /* Can do nothing. Just ignore the indicator */
+ return TRUE;
+ }
+
+ case XkbIM_NoAutomatic:
+ {
+ if (cached->names->
+ indicators[indicator_num] != None)
+ XkbSetNamedIndicator(display,
+ XkbUseCoreKbd,
+ cached->names->
+ indicators
+ [indicator_num], set,
+ False, NULL);
+ else {
+ XKeyboardControl xkc;
+ xkc.led = indicator_num;
+ xkc.led_mode =
+ set ? LedModeOn : LedModeOff;
+ XChangeKeyboardControl(display,
+ KBLed | KBLedMode,
+ &xkc);
+ XSync(display, False);
+ }
+
+ return TRUE;
+ }
+
+ case XkbIM_NoExplicit:
+ break;
+ }
+
+ /* The 'ctrls' field tells what controls tell this indicator to
+ * to turn on: RepeatKeys (0x1), SlowKeys (0x2), BounceKeys (0x4),
+ * StickyKeys (0x8), MouseKeys (0x10), AccessXKeys (0x20),
+ * TimeOut (0x40), Feedback (0x80), ToggleKeys (0x100),
+ * Overlay1 (0x200), Overlay2 (0x400), GroupsWrap (0x800),
+ * InternalMods (0x1000), IgnoreLockMods (0x2000),
+ * PerKeyRepeat (0x3000), or ControlsEnabled (0x4000)
+ */
+ if (map->ctrls) {
+ gulong which = map->ctrls;
+
+ XkbGetControls(display, XkbAllControlsMask, cached);
+ if (set)
+ cached->ctrls->enabled_ctrls |= which;
+ else
+ cached->ctrls->enabled_ctrls &= ~which;
+ XkbSetControls(display, which | XkbControlsEnabledMask,
+ cached);
+ }
+
+ /* The 'which_groups' field tells when this indicator turns on
+ * for the 'groups' field: base (0x1), latched (0x2), locked (0x4),
+ * or effective (0x8).
+ */
+ if (map->groups) {
+ gint i;
+ guint group = 1;
+
+ /* Turning on a group indicator is kind of tricky. For
+ * now, we will just Latch or Lock the first group we find
+ * if that is what this indicator does. Otherwise, we're
+ * just going to punt and get out of here.
+ */
+ if (set) {
+ for (i = XkbNumKbdGroups; --i >= 0;)
+ if ((1 << i) & map->groups) {
+ group = i;
+ break;
+ }
+ if (map->
+ which_groups & (XkbIM_UseLocked |
+ XkbIM_UseEffective)) {
+ /* Important: Groups should be ignored here - because they are handled separately! */
+ /* XklLockGroup( group ); */
+ } else if (map->which_groups & XkbIM_UseLatched)
+ XkbLatchGroup(display, XkbUseCoreKbd,
+ group);
+ else {
+ /* Can do nothing. Just ignore the indicator */
+ return TRUE;
+ }
+ } else
+ /* Turning off a group indicator will mean that we just
+ * Lock the first group that this indicator doesn't watch.
+ */
+ {
+ for (i = XkbNumKbdGroups; --i >= 0;)
+ if (!((1 << i) & map->groups)) {
+ group = i;
+ break;
+ }
+ xkl_xkb_lock_group(engine, group);
+ }
+ }
+
+ /* The 'which_mods' field tells when this indicator turns on
+ * for the modifiers: base (0x1), latched (0x2), locked (0x4),
+ * or effective (0x8).
+ *
+ * The 'real_mods' field tells whether this turns on when one of
+ * the real X modifiers is set: Shift (0x1), Lock (0x2), Control (0x4),
+ * Mod1 (0x8), Mod2 (0x10), Mod3 (0x20), Mod4 (0x40), or Mod5 (0x80).
+ *
+ * The 'virtual_mods' field tells whether this turns on when one of
+ * the virtual modifiers is set.
+ *
+ * The 'mask' field tells what real X modifiers the virtual_modifiers
+ * map to?
+ */
+ if (map->mods.real_mods || map->mods.mask) {
+ guint affect, mods;
+
+ affect = (map->mods.real_mods | map->mods.mask);
+
+ mods = set ? affect : 0;
+
+ if (map->
+ which_mods & (XkbIM_UseLocked | XkbIM_UseEffective))
+ XkbLockModifiers(display, XkbUseCoreKbd,
+ affect, mods);
+ else if (map->which_mods & XkbIM_UseLatched)
+ XkbLatchModifiers(display, XkbUseCoreKbd,
+ affect, mods);
+ else {
+ return TRUE;
+ }
+ }
+ return TRUE;
}
#endif
-int _XklXkbInit( void )
+gint
+xkl_xkb_init(XklEngine * engine)
{
+ Display *display = xkl_engine_get_display(engine);
+
#ifdef XKB_HEADERS_PRESENT
- int opcode;
- Bool _xklXkbExtPresent;
- static XklVTable xklXkbVTable =
-{
- "XKB",
- XKLF_CAN_TOGGLE_INDICATORS |
- XKLF_CAN_OUTPUT_CONFIG_AS_ASCII |
- XKLF_CAN_OUTPUT_CONFIG_AS_BINARY,
- _XklXkbConfigActivate,
- _XklXkbConfigInit,
- _XklXkbConfigLoadRegistry,
- _XklXkbConfigWriteFile,
- _XklXkbEventHandler,
- _XklXkbFreeAllInfo,
- _XklXkbGetGroupNames,
- _XklXkbGetMaxNumGroups,
- _XklXkbGetNumGroups,
- _XklXkbGetRealState,
- _XklXkbIfCachedInfoEqualsActual,
- _XklXkbLoadAllInfo,
- _XklXkbLockGroup,
- _XklXkbPauseListen,
- _XklXkbResumeListen,
- _XklXkbSetIndicators,
- };
-
- if( getenv( "XKL_XKB_DISABLE" ) != NULL )
- return -1;
-
- _xklXkbExtPresent = XkbQueryExtension( _xklDpy,
- &opcode, &_xklXkbEventType,
- &_xklXkbError, NULL, NULL );
- if( !_xklXkbExtPresent )
- {
- XSetErrorHandler( ( XErrorHandler ) _xklDefaultErrHandler );
- return -1;
- }
-
- XklDebug( 160,
- "xkbEvenType: %X, xkbError: %X, display: %p, root: " WINID_FORMAT
- "\n", _xklXkbEventType, _xklXkbError, _xklDpy, _xklRootWindow );
-
- xklXkbVTable.baseConfigAtom =
- XInternAtom( _xklDpy, _XKB_RF_NAMES_PROP_ATOM, False );
- xklXkbVTable.backupConfigAtom =
- XInternAtom( _xklDpy, "_XKB_RULES_NAMES_BACKUP", False );
-
- xklXkbVTable.defaultModel = "pc101";
- xklXkbVTable.defaultLayout = "us";
-
- xklVTable = &xklXkbVTable;
-
- /* First, we have to assign xklVTable -
- because this function uses it */
-
- if( _XklXkbConfigMultipleLayoutsSupported() )
- xklXkbVTable.features |= XKLF_MULTIPLE_LAYOUTS_SUPPORTED;
-
- return 0;
+ gint opcode;
+ gboolean xkl_xkb_ext_present;
+
+ xkl_engine_priv(engine, backend_id) = "XKB";
+ xkl_engine_priv(engine, features) = XKLF_CAN_TOGGLE_INDICATORS |
+ XKLF_CAN_OUTPUT_CONFIG_AS_ASCII |
+ XKLF_CAN_OUTPUT_CONFIG_AS_BINARY;
+ xkl_engine_priv(engine, activate_config_rec) =
+ xkl_xkb_activate_config_rec;
+ xkl_engine_priv(engine, init_config_registry) =
+ xkl_xkb_init_config_registry;
+ xkl_engine_priv(engine, load_config_registry) =
+ xkl_xkb_load_config_registry;
+ xkl_engine_priv(engine, write_config_rec_to_file) =
+ xkl_xkb_write_config_rec_to_file;
+ xkl_engine_priv(engine, get_groups_names) =
+ xkl_xkb_get_groups_names;
+ xkl_engine_priv(engine, get_max_num_groups) =
+ xkl_xkb_get_max_num_groups;
+ xkl_engine_priv(engine, get_num_groups) = xkl_xkb_get_num_groups;
+ xkl_engine_priv(engine, lock_group) = xkl_xkb_lock_group;
+ xkl_engine_priv(engine, process_x_event) = xkl_xkb_process_x_event;
+ xkl_engine_priv(engine, free_all_info) = xkl_xkb_free_all_info;
+ xkl_engine_priv(engine, if_cached_info_equals_actual) =
+ xkl_xkb_if_cached_info_equals_actual;
+ xkl_engine_priv(engine, load_all_info) = xkl_xkb_load_all_info;
+ xkl_engine_priv(engine, get_server_state) =
+ xkl_xkb_get_server_state;
+ xkl_engine_priv(engine, pause_listen) = xkl_xkb_pause_listen;
+ xkl_engine_priv(engine, resume_listen) = xkl_xkb_resume_listen;
+ xkl_engine_priv(engine, set_indicators) = xkl_xkb_set_indicators;
+ xkl_engine_priv(engine, finalize) = xkl_xkb_term;
+
+ if (getenv("XKL_XKB_DISABLE") != NULL)
+ return -1;
+
+ xkl_engine_priv(engine, backend) = g_new0(XklXkb, 1);
+
+ xkl_xkb_ext_present = XkbQueryExtension(display,
+ &opcode,
+ &xkl_engine_backend(engine,
+ XklXkb,
+ event_type),
+ &xkl_engine_backend(engine,
+ XklXkb,
+ error_code),
+ NULL, NULL);
+ if (!xkl_xkb_ext_present) {
+ XSetErrorHandler((XErrorHandler)
+ xkl_engine_priv(engine,
+ default_error_handler));
+ return -1;
+ }
+
+ xkl_debug(160,
+ "xkbEvenType: %X, xkbError: %X, display: %p, root: "
+ WINID_FORMAT "\n", xkl_engine_backend(engine, XklXkb,
+ event_type),
+ xkl_engine_backend(engine, XklXkb, error_code), display,
+ xkl_engine_priv(engine, root_window));
+
+ xkl_engine_priv(engine, base_config_atom) =
+ XInternAtom(display, _XKB_RF_NAMES_PROP_ATOM, False);
+ xkl_engine_priv(engine, backup_config_atom) =
+ XInternAtom(display, "_XKB_RULES_NAMES_BACKUP", False);
+
+ xkl_engine_priv(engine, default_model) = "pc101";
+ xkl_engine_priv(engine, default_layout) = "us";
+
+ /* First, we have to assign xkl_vtable -
+ because this function uses it */
+
+ if (xkl_xkb_multiple_layouts_supported(engine))
+ xkl_engine_priv(engine, features) |=
+ XKLF_MULTIPLE_LAYOUTS_SUPPORTED;
+
+ return 0;
#else
- XklDebug( 160,
- "NO XKB LIBS, display: %p, root: " WINID_FORMAT
- "\n", _xklDpy, _xklRootWindow );
- return -1;
+ xkl_debug(160,
+ "NO XKB LIBS, display: %p, root: " WINID_FORMAT
+ "\n", display, xkl_engine_priv(engine, root_window));
+ return -1;
#endif
}
+void
+xkl_xkb_term(XklEngine * engine)
+{
+}
+
#ifdef XKB_HEADERS_PRESENT
-const char *_XklXkbGetXkbEventName( int xkb_type )
+const gchar *
+xkl_xkb_event_get_name(gint xkb_type)
{
- /* Not really good to use the fact of consecutivity
- but XKB protocol extension is already standartized so... */
- static const char *evtNames[] = {
- "XkbNewKeyboardNotify",
- "XkbMapNotify",
- "XkbStateNotify",
- "XkbControlsNotify",
- "XkbIndicatorStateNotify",
- "XkbIndicatorMapNotify",
- "XkbNamesNotify",
- "XkbCompatMapNotify",
- "XkbBellNotify",
- "XkbActionMessage",
- "XkbAccessXNotify",
- "XkbExtensionDeviceNotify",
- "LASTEvent"
- };
- xkb_type -= XkbNewKeyboardNotify;
- if( xkb_type < 0 ||
- xkb_type >= ( sizeof( evtNames ) / sizeof( evtNames[0] ) ) )
- return "UNKNOWN";
- return evtNames[xkb_type];
+ /* Not really good to use the fact of consecutivity
+ but XKB protocol extension is already standartized so... */
+ static const gchar *evt_names[] = {
+ "XkbNewKeyboardNotify",
+ "XkbMapNotify",
+ "XkbStateNotify",
+ "XkbControlsNotify",
+ "XkbIndicatorStateNotify",
+ "XkbIndicatorMapNotify",
+ "XkbNamesNotify",
+ "XkbCompatMapNotify",
+ "XkbBellNotify",
+ "XkbActionMessage",
+ "XkbAccessXNotify",
+ "XkbExtensionDeviceNotify",
+ "LASTEvent"
+ };
+ xkb_type -= XkbNewKeyboardNotify;
+ if (xkb_type < 0 ||
+ xkb_type >= (sizeof(evt_names) / sizeof(evt_names[0])))
+ return "UNKNOWN/OOR";
+ return evt_names[xkb_type];
}
#endif