summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreenscreener <honzikcernoh@gmail.com>2022-07-24 14:48:29 +0200
committerPeter Hutterer <peter.hutterer@who-t.net>2022-11-24 08:43:27 +1000
commit2a9e5953f89a7085786326e07edcb53ad821aace (patch)
treefb85eb529b2d39f6b4888ff1f0fff5c374d672c0
parent6eefde01f04454c8b0df1dedd2bbf77086206c09 (diff)
downloadxf86-input-wacom-2a9e5953f89a7085786326e07edcb53ad821aace.tar.gz
Replace valuator array with valuator mask in convertAxes
ValuatorMask has been around since xserver 1.10, released in 2011.
-rw-r--r--src/gwacom/wacom-device.c6
-rw-r--r--src/wcmConfig.c3
-rw-r--r--src/x11/xf86Wacom.c277
-rw-r--r--src/xf86WacomDefs.h2
4 files changed, 213 insertions, 75 deletions
diff --git a/src/gwacom/wacom-device.c b/src/gwacom/wacom-device.c
index 87ac433..2a9c915 100644
--- a/src/gwacom/wacom-device.c
+++ b/src/gwacom/wacom-device.c
@@ -196,6 +196,12 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
+ValuatorMask *
+valuator_mask_new(int num_valuators)
+{
+ return NULL;
+}
+
WacomDevice*
wacom_device_new(WacomDriver *driver,
const char *name,
diff --git a/src/wcmConfig.c b/src/wcmConfig.c
index 014fc70..757492d 100644
--- a/src/wcmConfig.c
+++ b/src/wcmConfig.c
@@ -98,6 +98,9 @@ WacomDevicePtr wcmAllocate(void *frontend, const char *name)
priv->tap_timer = wcmTimerNew();
priv->touch_timer = wcmTimerNew();
+ /* reusable valuator mask */
+ priv->valuator_mask = valuator_mask_new(7);
+
return priv;
error:
diff --git a/src/x11/xf86Wacom.c b/src/x11/xf86Wacom.c
index aebf27a..4cabe36 100644
--- a/src/x11/xf86Wacom.c
+++ b/src/x11/xf86Wacom.c
@@ -397,11 +397,9 @@ valuatorNumber(enum WacomAxisType which)
}
static inline void
-convertAxes(const WacomAxisData *axes, int *first_out, int *num_out, int valuators_out[7])
+convertAxes(const WacomAxisData *axes, ValuatorMask *mask)
{
- int first = 7;
- int last = -1;
- int valuators[7] = {0};
+
for (enum WacomAxisType which = _WACOM_AXIS_LAST; which > 0; which >>= 1)
{
@@ -414,51 +412,43 @@ convertAxes(const WacomAxisData *axes, int *first_out, int *num_out, int valuato
/* Positions need to match wcmInitAxis */
pos = valuatorNumber(which);
- first = min(first, pos);
- last = max(last, pos);
- valuators[pos] = value;
+ valuator_mask_set(mask, pos, value);
}
-
- if (last < 0)
- first = 0;
- *first_out = first;
- *num_out = last - first + 1;
-
- memcpy(valuators_out, &valuators[first], *num_out * sizeof(valuators[0]));
}
void wcmEmitProximity(WacomDevicePtr priv, bool is_proximity_in,
const WacomAxisData *axes)
{
InputInfoPtr pInfo = priv->frontend;
- int valuators[7] = {0};
- int first_val, num_vals;
- convertAxes(axes, &first_val, &num_vals, valuators);
+ ValuatorMask *mask = priv->valuator_mask;
+ valuator_mask_zero(mask);
+ convertAxes(axes, mask);
- xf86PostProximityEventP(pInfo->dev, is_proximity_in, first_val, num_vals, valuators);
+ xf86PostProximityEventM(pInfo->dev, is_proximity_in, mask);
}
void wcmEmitMotion(WacomDevicePtr priv, bool is_absolute, const WacomAxisData *axes)
{
InputInfoPtr pInfo = priv->frontend;
- int valuators[7] = {0};
- int first_val, num_vals;
- convertAxes(axes, &first_val, &num_vals, valuators);
+ ValuatorMask *mask = priv->valuator_mask;
+ valuator_mask_zero(mask);
+ convertAxes(axes, mask);
- xf86PostMotionEventP(pInfo->dev, is_absolute, first_val, num_vals, valuators);
+ xf86PostMotionEventM(pInfo->dev, is_absolute, mask);
}
void wcmEmitButton(WacomDevicePtr priv, bool is_absolute, int button, bool is_press, const WacomAxisData *axes)
{
InputInfoPtr pInfo = priv->frontend;
- int valuators[7] = {0};
- int first_val, num_vals;
- convertAxes(axes, &first_val, &num_vals, valuators);
+ ValuatorMask *mask = priv->valuator_mask;
+ valuator_mask_zero(mask);
+ convertAxes(axes, mask);
- xf86PostButtonEventP(pInfo->dev, is_absolute, button, is_press, first_val, num_vals, valuators);
+
+ xf86PostButtonEventM(pInfo->dev, is_absolute, button, is_press, mask);
}
void wcmEmitTouch(WacomDevicePtr priv, int type, unsigned int touchid, int x, int y)
@@ -993,60 +983,191 @@ _X_EXPORT XF86ModuleData wacomModuleData =
#ifdef ENABLE_TESTS
#include "wacom-test-suite.h"
-TEST_CASE(test_convert_axes)
+#define MAX_VALUATORS 36
+
+struct _ValuatorMask {
+ int8_t last_bit; /* highest bit set in mask */
+ int8_t has_unaccelerated;
+ uint8_t mask[(MAX_VALUATORS + 7) / 8];
+ double valuators[MAX_VALUATORS]; /* valuator data */
+ double unaccelerated[MAX_VALUATORS]; /* valuator data */
+};
+
+// The following functions are copied from https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/dix/inpututils.c
+
+int
+CountBits(const uint8_t * mask, int len)
{
- WacomAxisData axes = {0};
- int first, num;
- int valuators[7];
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < len; i++)
+ if (BitIsOn(mask, i))
+ ret++;
+
+ return ret;
+}
+
+
+/**
+ * Alloc a valuator mask large enough for num_valuators.
+ */
+ValuatorMask *
+valuator_mask_new(int num_valuators)
+{
+ /* alloc a fixed size mask for now and ignore num_valuators. in the
+ * flying-car future, when we can dynamically alloc the masks and are
+ * not constrained by signals, we can start using num_valuators */
+ ValuatorMask *mask = calloc(1, sizeof(ValuatorMask));
+
+ if (mask == NULL)
+ return NULL;
-#define reset(v) \
- for (size_t _i = 0; _i < ARRAY_SIZE(v); _i++) \
- v[_i] = 0xab;
+ mask->last_bit = -1;
+ return mask;
+}
- reset(valuators);
+/**
+ * Reset mask to zero.
+ */
+void
+valuator_mask_zero(ValuatorMask *mask)
+{
+ memset(mask, 0, sizeof(*mask));
+ mask->last_bit = -1;
+}
- convertAxes(&axes, &first, &num, valuators);
- assert(first == 0);
- assert(num == 0);
- for (size_t i = 0; i< ARRAY_SIZE(valuators); i++)
- assert(valuators[i] == 0xab);
+/**
+ * Returns the current size of the mask (i.e. the highest number of
+ * valuators currently set + 1).
+ */
+int
+valuator_mask_size(const ValuatorMask *mask)
+{
+ return mask->last_bit + 1;
+}
+
+/**
+ * Returns the number of valuators set in the given mask.
+ */
+int
+valuator_mask_num_valuators(const ValuatorMask *mask)
+{
+ return CountBits(mask->mask, min(mask->last_bit + 1, MAX_VALUATORS));
+}
+
+/**
+ * Return true if the valuator is set in the mask, or false otherwise.
+ */
+int
+valuator_mask_isset(const ValuatorMask *mask, int valuator)
+{
+ return mask->last_bit >= valuator && BitIsOn(mask->mask, valuator);
+}
+
+static inline void
+_valuator_mask_set_double(ValuatorMask *mask, int valuator, double data)
+{
+ mask->last_bit = max(valuator, mask->last_bit);
+ SetBit(mask->mask, valuator);
+ mask->valuators[valuator] = data;
+}
+
+/**
+ * Set the valuator to the given floating-point data.
+ */
+void
+valuator_mask_set_double(ValuatorMask *mask, int valuator, double data)
+{
+ if (mask->has_unaccelerated) {
+ wcmLog(null, 0, "Do not mix valuator types, zero mask first\n");
+ }
+ _valuator_mask_set_double(mask, valuator, data);
+}
+
+/**
+ * Set the valuator to the given integer data.
+ */
+void
+valuator_mask_set(ValuatorMask *mask, int valuator, int data)
+{
+ valuator_mask_set_double(mask, valuator, data);
+}
+
+/**
+ * Return the requested valuator value as a double. If the mask bit is not
+ * set for the given valuator, the returned value is undefined.
+ */
+ double
+valuator_mask_get_double(const ValuatorMask *mask, int valuator)
+{
+ return mask->valuators[valuator];
+}
+
+/**
+ * Return the requested valuator value as an integer, rounding towards zero.
+ * If the mask bit is not set for the given valuator, the returned value is
+ * undefined.
+ */
+int
+valuator_mask_get(const ValuatorMask *mask, int valuator)
+{
+ return trunc(valuator_mask_get_double(mask, valuator));
+}
+
+
+TEST_CASE(test_convert_axes)
+{
+ WacomAxisData axes = {0};
+ ValuatorMask *mask = valuator_mask_new(7);
+
+ convertAxes(&axes, mask);
+ assert(valuator_mask_num_valuators(mask) == 0);
+ assert(valuator_mask_size(mask) == 0);
+ for (size_t i = 0; i< 9; i++)
+ assert(!valuator_mask_isset(mask, i));
- reset(valuators);
memset(&axes, 0, sizeof(axes));
+ valuator_mask_zero(mask);
/* Check conversion for single value with first_valuator != 0 */
wcmAxisSet(&axes, WACOM_AXIS_PRESSURE, 1); /* pos 2 */
- convertAxes(&axes, &first, &num, valuators);
- assert(first == 2);
- assert(num == 1);
- assert(valuators[0] == 1);
- assert(valuators[1] == 0xab);
- assert(valuators[2] == 0xab);
- assert(valuators[3] == 0xab);
- assert(valuators[4] == 0xab);
- assert(valuators[5] == 0xab);
- assert(valuators[6] == 0xab);
-
- reset(valuators);
+ convertAxes(&axes, mask);
+ assert(valuator_mask_num_valuators(mask) == 1);
+ assert(valuator_mask_size(mask) == 3);
+ assert(!valuator_mask_isset(mask, 0));
+ assert(!valuator_mask_isset(mask, 1));
+ assert(valuator_mask_isset(mask, 2));
+ assert(valuator_mask_get(mask, 2) == 1);
+ assert(!valuator_mask_isset(mask, 3));
+ assert(!valuator_mask_isset(mask, 4));
+ assert(!valuator_mask_isset(mask, 5));
+ assert(!valuator_mask_isset(mask, 6));
+ assert(!valuator_mask_isset(mask, 7));
+ assert(!valuator_mask_isset(mask, 8));
+
memset(&axes, 0, sizeof(axes));
+ valuator_mask_zero(mask);
/* Check conversion for gaps with first_valuator != 0 */
wcmAxisSet(&axes, WACOM_AXIS_PRESSURE, 1); /* pos 2 */
wcmAxisSet(&axes, WACOM_AXIS_WHEEL, 2); /* pos 5 */
- convertAxes(&axes, &first, &num, valuators);
- assert(first == 2);
- assert(num == 4);
- assert(valuators[0] == 1);
- assert(valuators[1] == 0);
- assert(valuators[2] == 0);
- assert(valuators[3] == 2);
- assert(valuators[4] == 0xab);
- assert(valuators[5] == 0xab);
- assert(valuators[6] == 0xab);
-
- reset(valuators);
+ convertAxes(&axes, mask);
+ assert(valuator_mask_num_valuators(mask) == 2);
+ assert(valuator_mask_size(mask) == 6);
+ assert(!valuator_mask_isset(mask, 0));
+ assert(!valuator_mask_isset(mask, 1));
+ assert(valuator_mask_isset(mask, 2));
+ assert(valuator_mask_get(mask, 2) == 1);
+ assert(!valuator_mask_isset(mask, 3));
+ assert(!valuator_mask_isset(mask, 4));
+ assert(valuator_mask_isset(mask, 5));
+ assert(valuator_mask_get(mask, 5) == 2);
+ assert(!valuator_mask_isset(mask, 6));
+
memset(&axes, 0, sizeof(axes));
+ valuator_mask_zero(mask);
/* Check conversion for valuators with duplicate uses. Note that this
* test is implementation-dependent: the loop in convertAxes decides
@@ -1059,17 +1180,23 @@ TEST_CASE(test_convert_axes)
wcmAxisSet(&axes, WACOM_AXIS_RING, 3); /* pos 5 */
wcmAxisSet(&axes, WACOM_AXIS_WHEEL, 2); /* also pos 5 */
- convertAxes(&axes, &first, &num, valuators);
- assert(first == 2);
- assert(num == 4);
- assert(valuators[0] == 1);
- assert(valuators[1] == 10);
- assert(valuators[2] == 11);
- assert(valuators[3] == 2);
- assert(valuators[4] == 0xab);
- assert(valuators[5] == 0xab);
- assert(valuators[6] == 0xab);
-
+ convertAxes(&axes, mask);
+ assert(valuator_mask_num_valuators(mask) == 4);
+ assert(valuator_mask_size(mask) == 6);
+ assert(!valuator_mask_isset(mask, 0));
+ assert(!valuator_mask_isset(mask, 1));
+ assert(valuator_mask_isset(mask, 2));
+ assert(valuator_mask_get(mask, 2) == 1);
+ assert(valuator_mask_isset(mask, 3));
+ assert(valuator_mask_get(mask, 3) == 10);
+ assert(valuator_mask_isset(mask, 4));
+ assert(valuator_mask_get(mask, 4) == 11);
+ assert(valuator_mask_isset(mask, 5));
+ assert(valuator_mask_get(mask, 5) == 2);
+ assert(!valuator_mask_isset(mask, 6));
+ assert(!valuator_mask_isset(mask, 7));
+
+ free(mask);
}
#endif
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index 886bf77..df21856 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -302,6 +302,8 @@ struct _WacomDeviceRec
WacomTimerPtr serial_timer; /* timer used for serial number property update */
WacomTimerPtr tap_timer; /* timer used for tap timing */
WacomTimerPtr touch_timer; /* timer used for touch switch property update */
+
+ ValuatorMask *valuator_mask; /* reusable valuator mask for sending events without reallocation */
};
#define MAX_SAMPLES 20