diff options
author | Sergey Udaltsov <svu@gnome.org> | 2006-03-12 04:20:01 +0000 |
---|---|---|
committer | Sergey Udaltsov <svu@gnome.org> | 2006-03-12 04:20:01 +0000 |
commit | 2c88cc80147b72eba939d6358939ef59d403c34e (patch) | |
tree | b6b145f6d50e1f4bba8145bef5963aee8a5f3180 /libxklavier/xklavier_xkb.c | |
parent | d7bc98fb5f9d55c37a08ceeedbc87cb70ee6f133 (diff) | |
download | libxklavier-2c88cc80147b72eba939d6358939ef59d403c34e.tar.gz |
branching 2.x, merging GLIBing to HEAD
Diffstat (limited to 'libxklavier/xklavier_xkb.c')
-rw-r--r-- | libxklavier/xklavier_xkb.c | 936 |
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, + ¤t_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 |