Hi I followed the instructions for evdev enabled kernel here https://github.com/wulf7/libudev-devd and it works fine! I needed to update libinput to latest version since it was required by xf86-input-libinput so I'm using latest version from https://github.com/jiixyj/libinput.
As for the wsp driver I've simply added REL_HWHEEL to get x/y scrolling and changed the back/forward events to x axis scrolling. See the attached patch. It's still really simple but adds a bit more functionality compared to what is allowed by the old mouse protocol. Of course, if you want advanced multi-touch gestures, it's need to be rewritten a lot. Although, I don't know how many X apps actually support this so maybe it's a lot of work for nothing... I also needed to change the order of horizontal scroll wheel and buttons with xinput set-button-map 6 3 2 1 4 5 7 6 I think wsp already puts out vertical scroll in opposite direction by default. I'm using xfce4 as desktop environment. On Fri, Aug 12, 2016 at 1:12 PM, Jan Kokemüller <jan.kokemuel...@gmail.com> wrote: > Hi, > > On 12.08.16 19:22, Lundberg, Johannes wrote: > >> Where can I find xf86-input-libinput for FreeBSD? Will the original >> source build? >> > > Yes, the original source (https://cgit.freedesktop.org/ > xorg/driver/xf86-input-libinput/) will build unmodified. > > I've copied libinput_drv.so to > /usr/local/lib/xorg/modules/input/libinput_drv.so > and installed "99-libinput.conf" into /usr/local/etc/X11/xorg.conf.d so > that X will use libinput for the /dev/input/event* devices by default and > not xf86-input-evdev or -synaptics. > > Libinput has pretty advanced multitouch scrolling and gesture support that > relies on evdev multitouch packets (https://www.kernel.org/doc/Do > cumentation/input/multi-touch-protocol.txt). Are you already sending > these packets, or are you sending relative (EV_REL) packets? Looking at the > wmt driver in the wulf7/evdev branch sending EV_ABS packets does not seem > too hard for USB based touchpads. > > It is probably easiest to boot Linux, dump all evdev packets from the > touchpad with the libevdev-events tool from libevdev, and then try to > emulate that output with the wsp driver. > > For testing smooth scrolling, gtk3-demo is pretty good; or recent versions > of Firefox with the MOZ_USE_XINPUT2 environment variable set to 1. > > -Jan > -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 秘密保持について:この電子メールは、名宛人に送信したものであり、秘匿特権の対象となる情報を含んでいます。 もし、名宛人以外の方が受信された場合、このメールの破棄、およびこのメールに関する一切の開示、 複写、配布、その他の利用、または記載内容に基づくいかなる行動もされないようお願い申し上げます。 --- CONFIDENTIALITY NOTE: The information in this email is confidential and intended solely for the addressee. Disclosure, copying, distribution or any other action of use of this email by person other than intended recipient, is prohibited. If you are not the intended recipient and have received this email in error, please destroy the original message.
diff --git a/sys/dev/usb/input/wsp.c b/sys/dev/usb/input/wsp.c index 694e0d9..21cc518 100644 --- a/sys/dev/usb/input/wsp.c +++ b/sys/dev/usb/input/wsp.c @@ -27,6 +27,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_evdev.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -54,6 +56,11 @@ __FBSDID("$FreeBSD$"); #include <sys/mouse.h> +#ifdef EVDEV +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> +#endif + #define WSP_DRIVER_NAME "wsp" #define WSP_BUFFER_MAX 1024 @@ -83,6 +90,7 @@ SYSCTL_INT(_hw_usb_wsp, OID_AUTO, debug, CTLFLAG_RWTUN, static struct wsp_tuning { int scale_factor; int z_factor; + int t_factor; int pressure_touch_threshold; int pressure_untouch_threshold; int pressure_tap_threshold; @@ -92,6 +100,7 @@ static struct wsp_tuning { { .scale_factor = 12, .z_factor = 5, + .t_factor = 5, .pressure_touch_threshold = 50, .pressure_untouch_threshold = 10, .pressure_tap_threshold = 120, @@ -113,6 +122,8 @@ SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scale_factor, CTLFLAG_RWTUN, &wsp_tuning.scale_factor, 0, "movement scale factor"); SYSCTL_INT(_hw_usb_wsp, OID_AUTO, z_factor, CTLFLAG_RWTUN, &wsp_tuning.z_factor, 0, "Z-axis scale factor"); +SYSCTL_INT(_hw_usb_wsp, OID_AUTO, t_factor, CTLFLAG_RWTUN, + &wsp_tuning.t_factor, 0, "T-axis scale factor"); SYSCTL_INT(_hw_usb_wsp, OID_AUTO, pressure_touch_threshold, CTLFLAG_RWTUN, &wsp_tuning.pressure_touch_threshold, 0, "touch pressure threshold"); SYSCTL_INT(_hw_usb_wsp, OID_AUTO, pressure_untouch_threshold, CTLFLAG_RWTUN, @@ -541,7 +552,12 @@ struct wsp_softc { u_int sc_pollrate; mousestatus_t sc_status; u_int sc_state; + u_int sc_fflags; #define WSP_ENABLED 0x01 +#ifdef EVDEV + int sc_evflags; +#define WSP_EVDEV_OPENED 1 +#endif struct tp_finger *index[MAX_FINGERS]; /* finger index data */ int16_t pos_x[MAX_FINGERS]; /* position array */ @@ -559,9 +575,12 @@ struct wsp_softc { int dz_count; #define WSP_DZ_MAX_COUNT 32 int dt_sum; /* T-axis cumulative movement */ + int dt_count; +#define WSP_DT_MAX_COUNT 32 int rdx; /* x axis remainder of divide by scale_factor */ int rdy; /* y axis remainder of divide by scale_factor */ int rdz; /* z axis remainder of divide by scale_factor */ + int rdt; /* t axis remainder of divide by scale_factor */ int tp_datalen; uint8_t o_ntouch; /* old touch finger status */ uint8_t finger; /* 0 or 1 *, check which finger moving */ @@ -572,11 +591,15 @@ struct wsp_softc { #define MAX_DISTANCE 2500 /* the max allowed distance */ uint8_t ibtn; /* button status in tapping */ uint8_t ntaps; /* finger status in tapping */ - uint8_t scr_mode; /* scroll status in movement */ -#define WSP_SCR_NONE 0 -#define WSP_SCR_VER 1 -#define WSP_SCR_HOR 2 + uint8_t scroll_mode; /* scroll status in movement */ +#define WSP_SCROLL_NONE 0 +#define WSP_SCROLL_VER 1 +#define WSP_SCROLL_HOR 2 uint8_t tp_data[WSP_BUFFER_MAX] __aligned(4); /* trackpad transferred data */ + +#ifdef EVDEV + struct evdev_dev *sc_evdev; +#endif }; /* @@ -588,6 +611,14 @@ static usb_fifo_open_t wsp_open; static usb_fifo_close_t wsp_close; static usb_fifo_ioctl_t wsp_ioctl; +static void wsp_start_rx(struct wsp_softc *sc); +static void wsp_stop_rx(struct wsp_softc *sc); + +#ifdef EVDEV +static evdev_open_t wsp_ev_open; +static evdev_close_t wsp_ev_close; +#endif + static struct usb_fifo_methods wsp_fifo_methods = { .f_open = &wsp_open, .f_close = &wsp_close, @@ -597,13 +628,20 @@ static struct usb_fifo_methods wsp_fifo_methods = { .basename[0] = WSP_DRIVER_NAME, }; +#ifdef EVDEV +static struct evdev_methods wsp_evdev_methods = { + .ev_open = &wsp_ev_open, + .ev_close = &wsp_ev_close, +}; +#endif + /* device initialization and shutdown */ static int wsp_enable(struct wsp_softc *sc); static void wsp_disable(struct wsp_softc *sc); /* updating fifo */ static void wsp_reset_buf(struct wsp_softc *sc); -static void wsp_add_to_queue(struct wsp_softc *, int, int, int, uint32_t); +static void wsp_add_to_queue(struct wsp_softc *, int, int, int, int, uint32_t); /* Device methods. */ static device_probe_t wsp_probe; @@ -799,7 +837,29 @@ wsp_attach(device_t dev) sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; sc->sc_touch = WSP_UNTOUCH; - sc->scr_mode = WSP_SCR_NONE; + sc->scroll_mode = WSP_SCROLL_NONE; + +#ifdef EVDEV + sc->sc_evdev = evdev_alloc(); + evdev_set_name(sc->sc_evdev, device_get_desc(dev)); + evdev_set_serial(sc->sc_evdev, "0"); + evdev_set_methods(sc->sc_evdev, sc, &wsp_evdev_methods); + evdev_support_prop(sc->sc_evdev, INPUT_PROP_POINTER); + evdev_support_event(sc->sc_evdev, EV_SYN); + evdev_support_event(sc->sc_evdev, EV_REL); + evdev_support_event(sc->sc_evdev, EV_KEY); + evdev_support_rel(sc->sc_evdev, REL_X); + evdev_support_rel(sc->sc_evdev, REL_Y); + evdev_support_rel(sc->sc_evdev, REL_WHEEL); + evdev_support_rel(sc->sc_evdev, REL_HWHEEL); + + for(int i = 0; i < sc->sc_hw.buttons; i++) + evdev_support_key(sc->sc_evdev, BTN_MOUSE + i); + + err = evdev_register(dev, sc->sc_evdev); + if (err) + goto detach; +#endif return (0); @@ -822,6 +882,11 @@ wsp_detach(device_t dev) usb_fifo_detach(&sc->sc_fifo); +#ifdef EVDEV + evdev_unregister(dev, sc->sc_evdev); + evdev_free(sc->sc_evdev); +#endif + usbd_transfer_unsetup(sc->sc_xfer, WSP_N_TRANSFER); mtx_destroy(&sc->sc_mutex); @@ -842,10 +907,12 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) int ibt = 0; /* button status */ int dx = 0; int dy = 0; - int dz = 0; + int dz = 0; + int dt = 0; int rdx = 0; int rdy = 0; int rdz = 0; + int rdt = 0; int len; int i; @@ -854,6 +921,9 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) if (sc->dz_count == 0) sc->dz_count = WSP_DZ_MAX_COUNT; + if (sc->dt_count == 0) + sc->dt_count = WSP_DT_MAX_COUNT; + usbd_xfer_status(xfer, &len, NULL, NULL, NULL); switch (USB_GET_STATE(xfer)) { @@ -967,7 +1037,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) switch (sc->ntaps) { case 1: if (!(params->caps & HAS_INTEGRATED_BUTTON)) { - wsp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON1DOWN); + wsp_add_to_queue(sc, 0, 0, 0, 0, MOUSE_BUTTON1DOWN); DPRINTFN(WSP_LLEVEL_INFO, "LEFT CLICK!\n"); } break; @@ -976,21 +1046,23 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) sc->dx_sum, sc->dy_sum); if (sc->distance < MAX_DISTANCE && abs(sc->dx_sum) < 5 && abs(sc->dy_sum) < 5) { - wsp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON3DOWN); + wsp_add_to_queue(sc, 0, 0, 0, 0, MOUSE_BUTTON3DOWN); DPRINTFN(WSP_LLEVEL_INFO, "RIGHT CLICK!\n"); } break; case 3: - wsp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON2DOWN); + wsp_add_to_queue(sc, 0, 0, 0, 0, MOUSE_BUTTON2DOWN); break; default: /* we don't handle taps of more than three fingers */ break; } - wsp_add_to_queue(sc, 0, 0, 0, 0); /* button release */ + wsp_add_to_queue(sc, 0, 0, 0, 0, 0); /* button release */ } + +#if 0 // Replace back/forward with horizontal scroll if ((sc->dt_sum / tun.scr_hor_threshold) != 0 && - sc->ntaps == 2 && sc->scr_mode == WSP_SCR_HOR) { + sc->ntaps == 2 && sc->scroll_mode == WSP_SCROLL_HOR) { /* * translate T-axis into button presses @@ -1001,20 +1073,23 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) else if (sc->dt_sum < 0) wsp_add_to_queue(sc, 0, 0, 0, 1UL << 4); } +#endif sc->dz_count = WSP_DZ_MAX_COUNT; - sc->dz_sum = 0; + sc->dt_count = WSP_DT_MAX_COUNT; sc->intr_count = 0; sc->ibtn = 0; sc->ntaps = 0; sc->finger = 0; sc->distance = 0; - sc->dt_sum = 0; sc->dx_sum = 0; sc->dy_sum = 0; + sc->dz_sum = 0; + sc->dt_sum = 0; sc->rdx = 0; sc->rdy = 0; sc->rdz = 0; - sc->scr_mode = WSP_SCR_NONE; + sc->rdt = 0; + sc->scroll_mode = WSP_SCROLL_NONE; } else if (sc->index[0]->touch_major >= tun.pressure_touch_threshold && sc->sc_touch == WSP_UNTOUCH) { /* ignore first touch */ sc->sc_touch = WSP_FIRST_TOUCH; @@ -1079,6 +1154,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) DPRINTFN(WSP_LLEVEL_INFO, "dx=%5d, dy=%5d, mov=%5d\n", dx, dy, sc->finger); } + if (sc->dz_count--) { rdz = (dy + sc->rdz) % tun.scale_factor; sc->dz_sum -= (dy + sc->rdz) / tun.scale_factor; @@ -1086,6 +1162,14 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) } if ((sc->dz_sum / tun.z_factor) != 0) sc->dz_count = 0; + + if (sc->dt_count--) { + rdt = (dx + sc->rdt) % tun.scale_factor; + sc->dt_sum += (dx + sc->rdt) / tun.scale_factor; + sc->rdt = rdt; + } + if ((sc->dt_sum / tun.t_factor) != 0) + sc->dt_count = 0; } rdx = (dx + sc->rdx) % tun.scale_factor; dx = (dx + sc->rdx) / tun.scale_factor; @@ -1099,45 +1183,49 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) sc->dy_sum += dy; if (ntouch == 2 && sc->sc_status.button == 0) { - if (sc->scr_mode == WSP_SCR_NONE && + + if (sc->scroll_mode == WSP_SCROLL_NONE && abs(sc->dx_sum) + abs(sc->dy_sum) > tun.scr_hor_threshold) - sc->scr_mode = abs(sc->dx_sum) > - abs(sc->dy_sum) * 2 ? WSP_SCR_HOR : WSP_SCR_VER; - DPRINTFN(WSP_LLEVEL_INFO, "scr_mode=%5d, count=%d, dx_sum=%d, dy_sum=%d\n", - sc->scr_mode, sc->intr_count, sc->dx_sum, sc->dy_sum); - if (sc->scr_mode == WSP_SCR_HOR) - sc->dt_sum += dx; - else - sc->dt_sum = 0; + sc->scroll_mode = abs(sc->dx_sum) > + abs(sc->dy_sum) * 2 ? WSP_SCROLL_HOR : WSP_SCROLL_VER; + + DPRINTFN(WSP_LLEVEL_INFO, "scroll_mode=%5d, count=%d, dx_sum=%d, dy_sum=%d\n", + sc->scroll_mode, sc->intr_count, sc->dx_sum, sc->dy_sum); dx = dy = 0; - if (sc->dz_count == 0) + if (sc->dz_count == 0) { dz = sc->dz_sum / tun.z_factor; - if (sc->scr_mode == WSP_SCR_HOR || - abs(sc->pos_x[0] - sc->pos_x[1]) > MAX_DISTANCE || - abs(sc->pos_y[0] - sc->pos_y[1]) > MAX_DISTANCE) - dz = 0; + } + if (sc->dt_count == 0) { + dt = sc->dt_sum / tun.t_factor; + } } if (ntouch == 3) - dx = dy = dz = 0; + dx = dy = dz = dt = 0; if (sc->intr_count < WSP_TAP_MAX_COUNT && - abs(dx) < 3 && abs(dy) < 3 && abs(dz) < 3) - dx = dy = dz = 0; + abs(dx) < 3 && abs(dy) < 3 && abs(dz) < 3 && abs(dt) < 3) + dx = dy = dz = dt = 0; else sc->intr_count = WSP_TAP_MAX_COUNT; - if (dx || dy || dz) + if (dx || dy || dz || dt) sc->sc_status.flags |= MOUSE_POSCHANGED; - DPRINTFN(WSP_LLEVEL_INFO, "dx=%5d, dy=%5d, dz=%5d, sc_touch=%x, btn=%x\n", - dx, dy, dz, sc->sc_touch, sc->sc_status.button); + DPRINTFN(WSP_LLEVEL_INFO, "dx=%5d, dy=%5d, dz=%5d, dt=%5d,sc_touch=%x, btn=%x\n", + dx, dy, dz, dt, sc->sc_touch, sc->sc_status.button); sc->sc_status.dx += dx; sc->sc_status.dy += dy; sc->sc_status.dz += dz; + /* No support for dt this (yet) */ + /* sc->sc_status.dt += dt; */ - wsp_add_to_queue(sc, dx, -dy, dz, sc->sc_status.button); + wsp_add_to_queue(sc, dx, -dy, dz, dt, sc->sc_status.button); if (sc->dz_count == 0) { sc->dz_sum = 0; sc->rdz = 0; } + if (sc->dt_count == 0) { + sc->dt_sum = 0; + sc->rdt = 0; + } } sc->pre_pos_x = sc->pos_x[0]; @@ -1152,14 +1240,17 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) case USB_ST_SETUP: tr_setup: /* check if we can put more data into the FIFO */ - if (usb_fifo_put_bytes_max( - sc->sc_fifo.fp[USB_FIFO_RX]) != 0) { - usbd_xfer_set_frame_len(xfer, 0, - sc->tp_datalen); - usbd_transfer_submit(xfer); + if (usb_fifo_put_bytes_max(sc->sc_fifo.fp[USB_FIFO_RX]) == 0) { +#ifdef EVDEV + if (sc->sc_evflags == 0) + break; +#else + break; +#endif } + usbd_xfer_set_frame_len(xfer, 0, sc->tp_datalen); + usbd_transfer_submit(xfer); break; - default: /* Error */ if (error != USB_ERR_CANCELLED) { /* try clear stall first */ @@ -1172,7 +1263,7 @@ tr_setup: static void wsp_add_to_queue(struct wsp_softc *sc, int dx, int dy, int dz, - uint32_t buttons_in) + int dt, uint32_t buttons_in) { uint32_t buttons_out; uint8_t buf[8]; @@ -1183,6 +1274,8 @@ wsp_add_to_queue(struct wsp_softc *sc, int dx, int dy, int dz, dy = imax(dy, -256); dz = imin(dz, 126); dz = imax(dz, -128); + dt = imin(dt, 126); + dt = imax(dt, -128); buttons_out = MOUSE_MSC_BUTTONS; if (buttons_in & MOUSE_BUTTON1DOWN) @@ -1207,7 +1300,63 @@ wsp_add_to_queue(struct wsp_softc *sc, int dx, int dy, int dz, } usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf, sc->sc_mode.packetsize, 1); + +#ifdef EVDEV + /* Push evdev event */ + if (dx != 0 || dy != 0) { + evdev_push_event(sc->sc_evdev, EV_REL, REL_X, dx); + evdev_push_event(sc->sc_evdev, EV_REL, REL_Y, -dy); + } + if (dz != 0) + evdev_push_event(sc->sc_evdev, EV_REL, REL_WHEEL, -dz); + if (dt != 0) { + evdev_push_event(sc->sc_evdev, EV_REL, REL_HWHEEL, dt); + } + evdev_push_mouse_btn(sc->sc_evdev, + (buttons_in & ~MOUSE_STDBUTTONS) | + (buttons_in & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) | + (buttons_in & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) | + (buttons_in & (1 << 0) ? MOUSE_BUTTON3DOWN : 0)); + evdev_sync(sc->sc_evdev); +#endif + +} + +#ifdef EVDEV +static int +wsp_ev_open(struct evdev_dev *evdev, void *ev_softc) +{ + struct wsp_softc *sc = (struct wsp_softc *)ev_softc; + + mtx_lock(&sc->sc_mutex); + + sc->sc_evflags = WSP_EVDEV_OPENED; + + if (sc->sc_fflags == 0) { + /* wsp_reset(sc); */ + wsp_start_rx(sc); + } + + mtx_unlock(&sc->sc_mutex); + + return (0); +} + +static void +wsp_ev_close(struct evdev_dev *evdev, void *ev_softc) +{ + struct wsp_softc *sc = (struct wsp_softc *)ev_softc; + + mtx_lock(&sc->sc_mutex); + + sc->sc_evflags = 0; + + if (sc->sc_fflags == 0) + wsp_stop_rx(sc); + + mtx_unlock(&sc->sc_mutex); } +#endif static void wsp_reset_buf(struct wsp_softc *sc) @@ -1217,9 +1366,8 @@ wsp_reset_buf(struct wsp_softc *sc) } static void -wsp_start_read(struct usb_fifo *fifo) +wsp_start_rx(struct wsp_softc *sc) { - struct wsp_softc *sc = usb_fifo_softc(fifo); int rate; /* Check if we should override the default polling interval */ @@ -1240,13 +1388,25 @@ wsp_start_read(struct usb_fifo *fifo) } static void -wsp_stop_read(struct usb_fifo *fifo) +wsp_start_read(struct usb_fifo *fifo) { struct wsp_softc *sc = usb_fifo_softc(fifo); + wsp_start_rx(sc); +} +static void +wsp_stop_rx(struct wsp_softc *sc) +{ usbd_transfer_stop(sc->sc_xfer[WSP_INTR_DT]); } +static void +wsp_stop_read(struct usb_fifo *fifo) +{ + struct wsp_softc *sc = usb_fifo_softc(fifo); + wsp_stop_rx(sc); +} + static int wsp_open(struct usb_fifo *fifo, int fflags) @@ -1255,6 +1415,7 @@ wsp_open(struct usb_fifo *fifo, int fflags) if (fflags & FREAD) { struct wsp_softc *sc = usb_fifo_softc(fifo); + sc->sc_fflags = fflags; int rc; if (sc->sc_state & WSP_ENABLED)
_______________________________________________ freebsd-current@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"