Date: Thu, 22 Dec 2016 21:29:57 +0000 (UTC) From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r310431 - in stable/11/sys/dev: evdev syscons vt Message-ID: <201612222129.uBMLTvXd050022@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gonzo Date: Thu Dec 22 21:29:57 2016 New Revision: 310431 URL: https://svnweb.freebsd.org/changeset/base/310431 Log: MFC r309823: [evdev] Adds evdev support to sysmouse(4) driver For horizontal (T-axis) wheel reporting which is not supported by sysmouse protocol kern.evdev.sysmouse_t_axis sysctl is introduced. It can take following values: 0 - no T-axis events (default) 1 - T-axis events are originated in ums(4) driver. 2 - T-axis events are originated in psm(4) driver. Submitted by: Vladimir Kondratiev <wulf@cicgroup.ru> Differential Revision: https://reviews.freebsd.org/D8597 Modified: stable/11/sys/dev/evdev/evdev.c stable/11/sys/dev/evdev/evdev.h stable/11/sys/dev/syscons/sysmouse.c stable/11/sys/dev/vt/vt_sysmouse.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/evdev/evdev.c ============================================================================== --- stable/11/sys/dev/evdev/evdev.c Thu Dec 22 21:11:42 2016 (r310430) +++ stable/11/sys/dev/evdev/evdev.c Thu Dec 22 21:29:57 2016 (r310431) @@ -63,11 +63,14 @@ enum evdev_sparse_result MALLOC_DEFINE(M_EVDEV, "evdev", "evdev memory"); int evdev_rcpt_mask = EVDEV_RCPT_SYSMOUSE | EVDEV_RCPT_KBDMUX; +int evdev_sysmouse_t_axis = 0; SYSCTL_NODE(_kern, OID_AUTO, evdev, CTLFLAG_RW, 0, "Evdev args"); SYSCTL_INT(_kern_evdev, OID_AUTO, rcpt_mask, CTLFLAG_RW, &evdev_rcpt_mask, 0, "Who is receiving events: bit0 - sysmouse, bit1 - kbdmux, " "bit2 - mouse hardware, bit3 - keyboard hardware"); +SYSCTL_INT(_kern_evdev, OID_AUTO, sysmouse_t_axis, CTLFLAG_RW, + &evdev_sysmouse_t_axis, 0, "Extract T-axis from 0-none, 1-ums, 2-psm"); static void evdev_start_repeat(struct evdev_dev *, uint16_t); static void evdev_stop_repeat(struct evdev_dev *); Modified: stable/11/sys/dev/evdev/evdev.h ============================================================================== --- stable/11/sys/dev/evdev/evdev.h Thu Dec 22 21:11:42 2016 (r310430) +++ stable/11/sys/dev/evdev/evdev.h Thu Dec 22 21:29:57 2016 (r310431) @@ -56,6 +56,22 @@ typedef void (evdev_keycode_t)(struct ev #define EVDEV_RCPT_HW_MOUSE (1<<2) #define EVDEV_RCPT_HW_KBD (1<<3) extern int evdev_rcpt_mask; +/* + * Sysmouse protocol does not support horizontal wheel movement reporting. + * To overcome this limitation different drivers use different sysmouse proto + * extensions. Set kern.evdev.sysmouse_t_axis to tell sysmouse evdev driver + * which protocol extension is used. + * 0 - do not extract horizontal wheel movement (default). + * 1 - ums(4) horizontal wheel encoding. T-axis is mapped to buttons 6 and 7 + * 2 - psm(4) wheels encoding: z = 1,-1 - vert. wheel, z = 2,-2 - horiz. wheel + */ +enum +{ + EVDEV_SYSMOUSE_T_AXIS_NONE = 0, + EVDEV_SYSMOUSE_T_AXIS_UMS = 1, + EVDEV_SYSMOUSE_T_AXIS_PSM = 2, +}; +extern int evdev_sysmouse_t_axis; #define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR #define ABS_MT_LAST ABS_MT_TOOL_Y Modified: stable/11/sys/dev/syscons/sysmouse.c ============================================================================== --- stable/11/sys/dev/syscons/sysmouse.c Thu Dec 22 21:11:42 2016 (r310430) +++ stable/11/sys/dev/syscons/sysmouse.c Thu Dec 22 21:29:57 2016 (r310431) @@ -28,6 +28,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_evdev.h" #include "opt_syscons.h" #include <sys/param.h> @@ -43,6 +44,11 @@ __FBSDID("$FreeBSD$"); #include <dev/syscons/syscons.h> +#ifdef EVDEV_SUPPORT +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> +#endif + #ifndef SC_NO_SYSMOUSE /* local variables */ @@ -50,6 +56,72 @@ static struct tty *sysmouse_tty; static int mouse_level; /* sysmouse protocol level */ static mousestatus_t mouse_status; +#ifdef EVDEV_SUPPORT +static struct evdev_dev *sysmouse_evdev; + +static void +smdev_evdev_init(void) +{ + int i; + + sysmouse_evdev = evdev_alloc(); + evdev_set_name(sysmouse_evdev, "System mouse"); + evdev_set_phys(sysmouse_evdev, "sysmouse"); + evdev_set_id(sysmouse_evdev, BUS_VIRTUAL, 0, 0, 0); + evdev_support_prop(sysmouse_evdev, INPUT_PROP_POINTER); + evdev_support_event(sysmouse_evdev, EV_SYN); + evdev_support_event(sysmouse_evdev, EV_REL); + evdev_support_event(sysmouse_evdev, EV_KEY); + evdev_support_rel(sysmouse_evdev, REL_X); + evdev_support_rel(sysmouse_evdev, REL_Y); + evdev_support_rel(sysmouse_evdev, REL_WHEEL); + evdev_support_rel(sysmouse_evdev, REL_HWHEEL); + for (i = 0; i < 8; i++) + evdev_support_key(sysmouse_evdev, BTN_MOUSE + i); + if (evdev_register(sysmouse_evdev)) { + evdev_free(sysmouse_evdev); + sysmouse_evdev = NULL; + } +} + +static void +smdev_evdev_write(int x, int y, int z, int buttons) +{ + + if (sysmouse_evdev == NULL || !(evdev_rcpt_mask & EVDEV_RCPT_SYSMOUSE)) + return; + + evdev_push_event(sysmouse_evdev, EV_REL, REL_X, x); + evdev_push_event(sysmouse_evdev, EV_REL, REL_Y, y); + switch (evdev_sysmouse_t_axis) { + case EVDEV_SYSMOUSE_T_AXIS_PSM: + switch (z) { + case 1: + case -1: + evdev_push_rel(sysmouse_evdev, REL_WHEEL, -z); + break; + case 2: + case -2: + evdev_push_rel(sysmouse_evdev, REL_HWHEEL, z / 2); + break; + } + break; + case EVDEV_SYSMOUSE_T_AXIS_UMS: + /* XXX: Edge triggering should be used here */ + if (buttons & (1 << 5)) + evdev_push_rel(sysmouse_evdev, REL_HWHEEL, 1); + else if (buttons & (1 << 6)) + evdev_push_rel(sysmouse_evdev, REL_HWHEEL, -1); + /* PASSTHROUGH */ + case EVDEV_SYSMOUSE_T_AXIS_NONE: + default: + evdev_push_rel(sysmouse_evdev, REL_WHEEL, -z); + } + evdev_push_mouse_btn(sysmouse_evdev, buttons); + evdev_sync(sysmouse_evdev); +} +#endif + static void smdev_close(struct tty *tp) { @@ -170,6 +242,9 @@ sm_attach_mouse(void *unused) return; sysmouse_tty = tty_alloc(&smdev_ttydevsw, NULL); tty_makedev(sysmouse_tty, NULL, "sysmouse"); +#ifdef EVDEV_SUPPORT + smdev_evdev_init(); +#endif } SYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sm_attach_mouse, NULL); @@ -220,7 +295,14 @@ sysmouse_event(mouse_info_t *info) mouse_status.flags |= ((x || y || z) ? MOUSE_POSCHANGED : 0) | (mouse_status.obutton ^ mouse_status.button); flags = mouse_status.flags; - if (flags == 0 || !tty_opened(sysmouse_tty)) + if (flags == 0) + goto done; + +#ifdef EVDEV_SUPPORT + smdev_evdev_write(x, y, z, mouse_status.button); +#endif + + if (!tty_opened(sysmouse_tty)) goto done; /* the first five bytes are compatible with MouseSystems' */ Modified: stable/11/sys/dev/vt/vt_sysmouse.c ============================================================================== --- stable/11/sys/dev/vt/vt_sysmouse.c Thu Dec 22 21:11:42 2016 (r310430) +++ stable/11/sys/dev/vt/vt_sysmouse.c Thu Dec 22 21:29:57 2016 (r310431) @@ -33,6 +33,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_evdev.h" + #include <sys/param.h> #include <sys/condvar.h> #include <sys/consio.h> @@ -50,6 +52,11 @@ __FBSDID("$FreeBSD$"); #include <dev/vt/vt.h> +#ifdef EVDEV_SUPPORT +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> +#endif + static d_open_t sysmouse_open; static d_close_t sysmouse_close; static d_read_t sysmouse_read; @@ -81,6 +88,72 @@ static MALLOC_DEFINE(M_SYSMOUSE, "sysmou static unsigned char *sysmouse_buffer; static unsigned int sysmouse_start, sysmouse_length; +#ifdef EVDEV_SUPPORT +static struct evdev_dev *sysmouse_evdev; + +static void +sysmouse_evdev_init(void) +{ + int i; + + sysmouse_evdev = evdev_alloc(); + evdev_set_name(sysmouse_evdev, "System mouse"); + evdev_set_phys(sysmouse_evdev, "sysmouse"); + evdev_set_id(sysmouse_evdev, BUS_VIRTUAL, 0, 0, 0); + evdev_support_prop(sysmouse_evdev, INPUT_PROP_POINTER); + evdev_support_event(sysmouse_evdev, EV_SYN); + evdev_support_event(sysmouse_evdev, EV_REL); + evdev_support_event(sysmouse_evdev, EV_KEY); + evdev_support_rel(sysmouse_evdev, REL_X); + evdev_support_rel(sysmouse_evdev, REL_Y); + evdev_support_rel(sysmouse_evdev, REL_WHEEL); + evdev_support_rel(sysmouse_evdev, REL_HWHEEL); + for (i = 0; i < 8; i++) + evdev_support_key(sysmouse_evdev, BTN_MOUSE + i); + if (evdev_register(sysmouse_evdev)) { + evdev_free(sysmouse_evdev); + sysmouse_evdev = NULL; + } +} + +static void +sysmouse_evdev_store(int x, int y, int z, int buttons) +{ + + if (sysmouse_evdev == NULL || !(evdev_rcpt_mask & EVDEV_RCPT_SYSMOUSE)) + return; + + evdev_push_event(sysmouse_evdev, EV_REL, REL_X, x); + evdev_push_event(sysmouse_evdev, EV_REL, REL_Y, y); + switch (evdev_sysmouse_t_axis) { + case EVDEV_SYSMOUSE_T_AXIS_PSM: + switch (z) { + case 1: + case -1: + evdev_push_rel(sysmouse_evdev, REL_WHEEL, -z); + break; + case 2: + case -2: + evdev_push_rel(sysmouse_evdev, REL_HWHEEL, z / 2); + break; + } + break; + case EVDEV_SYSMOUSE_T_AXIS_UMS: + /* XXX: Edge triggering should be used here */ + if (buttons & (1 << 5)) + evdev_push_rel(sysmouse_evdev, REL_HWHEEL, 1); + else if (buttons & (1 << 6)) + evdev_push_rel(sysmouse_evdev, REL_HWHEEL, -1); + /* PASSTHROUGH */ + case EVDEV_SYSMOUSE_T_AXIS_NONE: + default: + evdev_push_rel(sysmouse_evdev, REL_WHEEL, -z); + } + evdev_push_mouse_btn(sysmouse_evdev, buttons); + evdev_sync(sysmouse_evdev); +} +#endif + static int sysmouse_buf_read(struct uio *uio, unsigned int length) { @@ -170,6 +243,9 @@ sysmouse_process_event(mouse_info_t *mi) if (sysmouse_status.flags == 0) goto done; +#ifdef EVDEV_SUPPORT + sysmouse_evdev_store(x, y, z, sysmouse_status.button); +#endif /* The first five bytes are compatible with MouseSystems. */ buf[0] = MOUSE_MSC_SYNC | @@ -404,6 +480,9 @@ sysmouse_drvinit(void *unused) cv_init(&sysmouse_sleep, "sysmrd"); make_dev(&sysmouse_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "sysmouse"); +#ifdef EVDEV_SUPPORT + sysmouse_evdev_init(); +#endif } SYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sysmouse_drvinit, NULL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612222129.uBMLTvXd050022>