Hi,

This patch allows for modifier handling to be used by other plugins.
It contains some simple functions to update core's modifier map, get
the ignored mod mask, convert virtual to real mod masks and get
modifiers for a keycode. It is necessary for so that plugins like
VPSwitch can handle modifier key events in X without having to
re-implement code to understand those keycodes.

This should hopefully be useful for snap as well.

Cheers,

Sam

-- 
Sam Spilsbury
From 2a0e942650f337e9fe24d08dbd128b990fc6b7dd Mon Sep 17 00:00:00 2001
From: Sam Spilsbury <[email protected]>
Date: Fri, 6 Feb 2009 21:33:58 +0900
Subject: [PATCH] Separate Modifier handling into a separate class

---
 include/composite/composite.h |    3 -
 include/core/CMakeLists.txt   |    3 +-
 include/core/screen.h         |    4 +
 src/CMakeLists.txt            |    3 +-
 src/event.cpp                 |   25 +++---
 src/plugin.cpp                |    5 +
 src/privatescreen.h           |   12 +---
 src/screen.cpp                |  177 +++-------------------------------------
 8 files changed, 42 insertions(+), 190 deletions(-)

diff --git a/include/composite/composite.h b/include/composite/composite.h
index dc6a597..3f15364 100644
--- a/include/composite/composite.h
+++ b/include/composite/composite.h
@@ -1,6 +1,3 @@
-
-
-
 /*
  * Copyright © 2008 Dennis Kasprzyk
  * Copyright © 2007 Novell, Inc.
diff --git a/include/core/CMakeLists.txt b/include/core/CMakeLists.txt
index dc94393..81b8a53 100644
--- a/include/core/CMakeLists.txt
+++ b/include/core/CMakeLists.txt
@@ -5,6 +5,7 @@ set (_headers
     icon.h
     match.h
     metadata.h
+    modifierhandler.h
     option.h
     output.h
     plugin.h
@@ -24,4 +25,4 @@ set (_headers
 install (
     FILES ${_headers}
     DESTINATION ${includedir}/compiz/core
-)
\ No newline at end of file
+)
diff --git a/include/core/screen.h b/include/core/screen.h
index c30da1f..1114ab5 100644
--- a/include/core/screen.h
+++ b/include/core/screen.h
@@ -36,6 +36,7 @@
 #include <core/match.h>
 #include <core/privates.h>
 #include <core/region.h>
+#include <core/modifierhandler.h>
 
 class CompScreen;
 class PrivateScreen;
@@ -178,6 +179,8 @@ class CompScreen :
 
 	int syncEvent ();
 
+	ModifierHandler modHandler ();
+
 	SnDisplay * snDisplay ();
 	
 	Window activeWindow ();
@@ -359,6 +362,7 @@ class CompScreen :
 	friend class CompTimer;
 	friend class CompWindow;
 	friend class PrivateWindow;
+	friend class ModifierHandler;
 
     private:
 	PrivateScreen *priv;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2bf2db4..32c48b5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -39,6 +39,7 @@ add_executable (compiz
     point.cpp
     windowgeometry.cpp
     icon.cpp
+    modifierhandler.cpp
 )
 
 target_link_libraries (
@@ -48,4 +49,4 @@ target_link_libraries (
 install (
     TARGETS compiz
     DESTINATION ${exec_prefix}
-)
\ No newline at end of file
+)
diff --git a/src/event.cpp b/src/event.cpp
index 1aab5ac..53fbea3 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 = mModHandler.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 = mModHandler.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 = mModHandler.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 & ~mModHandler.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 = mModHandler.virtualToRealModMask (
 		action->key ().modifiers ());
 
 	    if (action->key ().keycode () == (int) event->keycode)
@@ -304,11 +305,11 @@ PrivateScreen::triggerKeyReleaseBindings (CompOption::Vector &options,
 {
     CompAction::State state = CompAction::StateTermKey;
     CompAction        *action;
-    unsigned int      modMask = REAL_MOD_MASK & ~ignoredModMask;
+    unsigned int      modMask = REAL_MOD_MASK & ~mModHandler.ignoredModMask ();
     unsigned int      bindMods;
     unsigned int      mods;
 
-    mods = keycodeToModifiers (event->keycode);
+    mods = mModHandler.keycodeToModifiers (event->keycode);
     if (!xkbEvent && !mods)
 	return false;
 
@@ -317,7 +318,7 @@ PrivateScreen::triggerKeyReleaseBindings (CompOption::Vector &options,
 	if (isTerminateBinding (option, CompAction::BindingTypeKey,
 				state, &action))
 	{
-	    bindMods = virtualToRealModMask (action->key ().modifiers ());
+	    bindMods = mModHandler.virtualToRealModMask (action->key ().modifiers ());
 
 	    if ((bindMods & modMask) == 0)
 	    {
@@ -345,7 +346,7 @@ PrivateScreen::triggerStateNotifyBindings (CompOption::Vector  &options,
 {
     CompAction::State state;
     CompAction        *action;
-    unsigned int      modMask = REAL_MOD_MASK & ~ignoredModMask;
+    unsigned int      modMask = REAL_MOD_MASK & ~mModHandler.ignoredModMask ();
     unsigned int      bindMods;
 
     if (event->event_type == KeyPress)
@@ -360,7 +361,7 @@ PrivateScreen::triggerStateNotifyBindings (CompOption::Vector  &options,
 		if (action->key ().keycode () == 0)
 		{
 		    bindMods =
-			virtualToRealModMask (action->key ().modifiers ());
+			mModHandler.virtualToRealModMask (action->key ().modifiers ());
 
 		    if ((event->mods & modMask & bindMods) == bindMods)
 		    {
@@ -380,7 +381,7 @@ PrivateScreen::triggerStateNotifyBindings (CompOption::Vector  &options,
 	    if (isTerminateBinding (option, CompAction::BindingTypeKey,
 				    state, &action))
 	    {
-		bindMods = virtualToRealModMask (action->key ().modifiers ());
+		bindMods = mModHandler.virtualToRealModMask (action->key ().modifiers ());
 
 		if ((event->mods & modMask & bindMods) != bindMods)
 		{
@@ -1477,7 +1478,7 @@ CompScreen::handleEvent (XEvent *event)
 	}
 	break;
     case MappingNotify:
-	priv->updateModifierMappings ();
+	priv->mModHandler.updateModifierMappings ();
 	break;
     case MapRequest:
 	w = findWindow (event->xmaprequest.window);
diff --git a/src/plugin.cpp b/src/plugin.cpp
index 61765f5..b29814d 100644
--- a/src/plugin.cpp
+++ b/src/plugin.cpp
@@ -190,6 +190,11 @@ dlloaderLoadPlugin (CompPlugin *p,
 	return cloaderLoadPlugin (p, path, name);
     }
 
+    error = dlerror ();
+
+    if (error)
+	fprintf (stderr, "errors while loading plugin %s:\n        %s\n", name, error);
+
     free (file);
 
     p->devPrivate.ptr = dlhand;
diff --git a/src/privatescreen.h b/src/privatescreen.h
index f5699b1..4fb97b8 100644
--- a/src/privatescreen.h
+++ b/src/privatescreen.h
@@ -319,12 +319,6 @@ class PrivateScreen {
 
 	void updateScreenInfo ();
 
-	void updateModifierMappings ();
-
-	unsigned int virtualToRealModMask (unsigned int modMask);
-
-	unsigned int keycodeToModifiers (int keycode);
-
 	Window getActiveWindow (Window root);
 
 	int getWmState (Window id);
@@ -423,6 +417,8 @@ class PrivateScreen {
 
 	std::vector<XineramaScreenInfo> screenInfo;
 
+	ModifierHandler mModHandler;
+
 	SnDisplay *snDisplay;
 
 	unsigned int lastPing;
@@ -433,10 +429,6 @@ class PrivateScreen {
 	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 642cf10..d0a0871 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;
 
 CompScreen *targetScreen = NULL;
@@ -586,12 +581,6 @@ const CompMetadata::OptionInfo coreOptionInfo[COMP_OPTION_NUM] = {
     { "focus_prevention_match", "match", 0, 0, 0 }
 };
 
-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
@@ -692,6 +681,11 @@ CompScreen::syncEvent ()
     return priv->syncEvent;
 }
 
+ModifierHandler
+CompScreen::modHandler ()
+{
+    return priv->mModHandler;
+}
 
 SnDisplay *
 CompScreen::snDisplay ()
@@ -891,142 +885,6 @@ CompScreen::setOption (const char        *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 (this->dpy, &minKeycode, &maxKeycode);
-    key = XGetKeyboardMapping (this->dpy,
-			       minKeycode, (maxKeycode - minKeycode + 1),
-			       &keysymsPerKeycode);
-
-    if (this->modMap)
-	XFreeModifiermap (this->modMap);
-
-    this->modMap = XGetModifierMapping (this->dpy);
-    if (this->modMap && this->modMap->max_keypermod > 0)
-    {
-	KeySym keysym;
-	int    index, size, mask;
-
-	size = maskTableSize * this->modMap->max_keypermod;
-
-	for (i = 0; i < size; i++)
-	{
-	    if (!this->modMap->modifiermap[i])
-		continue;
-
-	    index = 0;
-	    do
-	    {
-		keysym = XKeycodeToKeysym (this->dpy,
-					   this->modMap->modifiermap[i],
-					   index++);
-	    } while (!keysym && index < keysymsPerKeycode);
-
-	    if (keysym)
-	    {
-		mask = maskTable[i / this->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));
-
-	    this->ignoredModMask = LockMask |
-		(modMask[CompModNumLock]    & ~CompNoMask) |
-		(modMask[CompModScrollLock] & ~CompNoMask);
-
-	    this->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;
@@ -3005,9 +2863,9 @@ PrivateScreen::grabUngrabKeys (unsigned int modifiers,
 
     CompScreen::checkForError (dpy);
 
-    for (ignore = 0; ignore <= ignoredModMask; ignore++)
+    for (ignore = 0; ignore <= mModHandler.ignoredModMask (); ignore++)
     {
-	if (ignore & ~ignoredModMask)
+	if (ignore & ~mModHandler.ignoredModMask ())
 	    continue;
 
 	if (keycode != 0)
@@ -3020,15 +2878,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 * mModHandler.modMap ()->max_keypermod;
+			 k < (mod + 1) * mModHandler.modMap ()->max_keypermod;
 			 k++)
 		    {
-			if (modMap->modifiermap[k])
+			if (mModHandler.modMap ()->modifiermap[k])
 			{
 			    grabUngrabOneKey ((modifiers & ~(1 << mod)) |
 					      ignore,
-					      modMap->modifiermap[k],
+					      mModHandler.modMap ()->modifiermap[k],
 					      grab);
 			}
 		    }
@@ -3050,7 +2908,7 @@ PrivateScreen::addPassiveKeyGrab (CompAction::KeyBinding &key)
     unsigned int                 mask;
     std::list<KeyGrab>::iterator it;
 
-    mask = virtualToRealModMask (key.modifiers ());
+    mask = mModHandler.virtualToRealModMask (key.modifiers ());
 
     for (it = keyGrabs.begin (); it != keyGrabs.end (); it++)
     {
@@ -3085,7 +2943,7 @@ PrivateScreen::removePassiveKeyGrab (CompAction::KeyBinding &key)
     unsigned int                 mask;
     std::list<KeyGrab>::iterator it;
 
-    mask = virtualToRealModMask (key.modifiers ());
+    mask = mModHandler.virtualToRealModMask (key.modifiers ());
 
     for (it = keyGrabs.begin (); it != keyGrabs.end (); it++)
     {
@@ -4408,7 +4266,7 @@ CompScreen::init (const char *name)
 
     XSetErrorHandler (errorHandler);
 
-    priv->updateModifierMappings ();
+    priv->mModHandler.updateModifierMappings ();
 
     priv->snDisplay = sn_display_new (dpy, NULL, NULL);
     if (!priv->snDisplay)
@@ -4792,9 +4650,6 @@ CompScreen::~CompScreen ()
     XSync (priv->dpy, False);
     XCloseDisplay (priv->dpy);
 
-    if (priv->modMap)
-	XFreeModifiermap (priv->modMap);
-
     if (priv->watchPollFds)
 	free (priv->watchPollFds);
 
@@ -4816,8 +4671,6 @@ PrivateScreen::PrivateScreen (CompScreen *screen) :
     screenInfo (0),
     activeWindow (0),
     below (None),
-    modMap (0),
-    ignoredModMask (LockMask),
     autoRaiseTimer (),
     autoRaiseWindow (0),
     edgeDelayTimer (),
@@ -4855,8 +4708,6 @@ PrivateScreen::PrivateScreen (CompScreen *screen) :
     initialized (false),
     opt (COMP_OPTION_NUM)
 {
-    for (int i = 0; i < CompModNum; i++)
-	modMask[i] = CompNoMask;
     memset (history, 0, sizeof (history));
     gettimeofday (&lastTimeout, 0);
 }
-- 
1.5.6

_______________________________________________
Dev mailing list
[email protected]
http://lists.compiz-fusion.org/mailman/listinfo/dev

Reply via email to