diff options
Diffstat (limited to 'debian/patches/console_switch3.patch')
-rw-r--r-- | debian/patches/console_switch3.patch | 839 |
1 files changed, 839 insertions, 0 deletions
diff --git a/debian/patches/console_switch3.patch b/debian/patches/console_switch3.patch new file mode 100644 index 00000000..13c090d3 --- /dev/null +++ b/debian/patches/console_switch3.patch @@ -0,0 +1,839 @@ +2004-04-01 Marco Gerards <metgerards@student.han.nl> + + * Makefile (LCLHDRS): Add inputdev.h. + (pc_kbd.so.$(hurd-version)): Add kdioctlServer.o kbd-repeat.c. + (pc_kbd-LDLIBS): New variable. + * console.c (saved_id): New variable. + (saved_cons): Likewise. + (console_switch_away): New function. + (console_switch_back): Likewise. + * input.h (console_switch_away): New prototype. + (console_switch_back): Likewise. + * pc-kbd.c: Include "inputdev.h" and <argp.h>. + (repeater_node): New variable. + (doc): Likewise. + (options): Likewise. + (argp): Likewise. + (parse_opt): New function. + (pc_kbd_init): Parse the arguments. + (gnumach_v1_input_next): Pass the keyboard event to the repeater + if the repeater is active. + (pc_kbd_init): Parse the `--repeat' argument. + (pc_kbd_start): If a repeater node was specified, start it as a + translator on the given node. + (kev_type, mouse_motion, mouse_motion, Scancode, m_deltaX) + (m_deltaY, MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, MOUSE_MOTION) + (MOUSE_EVENT, IOCPARM_MASK, IOC_OUT, IOC_IN, _IOC, _IOR, _IOW) + (KDSKBDMODE, KB_EVENT, KB_ASCII, KDFKBDTYPE, KB_VANILLAKB) + (KB_EVENT, KBSETLEDS): Move from here... + * inputdev.h: ... to here. New file. + * kbd-repeat.c: New file. + + + +diff -upN ../../console-client/Makefile ./Makefile +--- ../../console-client/Makefile 2002-09-17 14:26:10.000000000 +0200 ++++ console-client/Makefile 2004-03-28 10:53:06.000000000 +0200 +@@ -21,7 +21,7 @@ makemode := utility + target = console + SRCS = console.c timer.c driver.c + LCLHDRS = timer.h driver.h display.h input.h bell.h \ +- unicode.h bdf.h \ ++ unicode.h bdf.h inputdev.h \ + vga-dynafont.h vga-dynacolor.h vga-hw.h vga.h + + OBJS = $(filter-out %.sh,$(SRCS:.c=.o)) +@@ -45,7 +45,9 @@ modules = vga pc_kbd generic_speaker + + vga.so.$(hurd-version): $(patsubst %.c,%_pic.o,bdf.c vga-dynafont.c \ + vga-dynacolor.c vga-support.c vga.c) +-pc_kbd.so.$(hurd-version): $(patsubst %.c,%_pic.o,pc-kbd.c) ++pc_kbd.so.$(hurd-version): $(patsubst %.c,%_pic.o,pc-kbd.c kdioctlServer.o kbd-repeat.c) ++pc_kbd-LDLIBS = -ltrivfs ++ + generic_speaker.so.$(hurd-version): $(patsubst %.c,%_pic.o,generic-speaker.c) + + ifneq ($(LIBNCURSESW),) +diff -upN ../../console-client/console.c ./console.c +--- ../../console-client/console.c 2004-03-24 23:53:17.000000000 +0100 ++++ console-client/console.c 2004-03-28 11:10:42.000000000 +0200 +@@ -47,6 +47,12 @@ static struct mutex global_lock; + displayed. */ + static vcons_t active_vcons = NULL; + ++/* Contains the VT id when switched away. */ ++static int saved_id = 0; ++ ++/* The console, used to switch back. */ ++static cons_t saved_cons; ++ + + /* Callbacks for input source drivers. */ + +@@ -94,6 +100,53 @@ console_switch (int id, int delta) + } + + ++/* Switch away from the console an external use of the console like ++ XFree. */ ++void ++console_switch_away (void) ++{ ++ mutex_lock (&global_lock); ++ saved_id = active_vcons->id; ++ saved_cons = active_vcons->cons; ++ cons_vcons_close (active_vcons); ++ active_vcons = NULL; ++ mutex_unlock (&global_lock); ++} ++ ++/* Switch back to the console client from an external user of the ++ console like XFree. */ ++void ++console_switch_back (void) ++{ ++ vcons_list_t conslist; ++ mutex_lock (&global_lock); ++ if (saved_cons) ++ { ++ error_t err; ++ ++ err = cons_lookup (saved_cons, saved_id, 1, &conslist); ++ if (err) ++ { ++ mutex_unlock (&global_lock); ++ return; ++ } ++ ++ err = cons_vcons_open (saved_cons, conslist, &active_vcons); ++ if (err) ++ { ++ mutex_unlock (&global_lock); ++ return; ++ } ++ ++ conslist->vcons = active_vcons; ++ saved_cons = NULL; ++ mutex_unlock (&active_vcons->lock); ++ } ++ mutex_unlock (&global_lock); ++} ++ ++ ++ + /* Enter SIZE bytes from the buffer BUF into the currently active + console. This can be called by the input driver at any time. */ + error_t +diff -upN ../../console-client/input.h ./input.h +--- ../../console-client/input.h 2002-09-17 14:26:10.000000000 +0200 ++++ console-client/input.h 2004-03-28 10:53:13.000000000 +0200 +@@ -1,5 +1,5 @@ + /* input.h - The interface to and for an input driver. +- Copyright (C) 2002 Free Software Foundation, Inc. ++ Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Written by Marcus Brinkmann. + + This file is part of the GNU Hurd. +@@ -65,6 +65,15 @@ void console_error (const wchar_t *const + /* Exit the console client. Does not return. */ + void console_exit (void); + ++/* Switch away from the console an external use of the console like ++ XFree. */ ++void console_switch_away (void); ++ ++/* Switch back to the console client from an external user of the ++ console like XFree. */ ++void console_switch_back (void); ++ ++ + #if QUAERENDO_INVENIETIS + /* Do not use, do not remove. */ + void console_deprecated (int key); +diff -upN ../../console-client/inputdev.h ./inputdev.h +--- ../../console-client/inputdev.h 1970-01-01 01:00:00.000000000 +0100 ++++ console-client/inputdev.h 2004-03-28 10:53:13.000000000 +0200 +@@ -0,0 +1,122 @@ ++/* inputdev.h - Interfaces for the PC pc-kbd and mouse input drivers. ++ Copyright (C) 2002, 2004 Free Software Foundation, Inc. ++ Written by Marco Gerards. ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ ++ ++/* This gross stuff is cut & pasted from Mach sources, as Mach doesn't ++ export the interface we are using here. */ ++ ++/* ++ * Mach Operating System ++ * Copyright (c) 1991,1990,1989 Carnegie Mellon University ++ * All Rights Reserved. ++ * ++ * Permission to use, copy, modify and distribute this software and its ++ * documentation is hereby granted, provided that both the copyright ++ * notice and this permission notice appear in all copies of the ++ * software, derivative works or modified versions, and any portions ++ * thereof, and that both notices appear in supporting documentation. ++ * ++ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ++ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ++ * ++ * Carnegie Mellon requests users of this software to return to ++ * ++ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU ++ * School of Computer Science ++ * Carnegie Mellon University ++ * Pittsburgh PA 15213-3890 ++ * ++ * any improvements or extensions that they make and grant Carnegie Mellon ++ * the rights to redistribute these changes. ++ */ ++ ++#ifndef _INPUTDEV_H_ ++#define _INPUTDEV_H_ 1 ++ ++typedef u_short kev_type; /* kd event type */ ++ ++/* (used for event records) */ ++struct mouse_motion { ++ short mm_deltaX; /* units? */ ++ short mm_deltaY; ++}; ++typedef u_char Scancode; ++ ++typedef struct { ++ kev_type type; /* see below */ ++ struct timeval time; /* timestamp */ ++ union { /* value associated with event */ ++ boolean_t up; /* MOUSE_LEFT .. MOUSE_RIGHT */ ++ Scancode sc; /* KEYBD_EVENT */ ++ struct mouse_motion mmotion; /* MOUSE_MOTION */ ++ } value; ++} kd_event; ++#define m_deltaX mmotion.mm_deltaX ++#define m_deltaY mmotion.mm_deltaY ++ ++/* ++ * kd_event ID's. ++ */ ++#define MOUSE_LEFT 1 /* mouse left button up/down */ ++#define MOUSE_MIDDLE 2 ++#define MOUSE_RIGHT 3 ++#define MOUSE_MOTION 4 /* mouse motion */ ++#define KEYBD_EVENT 5 /* key up/down */ ++ ++ ++#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ ++#define IOC_OUT 0x40000000 /* copy out parameters */ ++#define IOC_IN 0x80000000U /* copy in parameters */ ++ ++#ifndef _IOC ++#define _IOC(inout,group,num,len) \ ++ (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) ++#endif ++#ifndef _IOR ++#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) ++#endif ++#ifndef _IOW ++#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) ++#endif ++ ++#define KDSKBDMODE _IOW('K', 1, int) /* set keyboard mode */ ++#define KB_EVENT 1 ++#define KB_ASCII 2 ++ ++#define KDGKBDTYPE _IOR('K', 2, int) /* get keyboard type */ ++#define KB_VANILLAKB 0 ++ ++#define KDSETLEDS _IOW('K', 5, int) /* set keyboard leds */ ++ ++ ++/* End of Mach code. */ ++ ++ ++/* Amount of times the device was opened. Normally this translator ++ should be only opened once. */ ++extern int kbd_repeater_opened; ++ ++/* Place the keyboard event KEY in the keyboard buffer. */ ++void repeat_key (kd_event *key); ++ ++/* Set the repeater translator on the node PATH. */ ++error_t setrepeater (const char *path); ++ ++#endif /* _INPUTDEV_H_ */ +diff -upN ../../console-client/kbd-repeat.c ./kbd-repeat.c +--- ../../console-client/kbd-repeat.c 1970-01-01 01:00:00.000000000 +0100 ++++ console-client/kbd-repeat.c 2004-04-01 03:22:46.000000000 +0200 +@@ -0,0 +1,357 @@ ++/* kbd-repeat.c - Keyboard repeater. ++ Copyright (C) 2004 Free Software Foundation, Inc. ++ Written by Marco Gerards. ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ ++ ++ ++#include <hurd/trivfs.h> ++#include <stdlib.h> ++#include <error.h> ++#include <string.h> ++#include <fcntl.h> ++#include <sys/mman.h> ++ ++#include "kdioctl_S.h" ++#include "inputdev.h" ++#include "input.h" ++ ++/* The amount of keyboard events that can be stored in the keyboard buffer. */ ++#define KBDEVTBUFSZ 20 ++ ++/* The size of the keyboard buffer in bytes. */ ++#define KBDBUFSZ (KBDEVTBUFSZ * sizeof (kd_event)) ++ ++/* Return the position of X in the buffer. */ ++#define KBDBUF_POS(x) ((x) % KBDBUFSZ) ++ ++/* The keyboard buffer. */ ++struct kbdbuf ++{ ++ char keybuffer[KBDBUFSZ]; ++ int pos; ++ size_t size; ++ struct condition readcond; ++ struct condition writecond; ++} kbdbuf; ++ ++/* Wakeup for select */ ++static struct condition select_alert; ++ ++/* The global lock */ ++static struct mutex global_lock; ++ ++/* Bucket to handle the keyboard RPCs. */ ++static struct port_bucket *kbdbucket; ++ ++/* Amount of times the device was opened. Normally this translator ++ should be only opened once. */ ++int kbd_repeater_opened; ++ ++ ++static int ++kdioctl_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) ++{ ++ extern int kdioctl_server (mach_msg_header_t *inp, mach_msg_header_t *outp); ++ return kdioctl_server (inp, outp) || trivfs_demuxer (inp, outp); ++} ++ ++ ++/* Place the keyboard event KEY in the keyboard buffer. */ ++void ++repeat_key (kd_event *key) ++{ ++ kd_event *ev; ++ ++ mutex_lock (&global_lock); ++ while (kbdbuf.size + sizeof (kd_event) > KBDBUFSZ) ++ { ++ /* The input buffer is full, wait until there is some space. */ ++ if (hurd_condition_wait (&kbdbuf.writecond, &global_lock)) ++ { ++ mutex_unlock (&global_lock); ++ /* Interrupt, silently continue. */ ++ } ++ } ++ ev = (kd_event *) &kbdbuf.keybuffer[KBDBUF_POS (kbdbuf.pos ++ + kbdbuf.size)]; ++ kbdbuf.size += sizeof (kd_event); ++ memcpy (ev, key, sizeof (kd_event)); ++ condition_broadcast (&kbdbuf.readcond); ++ mutex_unlock (&global_lock); ++} ++ ++ ++/* Thread to handle operations on the kbdbucket. */ ++static any_t ++repeater_translator_function (void *arg) ++{ ++ ports_manage_port_operations_one_thread (kbdbucket, kdioctl_demuxer, 0); ++ return 0; ++} ++ ++ ++/* Set the repeater translator on the node PATH. */ ++error_t ++setrepeater (const char *path) ++{ ++ error_t err; ++ struct trivfs_control *control; ++ file_t node; ++ ++ kbdbucket = ports_create_bucket (); ++ ++ node = file_name_lookup (path, O_CREAT|O_NOTRANS, 0664); ++ if (node == MACH_PORT_NULL) ++ return errno; ++ ++ err = trivfs_create_control (node, 0, kbdbucket, 0, kbdbucket, &control); ++ if (! err) ++ { ++ mach_port_t right = ports_get_send_right (control); ++ err = file_set_translator (node, 0, FS_TRANS_EXCL | FS_TRANS_SET, 0, 0, 0, ++ right, MACH_MSG_TYPE_COPY_SEND); ++ mach_port_deallocate (mach_task_self (), right); ++ } ++ else ++ return err; ++ ++ mutex_init (&global_lock); ++ ++ condition_init (&kbdbuf.readcond); ++ condition_init (&kbdbuf.writecond); ++ ++ condition_init (&select_alert); ++ condition_implies (&kbdbuf.readcond, &select_alert); ++ ++ cthread_detach (cthread_fork (repeater_translator_function, 0)); ++ ++ return 0; ++} ++ ++ ++/* Just act like the Mach kbd device. */ ++int trivfs_fstype = FSTYPE_DEV; ++int trivfs_fsid = 0; ++ ++int trivfs_allow_open = O_READ; ++ ++int trivfs_support_read = 1; ++int trivfs_support_write = 0; ++int trivfs_support_exec = 0; ++ ++error_t ++trivfs_S_io_select (struct trivfs_protid *cred, mach_port_t reply, ++ mach_msg_type_name_t reply_type, int *type) ++{ ++ int available = 0; ++ ++ if (!cred) ++ return EOPNOTSUPP; ++ ++ if (*type & ~SELECT_READ) ++ return EINVAL; ++ ++ if (*type == 0) ++ return 0; ++ ++ available = 0; ++ ++ mutex_lock (&global_lock); ++ while (1) ++ { ++ if (available && kbdbuf.size > 0) ++ { ++ *type = SELECT_READ; ++ mutex_unlock (&global_lock); ++ ++ return 0; ++ } ++ ++ if (cred->po->openmodes & O_NONBLOCK) ++ { ++ mutex_unlock (&global_lock); ++ ++ return EWOULDBLOCK; ++ } ++ ++ ports_interrupt_self_on_port_death (cred, reply); ++ if (hurd_condition_wait (&select_alert, &global_lock)) ++ { ++ *type = 0; ++ mutex_unlock (&global_lock); ++ ++ return EINTR; ++ } ++ } ++} ++ ++ ++void ++trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *st) ++{ ++ /* Mark the node as a read-only plain file. */ ++ st->st_mode &= ~(S_IFMT); ++ st->st_mode |= (S_IRUSR | S_IFCHR); ++ ++ st->st_size = 0; ++ st->st_blocks = 0; ++ ++} ++ ++ ++/* No one wants this. Use the console client to terminate the console ++ client or send a signal. */ ++error_t ++trivfs_goaway (struct trivfs_control *cntl, int flags) ++{ ++ return EOPNOTSUPP; ++} ++ ++ ++static error_t ++open_hook (struct trivfs_peropen *peropen) ++{ ++ /* Make sure the console does not access the hardware anymore. */ ++ if (! kbd_repeater_opened) ++ console_switch_away (); ++ kbd_repeater_opened++; ++ ++ return 0; ++} ++ ++ ++static void ++close_hook (struct trivfs_peropen *peropen) ++{ ++ kbd_repeater_opened--; ++ ++ /* Allow the console to access the hardware again. */ ++ if (! kbd_repeater_opened) ++ { ++ console_switch_back (); ++ kbdbuf.pos = 0; ++ kbdbuf.size = 0; ++ ++ } ++} ++ ++ ++/* Read data from an IO object. If offset is -1, read from the object ++ maintained file pointer. If the object is not seekable, offset is ++ ignored. The amount desired to be read is in AMOUNT. */ ++error_t ++trivfs_S_io_read (struct trivfs_protid *cred, ++ mach_port_t reply, mach_msg_type_name_t reply_type, ++ char **data, mach_msg_type_number_t *data_len, ++ loff_t offs, mach_msg_type_number_t amount) ++{ ++ /* Deny access if they have bad credentials. */ ++ if (! cred) ++ return EOPNOTSUPP; ++ else if (! (cred->po->openmodes & O_READ)) ++ return EBADF; ++ ++ ++ mutex_lock (&global_lock); ++ while (amount > kbdbuf.size) ++ { ++ if (cred->po->openmodes & O_NONBLOCK && amount > kbdbuf.size) ++ { ++ mutex_unlock (&global_lock); ++ return EWOULDBLOCK; ++ } ++ ++ if (hurd_condition_wait (&kbdbuf.readcond, &global_lock)) ++ { ++ mutex_unlock (&global_lock); ++ return EINTR; ++ } ++ } ++ ++ if (amount > 0) ++ { ++ char *keydata; ++ unsigned int i = 0; ++ ++ /* Allocate a buffer when this is required. */ ++ if (*data_len < amount) ++ { ++ *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); ++ if (*data == MAP_FAILED) ++ { ++ mutex_unlock (&global_lock); ++ return ENOMEM; ++ } ++ } ++ ++ /* Copy the bytes to the user's buffer and remove them from the ++ keyboard buffer. */ ++ keydata = *data; ++ while (i != amount) ++ { ++ keydata[i++] = kbdbuf.keybuffer[kbdbuf.pos++]; ++ kbdbuf.pos = KBDBUF_POS (kbdbuf.pos); ++ } ++ kbdbuf.size -= amount; ++ condition_broadcast (&kbdbuf.writecond); ++ } ++ ++ *data_len = amount; ++ mutex_unlock (&global_lock); ++ ++ return 0; ++} ++ ++ ++/* Change current read/write offset */ ++error_t ++trivfs_S_io_seek (struct trivfs_protid *cred, ++ mach_port_t reply, mach_msg_type_name_t reply_type, ++ off_t offs, int whence, off_t *new_offs) ++{ ++ if (!cred) ++ return EOPNOTSUPP; ++ else ++ return ESPIPE; ++} ++ ++ ++/* If this variable is set, it is called every time a new peropen ++ structure is created and initialized. */ ++error_t (*trivfs_peropen_create_hook)(struct trivfs_peropen *) = open_hook; ++ ++/* If this variable is set, it is called every time a peropen structure ++ is about to be destroyed. */ ++void (*trivfs_peropen_destroy_hook) (struct trivfs_peropen *) = close_hook; ++ ++ ++/* Some RPC calls for controlling the keyboard. These calls are just ++ ignored and just exist to make XFree happy. */ ++ ++kern_return_t ++S_kdioctl_kdskbdmode (io_t port, int mode) ++{ ++ return 0; ++} ++ ++ ++kern_return_t ++S_kdioctl_kdgkbdmode (io_t port, int *mode) ++{ ++ return 0; ++} +diff -upN ../../console-client/pc-kbd.c ./pc-kbd.c +--- ../../console-client/pc-kbd.c 2004-02-02 22:25:10.000000000 +0100 ++++ console-client/pc-kbd.c 2004-03-28 11:35:46.000000000 +0200 +@@ -23,6 +23,7 @@ + #include <string.h> + #include <iconv.h> + #include <sys/mman.h> ++#include <argp.h> + + #include <device/device.h> + #include <cthreads.h> +@@ -31,6 +32,7 @@ + #include <hurd/cons.h> + + #include "driver.h" ++#include "inputdev.h" + + + /* The keyboard device in the kernel. */ +@@ -52,6 +54,10 @@ int gnumach_v1_compat; + /* Forward declaration. */ + static struct input_ops pc_kbd_ops; + ++ ++/* The node on which the repeater translator is set. */ ++static char *repeater_node; ++ + + /* A list of scan codes generated by the keyboard, in the set 2 encoding. */ + enum scancode +@@ -558,87 +564,6 @@ enum scancode sc_set1_to_set2_x1[] = + SC_X1_DEL + }; + +- +-/* This gross stuff is cut & pasted from Mach sources, as Mach doesn't +- export the interface we are using here. */ +- +-/* +- * Mach Operating System +- * Copyright (c) 1991,1990,1989 Carnegie Mellon University +- * All Rights Reserved. +- * +- * Permission to use, copy, modify and distribute this software and its +- * documentation is hereby granted, provided that both the copyright +- * notice and this permission notice appear in all copies of the +- * software, derivative works or modified versions, and any portions +- * thereof, and that both notices appear in supporting documentation. +- * +- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" +- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR +- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. +- * +- * Carnegie Mellon requests users of this software to return to +- * +- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU +- * School of Computer Science +- * Carnegie Mellon University +- * Pittsburgh PA 15213-3890 +- * +- * any improvements or extensions that they make and grant Carnegie Mellon +- * the rights to redistribute these changes. +- */ +- +-typedef u_short kev_type; /* kd event type */ +- +-/* (used for event records) */ +-struct mouse_motion { +- short mm_deltaX; /* units? */ +- short mm_deltaY; +-}; +-typedef u_char Scancode; +- +-typedef struct { +- kev_type type; /* see below */ +- struct timeval time; /* timestamp */ +- union { /* value associated with event */ +- boolean_t up; /* MOUSE_LEFT .. MOUSE_RIGHT */ +- Scancode sc; /* KEYBD_EVENT */ +- struct mouse_motion mmotion; /* MOUSE_MOTION */ +- } value; +-} kd_event; +-#define m_deltaX mmotion.mm_deltaX +-#define m_deltaY mmotion.mm_deltaY +- +-/* +- * kd_event ID's. +- */ +-#define MOUSE_LEFT 1 /* mouse left button up/down */ +-#define MOUSE_MIDDLE 2 +-#define MOUSE_RIGHT 3 +-#define MOUSE_MOTION 4 /* mouse motion */ +-#define KEYBD_EVENT 5 /* key up/down */ +- +- +-#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ +-#define IOC_OUT 0x40000000 /* copy out parameters */ +-#define IOC_IN 0x80000000U /* copy in parameters */ +-#define _IOC(inout,group,num,len) \ +- (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) +-#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) +-#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) +- +-#define KDSKBDMODE _IOW('K', 1, int) /* set keyboard mode */ +-#define KB_EVENT 1 +-#define KB_ASCII 2 +- +-#define KDGKBDTYPE _IOR('K', 2, int) /* get keyboard type */ +-#define KB_VANILLAKB 0 +- +-#define KDSETLEDS _IOW('K', 5, int) /* set keyboard leds */ +- +- +-/* End of Mach code. */ +- + static enum scancode + gnumach_v1_input_next () + { +@@ -658,6 +583,13 @@ gnumach_v1_input_next () + terminate. */ + if (err) + return 0; ++ ++ if (kbd_repeater_opened && data_buf.type == KEYBD_EVENT) ++ { ++ repeat_key (&data_buf); ++ data_buf.type = 0; ++ continue; ++ } + } + while (data_buf.type != KEYBD_EVENT); + +@@ -1088,10 +1020,56 @@ input_loop (any_t unused) + + + ++ ++ ++static const char doc[] = "PC Keyboard Driver"; ++ ++static const struct argp_option options[] = ++ { ++ {"repeat", 'r', "NODE", 0, "Set a repeater translator on NODE"}, ++ { 0 } ++ }; ++ ++static error_t ++parse_opt (int key, char *arg, struct argp_state *state) ++{ ++ int *pos = (int *) state->input; ++ ++ switch (key) ++ { ++ case 'r': ++ repeater_node = arg; ++ break; ++ ++ case ARGP_KEY_END: ++ break; ++ ++ default: ++ return ARGP_ERR_UNKNOWN; ++ } ++ ++ *pos = state->next; ++ return 0; ++} ++ ++static struct argp argp = {options, parse_opt, 0, doc}; ++ + /* Initialize the PC keyboard driver. */ + static error_t + pc_kbd_init (void **handle, int no_exit, int argc, char *argv[], int *next) + { ++ error_t err; ++ int pos = 1; ++ ++ /* Parse the arguments. */ ++ err = argp_parse (&argp, argc, argv, ARGP_IN_ORDER | ARGP_NO_EXIT ++ | ARGP_SILENT, 0 , &pos); ++ *next += pos - 1; ++ ++ if (err && err != EINVAL) ++ return err; ++ ++ + return 0; + } + +@@ -1156,6 +1134,10 @@ pc_kbd_start (void *handle) + iconv_close (cd); + return err; + } ++ ++ if (repeater_node) ++ setrepeater (repeater_node); ++ + cthread_detach (cthread_fork (input_loop, NULL)); + + return 0; |