|
Packit |
7e555f |
/*
|
|
Packit |
7e555f |
* Copyright (C) 2002-2006 Sergey V. Udaltsov <svu@gnome.org>
|
|
Packit |
7e555f |
*
|
|
Packit |
7e555f |
* This library is free software; you can redistribute it and/or
|
|
Packit |
7e555f |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
7e555f |
* License as published by the Free Software Foundation; either
|
|
Packit |
7e555f |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
7e555f |
*
|
|
Packit |
7e555f |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
7e555f |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
7e555f |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
7e555f |
* Lesser General Public License for more details.
|
|
Packit |
7e555f |
*
|
|
Packit |
7e555f |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
7e555f |
* License along with this library; if not, write to the
|
|
Packit |
7e555f |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Packit |
7e555f |
* Boston, MA 02111-1307, USA.
|
|
Packit |
7e555f |
*/
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
#include <time.h>
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
#include <X11/Xatom.h>
|
|
Packit |
7e555f |
#include <X11/Xlib.h>
|
|
Packit |
7e555f |
#include <X11/Xutil.h>
|
|
Packit |
7e555f |
#include <X11/keysym.h>
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
#include "xklavier_private.h"
|
|
Packit |
7e555f |
#include "xklavier_private_xmm.h"
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
static gint
|
|
Packit |
7e555f |
xkl_xmm_process_keypress_event(XklEngine * engine, XKeyPressedEvent * kpe)
|
|
Packit |
7e555f |
{
|
|
Packit |
7e555f |
if (xkl_engine_is_listening_for(engine, XKLL_MANAGE_LAYOUTS)) {
|
|
Packit |
7e555f |
gint current_shortcut = 0;
|
|
Packit |
7e555f |
const XmmSwitchOption *sop;
|
|
Packit |
7e555f |
xkl_debug(200, "Processing the KeyPress event\n");
|
|
Packit |
7e555f |
sop = xkl_xmm_find_switch_option(engine, kpe->keycode,
|
|
Packit |
7e555f |
kpe->state,
|
|
Packit |
7e555f |
¤t_shortcut);
|
|
Packit |
7e555f |
if (sop != NULL) {
|
|
Packit |
7e555f |
XklState state;
|
|
Packit |
7e555f |
xkl_debug(150, "It is THE shortcut\n");
|
|
Packit |
7e555f |
xkl_xmm_get_server_state(engine, &state);
|
|
Packit |
7e555f |
if (state.group != -1) {
|
|
Packit |
7e555f |
gint new_group =
|
|
Packit |
7e555f |
(state.group +
|
|
Packit |
7e555f |
sop->shortcut_steps[current_shortcut])
|
|
Packit |
7e555f |
%
|
|
Packit |
7e555f |
g_strv_length(xkl_engine_backend
|
|
Packit |
7e555f |
(engine, XklXmm,
|
|
Packit |
7e555f |
current_config).layouts);
|
|
Packit |
7e555f |
xkl_debug(150,
|
|
Packit |
7e555f |
"Setting new xmm group %d\n",
|
|
Packit |
7e555f |
new_group);
|
|
Packit |
7e555f |
xkl_xmm_lock_group(engine, new_group);
|
|
Packit |
7e555f |
return 1;
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
return 0;
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
static gint
|
|
Packit |
7e555f |
xkl_xmm_process_property_event(XklEngine * engine, XPropertyEvent * kpe)
|
|
Packit |
7e555f |
{
|
|
Packit |
7e555f |
Atom state_atom = xkl_engine_backend(engine, XklXmm, state_atom);
|
|
Packit |
7e555f |
xkl_debug(200, "Processing the PropertyNotify event: %d/%d\n",
|
|
Packit |
7e555f |
kpe->atom, state_atom);
|
|
Packit |
7e555f |
/*
|
|
Packit |
7e555f |
* Group is changed!
|
|
Packit |
7e555f |
*/
|
|
Packit |
7e555f |
if (kpe->atom == state_atom) {
|
|
Packit |
7e555f |
XklState state;
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
xkl_xmm_get_server_state(engine, &state);
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
if (xkl_engine_is_listening_for
|
|
Packit |
7e555f |
(engine, XKLL_MANAGE_LAYOUTS)) {
|
|
Packit |
7e555f |
xkl_debug(150,
|
|
Packit |
7e555f |
"Current group from the root window property %d\n",
|
|
Packit |
7e555f |
state.group);
|
|
Packit |
7e555f |
xkl_xmm_shortcuts_ungrab(engine);
|
|
Packit |
7e555f |
xkl_xmm_actualize_group(engine, state.group);
|
|
Packit |
7e555f |
xkl_xmm_shortcuts_grab(engine);
|
|
Packit |
7e555f |
return 1;
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
if (xkl_engine_is_listening_for
|
|
Packit |
7e555f |
(engine,
|
|
Packit |
7e555f |
XKLL_MANAGE_WINDOW_STATES) |
|
|
Packit |
7e555f |
xkl_engine_is_listening_for(engine,
|
|
Packit |
7e555f |
XKLL_TRACK_KEYBOARD_STATE))
|
|
Packit |
7e555f |
{
|
|
Packit |
7e555f |
xkl_debug(150,
|
|
Packit |
7e555f |
"XMM state changed, new 'group' %d\n",
|
|
Packit |
7e555f |
state.group);
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
xkl_engine_process_state_modification(engine,
|
|
Packit |
7e555f |
GROUP_CHANGED,
|
|
Packit |
7e555f |
state.group,
|
|
Packit |
7e555f |
0, False);
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
} else
|
|
Packit |
7e555f |
/*
|
|
Packit |
7e555f |
* Configuration is changed!
|
|
Packit |
7e555f |
*/
|
|
Packit |
7e555f |
if (kpe->atom == xkl_engine_priv(engine, base_config_atom)) {
|
|
Packit |
7e555f |
xkl_engine_reset_all_info(engine, TRUE,
|
|
Packit |
7e555f |
"base config atom changed");
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
return 0;
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
/*
|
|
Packit |
7e555f |
* XMM event handler
|
|
Packit |
7e555f |
*/
|
|
Packit |
7e555f |
gint
|
|
Packit |
7e555f |
xkl_xmm_process_x_event(XklEngine * engine, XEvent * xev)
|
|
Packit |
7e555f |
{
|
|
Packit |
7e555f |
switch (xev->type) {
|
|
Packit |
7e555f |
case KeyPress:
|
|
Packit |
7e555f |
return xkl_xmm_process_keypress_event(engine,
|
|
Packit |
7e555f |
(XKeyPressedEvent *)
|
|
Packit |
7e555f |
xev);
|
|
Packit |
7e555f |
case PropertyNotify:
|
|
Packit |
7e555f |
return xkl_xmm_process_property_event(engine,
|
|
Packit |
7e555f |
(XPropertyEvent *)
|
|
Packit |
7e555f |
xev);
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
return 0;
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
/*
|
|
Packit |
7e555f |
* We have to find which of Shift/Lock/Control/ModX masks
|
|
Packit |
7e555f |
* belong to Caps/Num/Scroll lock
|
|
Packit |
7e555f |
*/
|
|
Packit |
7e555f |
static void
|
|
Packit |
7e555f |
xkl_xmm_init_xmm_indicators_map(XklEngine * engine,
|
|
Packit |
7e555f |
guint * p_caps_lock_mask,
|
|
Packit |
7e555f |
guint * p_num_lock_mask,
|
|
Packit |
7e555f |
guint * p_scroll_lock_mask)
|
|
Packit |
7e555f |
{
|
|
Packit |
7e555f |
XModifierKeymap *xmkm = NULL;
|
|
Packit |
7e555f |
KeyCode *kcmap, nlkc, clkc, slkc;
|
|
Packit |
7e555f |
int m, k, mask;
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
Display *display = xkl_engine_get_display(engine);
|
|
Packit |
7e555f |
xmkm = XGetModifierMapping(display);
|
|
Packit |
7e555f |
if (xmkm) {
|
|
Packit |
7e555f |
clkc = XKeysymToKeycode(display, XK_Num_Lock);
|
|
Packit |
7e555f |
nlkc = XKeysymToKeycode(display, XK_Caps_Lock);
|
|
Packit |
7e555f |
slkc = XKeysymToKeycode(display, XK_Scroll_Lock);
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
kcmap = xmkm->modifiermap;
|
|
Packit |
7e555f |
mask = 1;
|
|
Packit |
7e555f |
for (m = 8; --m >= 0; mask <<= 1)
|
|
Packit |
7e555f |
for (k = xmkm->max_keypermod; --k >= 0; kcmap++) {
|
|
Packit |
7e555f |
if (*kcmap == clkc)
|
|
Packit |
7e555f |
*p_caps_lock_mask = mask;
|
|
Packit |
7e555f |
if (*kcmap == slkc)
|
|
Packit |
7e555f |
*p_scroll_lock_mask = mask;
|
|
Packit |
7e555f |
if (*kcmap == nlkc)
|
|
Packit |
7e555f |
*p_num_lock_mask = mask;
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
XFreeModifiermap(xmkm);
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
void
|
|
Packit |
7e555f |
xkl_xmm_grab_ignoring_indicators(XklEngine * engine, gint keycode,
|
|
Packit |
7e555f |
guint modifiers)
|
|
Packit |
7e555f |
{
|
|
Packit |
7e555f |
guint caps_lock_mask = 0, num_lock_mask = 0, scroll_lock_mask = 0;
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
xkl_xmm_init_xmm_indicators_map(engine, &caps_lock_mask,
|
|
Packit |
7e555f |
&num_lock_mask, &scroll_lock_mask);
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
#define GRAB(mods) \
|
|
Packit |
7e555f |
xkl_engine_grab_key(engine, keycode, modifiers|(mods))
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
GRAB(0);
|
|
Packit |
7e555f |
GRAB(caps_lock_mask);
|
|
Packit |
7e555f |
GRAB(num_lock_mask);
|
|
Packit |
7e555f |
GRAB(scroll_lock_mask);
|
|
Packit |
7e555f |
GRAB(caps_lock_mask | num_lock_mask);
|
|
Packit |
7e555f |
GRAB(caps_lock_mask | scroll_lock_mask);
|
|
Packit |
7e555f |
GRAB(num_lock_mask | scroll_lock_mask);
|
|
Packit |
7e555f |
GRAB(caps_lock_mask | num_lock_mask | scroll_lock_mask);
|
|
Packit |
7e555f |
#undef GRAB
|
|
Packit |
7e555f |
}
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
void
|
|
Packit |
7e555f |
xkl_xmm_ungrab_ignoring_indicators(XklEngine * engine, gint keycode,
|
|
Packit |
7e555f |
guint modifiers)
|
|
Packit |
7e555f |
{
|
|
Packit |
7e555f |
guint caps_lock_mask = 0, num_lock_mask = 0, scroll_lock_mask = 0;
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
xkl_xmm_init_xmm_indicators_map(engine, &caps_lock_mask,
|
|
Packit |
7e555f |
&num_lock_mask, &scroll_lock_mask);
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
#define UNGRAB(mods) \
|
|
Packit |
7e555f |
xkl_engine_ungrab_key(engine, keycode, modifiers|(mods))
|
|
Packit |
7e555f |
|
|
Packit |
7e555f |
UNGRAB(0);
|
|
Packit |
7e555f |
UNGRAB(caps_lock_mask);
|
|
Packit |
7e555f |
UNGRAB(num_lock_mask);
|
|
Packit |
7e555f |
UNGRAB(scroll_lock_mask);
|
|
Packit |
7e555f |
UNGRAB(caps_lock_mask | num_lock_mask);
|
|
Packit |
7e555f |
UNGRAB(caps_lock_mask | scroll_lock_mask);
|
|
Packit |
7e555f |
UNGRAB(num_lock_mask | scroll_lock_mask);
|
|
Packit |
7e555f |
UNGRAB(caps_lock_mask | num_lock_mask | scroll_lock_mask);
|
|
Packit |
7e555f |
#undef UNGRAB
|
|
Packit |
7e555f |
}
|