diff -uNr linux.orig/CREDITS linux/CREDITS --- linux.orig/CREDITS Fri Feb 16 20:15:23 2001 +++ linux/CREDITS Sun Apr 1 10:56:39 2001 @@ -2824,6 +2824,15 @@ S: 10200 Prague 10, Hostivar S: Czech Republic +N: H. van Rein +E: vanrein@cs.utwente.nl +W: http://www.cs.utwente.nl/~vanrein +D: Funkey, the support for nonstd function keys through the /dev/funkey device. +S: Binnenes 67 +S: 9407 CX Assen +S: The Netherlands + + N: James R. Van Zandt E: jrv@vanzandt.mv.com P: 1024/E298966D F0 37 4F FD E5 7E C5 E6 F1 A0 1E 22 6F 46 DA 0C diff -uNr linux.orig/Documentation/Configure.help linux/Documentation/Configure.help --- linux.orig/Documentation/Configure.help Mon Feb 19 13:18:18 2001 +++ linux/Documentation/Configure.help Sun Mar 25 09:46:14 2001 @@ -2925,6 +2925,17 @@ Say Y. +Funny Functional Key support +CONFIG_FUNKEY + New keyboards are sometimes equipped with special keys for functions + such as volume control, that should not generate text but invoke a + function instead. Handling through the console is dependent of the + kbd_mode and is generally unsupported under XFree86. + By selecting this option, a character special device /dev/funkey can + be tapped for such keys. + Sail to http://home.zonnet.nl/vanrein/funkey for information and the + matching "funky" daemon. + Video mode selection support CONFIG_VIDEO_SELECT This enables support for text mode selection on kernel startup. If diff -uNr linux.orig/drivers/char/Config.in linux/drivers/char/Config.in --- linux.orig/drivers/char/Config.in Tue Feb 13 17:13:43 2001 +++ linux/drivers/char/Config.in Sun Mar 25 09:47:23 2001 @@ -8,6 +8,7 @@ if [ "$CONFIG_VT" = "y" ]; then bool ' Support for console on virtual terminal' CONFIG_VT_CONSOLE fi +bool 'Funny/Function Key support' CONFIG_FUNKEY tristate 'Standard/generic (8250/16550 and compatible UARTs) serial support' CONFIG_SERIAL if [ "$CONFIG_SERIAL" = "y" ]; then bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE diff -uNr linux.orig/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- linux.orig/drivers/char/keyboard.c Mon Oct 16 15:58:51 2000 +++ linux/drivers/char/keyboard.c Mon Mar 26 21:51:40 2001 @@ -4,6 +4,8 @@ * Written for linux by Johan Myreen as a translation from * the assembly version by Linus (with diacriticals added) * + * Support for /dev/funkey added by Rick van Rein, April 2000 + * * Some additional features added by Christoph Niemann (ChN), March 1993 * * Loadable keymaps by Risto Kankkunen, May 1993 @@ -32,9 +34,11 @@ #include #include #include +#include #include #include +#include #include #include @@ -110,17 +114,25 @@ static k_handfn do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift, do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2, +#ifdef CONFIG_FUNKEY + do_funkey, do_ignore; +#else do_ignore; +#endif static k_hand key_handler[16] = { do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift, do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2, +#ifdef CONFIG_FUNKEY + do_funkey, do_ignore +#else do_ignore, do_ignore +#endif }; /* Key types processed even in raw modes */ -#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT)) +#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) | (1 << KT_FUNKEY)) typedef void (*void_fnp)(void); typedef void (void_fn)(void); @@ -144,7 +156,13 @@ 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1, NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1, 255, - NR_LOCK - 1, 255 + NR_LOCK - 1, +#ifdef CONFIG_FUNKEY + 255, 127 +#else + 255 +#endif + }; const int NR_TYPES = SIZE(max_vals); @@ -374,6 +392,33 @@ put_queue(10); } +#ifdef CONFIG_FUNKEY + +DECLARE_WAIT_QUEUE_HEAD(funkey_wait); +static unsigned char funkey_queue [256]; +static unsigned char funkey_wpos=0; +static unsigned char funkey_rpos=0; + +void put_funkey_queue (int ch) +{ + funkey_queue [funkey_wpos++] = ch & 0xff; + if (funkey_wpos != funkey_rpos) { + wake_up(&funkey_wait); + } +} + +unsigned char get_funkey_queue (void) +{ + if (funkey_wpos == funkey_rpos) { + interruptible_sleep_on (&funkey_wait); + if (funkey_wpos == funkey_rpos) + return 0; + } + return funkey_queue [funkey_rpos++]; +} + +#endif + static void caps_toggle(void) { if (rep) @@ -630,6 +675,15 @@ printk(KERN_ERR "do_fn called with value=%d\n", value); } +#ifdef CONFIG_FUNKEY +static void do_funkey(unsigned char value, char up_flag) +{ + if (up_flag) + value |= 0x80; + put_funkey_queue (value); +} +#endif + static void do_pad(unsigned char value, char up_flag) { static const char *pad_chars = "0123456789+-*/\015,.?()"; @@ -884,6 +938,70 @@ return leds; } +#ifdef CONFIG_FUNKEY + +ssize_t read_funkey (struct file *f, char *buf, size_t toget, loff_t *offs) +{ + unsigned char keycode=get_funkey_queue (); + int err; + if (!keycode) + return -EINTR; + if ((err = verify_area(VERIFY_WRITE, buf, 1L))) + return err; + put_user (keycode, buf); + return 1; +} + +ssize_t write_funkey (struct file *f, char *buf, size_t toget, loff_t *offs) +{ + return -EINVAL; +} + +static int funkey_opencnt=0; +int open_funkey (struct inode *in, struct file *f) +{ + if (funkey_opencnt) + return -EBUSY; + funkey_opencnt++; + funkey_rpos=funkey_wpos; + return 0; +} + +int close_funkey (struct inode *in, struct file *f) +{ + funkey_opencnt--; + return 0; +} + +/* The /dev/funkey device broadcasts the key codes from the + * keyboard, regardless of the kbd_mode of the console and regardless of + * settings in the keymaps. + */ +static struct file_operations funkey_file_operations = { + NULL, /* Module ? */ + NULL, /* seek */ + read_funkey, + write_funkey, + NULL, /* readdir */ + NULL, /* poll */ + NULL, /* ioctl */ + NULL, /* mmap */ + open_funkey, + NULL, /* flush */ + close_funkey, + NULL, /* revalidate */ + NULL /* sync */ +}; + + + +void init_dev_funkey (void) +{ + register_chrdev (0, "funkey", &funkey_file_operations); +} + +#endif + /* * This routine is the bottom half of the keyboard interrupt * routine, and runs with all interrupts enabled. It does @@ -936,5 +1054,9 @@ pm_kbd = pm_register(PM_SYS_DEV, PM_SYS_KBC, NULL); +#ifdef CONFIG_FUNKEY + init_dev_funkey (); +#endif + return 0; } diff -uNr linux.orig/drivers/char/testkeys linux/drivers/char/testkeys --- linux.orig/drivers/char/testkeys Wed Dec 31 19:00:00 1969 +++ linux/drivers/char/testkeys Sun Mar 25 10:08:00 2001 @@ -0,0 +1 @@ +keycode 123 = F40 diff -uNr linux.orig/include/linux/keyboard.h linux/include/linux/keyboard.h --- linux.orig/include/linux/keyboard.h Wed Feb 21 19:11:42 2001 +++ linux/include/linux/keyboard.h Mon Mar 26 21:28:31 2001 @@ -45,6 +45,7 @@ #define KT_ASCII 9 #define KT_LOCK 10 #define KT_SLOCK 12 +#define KT_FUNKEY 14 #define K(t,v) (((t)<<8)|(v)) #define KTYP(x) ((x) >> 8)