svn commit: r310431 - in stable/11/sys/dev: evdev syscons vt

Oleksandr Tymoshenko gonzo at FreeBSD.org
Thu Dec 22 21:29:59 UTC 2016


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 at 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);


More information about the svn-src-all mailing list