Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2014-01-13 20:50:12 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2014-01-13 20:51:17 +0400
commit75ab57efed93204659c626fa8d5aa94837984de4 (patch)
tree6836963e1807d2ba02d20109c13f34129eeae893 /intern/ghost
parent02386bd1e3b09dfa5716355af04c0f846291e641 (diff)
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
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp39
1 files changed, 31 insertions, 8 deletions
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 3b12d917ced..1d625a5329f 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;