kbdcontrol - Add support for kbdmux
authorAlex Hornung <ahornung@gmail.com>
Thu, 10 Sep 2009 10:04:46 +0000 (11:04 +0100)
committerAlex Hornung <ahornung@gmail.com>
Fri, 11 Sep 2009 06:58:21 +0000 (07:58 +0100)
* Add support to kbdcontrol to attach and detach keyboards from the
  keyboard multiplexer (kbdmux).

Obtained-from: FreeBSD

usr.sbin/kbdcontrol/kbdcontrol.1
usr.sbin/kbdcontrol/kbdcontrol.c

index bbd7887..718e100 100644 (file)
@@ -23,6 +23,8 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl dFKix
+.Op Fl A Ar name
+.Op Fl a Ar name
 .Oo
 .Fl b
 .Ar duration . Ns Ar pitch | Ar belltype
@@ -54,6 +56,26 @@ below.
 .Pp
 The following command line options are supported:
 .Bl -tag -width indent
+.It Fl A Ar name
+Detach the keyboard, specified by the keyboard device name, from the keyboard
+multiplexer.
+When using this option, the standard input of the
+.Nm
+process should be redirected from the keyboard multilpexor keyboard device
+(if keyboard multiplexor is not active keyboard) or
+.Pa /dev/console
+(if keyboard multiplexor is active keyboard and
+you are not working on the system console).
+.It Fl a Ar name
+Attach the keyboard, specified by the keyboard device name, to the keyboard
+multiplexer.
+When using this option, the standard input of the
+.Nm
+process should be redirected from the keyboard multilpexor keyboard device
+(if keyboard multiplexor is not active keyboard) or
+.Pa /dev/console
+(if keyboard multiplexor is active keyboard and
+you are not working on the system console).
 .It Fl b Xo
 .Ar duration . Ns Ar pitch | Ar belltype
 .Xc
index 299f56c..45747e0 100644 (file)
@@ -28,6 +28,7 @@
  * $FreeBSD: src/usr.sbin/kbdcontrol/kbdcontrol.c,v 1.30.2.2 2001/06/08 18:27:32 sobomax Exp $
  * $DragonFly: src/usr.sbin/kbdcontrol/kbdcontrol.c,v 1.5 2005/10/30 23:00:57 swildner Exp $
  */
+#include <sys/kbio.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -99,6 +100,7 @@ char                 letter;
 int            token;
 
 int            get_accent_definition_line(accentmap_t *);
+void   mux_keyboard(u_int op, char *kbd);
 int            get_key_definition_line(keymap_t *);
 void           usage(void);
 
@@ -1052,12 +1054,75 @@ release_keyboard(void)
                warn("unable to release the keyboard");
 }
 
+void
+mux_keyboard(u_int op, char *kbd)
+{
+       keyboard_info_t info;
+       char            *unit, *ep;
+
+       /*
+        * If stdin is not associated with a keyboard, the following ioctl
+        * will fail.
+        */
+       if (ioctl(0, KDGKBINFO, &info) == -1) {
+               warn("unable to obtain keyboard information");
+               return;
+       }
+#if 1
+       printf("kbd%d\n", info.kb_index);
+       printf("    %.*s%d, type:%s (%d)\n",
+               (int)sizeof(info.kb_name), info.kb_name, info.kb_unit,
+               get_kbd_type_name(info.kb_type), info.kb_type);
+#endif
+       /*
+        * split kbd into name and unit. find the right most part of the
+        * kbd string that consist of only digits.
+        */
+
+       memset(&info, 0, sizeof(info));
+
+       info.kb_unit = -1;
+       ep = kbd - 1;
+
+       do {
+               unit = strpbrk(ep + 1, "0123456789");
+               if (unit != NULL) {
+                       info.kb_unit = strtol(unit, &ep, 10);
+                       if (*ep != '\0')
+                               info.kb_unit = -1;
+               }
+       } while (unit != NULL && info.kb_unit == -1);
+
+       if (info.kb_unit == -1) {
+               warnx("unable to find keyboard driver unit in '%s'", kbd);
+               return;
+       }
+
+       if (unit == kbd) {
+               warnx("unable to find keyboard driver name in '%s'", kbd);
+               return;
+       }
+       if (unit - kbd >= (int) sizeof(info.kb_name)) {
+               warnx("keyboard name '%s' is too long", kbd);
+               return;
+       }
+
+       strncpy(info.kb_name, kbd, unit - kbd);
+
+       /*
+        * If stdin is not associated with a kbdmux(4) keyboard, the following
+        * ioctl will fail.
+        */
+
+       if (ioctl(0, op, &info) == -1)
+               warn("unable to (un)mux the keyboard");
+}
 
 void
 usage(void)
 {
        fprintf(stderr, "%s\n%s\n%s\n",
-"usage: kbdcontrol [-dFKix] [-b duration.pitch | [quiet.]belltype]",
+"usage: kbdcontrol [-dFKix] [-A name] [-a name] [-b duration.pitch | [quiet.]belltype]",
 "                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
 "                  [-h size] [-k device] [-L mapfile]");
        exit(1);
@@ -1069,8 +1134,12 @@ main(int argc, char **argv)
 {
        int             opt;
 
-       while((opt = getopt(argc, argv, "b:df:h:iKk:Fl:L:r:x")) != -1)
+       while((opt = getopt(argc, argv, "A:a:b:df:h:iKk:Fl:L:r:x")) != -1)
                switch(opt) {
+                       case 'A':
+                       case 'a':
+                               mux_keyboard((opt == 'A')? KBRELKBD : KBADDKBD, optarg);
+                               break;
                        case 'b':
                                set_bell_values(optarg);
                                break;