diff options
Diffstat (limited to 'sys-utils/kbdrate.c')
-rw-r--r-- | sys-utils/kbdrate.c | 194 |
1 files changed, 132 insertions, 62 deletions
diff --git a/sys-utils/kbdrate.c b/sys-utils/kbdrate.c index d8632a204..e61fb8906 100644 --- a/sys-utils/kbdrate.c +++ b/sys-utils/kbdrate.c @@ -23,31 +23,55 @@ kbdrate -r 0 -d 0 set rate to 2.0 cps and delay to 250 mS I find it useful to put kbdrate in my /etc/rc file so that the keyboard rate is set to something that I find comfortable at boot time. This sure beats rebuilding the kernel! -*/ -/********************** CUT HERE *****************************/ -/* kbdrate.c -- Set keyboard typematic rate (and delay) - * Created: Thu Apr 23 12:24:30 1992 - * Revised: Wed Jun 22 22:40:46 1994 by faith@cs.unc.edu - * Author: Rickard E. Faith, faith@cs.unc.edu - * Copyright 1992 Rickard E. Faith. Distributed under the GPL. - * This program comes with ABSOLUTELY NO WARRANTY. - * Usage: kbdrate [-r rate] [-d delay] [-s] - * Rate can range from 2.0 to 30.0 (units are characters per second) - * Delay can range from 250 to 1000 (units are milliseconds) - * -s suppressed message - * Compiles under gcc 2.1 for Linux (tested with the pre-0.96 kernel) - * - * Wed Jun 22 21:35:43 1994, faith@cs.unc.edu: - * Changed valid_rates per suggestion by Andries.Brouwer@cwi.nl. - * Wed Jun 22 22:18:29 1994, faith@cs.unc.edu: - * Added patch for AUSTIN notebooks from John Bowman - * (bowman@hagar.ph.utexas.edu) - */ + + kbdrate.c -- Set keyboard typematic rate (and delay) + Created: Thu Apr 23 12:24:30 1992 + Author: Rickard E. Faith, faith@cs.unc.edu + + Copyright 1992 Rickard E. Faith. Distributed under the GPL. + This program comes with ABSOLUTELY NO WARRANTY. + Usage: kbdrate [-r rate] [-d delay] [-s] + Rate can range from 2.0 to 30.0 (units are characters per second) + Delay can range from 250 to 1000 (units are milliseconds) + -s suppressed message + Compiles under gcc 2.1 for Linux (tested with the pre-0.96 kernel) + + Wed Jun 22 21:35:43 1994, faith@cs.unc.edu: + Changed valid_rates per suggestion by Andries.Brouwer@cwi.nl. + Wed Jun 22 22:18:29 1994, faith@cs.unc.edu: + Added patch for AUSTIN notebooks from John Bowman + (bowman@hagar.ph.utexas.edu) + + Linux/68k modifications by Roman Hodek + (Roman.Hodek@informatik.uni-erlangen.de): + + Reading/writing the Intel I/O ports via /dev/port is not the + English way... Such hardware dependant stuff can never work on + other architectures. + + Linux/68k has an new ioctl for setting the keyboard repeat rate + and delay. Both values are counted in msecs, the kernel will do + any rounding to values possible with the underlying hardware. + + kbdrate now first tries if the KDKBDREP ioctl is available. If it + is, it is used, else the old method is applied. + +*/ #include <stdio.h> +#include <unistd.h> #include <stdlib.h> #include <sys/file.h> +#include <sys/ioctl.h> +#include <linux/version.h> +#if LINUX_VERSION_CODE >= 131072 +/* Kd.h is not available with all linux versions. 131072 is equivalent + to linux 2.0.0 */ +#include <linux/kd.h> +#endif + +#define VERSION "1.3" static int valid_rates[] = { 300, 267, 240, 218, 200, 185, 171, 160, 150, 133, 120, 109, 100, 92, 86, 80, 75, 67, @@ -58,7 +82,12 @@ static int valid_rates[] = { 300, 267, 240, 218, 200, 185, 171, 160, 150, static int valid_delays[] = { 250, 500, 750, 1000 }; #define DELAY_COUNT (sizeof( valid_delays ) / sizeof( int )) -void main( int argc, char **argv ) +#ifdef KDKBDREP +static int ioctl_possible = 0; +struct kbd_repeat kbdrep_s; +#endif + +int main( int argc, char **argv ) { double rate = 10.9; /* Default rate */ int delay = 250; /* Default delay */ @@ -72,7 +101,7 @@ void main( int argc, char **argv ) extern char *optarg; extern int optind; - while ( (c = getopt( argc, argv, "r:d:s" )) != EOF ) + while ( (c = getopt( argc, argv, "r:d:sv" )) != EOF ) switch (c) { case 'r': rate = atof( optarg ); @@ -83,48 +112,89 @@ void main( int argc, char **argv ) case 's': silent = 1; break; + case 'v': + fprintf( stderr, "util-linux kbdrate " VERSION "\n"); + exit(0); } - for (i = 0; i < RATE_COUNT; i++) - if (rate * 10 >= valid_rates[i]) { - value &= 0x60; - value |= i; - break; - } - - for (i = 0; i < DELAY_COUNT; i++) - if (delay <= valid_delays[i]) { - value &= 0x1f; - value |= i << 5; - break; - } - - if ( (fd = open( "/dev/port", O_RDWR )) < 0) { - perror( "Cannot open /dev/port" ); - exit( 1 ); +#ifdef KDKBDREP + kbdrep_s.rate = -1; /* don't change, just test */ + kbdrep_s.delay = -1; + if (ioctl( 0, KDKBDREP, &kbdrep_s )) { + if (errno == EINVAL) + ioctl_possible = 0; + else { + perror( "ioctl(KDKBDREP)" ); + exit( 1 ); + } + } else ioctl_possible = 1; + + if (ioctl_possible) { + kbdrep_s.rate = 1000.0 / rate; /* convert cps to msec */ + if (kbdrep_s.rate < 1) kbdrep_s.rate = 1; + kbdrep_s.delay = delay; + if (kbdrep_s.delay < 1) kbdrep_s.delay = 1; + + if (ioctl( 0, KDKBDREP, &kbdrep_s )) { + perror( "ioctl(KDKBDREP)" ); + exit( 1 ); + } + + if (!silent) + printf( "Typematic Rate set to %.1f cps (delay = %d mS)\n", + 1000.0 / (double)kbdrep_s.rate, kbdrep_s.delay ); + } else { +#endif + + /* The ioport way */ + + for (i = 0; i < RATE_COUNT; i++) + if (rate * 10 >= valid_rates[i]) { + value &= 0x60; + value |= i; + break; + } + + + for (i = 0; i < DELAY_COUNT; i++) + if (delay <= valid_delays[i]) { + value &= 0x1f; + value |= i << 5; + break; + } + + if ( (fd = open( "/dev/port", O_RDWR )) < 0) { + perror( "Cannot open /dev/port" ); + exit( 1 ); + } + + do { + lseek( fd, 0x64, 0 ); + read( fd, &data, 1 ); + } while ((data & 2) == 2 ); /* wait */ + + lseek( fd, 0x60, 0 ); + data = 0xf3; /* set typematic rate */ + write( fd, &data, 1 ); + + do { + lseek( fd, 0x64, 0 ); + read( fd, &data, 1 ); + } while ((data & 2) == 2 ); /* wait */ + + lseek( fd, 0x60, 0 ); + sleep( 1 ); + write( fd, &value, 1 ); + + close( fd ); + + if (!silent) printf( "Typematic Rate set to %.1f cps (delay = %d mS)\n", + valid_rates[value & 0x1f] / 10.0, + valid_delays[ (value & 0x60) >> 5 ] ); + +#ifdef KDKBREP } +#endif - do { - lseek( fd, 0x64, 0 ); - read( fd, &data, 1 ); - } while ((data & 2) == 2 ); /* wait */ - - lseek( fd, 0x60, 0 ); - data = 0xf3; /* set typematic rate */ - write( fd, &data, 1 ); - - do { - lseek( fd, 0x64, 0 ); - read( fd, &data, 1 ); - } while ((data & 2) == 2 ); /* wait */ - - lseek( fd, 0x60, 0 ); - sleep( 1 ); - write( fd, &value, 1 ); - - close( fd ); - - if (!silent) printf( "Typematic Rate set to %.1f cps (delay = %d mS)\n", - valid_rates[value & 0x1f] / 10.0, - valid_delays[ (value & 0x60) >> 5 ] ); + return 0; } |