tech-x11 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Proposed changes for xf86-input-ws to better support tablets and digitizers
Dear tech-x11,
I have used the patch below for a bit, and it suits my use case
quite well. This e-mail requests feedback on whether these changes
are worth integrating for other users.
The patch:
a) extends the xorg.conf configuration for "ws" to allow minimum
and maximum Z and W values to be specified (it was already possible
to do so for X and Y, but Z and W were omitted),
b) adds a "WS Pointer Pressure Calibration" property for xinput, similar
to the "WS Pointer Axis Calibration" property,
with the main purpose of supporting pointing devices with pressure data.
--
Kind regards,
Yorick Hardy
Index: external/mit/xf86-input-ws/dist/src/ws.h
===================================================================
RCS file: /cvsroot/xsrc/external/mit/xf86-input-ws/dist/src/ws.h,v
retrieving revision 1.3
diff -u -u -r1.3 ws.h
--- external/mit/xf86-input-ws/dist/src/ws.h 1 Jan 2019 00:34:52 -0000 1.3
+++ external/mit/xf86-input-ws/dist/src/ws.h 24 Oct 2019 18:53:16 -0000
@@ -27,7 +27,7 @@
# define DBG(lvl, f)
#endif
-#define NAXES 2 /* X and Y axes only */
+#define NAXES 4 /* X, Y, Z and W axes */
#define NBUTTONS 32 /* max theoretical buttons */
#define DFLTBUTTONS 3 /* default number of buttons */
#define NUMEVENTS 16 /* max # of ws events to read at once */
@@ -38,6 +38,7 @@
unsigned int buttons; /* # of buttons */
unsigned int lastButtons; /* last state of buttons */
int min_x, max_x, min_y, max_y; /* coord space */
+ int min_z, max_z, min_w, max_w; /* coord space */
int swap_axes;
int raw;
int inv_x, inv_y;
Index: external/mit/xf86-input-ws/dist/include/ws-properties.h
===================================================================
RCS file: /cvsroot/xsrc/external/mit/xf86-input-ws/dist/include/ws-properties.h,v
retrieving revision 1.1.1.1
diff -u -u -r1.1.1.1 ws-properties.h
--- external/mit/xf86-input-ws/dist/include/ws-properties.h 27 Nov 2009 14:17:19 -0000 1.1.1.1
+++ external/mit/xf86-input-ws/dist/include/ws-properties.h 24 Oct 2019 18:53:37 -0000
@@ -27,6 +27,10 @@
/* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */
#define WS_PROP_CALIBRATION "WS Pointer Axis Calibration"
+/* Run-time pressure calibration */
+/* CARD32, 2 values [minz, maxz], or no values for unset */
+#define WS_PROP_PRESSURE "WS Pointer Pressure Calibration"
+
/* Swap x and y axis. */
/* BOOL */
#define WS_PROP_SWAP_AXES "WS Pointer Axes Swap"
Index: external/mit/xf86-input-ws/dist/src/ws.c
===================================================================
RCS file: /cvsroot/xsrc/external/mit/xf86-input-ws/dist/src/ws.c,v
retrieving revision 1.11
diff -u -u -r1.11 ws.c
--- external/mit/xf86-input-ws/dist/src/ws.c 14 Apr 2017 19:19:43 -0000 1.11
+++ external/mit/xf86-input-ws/dist/src/ws.c 24 Oct 2019 18:54:07 -0000
@@ -66,6 +66,7 @@
static int wsSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr, BOOL);
static Atom prop_calibration = 0;
+static Atom prop_pressure = 0;
static Atom prop_swap = 0;
#ifdef DEBUG
@@ -271,7 +272,13 @@
priv->max_x = screenInfo.screens[priv->screen_no]->width - 1;
priv->min_y = 0;
priv->max_y = screenInfo.screens[priv->screen_no]->height - 1;
- priv->raw = 0;
+ priv->min_z = -1;
+ priv->max_z = -1;
+ priv->min_w = -1;
+ priv->max_w = -1;
+ priv->raw = 0;
+ /* Allow options to override this */
+ priv->raw = xf86SetBoolOption(pInfo->options, "Raw", priv->raw);
/* don't rely on the device type - we may be listening to a mux */
if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS,
@@ -302,6 +309,8 @@
xf86Msg(X_CONFIG,
"%s device will work in raw mode\n",
pInfo->name);
+ /* Assume a touch panel / tablet since we are in raw mode */
+ priv->type = WSMOUSE_TYPE_TPANEL;
}
/* Allow options to override this */
@@ -317,6 +326,18 @@
priv->max_y = xf86SetIntOption(pInfo->options, "MaxY", priv->max_y);
xf86Msg(X_INFO, "%s maximum y position: %d\n",
pInfo->name, priv->max_y);
+ priv->min_z = xf86SetIntOption(pInfo->options, "MinZ", priv->min_z);
+ xf86Msg(X_INFO, "%s minimum z position: %d\n",
+ pInfo->name, priv->min_z);
+ priv->max_z = xf86SetIntOption(pInfo->options, "MaxZ", priv->max_z);
+ xf86Msg(X_INFO, "%s maximum z position: %d\n",
+ pInfo->name, priv->max_z);
+ priv->min_w = xf86SetIntOption(pInfo->options, "MinW", priv->min_w);
+ xf86Msg(X_INFO, "%s minimum w position: %d\n",
+ pInfo->name, priv->min_w);
+ priv->max_w = xf86SetIntOption(pInfo->options, "MaxW", priv->max_w);
+ xf86Msg(X_INFO, "%s maximum w position: %d\n",
+ pInfo->name, priv->max_w);
pInfo->device_control = wsProc;
pInfo->read_input = wsReadInput;
@@ -405,7 +426,7 @@
InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate;
WSDevicePtr priv = (WSDevicePtr)pInfo->private;
unsigned char map[NBUTTONS + 1];
- int i, xmin, xmax, ymin, ymax;
+ int i, xmin, xmax, ymin, ymax, zmin, zmax, wmin, wmax;
Atom btn_labels[NBUTTONS] = {0};
Atom axes_labels[NAXES] = {0};
@@ -434,6 +455,11 @@
ymax = -1;
}
+ zmin = priv->min_z;
+ zmax = priv->max_z;
+ wmin = priv->min_w;
+ wmax = priv->max_w;
+
if (priv->swap_axes) {
int tmp;
tmp = xmin;
@@ -446,9 +472,13 @@
if ((priv->type == WSMOUSE_TYPE_TPANEL)) {
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+ axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
+ axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_DISTANCE);
} else {
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+ axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Z);
+ axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
}
if (!InitValuatorClassDeviceStruct(pWS,
NAXES,
@@ -478,6 +508,24 @@
);
xf86InitValuatorDefaults(pWS, 1);
+ xf86InitValuatorAxisStruct(pWS, 2,
+ axes_labels[2],
+ zmin, zmax, 1, 0, 1
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
+ , priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative
+#endif
+ );
+ xf86InitValuatorDefaults(pWS, 2);
+
+ xf86InitValuatorAxisStruct(pWS, 3,
+ axes_labels[3],
+ wmin, wmax, 1, 0, 1
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
+ , priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative
+#endif
+ );
+ xf86InitValuatorDefaults(pWS, 3);
+
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
xf86MotionHistoryAllocate(pInfo);
AssignTypeAndName(pWS, pInfo->atom, pInfo->name);
@@ -582,7 +630,7 @@
int n, c;
struct wscons_event *event = eventList;
unsigned char *pBuf;
- int ax, ay;
+ int ax, ay, az, aw;
priv = pInfo->private;
@@ -602,7 +650,7 @@
int dx = 0, dy = 0, dz = 0, dw = 0;
int zbutton = 0, wbutton = 0;
- ax = 0; ay = 0;
+ ax = 0; ay = 0; az = 0; aw = 0;
switch (event->type) {
case WSCONS_EVENT_MOUSE_UP:
@@ -642,14 +690,15 @@
dz = event->value;
break;
case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
- /* ignore those */
- ++event;
- continue;
+ az = event->value;
break;
case WSCONS_EVENT_MOUSE_DELTA_W:
DBG(4, ErrorF("Relative W %d\n", event->value));
dw = event->value;
break;
+ case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
+ aw = event->value;
+ break;
default:
xf86Msg(X_WARNING, "%s: bad wsmouse event type=%d\n",
pInfo->name, event->type);
@@ -720,6 +769,16 @@
DBG(3, ErrorF("postMotionEvent y %d\n", ay));
xf86PostMotionEvent(pInfo->dev, 1, 1, 1, ay);
}
+ if (az) {
+ /* absolute position event */
+ DBG(3, ErrorF("postMotionEvent Z %d\n", az));
+ xf86PostMotionEvent(pInfo->dev, 1, 2, 1, az);
+ }
+ if (aw) {
+ /* absolute position event */
+ DBG(3, ErrorF("postMotionEvent W %d\n", aw));
+ xf86PostMotionEvent(pInfo->dev, 1, 3, 1, aw);
+ }
++event;
}
return;
@@ -823,6 +882,13 @@
XISetDevicePropertyDeletable(device, prop_calibration, FALSE);
+ prop_pressure = MakeAtom(WS_PROP_PRESSURE,
+ strlen(WS_PROP_PRESSURE), TRUE);
+ rc = XIChangeDeviceProperty(device, prop_pressure, XA_INTEGER, 32,
+ PropModeReplace, 2, &priv->min_z, FALSE);
+ if (rc != Success)
+ return;
+
prop_swap = MakeAtom(WS_PROP_SWAP_AXES,
strlen(WS_PROP_SWAP_AXES), TRUE);
rc = XIChangeDeviceProperty(device, prop_swap, XA_INTEGER, 8,
@@ -841,7 +907,8 @@
struct wsmouse_calibcoords coords;
int need_update = 0;
AxisInfoPtr ax = device->valuator->axes,
- ay = device->valuator->axes + 1;
+ ay = device->valuator->axes + 1,
+ az = device->valuator->axes + 2;
DBG(1, ErrorF("wsSetProperty %s\n", NameForAtom(atom)));
@@ -884,6 +951,26 @@
ay->max_value = priv->max_x;
}
}
+ } else if (atom == prop_pressure) {
+ if (val->format != 32 || val->type != XA_INTEGER)
+ return BadMatch;
+ if (val->size != 2 && val->size != 0)
+ return BadMatch;
+ if (!checkonly) {
+ if (val->size == 0) {
+ DBG(1, ErrorF(" uncalibrate pressure\n"));
+ priv->min_z = 0;
+ priv->max_z = -1;
+ } else {
+ priv->min_z = ((int *)(val->data))[0];
+ priv->max_z = ((int *)(val->data))[1];
+ DBG(1, ErrorF(" calibrate pressure %d %d\n",
+ priv->min_z, priv->max_z));
+ }
+ /* Update axes descriptors */
+ az->min_value = priv->min_z;
+ az->max_value = priv->max_z;
+ }
} else if (atom == prop_swap) {
if (val->format != 8 || val->type != XA_INTEGER ||
val->size != 1)
Index: external/mit/xf86-input-ws/dist/man/ws.man
===================================================================
RCS file: /cvsroot/xsrc/external/mit/xf86-input-ws/dist/man/ws.man,v
retrieving revision 1.3
diff -u -r1.3 ws.man
--- external/mit/xf86-input-ws/dist/man/ws.man 2 Aug 2011 09:30:15 -0000 1.3
+++ external/mit/xf86-input-ws/dist/man/ws.man 25 Oct 2019 19:25:51 -0000
@@ -143,6 +143,9 @@
1 boolean value (8 bits, 0 or 1). 1 swaps x/y axes. This property
is present only for devices with absolute coordinates (ie
tablets and touchscreens).
+.TP 7
+.BI "WS Pointer Pressure Calibration"
+2 32 bits values, in the order min-z, max-z.
.SH "SEE ALSO"
__xservername__(1), xinput(1), __xconfigfile__(__filemansuffix__),
Home |
Main Index |
Thread Index |
Old Index