summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@gmail.com>2009-07-01 21:26:10 +0800
committerJoel Bosveld <Joel.Bosveld@gmail.com>2009-07-01 23:09:59 +0800
commit3b3f9ce97cf85f0bb4f973ce409c74b7b4fde871 (patch)
tree92bcdcb60f9debd2033b0560851b3f2b1cae0bb2 /src
parent8f734f64d025eeaecc9ca9ab5b250dc305a425ea (diff)
downloadzcomp-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.txt1
-rw-r--r--src/event.cpp27
-rw-r--r--src/main.cpp8
-rw-r--r--src/modifierhandler.cpp204
-rw-r--r--src/privatescreen.h10
-rw-r--r--src/screen.cpp171
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);