[evdev] Add evdev support to kbdmux(4) driver
To enable event sourcing from kbdmux(4) kern.evdev.rcpt_mask value should have bit 1 set (this is default) Submitted by: Vladimir Kondratiev <wulf@cicgroup.ru> MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D8437
This commit is contained in:
parent
6ce45c6ac3
commit
97fc5dbe89
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=308668
@ -32,6 +32,7 @@
|
||||
*/
|
||||
|
||||
#include "opt_compat.h"
|
||||
#include "opt_evdev.h"
|
||||
#include "opt_kbd.h"
|
||||
#include "opt_kbdmux.h"
|
||||
|
||||
@ -64,6 +65,11 @@
|
||||
|
||||
#include <dev/kbd/kbdtables.h>
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
#include <dev/evdev/evdev.h>
|
||||
#include <dev/evdev/input.h>
|
||||
#endif
|
||||
|
||||
#define KEYBOARD_NAME "kbdmux"
|
||||
|
||||
MALLOC_DECLARE(M_KBDMUX);
|
||||
@ -159,6 +165,11 @@ struct kbdmux_state
|
||||
u_int ks_composed_char; /* composed char code */
|
||||
u_char ks_prefix; /* AT scan code prefix */
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
struct evdev_dev * ks_evdev;
|
||||
int ks_evdev_state;
|
||||
#endif
|
||||
|
||||
SLIST_HEAD(, kbdmux_kbd) ks_kbds; /* keyboards */
|
||||
|
||||
KBDMUX_LOCK_DECL_GLOBAL;
|
||||
@ -371,6 +382,12 @@ static keyboard_switch_t kbdmuxsw = {
|
||||
.diag = genkbd_diag,
|
||||
};
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
static const struct evdev_methods kbdmux_evdev_methods = {
|
||||
.ev_event = evdev_ev_kbd_event,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return the number of found keyboards
|
||||
*/
|
||||
@ -404,6 +421,10 @@ kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
accentmap_t *accmap = NULL;
|
||||
fkeytab_t *fkeymap = NULL;
|
||||
int error, needfree, fkeymap_size, delay[2];
|
||||
#ifdef EVDEV_SUPPORT
|
||||
struct evdev_dev *evdev;
|
||||
char phys_loc[NAMELEN];
|
||||
#endif
|
||||
|
||||
if (*kbdp == NULL) {
|
||||
*kbdp = kbd = malloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO);
|
||||
@ -464,6 +485,30 @@ kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
delay[1] = kbd->kb_delay2;
|
||||
kbdmux_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
/* register as evdev provider */
|
||||
evdev = evdev_alloc();
|
||||
evdev_set_name(evdev, "System keyboard multiplexer");
|
||||
snprintf(phys_loc, NAMELEN, KEYBOARD_NAME"%d", unit);
|
||||
evdev_set_phys(evdev, phys_loc);
|
||||
evdev_set_id(evdev, BUS_VIRTUAL, 0, 0, 0);
|
||||
evdev_set_methods(evdev, kbd, &kbdmux_evdev_methods);
|
||||
evdev_support_event(evdev, EV_SYN);
|
||||
evdev_support_event(evdev, EV_KEY);
|
||||
evdev_support_event(evdev, EV_LED);
|
||||
evdev_support_event(evdev, EV_REP);
|
||||
evdev_support_all_known_keys(evdev);
|
||||
evdev_support_led(evdev, LED_NUML);
|
||||
evdev_support_led(evdev, LED_CAPSL);
|
||||
evdev_support_led(evdev, LED_SCROLLL);
|
||||
|
||||
if (evdev_register(evdev))
|
||||
evdev_free(evdev);
|
||||
else
|
||||
state->ks_evdev = evdev;
|
||||
state->ks_evdev_state = 0;
|
||||
#endif
|
||||
|
||||
KBD_INIT_DONE(kbd);
|
||||
}
|
||||
|
||||
@ -532,6 +577,10 @@ kbdmux_term(keyboard_t *kbd)
|
||||
|
||||
kbd_unregister(kbd);
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
evdev_free(state->ks_evdev);
|
||||
#endif
|
||||
|
||||
KBDMUX_LOCK_DESTROY(state);
|
||||
bzero(state, sizeof(*state));
|
||||
free(state, M_KBDMUX);
|
||||
@ -694,6 +743,20 @@ kbdmux_read_char(keyboard_t *kbd, int wait)
|
||||
|
||||
kbd->kb_count ++;
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
/* push evdev event */
|
||||
if (evdev_rcpt_mask & EVDEV_RCPT_KBDMUX && state->ks_evdev != NULL) {
|
||||
uint16_t key = evdev_scancode2key(&state->ks_evdev_state,
|
||||
scancode);
|
||||
|
||||
if (key != KEY_RESERVED) {
|
||||
evdev_push_event(state->ks_evdev, EV_KEY,
|
||||
key, scancode & 0x80 ? 0 : 1);
|
||||
evdev_sync(state->ks_evdev);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* return the byte as is for the K_RAW mode */
|
||||
if (state->ks_mode == K_RAW) {
|
||||
KBDMUX_UNLOCK(state);
|
||||
@ -1120,7 +1183,11 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
|
||||
}
|
||||
|
||||
KBD_LED_VAL(kbd) = *(int *)arg;
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
if (state->ks_evdev != NULL &&
|
||||
evdev_rcpt_mask & EVDEV_RCPT_KBDMUX)
|
||||
evdev_push_leds(state->ks_evdev, *(int *)arg);
|
||||
#endif
|
||||
/* KDSETLED on all slave keyboards */
|
||||
SLIST_FOREACH(k, &state->ks_kbds, next)
|
||||
(void)kbdd_ioctl(k->kbd, KDSETLED, arg);
|
||||
@ -1197,7 +1264,11 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
|
||||
|
||||
kbd->kb_delay1 = delays[(mode >> 5) & 3];
|
||||
kbd->kb_delay2 = rates[mode & 0x1f];
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
if (state->ks_evdev != NULL &&
|
||||
evdev_rcpt_mask & EVDEV_RCPT_KBDMUX)
|
||||
evdev_push_repeats(state->ks_evdev, kbd);
|
||||
#endif
|
||||
/* perform command on all slave keyboards */
|
||||
SLIST_FOREACH(k, &state->ks_kbds, next)
|
||||
(void)kbdd_ioctl(k->kbd, cmd, arg);
|
||||
@ -1396,4 +1467,6 @@ kbdmux_modevent(module_t mod, int type, void *data)
|
||||
}
|
||||
|
||||
DEV_MODULE(kbdmux, kbdmux_modevent, NULL);
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
MODULE_DEPEND(kbdmux, evdev, 1, 1, 1);
|
||||
#endif
|
||||
|
@ -4,7 +4,8 @@
|
||||
.PATH: ${.CURDIR}/../../dev/kbdmux
|
||||
|
||||
KMOD= kbdmux
|
||||
SRCS= kbdmux.c opt_compat.h opt_kbd.h opt_kbdmux.h bus_if.h device_if.h
|
||||
SRCS= kbdmux.c opt_compat.h opt_evdev.h opt_kbd.h opt_kbdmux.h bus_if.h \
|
||||
device_if.h
|
||||
|
||||
.if !defined(KERNBUILDDIR)
|
||||
opt_compat.h:
|
||||
|
Loading…
Reference in New Issue
Block a user