diff options
author | Sam Spilsbury <smspillaz@gmail.com> | 2009-07-01 21:26:10 +0800 |
---|---|---|
committer | Joel Bosveld <Joel.Bosveld@gmail.com> | 2009-07-01 23:09:59 +0800 |
commit | 3b3f9ce97cf85f0bb4f973ce409c74b7b4fde871 (patch) | |
tree | 92bcdcb60f9debd2033b0560851b3f2b1cae0bb2 /src | |
parent | 8f734f64d025eeaecc9ca9ab5b250dc305a425ea (diff) | |
download | zcomp-3b3f9ce97cf85f0bb4f973ce409c74b7b4fde871.tar.gz zcomp-3b3f9ce97cf85f0bb4f973ce409c74b7b4fde871.tar.bz2 |
Move modifier handling into a separate top level class exposed to plugins
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/event.cpp | 27 | ||||
-rw-r--r-- | src/main.cpp | 8 | ||||
-rw-r--r-- | src/modifierhandler.cpp | 204 | ||||
-rw-r--r-- | src/privatescreen.h | 10 | ||||
-rw-r--r-- | src/screen.cpp | 171 |
6 files changed, 237 insertions, 184 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e10e620..afe541e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,6 +47,7 @@ add_executable (compiz point.cpp windowgeometry.cpp icon.cpp + modifierhandler.cpp ${_bcop_sources} ) diff --git a/src/event.cpp b/src/event.cpp index c281fac..12a64ab 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -146,7 +146,8 @@ PrivateScreen::triggerButtonPressBindings (CompOption::Vector &options, { CompAction::State state = CompAction::StateInitButton; CompAction *action; - unsigned int modMask = REAL_MOD_MASK & ~ignoredModMask; + unsigned int ignored = modHandler->ignoredModMask (); + unsigned int modMask = REAL_MOD_MASK & ~ignored; unsigned int bindMods; unsigned int edge = 0; @@ -181,7 +182,7 @@ PrivateScreen::triggerButtonPressBindings (CompOption::Vector &options, { if (action->button ().button () == (int) event->button) { - bindMods = virtualToRealModMask ( + bindMods = modHandler->virtualToRealModMask ( action->button ().modifiers ()); if ((bindMods & modMask) == (event->state & modMask)) @@ -198,7 +199,7 @@ PrivateScreen::triggerButtonPressBindings (CompOption::Vector &options, if ((action->button ().button () == (int) event->button) && (action->edgeMask () & edge)) { - bindMods = virtualToRealModMask ( + bindMods = modHandler->virtualToRealModMask ( action->button ().modifiers ()); if ((bindMods & modMask) == (event->state & modMask)) @@ -246,7 +247,7 @@ PrivateScreen::triggerKeyPressBindings (CompOption::Vector &options, { CompAction::State state = 0; CompAction *action; - unsigned int modMask = REAL_MOD_MASK & ~ignoredModMask; + unsigned int modMask = REAL_MOD_MASK & ~modHandler->ignoredModMask (); unsigned int bindMods; if (event->keycode == escapeKeyCode) @@ -276,7 +277,7 @@ PrivateScreen::triggerKeyPressBindings (CompOption::Vector &options, if (isInitiateBinding (option, CompAction::BindingTypeKey, state, &action)) { - bindMods = virtualToRealModMask ( + bindMods = modHandler->virtualToRealModMask ( action->key ().modifiers ()); if (action->key ().keycode () == (int) event->keycode) @@ -304,11 +305,12 @@ PrivateScreen::triggerKeyReleaseBindings (CompOption::Vector &options, { CompAction::State state = CompAction::StateTermKey; CompAction *action; - unsigned int modMask = REAL_MOD_MASK & ~ignoredModMask; + unsigned int ignored = modHandler->ignoredModMask (); + unsigned int modMask = REAL_MOD_MASK & ~ignored; unsigned int bindMods; unsigned int mods; - mods = keycodeToModifiers (event->keycode); + mods = modHandler->keycodeToModifiers (event->keycode); if (!xkbEvent && !mods) return false; @@ -317,7 +319,7 @@ PrivateScreen::triggerKeyReleaseBindings (CompOption::Vector &options, if (isTerminateBinding (option, CompAction::BindingTypeKey, state, &action)) { - bindMods = virtualToRealModMask (action->key ().modifiers ()); + bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); if ((bindMods & modMask) == 0) { @@ -345,7 +347,8 @@ PrivateScreen::triggerStateNotifyBindings (CompOption::Vector &options, { CompAction::State state; CompAction *action; - unsigned int modMask = REAL_MOD_MASK & ~ignoredModMask; + unsigned int ignored = modHandler->ignoredModMask (); + unsigned int modMask = REAL_MOD_MASK & ~ignored; unsigned int bindMods; if (event->event_type == KeyPress) @@ -360,7 +363,7 @@ PrivateScreen::triggerStateNotifyBindings (CompOption::Vector &options, if (action->key ().keycode () == 0) { bindMods = - virtualToRealModMask (action->key ().modifiers ()); + modHandler->virtualToRealModMask (action->key ().modifiers ()); if ((event->mods & modMask & bindMods) == bindMods) { @@ -380,7 +383,7 @@ PrivateScreen::triggerStateNotifyBindings (CompOption::Vector &options, if (isTerminateBinding (option, CompAction::BindingTypeKey, state, &action)) { - bindMods = virtualToRealModMask (action->key ().modifiers ()); + bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); if ((event->mods & modMask & bindMods) != bindMods) { @@ -1494,7 +1497,7 @@ CompScreen::handleEvent (XEvent *event) } break; case MappingNotify: - priv->updateModifierMappings (); + modHandler->updateModifierMappings (); break; case MapRequest: w = findWindow (event->xmaprequest.window); diff --git a/src/main.cpp b/src/main.cpp index 957effe..100de7b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -187,6 +187,11 @@ main (int argc, char **argv) if (!screen) return 1; + modHandler = new ModifierHandler (); + + if (!modHandler) + return 1; + if (!plugins.empty ()) { CompOption::Value::Vector list; @@ -208,6 +213,8 @@ main (int argc, char **argv) if (!screen->init (displayName)) return 1; + modHandler->updateModifierMappings (); + if (!disableSm) CompSession::init (clientId); @@ -217,6 +224,7 @@ main (int argc, char **argv) CompSession::close (); delete screen; + delete modHandler; if (restartSignal) { diff --git a/src/modifierhandler.cpp b/src/modifierhandler.cpp new file mode 100644 index 0000000..3e7c480 --- /dev/null +++ b/src/modifierhandler.cpp @@ -0,0 +1,204 @@ +/* + * Copyright © 2008 Dennis Kasprzyk + * Copyright © 2007 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Dennis Kasprzyk not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Dennis Kasprzyk makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org> + * David Reveman <davidr@novell.com> + * Sam Spilsbury <smspillaz@gmail.com> + */ + +#include <core/screen.h> +#include "privatescreen.h" + +const unsigned int ModifierHandler::virtualModMask[7] = { + CompAltMask, CompMetaMask, CompSuperMask, CompHyperMask, + CompModeSwitchMask, CompNumLockMask, CompScrollLockMask +}; + +const int ModifierHandler::maskTable[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, + Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask +}; + +unsigned int +ModifierHandler::ignoredModMask () +{ + return mIgnoredModMask; +} + +const XModifierKeymap * +ModifierHandler::modMap () +{ + return mModMap; +} + +void +ModifierHandler::updateModifierMappings () +{ + unsigned int modMask[CompModNum]; + int i, minKeycode, maxKeycode, keysymsPerKeycode = 0; + KeySym* key; + + for (i = 0; i < CompModNum; i++) + modMask[i] = 0; + + XDisplayKeycodes (screen->dpy (), &minKeycode, &maxKeycode); + key = XGetKeyboardMapping (screen->dpy (), + minKeycode, (maxKeycode - minKeycode + 1), + &keysymsPerKeycode); + + if (mModMap) + XFreeModifiermap (mModMap); + + mModMap = XGetModifierMapping (screen->dpy ()); + if (mModMap && mModMap->max_keypermod > 0) + { + KeySym keysym; + int index, size, mask; + + size = maskTableSize * mModMap->max_keypermod; + + for (i = 0; i < size; i++) + { + if (!mModMap->modifiermap[i]) + continue; + + index = 0; + do + { + keysym = XKeycodeToKeysym (screen->dpy (), + mModMap->modifiermap[i], + index++); + } while (!keysym && index < keysymsPerKeycode); + + if (keysym) + { + mask = maskTable[i / mModMap->max_keypermod]; + + if (keysym == XK_Alt_L || + keysym == XK_Alt_R) + { + modMask[CompModAlt] |= mask; + } + else if (keysym == XK_Meta_L || + keysym == XK_Meta_R) + { + modMask[CompModMeta] |= mask; + } + else if (keysym == XK_Super_L || + keysym == XK_Super_R) + { + modMask[CompModSuper] |= mask; + } + else if (keysym == XK_Hyper_L || + keysym == XK_Hyper_R) + { + modMask[CompModHyper] |= mask; + } + else if (keysym == XK_Mode_switch) + { + modMask[CompModModeSwitch] |= mask; + } + else if (keysym == XK_Scroll_Lock) + { + modMask[CompModScrollLock] |= mask; + } + else if (keysym == XK_Num_Lock) + { + modMask[CompModNumLock] |= mask; + } + } + } + + for (i = 0; i < CompModNum; i++) + { + if (!modMask[i]) + modMask[i] = CompNoMask; + } + + if (memcmp (modMask, mModMask, sizeof (modMask))) + { + memcpy (mModMask, modMask, sizeof (modMask)); + + mIgnoredModMask = LockMask | + (modMask[CompModNumLock] & ~CompNoMask) | + (modMask[CompModScrollLock] & ~CompNoMask); + + screen->priv->updatePassiveKeyGrabs (); + } + } + + if (key) + XFree (key); +} + +unsigned int +ModifierHandler::virtualToRealModMask (unsigned int modMask) +{ + int i; + + for (i = 0; i < CompModNum; i++) + { + if (modMask & virtualModMask[i]) + { + modMask &= ~virtualModMask[i]; + modMask |= mModMask[i]; + } + } + + return modMask; +} + +unsigned int +ModifierHandler::keycodeToModifiers (int keycode) +{ + unsigned int mods = 0; + int mod, k; + + for (mod = 0; mod < maskTableSize; mod++) + { + for (k = 0; k < mModMap->max_keypermod; k++) + { + if (mModMap->modifiermap[mod * + mModMap->max_keypermod + k] == keycode) + mods |= maskTable[mod]; + } + } + + return mods; +} + +ModifierHandler::ModifierHandler () : + mIgnoredModMask (LockMask), + mModMap (0) +{ + for (int i = 0; i < ModNum; i++) + mModMask[i] = NoMask; +} + +ModifierHandler::~ModifierHandler () +{ + if (mModMap) + XFreeModifiermap (mModMap); + + mModMap = NULL; +} diff --git a/src/privatescreen.h b/src/privatescreen.h index 79ef8cf..bc79261 100644 --- a/src/privatescreen.h +++ b/src/privatescreen.h @@ -230,12 +230,6 @@ class PrivateScreen : public CoreOptions { void updateScreenInfo (); - void updateModifierMappings (); - - unsigned int virtualToRealModMask (unsigned int modMask); - - unsigned int keycodeToModifiers (int keycode); - Window getActiveWindow (Window root); int getWmState (Window id); @@ -343,10 +337,6 @@ class PrivateScreen : public CoreOptions { Window below; char displayString[256]; - XModifierKeymap *modMap; - unsigned int modMask[CompModNum]; - unsigned int ignoredModMask; - KeyCode escapeKeyCode; KeyCode returnKeyCode; diff --git a/src/screen.cpp b/src/screen.cpp index 1af7adf..05945ff 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -61,11 +61,6 @@ #include "privatescreen.h" #include "privatewindow.h" -static unsigned int virtualModMask[] = { - CompAltMask, CompMetaMask, CompSuperMask, CompHyperMask, - CompModeSwitchMask, CompNumLockMask, CompScrollLockMask -}; - bool inHandleEvent = false; bool screenInitalized = false; @@ -91,6 +86,7 @@ typedef struct { CompScreen *screen; +ModifierHandler *modHandler; PluginClassStorage::Indices screenPluginClassIndices (0); @@ -492,12 +488,6 @@ ScreenInterface::sessionEvent (CompSession::Event event, WRAPABLE_DEF (sessionEvent, event, arguments) -static const int maskTable[] = { - ShiftMask, LockMask, ControlMask, Mod1Mask, - Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask -}; -static const int maskTableSize = sizeof (maskTable) / sizeof (int); - static int errors = 0; static int @@ -742,140 +732,6 @@ PrivateScreen::setOption (const CompString &name, } void -PrivateScreen::updateModifierMappings () -{ - unsigned int modMask[CompModNum]; - int i, minKeycode, maxKeycode, keysymsPerKeycode = 0; - KeySym* key; - - for (i = 0; i < CompModNum; i++) - modMask[i] = 0; - - XDisplayKeycodes (dpy, &minKeycode, &maxKeycode); - key = XGetKeyboardMapping (dpy, minKeycode, maxKeycode - minKeycode + 1, - &keysymsPerKeycode); - - if (modMap) - XFreeModifiermap (modMap); - - modMap = XGetModifierMapping (dpy); - if (modMap && modMap->max_keypermod > 0) - { - KeySym keysym; - int index, size, mask; - - size = maskTableSize * modMap->max_keypermod; - - for (i = 0; i < size; i++) - { - if (!modMap->modifiermap[i]) - continue; - - index = 0; - do - { - keysym = XKeycodeToKeysym (dpy, modMap->modifiermap[i], - index++); - } while (!keysym && index < keysymsPerKeycode); - - if (keysym) - { - mask = maskTable[i / modMap->max_keypermod]; - - if (keysym == XK_Alt_L || - keysym == XK_Alt_R) - { - modMask[CompModAlt] |= mask; - } - else if (keysym == XK_Meta_L || - keysym == XK_Meta_R) - { - modMask[CompModMeta] |= mask; - } - else if (keysym == XK_Super_L || - keysym == XK_Super_R) - { - modMask[CompModSuper] |= mask; - } - else if (keysym == XK_Hyper_L || - keysym == XK_Hyper_R) - { - modMask[CompModHyper] |= mask; - } - else if (keysym == XK_Mode_switch) - { - modMask[CompModModeSwitch] |= mask; - } - else if (keysym == XK_Scroll_Lock) - { - modMask[CompModScrollLock] |= mask; - } - else if (keysym == XK_Num_Lock) - { - modMask[CompModNumLock] |= mask; - } - } - } - - for (i = 0; i < CompModNum; i++) - { - if (!modMask[i]) - modMask[i] = CompNoMask; - } - - if (memcmp (modMask, this->modMask, sizeof (modMask))) - { - memcpy (this->modMask, modMask, sizeof (modMask)); - - ignoredModMask = LockMask | - (modMask[CompModNumLock] & ~CompNoMask) | - (modMask[CompModScrollLock] & ~CompNoMask); - - updatePassiveKeyGrabs (); - } - } - - if (key) - XFree (key); -} - -unsigned int -PrivateScreen::virtualToRealModMask (unsigned int modMask) -{ - int i; - - for (i = 0; i < CompModNum; i++) - { - if (modMask & virtualModMask[i]) - { - modMask &= ~virtualModMask[i]; - modMask |= this->modMask[i]; - } - } - - return modMask; -} - -unsigned int -PrivateScreen::keycodeToModifiers (int keycode) -{ - unsigned int mods = 0; - int mod, k; - - for (mod = 0; mod < maskTableSize; mod++) - { - for (k = 0; k < modMap->max_keypermod; k++) - { - if (modMap->modifiermap[mod * - modMap->max_keypermod + k] == keycode) - mods |= maskTable[mod]; - } - } - - return mods; -} - -void PrivateScreen::processEvents () { XEvent event; @@ -2855,9 +2711,9 @@ PrivateScreen::grabUngrabKeys (unsigned int modifiers, CompScreen::checkForError (dpy); - for (ignore = 0; ignore <= ignoredModMask; ignore++) + for (ignore = 0; ignore <= modHandler->ignoredModMask (); ignore++) { - if (ignore & ~ignoredModMask) + if (ignore & ~modHandler->ignoredModMask ()) continue; if (keycode != 0) @@ -2870,15 +2726,15 @@ PrivateScreen::grabUngrabKeys (unsigned int modifiers, { if (modifiers & (1 << mod)) { - for (k = mod * modMap->max_keypermod; - k < (mod + 1) * modMap->max_keypermod; + for (k = mod * modHandler->modMap ()->max_keypermod; + k < (mod + 1) * modHandler->modMap ()->max_keypermod; k++) { - if (modMap->modifiermap[k]) + if (modHandler->modMap ()->modifiermap[k]) { grabUngrabOneKey ((modifiers & ~(1 << mod)) | ignore, - modMap->modifiermap[k], + modHandler->modMap ()->modifiermap[k], grab); } } @@ -2900,7 +2756,7 @@ PrivateScreen::addPassiveKeyGrab (CompAction::KeyBinding &key) unsigned int mask; std::list<KeyGrab>::iterator it; - mask = virtualToRealModMask (key.modifiers ()); + mask = modHandler->virtualToRealModMask (key.modifiers ()); for (it = keyGrabs.begin (); it != keyGrabs.end (); it++) { @@ -2935,7 +2791,7 @@ PrivateScreen::removePassiveKeyGrab (CompAction::KeyBinding &key) unsigned int mask; std::list<KeyGrab>::iterator it; - mask = virtualToRealModMask (key.modifiers ()); + mask = modHandler->virtualToRealModMask (key.modifiers ()); for (it = keyGrabs.begin (); it != keyGrabs.end (); it++) { @@ -4160,8 +4016,6 @@ CompScreen::init (const char *name) XSetErrorHandler (errorHandler); - priv->updateModifierMappings (); - priv->snDisplay = sn_display_new (dpy, NULL, NULL); if (!priv->snDisplay) return true; @@ -4523,9 +4377,6 @@ CompScreen::~CompScreen () if (priv->snDisplay) sn_display_unref (priv->snDisplay); - if (priv->modMap) - XFreeModifiermap (priv->modMap); - if (priv->watchPollFds) free (priv->watchPollFds); @@ -4550,8 +4401,6 @@ PrivateScreen::PrivateScreen (CompScreen *screen) : screenInfo (0), activeWindow (0), below (None), - modMap (0), - ignoredModMask (LockMask), autoRaiseTimer (), autoRaiseWindow (0), edgeDelayTimer (), @@ -4586,8 +4435,6 @@ PrivateScreen::PrivateScreen (CompScreen *screen) : desktopHintSize (0), initialized (false) { - for (int i = 0; i < CompModNum; i++) - modMask[i] = CompNoMask; memset (history, 0, sizeof (history)); gettimeofday (&lastTimeout, 0); |