summaryrefslogtreecommitdiff
path: root/libxklavier/xklavier_xmm.c
diff options
context:
space:
mode:
Diffstat (limited to 'libxklavier/xklavier_xmm.c')
-rwxr-xr-xlibxklavier/xklavier_xmm.c481
1 files changed, 271 insertions, 210 deletions
diff --git a/libxklavier/xklavier_xmm.c b/libxklavier/xklavier_xmm.c
index 83818a1..e37b3d8 100755
--- a/libxklavier/xklavier_xmm.c
+++ b/libxklavier/xklavier_xmm.c
@@ -2,10 +2,10 @@
#include <stdlib.h>
#include <string.h>
+#include <X11/Xmd.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
#include <X11/keysym.h>
#include "config.h"
@@ -15,264 +15,325 @@
#define SHORTCUT_OPTION_PREFIX "grp:"
-char* currentXmmRules = NULL;
+const gchar **
+xkl_xmm_get_groups_names(XklEngine * engine)
+{
+ return (const gchar **) xkl_engine_backend(engine, XklXmm,
+ current_config).layouts;
+}
+
+void
+xkl_xmm_shortcuts_grab(XklEngine * engine)
+{
+ const XmmShortcut *shortcut;
+ const XmmSwitchOption *option =
+ xkl_xmm_shortcut_get_current(engine);
-XklConfigRec currentXmmConfig;
+ xkl_debug(150, "Found shortcut option: %p\n", option);
+ if (option == NULL)
+ return;
-Atom xmmStateAtom;
+ shortcut = option->shortcuts;
+ while (shortcut->keysym != XK_VoidSymbol) {
+ int keycode =
+ XKeysymToKeycode(xkl_engine_get_display(engine),
+ shortcut->keysym);
+ xkl_xmm_grab_ignoring_indicators(engine, keycode,
+ shortcut->modifiers);
+ shortcut++;
+ }
+}
-const char **_XklXmmGetGroupNames( void )
+void
+xkl_xmm_shortcuts_ungrab(XklEngine * engine)
{
- return (const char **)currentXmmConfig.layouts;
+ const XmmShortcut *shortcut;
+ const XmmSwitchOption *option =
+ xkl_xmm_shortcut_get_current(engine);
+
+ if (option == NULL)
+ return;
+
+ shortcut = option->shortcuts;
+ while (shortcut->keysym != XK_VoidSymbol) {
+ int keycode =
+ XKeysymToKeycode(xkl_engine_get_display(engine),
+ shortcut->keysym);
+ xkl_xmm_ungrab_ignoring_indicators(engine, keycode,
+ shortcut->modifiers);
+ shortcut++;
+ }
}
-void _XklXmmGrabShortcuts( void )
+XmmSwitchOption *
+xkl_xmm_shortcut_get_current(XklEngine * engine)
{
- int i;
- XmmShortcutPtr shortcut;
- const XmmSwitchOptionPtr option = _XklXmmGetCurrentShortcut();
-
- XklDebug( 150, "Found shortcut option: %p\n", option );
- if( option == NULL )
- return;
-
- shortcut = option->shortcuts;
- for( i = option->numShortcuts; --i >= 0; shortcut++ )
- {
- int keycode = XKeysymToKeycode( _xklDpy, shortcut->keysym );
- _XklXmmGrabIgnoringIndicators( keycode,
- shortcut->modifiers );
- }
+ const gchar *option_name =
+ xkl_xmm_shortcut_get_current_option_name(engine);
+
+ xkl_debug(150, "Configured switch option: [%s]\n", option_name);
+
+ if (option_name == NULL)
+ return NULL;
+
+ return (XmmSwitchOption *)
+ g_hash_table_lookup(xkl_engine_backend
+ (engine, XklXmm, switch_options),
+ (gconstpointer) option_name);
}
-void _XklXmmUngrabShortcuts( void )
+const gchar *
+xkl_xmm_shortcut_get_current_option_name(XklEngine * engine)
{
- int i;
- XmmShortcutPtr shortcut;
- const XmmSwitchOptionPtr option = _XklXmmGetCurrentShortcut();
-
- if( option == NULL )
- return;
-
- shortcut = option->shortcuts;
- for( i = option->numShortcuts; --i >= 0; shortcut++ )
- {
- int keycode = XKeysymToKeycode( _xklDpy, shortcut->keysym );
- _XklXmmUngrabIgnoringIndicators( keycode,
- shortcut->modifiers );
- }
+ gchar **option =
+ xkl_engine_backend(engine, XklXmm, current_config).options;
+ if (option == NULL)
+ return NULL;
+
+ while (*option != NULL) {
+ /* starts with "grp:" */
+ if (strstr(*option, SHORTCUT_OPTION_PREFIX) != NULL) {
+ return *option + sizeof SHORTCUT_OPTION_PREFIX - 1;
+ }
+ option++;
+ }
+ return NULL;
}
-XmmSwitchOptionPtr _XklXmmGetCurrentShortcut( void )
+const XmmSwitchOption *
+xkl_xmm_find_switch_option(XklEngine * engine, gint keycode,
+ guint state, gint * current_shortcut_rv)
{
- const char* optionName = _XklXmmGetCurrentShortcutOptionName();
- XmmSwitchOptionPtr switchOption = allSwitchOptions;
- XklDebug( 150, "Configured switch option: [%s]\n", optionName );
- if( optionName == NULL )
- return NULL;
- while( switchOption->optionName != NULL )
- {
- if( !strcmp( switchOption->optionName, optionName ) )
- return switchOption;
- switchOption++;
- }
- return NULL;
+ const XmmSwitchOption *rv = xkl_xmm_shortcut_get_current(engine);
+
+ if (rv != NULL) {
+ XmmShortcut *sc = rv->shortcuts;
+ while (sc->keysym != XK_VoidSymbol) {
+ if ((XKeysymToKeycode
+ (xkl_engine_get_display(engine),
+ sc->keysym) == keycode)
+ && ((state & sc->modifiers) == sc->modifiers)) {
+ return rv;
+ }
+ sc++;
+ }
+ }
+ return NULL;
}
-const char* _XklXmmGetCurrentShortcutOptionName( void )
+gint
+xkl_xmm_resume_listen(XklEngine * engine)
{
- int i;
- char** option = currentXmmConfig.options;
- for( i = currentXmmConfig.numOptions; --i >= 0; option++ )
- {
- /* starts with "grp:" */
- if( strstr( *option, SHORTCUT_OPTION_PREFIX ) != NULL )
- {
- return *option + sizeof SHORTCUT_OPTION_PREFIX - 1;
- }
- }
- return NULL;
+ if (xkl_engine_priv(engine, listener_type) & XKLL_MANAGE_LAYOUTS)
+ xkl_xmm_shortcuts_grab(engine);
+ return 0;
}
-XmmSwitchOptionPtr _XklXmmFindSwitchOption( unsigned keycode,
- unsigned state,
- int* currentShortcut_rv )
+gint
+xkl_xmm_pause_listen(XklEngine * engine)
{
- const XmmSwitchOptionPtr rv = _XklXmmGetCurrentShortcut();
- int i;
-
- if( rv != NULL )
- {
- XmmShortcutPtr sc = rv->shortcuts;
- for( i=rv->numShortcuts; --i>=0; sc++ )
- {
- if( ( XKeysymToKeycode( _xklDpy, sc->keysym ) == keycode ) &&
- ( ( state & sc->modifiers ) == sc->modifiers ) )
- {
- return rv;
- }
- }
- }
- return NULL;
+ if (xkl_engine_priv(engine, listener_type) & XKLL_MANAGE_LAYOUTS)
+ xkl_xmm_shortcuts_ungrab(engine);
+ return 0;
}
-int _XklXmmResumeListen( void )
+guint
+xkl_xmm_get_max_num_groups(XklEngine * engine)
{
- if( _xklListenerType & XKLL_MANAGE_LAYOUTS )
- _XklXmmGrabShortcuts();
- return 0;
+ return 0;
}
-int _XklXmmPauseListen( void )
+guint
+xkl_xmm_get_num_groups(XklEngine * engine)
{
- if( _xklListenerType & XKLL_MANAGE_LAYOUTS )
- _XklXmmUngrabShortcuts();
- return 0;
+ gint rv = 0;
+ gchar **p =
+ xkl_engine_backend(engine, XklXmm, current_config).layouts;
+ if (p != NULL)
+ while (*p++ != NULL)
+ rv++;
+ return rv;
}
-unsigned _XklXmmGetMaxNumGroups( void )
+void
+xkl_xmm_free_all_info(XklEngine * engine)
{
- return 0;
+ gchar *current_rules =
+ xkl_engine_backend(engine, XklXmm, current_rules);
+ if (current_rules != NULL) {
+ g_free(current_rules);
+ current_rules = NULL;
+ xkl_engine_backend(engine, XklXmm, current_rules) = NULL;
+ }
+ xkl_config_rec_reset(&xkl_engine_backend
+ (engine, XklXmm, current_config));
}
-unsigned _XklXmmGetNumGroups( void )
+gboolean
+xkl_xmm_if_cached_info_equals_actual(XklEngine * engine)
{
- return currentXmmConfig.numLayouts;
+ return FALSE;
}
-
-void _XklXmmFreeAllInfo( void )
+
+gboolean
+xkl_xmm_load_all_info(XklEngine * engine)
{
- if( currentXmmRules != NULL )
- {
- free( currentXmmRules );
- currentXmmRules = NULL;
- }
- XklConfigRecReset( &currentXmmConfig );
+ return
+ xkl_config_rec_get_full_from_server(&xkl_engine_backend
+ (engine, XklXmm,
+ current_rules),
+ &xkl_engine_backend(engine,
+ XklXmm,
+ current_config),
+ engine);
}
-Bool _XklXmmIfCachedInfoEqualsActual( void )
+void
+xkl_xmm_get_server_state(XklEngine * engine, XklState * state)
{
- return False;
+ unsigned char *propval = NULL;
+ Atom actual_type;
+ int actual_format;
+ unsigned long bytes_remaining;
+ unsigned long actual_items;
+ int result;
+
+ memset(state, 0, sizeof(*state));
+
+ result =
+ XGetWindowProperty(xkl_engine_get_display(engine),
+ xkl_engine_priv(engine, root_window),
+ xkl_engine_backend(engine, XklXmm,
+ state_atom), 0L, 1L,
+ False, XA_INTEGER, &actual_type,
+ &actual_format, &actual_items,
+ &bytes_remaining, &propval);
+
+ if (Success == result) {
+ if (actual_format == 32 || actual_items == 1) {
+ state->group = *(CARD32 *) propval;
+ } else {
+ xkl_debug(160,
+ "Could not get the xmodmap current group\n");
+ }
+ XFree(propval);
+ } else {
+ xkl_debug(160,
+ "Could not get the xmodmap current group: %d\n",
+ result);
+ }
}
-Bool _XklXmmLoadAllInfo( )
+void
+xkl_xmm_actualize_group(XklEngine * engine, gint group)
{
- return _XklConfigGetFullFromServer( &currentXmmRules, &currentXmmConfig );
+ char cmd[1024];
+ int res;
+ const gchar *layout_name = NULL;
+
+ if (xkl_xmm_get_num_groups(engine) < group)
+ return;
+
+ layout_name =
+ xkl_engine_backend(engine, XklXmm,
+ current_config).layouts[group];
+
+ snprintf(cmd, sizeof cmd,
+ "xmodmap %s/xmodmap.%s", XMODMAP_BASE, layout_name);
+
+ res = system(cmd);
+ if (res > 0) {
+ xkl_debug(0, "xmodmap error %d\n", res);
+ } else if (res < 0) {
+ xkl_debug(0, "Could not execute xmodmap: %d\n", res);
+ }
+ XSync(xkl_engine_get_display(engine), False);
}
-void _XklXmmGetRealState( XklState * state )
+void
+xkl_xmm_lock_group(XklEngine * engine, gint group)
{
- unsigned char *propval = NULL;
- Atom actualType;
- int actualFormat;
- unsigned long bytesRemaining;
- unsigned long actualItems;
- int result;
-
- memset( state, 0, sizeof( *state ) );
-
- result = XGetWindowProperty( _xklDpy, _xklRootWindow, xmmStateAtom, 0L, 1L,
- False, XA_INTEGER, &actualType, &actualFormat,
- &actualItems, &bytesRemaining,
- &propval );
-
- if( Success == result )
- {
- if( actualFormat == 32 || actualItems == 1 )
- {
- state->group = *(CARD32*)propval;
- } else
- {
- XklDebug( 160, "Could not get the xmodmap current group\n" );
- }
- XFree( propval );
- } else
- {
- XklDebug( 160, "Could not get the xmodmap current group: %d\n", result );
- }
+ CARD32 propval;
+
+ if (xkl_xmm_get_num_groups(engine) < group)
+ return;
+
+ /* updating the status property */
+ propval = group;
+ Display *display = xkl_engine_get_display(engine);
+ XChangeProperty(display, xkl_engine_priv(engine, root_window),
+ xkl_engine_backend(engine, XklXmm, state_atom),
+ XA_INTEGER, 32, PropModeReplace,
+ (unsigned char *) &propval, 1);
+ XSync(display, False);
}
-void _XklXmmActualizeGroup( int group )
+void
+xkl_xmm_set_indicators(XklEngine * engine, const XklState * window_state)
{
- char cmd[1024];
- int res;
- const char* layoutName = NULL;
-
- if( currentXmmConfig.numLayouts < group )
- return;
-
- layoutName = currentXmmConfig.layouts[group];
-
- snprintf( cmd, sizeof cmd,
- "xmodmap %s/xmodmap.%s",
- XMODMAP_BASE, layoutName );
-
- res = system( cmd );
- if( res > 0 )
- {
- XklDebug( 0, "xmodmap error %d\n", res );
- } else if( res < 0 )
- {
- XklDebug( 0, "Could not execute xmodmap: %d\n", res );
- }
- XSync( _xklDpy, False );
}
-void _XklXmmLockGroup( int group )
+
+gint
+xkl_xmm_init(XklEngine * engine)
{
- CARD32 propval;
-
- if( currentXmmConfig.numLayouts < group )
- return;
-
- /* updating the status property */
- propval = group;
- XChangeProperty( _xklDpy, _xklRootWindow, xmmStateAtom,
- XA_INTEGER, 32, PropModeReplace,
- (unsigned char*)&propval, 1 );
- XSync( _xklDpy, False );
+ xkl_engine_priv(engine, backend_id) = "xmodmap";
+ xkl_engine_priv(engine, features) =
+ XKLF_MULTIPLE_LAYOUTS_SUPPORTED |
+ XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT;
+ xkl_engine_priv(engine, activate_config_rec) =
+ xkl_xmm_activate_config_rec;
+ xkl_engine_priv(engine, init_config_registry) =
+ xkl_xmm_init_config_registry;
+ xkl_engine_priv(engine, load_config_registry) =
+ xkl_xmm_load_config_registry;
+ xkl_engine_priv(engine, write_config_rec_to_file) = NULL;
+
+ xkl_engine_priv(engine, get_groups_names) =
+ xkl_xmm_get_groups_names;
+ xkl_engine_priv(engine, get_max_num_groups) =
+ xkl_xmm_get_max_num_groups;
+ xkl_engine_priv(engine, get_num_groups) = xkl_xmm_get_num_groups;
+ xkl_engine_priv(engine, lock_group) = xkl_xmm_lock_group;
+
+ xkl_engine_priv(engine, process_x_event) = xkl_xmm_process_x_event;
+ xkl_engine_priv(engine, free_all_info) = xkl_xmm_free_all_info;
+ xkl_engine_priv(engine, if_cached_info_equals_actual) =
+ xkl_xmm_if_cached_info_equals_actual;
+ xkl_engine_priv(engine, load_all_info) = xkl_xmm_load_all_info;
+ xkl_engine_priv(engine, get_server_state) =
+ xkl_xmm_get_server_state;
+ xkl_engine_priv(engine, pause_listen) = xkl_xmm_pause_listen;
+ xkl_engine_priv(engine, resume_listen) = xkl_xmm_resume_listen;
+ xkl_engine_priv(engine, set_indicators) = xkl_xmm_set_indicators;
+ xkl_engine_priv(engine, finalize) = xkl_xmm_term;
+
+ if (getenv("XKL_XMODMAP_DISABLE") != NULL)
+ return -1;
+
+ Display *display = xkl_engine_get_display(engine);
+ xkl_engine_priv(engine, base_config_atom) =
+ XInternAtom(display, "_XMM_NAMES", False);
+ xkl_engine_priv(engine, backup_config_atom) =
+ XInternAtom(display, "_XMM_NAMES_BACKUP", False);
+
+ xkl_engine_priv(engine, backend) = g_new0(XklXmm, 1);
+
+ xkl_engine_backend(engine, XklXmm, state_atom) =
+ XInternAtom(display, "_XMM_STATE", False);
+
+ xkl_engine_priv(engine, default_model) = "generic";
+ xkl_engine_priv(engine, default_layout) = "us";
+
+ xkl_xmm_init_switch_options((XklXmm *)
+ xkl_engine_priv(engine, backend));
+
+ return 0;
}
-int _XklXmmInit( void )
+void
+xkl_xmm_term(XklEngine * engine)
{
- static XklVTable xklXmmVTable =
- {
- "xmodmap",
- XKLF_MULTIPLE_LAYOUTS_SUPPORTED |
- XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT,
- _XklXmmConfigActivate,
- _XklXmmConfigInit,
- _XklXmmConfigLoadRegistry,
- NULL,
- _XklXmmEventHandler,
- _XklXmmFreeAllInfo,
- _XklXmmGetGroupNames,
- _XklXmmGetMaxNumGroups,
- _XklXmmGetNumGroups,
- _XklXmmGetRealState,
- _XklXmmIfCachedInfoEqualsActual,
- _XklXmmLoadAllInfo,
- _XklXmmLockGroup,
- _XklXmmPauseListen,
- _XklXmmResumeListen,
- NULL,
- };
-
- if( getenv( "XKL_XMODMAP_DISABLE" ) != NULL )
- return -1;
-
- xklXmmVTable.baseConfigAtom =
- XInternAtom( _xklDpy, "_XMM_NAMES", False );
- xklXmmVTable.backupConfigAtom =
- XInternAtom( _xklDpy, "_XMM_NAMES_BACKUP", False );
-
- xmmStateAtom =
- XInternAtom( _xklDpy, "_XMM_STATE", False );
-
- xklXmmVTable.defaultModel = "generic";
- xklXmmVTable.defaultLayout = "us";
-
- xklVTable = &xklXmmVTable;
-
- return 0;
+ xkl_xmm_term_switch_options((XklXmm *)
+ xkl_engine_priv(engine, backend));
}