Author: gonzo
Date: Tue Nov 15 04:12:19 2016
New Revision: 308668
URL: https://svnweb.freebsd.org/changeset/base/308668

Log:
  [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 <w...@cicgroup.ru>
  MFC after:    1 week
  Differential Revision:        https://reviews.freebsd.org/D8437

Modified:
  head/sys/dev/kbdmux/kbdmux.c
  head/sys/modules/kbdmux/Makefile

Modified: head/sys/dev/kbdmux/kbdmux.c
==============================================================================
--- head/sys/dev/kbdmux/kbdmux.c        Tue Nov 15 03:43:10 2016        
(r308667)
+++ head/sys/dev/kbdmux/kbdmux.c        Tue Nov 15 04:12:19 2016        
(r308668)
@@ -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,
         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,
                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 @@ next_code:
 
        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
                }
 
                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
 
                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, 
 }
 
 DEV_MODULE(kbdmux, kbdmux_modevent, NULL);
-
+#ifdef EVDEV_SUPPORT
+MODULE_DEPEND(kbdmux, evdev, 1, 1, 1);
+#endif

Modified: head/sys/modules/kbdmux/Makefile
==============================================================================
--- head/sys/modules/kbdmux/Makefile    Tue Nov 15 03:43:10 2016        
(r308667)
+++ head/sys/modules/kbdmux/Makefile    Tue Nov 15 04:12:19 2016        
(r308668)
@@ -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:
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to