[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53850] trunk/blender/intern/ghost/intern/ GHOST_SystemX11.cpp: fix for glitch in X11 with tablets.

Campbell Barton ideasman42 at gmail.com
Wed Jan 16 19:05:18 CET 2013


Revision: 53850
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53850
Author:   campbellbarton
Date:     2013-01-16 18:05:17 +0000 (Wed, 16 Jan 2013)
Log Message:
-----------
fix for glitch in X11 with tablets.

Notices this while using continuous-grab, since this is disabled when the tablet is being used.
Quite often I would use the tablet then drag a button with the mouse but blender would still have the tablet enabled.
This error would cause other parts of blender to behave incorrectly too since wmEvents would have wmTabletData set, operators check for this in some cases.


The problem was blender didn't reliably get ProximityOut events, eg:
  moving the cursor outside the window with the tablet, then back over the window with the mouse -
  meant blender didn't get a 'ProximityOut' event and would keep the active stylus value set.

For now, when the processing events and the active stylus is set, run a check that the tablet is still in proximity.

Modified Paths:
--------------
    trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp	2013-01-16 17:07:29 UTC (rev 53849)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp	2013-01-16 18:05:17 UTC (rev 53850)
@@ -518,6 +518,40 @@
 }
 #endif /* WITH_X11_XINPUT */
 
+#ifdef WITH_X11_XINPUT
+static bool checkTabletProximity(Display *display, XDevice *device)
+{
+	/* see: state.c from xinput, to get more data out of the device */
+	XDeviceState *state;
+
+	state = XQueryDeviceState(display, device);
+
+	if (state) {
+		XInputClass *cls = state->data;
+		// printf("%d class%s :\n", state->num_classes,
+		//       (state->num_classes > 1) ? "es" : "");
+		for(int loop=0; loop < state->num_classes; loop++) {
+			switch(cls->c_class) {
+				case ValuatorClass:
+					XValuatorState *val_state = (XValuatorState *) cls;
+					// printf("ValuatorClass Mode=%s Proximity=%s\n",
+					//        val_state->mode & 1 ? "Absolute" : "Relative",
+					//        val_state->mode & 2 ? "Out" : "In");
+
+					if ((val_state->mode & 2) == 0) {
+						XFreeDeviceState(state);
+						return true;
+					}
+					break;
+			}
+			cls = (XInputClass *) ((char *) cls + cls->length);
+		}
+		XFreeDeviceState(state);
+	}
+	return false;
+}
+#endif /* WITH_X11_XINPUT */
+
 void
 GHOST_SystemX11::processEvent(XEvent *xe)
 {
@@ -527,7 +561,23 @@
 	if (!window) {
 		return;
 	}
-	
+
+#ifdef WITH_X11_XINPUT
+	/* Proximity-Out Events are not reliable, if the tablet is active - check on each event
+	 * this adds a little overhead but only while the tablet is in use.
+	 * in the futire we could have a ghost call window->CheckTabletProximity()
+	 * but for now enough parts of the code are checking 'Active'
+	 * - campbell */
+	if (window->GetTabletData()->Active != GHOST_kTabletModeNone) {
+		if (checkTabletProximity(xe->xany.display, m_xtablet.StylusDevice) == false &&
+		    checkTabletProximity(xe->xany.display, m_xtablet.EraserDevice) == false)
+		{
+			// printf("proximity disable\n");
+			window->GetTabletData()->Active = GHOST_kTabletModeNone;
+		}
+	}
+#endif /* WITH_X11_XINPUT */
+
 	switch (xe->type) {
 		case Expose:
 		{




More information about the Bf-blender-cvs mailing list