summaryrefslogtreecommitdiffstats
path: root/master/jmm-fix-racy-zforce-driver
diff options
context:
space:
mode:
Diffstat (limited to 'master/jmm-fix-racy-zforce-driver')
-rw-r--r--master/jmm-fix-racy-zforce-driver204
1 files changed, 204 insertions, 0 deletions
diff --git a/master/jmm-fix-racy-zforce-driver b/master/jmm-fix-racy-zforce-driver
new file mode 100644
index 0000000..1873acb
--- /dev/null
+++ b/master/jmm-fix-racy-zforce-driver
@@ -0,0 +1,204 @@
+diff --git a/driver/kobomultitouch_drv.c b/driver/kobomultitouch_drv.c
+index 1dbdb9d..8e39c53 100644
+--- a/driver/kobomultitouch_drv.c
++++ b/driver/kobomultitouch_drv.c
+@@ -19,6 +19,14 @@
+ *
+ **************************************************************************/
+
++/* The zforce driver deactivates the touch screen some time after close() */
++/* and doesn't check for an open that might have occured mean while */
++/* thus leaving the device dead in the water */
++/* define this to open and close the device only once, discarding packets */
++/* when the Xserver doesn't want them */
++
++#define DRIVER_IS_RACY
++
+ #include "gestures.h"
+
+ #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
+@@ -38,6 +46,14 @@ static const float hswipe_fraction = 0.25;
+ static const float scale_fraction = 0.05;
+ static const float rot_fraction = 0.05;
+
++struct Private {
++ struct MTouch *mt;
++ int on;
++ void *input_handler;
++};
++
++static void read_input(LocalDevicePtr local);
++
+ /* button mapping simplified */
+ #define PROPMAP(m, x, y) m[x] = XIGetKnownProperty(y)
+
+@@ -86,9 +102,18 @@ static void initButtonLabels(Atom map[DIM_BUTTON])
+ }
+ #endif
+
++static void read_input_handler(int fd, pointer data)
++{
++ LocalDevicePtr local = (LocalDevicePtr) data;
++ struct Private *priv = local->private;
++
++ read_input(local);
++}
++
+ static int device_init(DeviceIntPtr dev, LocalDevicePtr local)
+ {
+- struct MTouch *mt = local->private;
++ struct Private *priv = local->private;
++ struct MTouch *mt = priv->mt;
+ unsigned char btmap[DIM_BUTTON + 1] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+ };
+@@ -107,7 +132,17 @@ static int device_init(DeviceIntPtr dev, LocalDevicePtr local)
+ xf86Msg(X_ERROR, "kobomultitouch: cannot configure device\n");
+ return !Success;
+ }
++#ifndef DRIVER_IS_RACY
+ xf86CloseSerial(local->fd);
++#else
++ if (open_mtouch(mt, local->fd)) {
++ xf86Msg(X_ERROR, "kobomultitouch: cannot grab device\n");
++ return !Success;
++ }
++
++ priv->on = 0;
++ priv->input_handler = xf86AddInputHandler(local->fd, read_input_handler, local);
++#endif
+
+ #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
+ InitPointerDeviceStruct((DevicePtr)dev,
+@@ -164,7 +199,10 @@ static int device_init(DeviceIntPtr dev, LocalDevicePtr local)
+
+ static int device_on(LocalDevicePtr local)
+ {
+- struct MTouch *mt = local->private;
++ struct Private *priv = local->private;
++ struct MTouch *mt = priv->mt;
++
++#ifndef DRIVER_IS_RACY
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd < 0) {
+ xf86Msg(X_ERROR, "kobomultitouch: cannot open device\n");
+@@ -175,16 +213,26 @@ static int device_on(LocalDevicePtr local)
+ return !Success;
+ }
+ xf86AddEnabledDevice(local);
++#else
++ priv->on = 1;
++#endif
+ return Success;
+ }
+
+ static int device_off(LocalDevicePtr local)
+ {
+- struct MTouch *mt = local->private;
++ struct Private *priv = local->private;
++ struct MTouch *mt = priv->mt;
++
++#ifndef DRIVER_IS_RACY
+ xf86RemoveEnabledDevice(local);
+ if (close_mtouch(mt, local->fd))
+ xf86Msg(X_WARNING, "kobomultitouch: cannot ungrab device\n");
+ xf86CloseSerial(local->fd);
++#else
++ priv->on = 0;
++#endif
++
+ return Success;
+ }
+
+@@ -281,7 +329,8 @@ static void handle_gestures(LocalDevicePtr local,
+ static void read_input(LocalDevicePtr local)
+ {
+ struct Gestures gs;
+- struct MTouch *mt = local->private;
++ struct Private *priv = local->private;
++ struct MTouch *mt = priv->mt;
+
+ //while (read_packet(mt, local->fd) > 0) {
+ // extract_gestures(&gs, mt);
+@@ -292,6 +341,7 @@ static void read_input(LocalDevicePtr local)
+ // handle_gestures(local, &gs, &mt->caps);
+ //}
+ while (read_packet(mt, local->fd) > 0) {
++ if (!priv->on) continue;
+ extract_mouse_gestures(&gs, mt);
+ handle_gestures(local, &gs, &mt->caps);
+ }
+@@ -324,12 +374,21 @@ static Bool device_control(DeviceIntPtr dev, int mode)
+ static int preinit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+ {
+ struct MTouch *mt;
++ struct Private *priv;
+
+ mt = calloc(1, sizeof(*mt));
+ if (!mt)
+ return BadAlloc;
+
+- pInfo->private = mt;
++ priv = calloc(1, sizeof(*priv));
++ if (!priv) {
++ free(mt);
++ return BadAlloc;
++ }
++
++ priv->mt = mt;
++
++ pInfo->private = priv;
+ pInfo->type_name = XI_TOUCHSCREEN;
+ pInfo->device_control = device_control;
+ pInfo->read_input = read_input;
+@@ -343,18 +402,26 @@ static int preinit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+ static InputInfoPtr preinit(InputDriverPtr drv, IDevPtr dev, int flags)
+ {
+ struct MTouch *mt;
++ struct Private *priv;
+ InputInfoPtr local = xf86AllocateInput(drv, 0);
++
+ if (!local)
+ goto error;
+ mt = calloc(1, sizeof(struct MTouch));
+ if (!mt)
+ goto error;
++ priv = calloc(1, sizeof(*priv));
++ if (!priv) {
++ free(mt);
++ return BadAlloc;
++ }
++ priv->mt = mt;
+
+ local->name = dev->identifier;
+ local->type_name = XI_TOUCHSCREEN;
+ local->device_control = device_control;
+ local->read_input = read_input;
+- local->private = mt;
++ local->private = priv;
+ local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
+ local->conf_idev = dev;
+
+@@ -370,7 +437,21 @@ static InputInfoPtr preinit(InputDriverPtr drv, IDevPtr dev, int flags)
+
+ static void uninit(InputDriverPtr drv, InputInfoPtr local, int flags)
+ {
+- free(local->private);
++ struct Private *priv = local->private;
++
++ xf86Msg(X_WARNING, "%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__);
++
++#ifdef DRIVER_IS_RACY
++ if (priv->input_handler) xf86RemoveInputHandler(priv->input_handler);
++
++ if (close_mtouch(priv->mt, local->fd))
++ xf86Msg(X_WARNING, "kobomultitouch: cannot ungrab device\n");
++
++ xf86CloseSerial(local->fd);
++#endif
++
++ if (priv) free(priv->mt);
++ free(priv);
+ local->private = 0;
+ xf86DeleteInput(local, 0);
+ }