On Thu, Sep 08, 2016 at 07:44:33PM +0200, Ulf Brosziewski wrote:
> Maybe one day I'll get it right:
>     s/wsmouse_input_sync()/wsmouse_input_sync(ms->sc_wsmousedev)/

Haha, you did get it right indeed. Attached my working updated patch,
with your suggested API usage. Looks cleaner like this.

I've also made some progress regarding the scaling bug. It seems the
device is not properly detached from Xorg when it is unplugged, because
the log starts getting spammed with loads of messages like this:

[   202.482] (EE) ws: wacom: read error Input/output error

When I create an xorg.conf that only contains the wsmouse device of the
Wacom tablet and disabled all other wsmouse devices,  I cannot controle
the device anymore after plugging it in again. Without the xorg.conf I
can control it, but with the wrong scale.

I think this difference is caused by the fact that the "all containing"
/dev/wsmouse is still passing data to Xorg for the Wacom device, but
the tablet specific /dev/wsmouse1 device is not. Switchting to a console
somehow forces Xorg to reopen the /dev/wsmouse1 device which results in
a working mouse pointer (or in good scaled mouse pointer movement in the
case of not using an xorg.conf file to disable other wsmouse devices).

Does anybody see why the ws driver start to print these errors? Am I
missing an important call on detachment?

Thanks.

Frank
Index: share/man/man4/uwacom.4
===================================================================
RCS file: share/man/man4/uwacom.4
diff -N share/man/man4/uwacom.4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ share/man/man4/uwacom.4     5 Sep 2016 18:36:32 -0000
@@ -0,0 +1,60 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2016 Frank Groeneveld <fr...@frankgroeneveld.nl>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: September 5 2016 $
+.Dt UWACOM 4
+.Os
+.Sh NAME
+.Nm uwacom
+.Nd Wacom USB tablets
+.Sh SYNOPSIS
+.Cd "uwacom*  at uhidev?"
+.Cd "wsmouse* at uwacom? mux 0"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides basic support for Wacom USB tablets.
+Access to these devices is through the
+.Xr wscons 4
+framework.
+.Pp
+Absolute positioning of the mouse cursor can be done by hovering the pen above 
the tablet. Touching the tablet with the pen tip will emulate mouse button 0, 
while the two pen buttons will emulate button 1 and button 2.
+.Pp
+The
+.Nm
+driver supports the following Wacom tablets:
+.Pp
+.Bl -column "Intuos Draw" "Model Number" -offset 6n
+.It Em Name Ta Model Number
+.It Li Intuos Draw Ta CTL-490
+.Sh SEE ALSO
+.Xr uhidev 4 ,
+.Xr usb 4 ,
+.Xr wsmouse 4
+.Sh HISTORY
+The
+.Nm
+driver
+first appeared in
+.Ox 6.1 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Frank Groeneveld fr...@frankgroeneveld.nl .
+.Sh BUGS
+To make axis scaling work correctly, the device should be plugged in when X 
starts. Advanced features such as pen tip pressure are not supported.
Index: sys/arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.432
diff -u -p -r1.432 GENERIC
--- sys/arch/amd64/conf/GENERIC 4 Sep 2016 10:22:05 -0000       1.432
+++ sys/arch/amd64/conf/GENERIC 5 Sep 2016 18:36:32 -0000
@@ -244,6 +244,8 @@ umass*      at uhub?                # USB Mass Storage devi
 ubcmtp*        at uhub?                # Broadcom USB trackpad
 wsmouse* at ubcmtp? mux 0
 uhidev*        at uhub?                # Human Interface Devices
+uwacom*        at uhidev?              # USB Wacom tablet
+wsmouse* at uwacom? mux 0
 ums*   at uhidev?              # USB mouse
 wsmouse* at ums? mux 0
 uts*   at uhub?                # USB touchscreen
Index: sys/dev/hid/hid.h
===================================================================
RCS file: /cvs/src/sys/dev/hid/hid.h,v
retrieving revision 1.4
diff -u -p -r1.4 hid.h
--- sys/dev/hid/hid.h   20 Jan 2016 01:26:00 -0000      1.4
+++ sys/dev/hid/hid.h   5 Sep 2016 18:36:32 -0000
@@ -127,6 +127,7 @@ int hid_is_collection(const void *, int,
 #define HUP_MICROSOFT          0xff00
 /* XXX compat */
 #define HUP_APPLE              0x00ff
+#define HUP_WACOM              0xff00
 
 /* Usages, Power Device */
 #define HUP_INAME              0x0001
Index: sys/dev/usb/files.usb
===================================================================
RCS file: /cvs/src/sys/dev/usb/files.usb,v
retrieving revision 1.130
diff -u -p -r1.130 files.usb
--- sys/dev/usb/files.usb       3 Sep 2016 13:37:45 -0000       1.130
+++ sys/dev/usb/files.usb       5 Sep 2016 18:36:32 -0000
@@ -435,3 +435,8 @@ file        dev/usb/uberry.c                uberry
 device upd: hid
 attach upd at uhidbus
 file   dev/usb/upd.c                   upd
+
+# Wacom tablets
+device uwacom: hid, hidms, wsmousedev
+attach uwacom at uhidbus
+file   dev/usb/uwacom.c                uwacom
Index: sys/dev/usb/usbdevs
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.666
diff -u -p -r1.666 usbdevs
--- sys/dev/usb/usbdevs 1 Jun 2016 09:48:20 -0000       1.666
+++ sys/dev/usb/usbdevs 5 Sep 2016 18:36:32 -0000
@@ -4397,6 +4397,7 @@ product WACOM GRAPHIRE            0x0010  Graphire
 product WACOM GRAPHIRE3_4X5    0x0013  Graphire3 4x5
 product WACOM GRAPHIRE4_4X5    0x0015  Graphire4 Classic A6
 product WACOM INTUOSA5         0x0021  Intuos A5
+product WACOM INTUOS_DRAW      0x033b  Intuos Draw (CTL-490)
 
 /* WAGO Kontakttechnik products */
 product WAGO SERVICECABLE      0x07a6  Service Cable 750-923
Index: sys/dev/usb/usbdevs.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v
retrieving revision 1.678
diff -u -p -r1.678 usbdevs.h
--- sys/dev/usb/usbdevs.h       1 Jun 2016 09:48:54 -0000       1.678
+++ sys/dev/usb/usbdevs.h       5 Sep 2016 18:36:32 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdevs.h,v 1.678 2016/06/01 09:48:54 mglocker Exp $  */
+/*     $OpenBSD$       */
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -4404,6 +4404,7 @@
 #define        USB_PRODUCT_WACOM_GRAPHIRE3_4X5 0x0013          /* Graphire3 
4x5 */
 #define        USB_PRODUCT_WACOM_GRAPHIRE4_4X5 0x0015          /* Graphire4 
Classic A6 */
 #define        USB_PRODUCT_WACOM_INTUOSA5      0x0021          /* Intuos A5 */
+#define        USB_PRODUCT_WACOM_INTUOS_DRAW   0x033b          /* Intuos Draw 
(CTL-490) */
 
 /* WAGO Kontakttechnik products */
 #define        USB_PRODUCT_WAGO_SERVICECABLE   0x07a6          /* Service 
Cable 750-923 */
Index: sys/dev/usb/usbdevs_data.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs_data.h,v
retrieving revision 1.672
diff -u -p -r1.672 usbdevs_data.h
--- sys/dev/usb/usbdevs_data.h  1 Jun 2016 09:48:54 -0000       1.672
+++ sys/dev/usb/usbdevs_data.h  5 Sep 2016 18:36:32 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdevs_data.h,v 1.672 2016/06/01 09:48:54 mglocker Exp $     
*/
+/*     $OpenBSD$       */
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -11208,6 +11208,10 @@ const struct usb_known_product usb_known
        {
            USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOSA5,
            "Intuos A5",
+       },
+       {
+           USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOS_DRAW,
+           "Intuos Draw (CTL-490)",
        },
        {
            USB_VENDOR_WAGO, USB_PRODUCT_WAGO_SERVICECABLE,
Index: sys/dev/usb/uwacom.c
===================================================================
RCS file: sys/dev/usb/uwacom.c
diff -N sys/dev/usb/uwacom.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/dev/usb/uwacom.c        5 Sep 2016 18:36:32 -0000
@@ -0,0 +1,233 @@
+/*     $OpenBSD$       */
+
+/*
+ * Copyright (c) 2016 Frank Groeneveld <fr...@frankgroeneveld.nl>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Driver for USB Wacom tablets */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbhid.h>
+
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdevs.h>
+#include <dev/usb/uhidev.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#include <dev/hid/hidmsvar.h>
+
+struct uwacom_softc {
+       struct uhidev           sc_hdev;
+       struct hidms            sc_ms;
+       struct hid_location     sc_loc_tip_press;
+};
+
+struct cfdriver uwacom_cd = {
+       NULL, "uwacom", DV_DULL
+};
+
+
+const struct usb_devno uwacom_devs[] = {
+       { USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOS_DRAW }
+};
+
+int    uwacom_match(struct device *, void *, void *);
+void   uwacom_attach(struct device *, struct device *, void *);
+int    uwacom_detach(struct device *, int);
+void   uwacom_intr(struct uhidev *, void *, u_int);
+int    uwacom_enable(void *);
+void   uwacom_disable(void *);
+int    uwacom_ioctl(void *, u_long, caddr_t, int, struct proc *);
+
+const struct cfattach uwacom_ca = {
+       sizeof(struct uwacom_softc), uwacom_match, uwacom_attach, uwacom_detach
+};
+
+const struct wsmouse_accessops uwacom_accessops = {
+       uwacom_enable,
+       uwacom_ioctl,
+       uwacom_disable,
+};
+
+int
+uwacom_match(struct device *parent, void *match, void *aux)
+{
+       struct uhidev_attach_arg *uha = aux;
+       int size;
+       void *desc;
+
+       if (usb_lookup(uwacom_devs, uha->uaa->vendor,
+           uha->uaa->product) == NULL)
+               return (UMATCH_NONE);
+
+       uhidev_get_report_desc(uha->parent, &desc, &size);
+
+       if (!hid_locate(desc, size, HID_USAGE2(HUP_WACOM, HUG_POINTER),
+           uha->reportid, hid_input, NULL, NULL))
+               return (UMATCH_NONE);
+
+       return (UMATCH_IFACECLASS);
+}
+
+void
+uwacom_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct uwacom_softc *sc = (struct uwacom_softc *)self;
+       struct hidms *ms = &sc->sc_ms;
+       struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
+       struct usb_attach_arg *uaa = uha->uaa;
+       int size, repid;
+       void *desc;
+
+       sc->sc_hdev.sc_intr = uwacom_intr;
+       sc->sc_hdev.sc_parent = uha->parent;
+       sc->sc_hdev.sc_udev = uaa->device;
+       sc->sc_hdev.sc_report_id = uha->reportid;
+
+       uhidev_get_report_desc(uha->parent, &desc, &size);
+       repid = uha->reportid;
+       sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
+       sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
+       sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
+
+       ms->sc_device = self;
+       ms->sc_rawmode = 1;
+       ms->sc_flags = HIDMS_ABSX | HIDMS_ABSY;
+       ms->sc_num_buttons = 3;
+       ms->sc_loc_x.pos = 8;
+       ms->sc_loc_x.size = 16;
+       ms->sc_loc_y.pos = 24;
+       ms->sc_loc_y.size = 16;
+
+       ms->sc_tsscale.minx = 0;
+       ms->sc_tsscale.maxx = 7600;
+       ms->sc_tsscale.miny = 0;
+       ms->sc_tsscale.maxy = 4750;
+
+       ms->sc_loc_btn[0].pos = 0;
+       ms->sc_loc_btn[0].size = 1;
+       ms->sc_loc_btn[1].pos = 1;
+       ms->sc_loc_btn[1].size = 1;
+       ms->sc_loc_btn[2].pos = 2;
+       ms->sc_loc_btn[2].size = 1;
+
+       sc->sc_loc_tip_press.pos = 43;
+       sc->sc_loc_tip_press.size = 8;
+
+       hidms_attach(ms, &uwacom_accessops);
+}
+
+int
+uwacom_detach(struct device *self, int flags)
+{
+       struct uwacom_softc *sc = (struct uwacom_softc *)self;
+       struct hidms *ms = &sc->sc_ms;
+
+       return hidms_detach(ms, flags);
+}
+
+void
+uwacom_intr(struct uhidev *addr, void *buf, u_int len)
+{
+       struct uwacom_softc *sc = (struct uwacom_softc *)addr;
+       struct hidms *ms = &sc->sc_ms;
+       u_int32_t buttons = 0;
+       uint8_t *data = (uint8_t *)buf;
+       int i, x, y, pressure;
+
+       if (ms->sc_enabled == 0)
+               return;
+
+       /* ignore proximity, it will cause invalid button 2 events */
+       if ((data[0] & 0xf0) == 0xc0)
+               return;
+
+       x = be16toh(hid_get_data(data, len, &ms->sc_loc_x));
+       y = be16toh(hid_get_data(data, len, &ms->sc_loc_y));
+       pressure = hid_get_data(data, len, &sc->sc_loc_tip_press);
+
+       for (i = 0; i < ms->sc_num_buttons; i++)
+               if (hid_get_data(data, len, &ms->sc_loc_btn[i]))
+                       buttons |= (1 << i);
+
+       /* button 0 reporting is flaky, use tip pressure for it */
+       if (pressure > 10)
+               buttons |= 1;
+       else
+               buttons &= ~1;
+
+       if (x != 0 || y != 0 || buttons != ms->sc_buttons) {
+               wsmouse_position(ms->sc_wsmousedev, x, y);
+               wsmouse_buttons(ms->sc_wsmousedev, buttons);
+               wsmouse_input_sync(ms->sc_wsmousedev);
+       }
+}
+
+int
+uwacom_enable(void *v)
+{
+       struct uwacom_softc *sc = v;
+       struct hidms *ms = &sc->sc_ms;
+       int rv;
+
+       if (usbd_is_dying(sc->sc_hdev.sc_udev))
+               return EIO;
+
+       if ((rv = hidms_enable(ms)) != 0)
+               return rv;
+
+       return uhidev_open(&sc->sc_hdev);
+}
+
+void
+uwacom_disable(void *v)
+{
+       struct uwacom_softc *sc = v;
+       struct hidms *ms = &sc->sc_ms;
+
+       hidms_disable(ms);
+       uhidev_close(&sc->sc_hdev);
+}
+
+int
+uwacom_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+       struct uwacom_softc *sc = v;
+       struct hidms *ms = &sc->sc_ms;
+       int rc;
+
+       switch (cmd) {
+       case WSMOUSEIO_GTYPE:
+               *(u_int *)data = WSMOUSE_TYPE_TPANEL;
+               return 0;
+       }
+
+       rc = uhidev_ioctl(&sc->sc_hdev, cmd, data, flag, p);
+       if (rc != -1)
+               return rc;
+
+       return hidms_ioctl(ms, cmd, data, flag, p);
+}

Reply via email to