Commit: 75ab57efed93204659c626fa8d5aa94837984de4
Author: Bastien Montagne
Date:   Mon Jan 13 17:50:12 2014 +0100
https://developer.blender.org/rB75ab57efed93204659c626fa8d5aa94837984de4

Fix T38190: Linux tablet: Issue with XInput/GHOST?

With edits by Campbell, thanks!

Looks like in some cases (driver dependent?), `XDeviceMotionEvent` get 
generated with only part of expected data
(e.g. only x coordinate, only pressure, etc.), data which did not change since 
last event being NULL.
We know which data to actually handle with `XDeviceMotionEvent.first_axis` and 
`XDeviceMotionEvent.axes_count` values.

Reviewed by: campbellbarton

Differential Revision: https://developer.blender.org/D208

===================================================================

M       intern/ghost/intern/GHOST_SystemX11.cpp

===================================================================

diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp 
b/intern/ghost/intern/GHOST_SystemX11.cpp
index 3b12d91..1d625a5 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -1148,21 +1148,44 @@ GHOST_SystemX11::processEvent(XEvent *xe)
 #ifdef WITH_X11_XINPUT
                        if (xe->type == m_xtablet.MotionEvent) {
                                XDeviceMotionEvent *data = (XDeviceMotionEvent 
*)xe;
+                               const unsigned char axis_first = 
data->first_axis;
+                               const unsigned char axes_end = axis_first + 
data->axes_count;  /* after the last */
+                               int axis_value;
 
                                /* stroke might begin without leading ProxyIn 
event,
                                 * this happens when window is opened when 
stylus is already hovering
                                 * around tablet surface */
                                setTabletMode(this, window, data->deviceid);
 
-                               window->GetTabletData()->Pressure =
-                                       data->axis_data[2] / 
((float)m_xtablet.PressureLevels);
+                               /* Note: This event might be generated with 
incomplete dataset (don't exactly know why, looks like in
+                                *       some cases, if the value does not 
change, it is not included in subsequent XDeviceMotionEvent
+                                *       events). So we have to check which 
values this event actually contains!
+                                */
+
+#define AXIS_VALUE_GET(axis, val)  ((axis_first <= axis && axes_end > axis) && 
((void)(val = data->axis_data[axis]), true))
+
+                               if (AXIS_VALUE_GET(2, axis_value)) {
+                                       window->GetTabletData()->Pressure = 
axis_value / ((float)m_xtablet.PressureLevels);
+                               }
+
+                               /* the (short) cast and the & 0xffff is bizarre 
and unexplained anywhere,
+                                * but I got garbage data without it. Found it 
in the xidump.c source --matt
+                                *
+                                * The '& 0xffff' just truncates the value to 
its two lowest bytes, this probably means
+                                * some drivers do not properly set the whole 
int value? Since we convert to float afterward,
+                                * I don't think we need to cast to short here, 
but do not have a device to check this. --mont29
+                                */
+                               if (AXIS_VALUE_GET(3, axis_value)) {
+                                       window->GetTabletData()->Xtilt = 
(short)(axis_value & 0xffff) /
+                                                                        
((float)m_xtablet.XtiltLevels);
+                               }
+                               if (AXIS_VALUE_GET(4, axis_value)) {
+                                       window->GetTabletData()->Ytilt = 
(short)(axis_value & 0xffff) /
+                                                                        
((float)m_xtablet.YtiltLevels);
+                               }
+
+#undef AXIS_VALUE_GET
 
-                               /* the (short) cast and the &0xffff is bizarre 
and unexplained anywhere,
-                                * but I got garbage data without it. Found it 
in the xidump.c source --matt */
-                               window->GetTabletData()->Xtilt =
-                                       (short)(data->axis_data[3] & 0xffff) / 
((float)m_xtablet.XtiltLevels);
-                               window->GetTabletData()->Ytilt =
-                                       (short)(data->axis_data[4] & 0xffff) / 
((float)m_xtablet.YtiltLevels);
                        }
                        else if (xe->type == m_xtablet.ProxInEvent) {
                                XProximityNotifyEvent *data = 
(XProximityNotifyEvent *)xe;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to