mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-30 21:54:50 +00:00
[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> MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D8597
This commit is contained in:
parent
c837b8e35f
commit
4af79d4f2b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=309823
|
@ -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 *);
|
||||
|
|
|
@ -56,6 +56,22 @@ typedef void (evdev_keycode_t)(struct evdev_dev *, void *,
|
|||
#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
|
||||
|
|
|
@ -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' */
|
||||
|
|
|
@ -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, "sysmouse", "sysmouse device");
|
|||
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);
|
||||
|
|
Loading…
Reference in a new issue