loadkeys: Remove OPT_QUIET option
[platform/upstream/kbd.git] / src / kbdrate.c
index 8896e97..8d0df5a 100644 (file)
@@ -47,7 +47,7 @@ beats rebuilding the kernel!
                                (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
+  English way... Such hardware dependent stuff can never work on
   other architectures.
   
   Linux/68k has an new ioctl for setting the keyboard repeat rate
@@ -63,8 +63,8 @@ beats rebuilding the kernel!
   1999-03-17
   Linux/SPARC modifications by Jeffrey Connell <ankh@canuck.gen.nz>:
   It seems that the KDKBDREP ioctl is not available on this platform.
-  However, Linux/SPARC has its own ioctl for this, with yet another
-  different measurement system.  Thus, try for KIOCSRATE, too.
+  However, Linux/SPARC has its own ioctl for this (since 2.1.30),
+  with yet another measurement system.  Thus, try for KIOCSRATE, too.
 
 */
 
@@ -74,16 +74,25 @@ beats rebuilding the kernel!
 #include <errno.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
-
-#include "../defines.h"
-#ifdef HAVE_kd_h
 #include <linux/kd.h>
-#endif
+
 #ifdef __sparc__
 #include <asm/param.h>
-#include <asm/kbio.h>
 #endif
 
+#ifdef COMPAT_HEADERS
+#include "compat/linux-kd.h"
+#endif
+
+/* Equal to kernel version, but field names vary. */
+struct my_kbd_repeat {
+        int delay;        /* in msec; <= 0: don't change */
+        int period;       /* in msec; <= 0: don't change */
+                         /* earlier this field was misnamed "rate" */
+};
+
+#include <signal.h>
+
 #include "nls.h"
 #include "version.h"
 
@@ -98,56 +107,84 @@ static int valid_delays[] = { 250, 500, 750, 1000 };
 
 static int
 KDKBDREP_ioctl_ok(double rate, int delay, int silent) {
-#ifdef KDKBDREP
-       /* This ioctl is defined in <linux/kd.h> but is not
-          implemented anywhere - must be in some m68k patches. */
-       struct kbd_repeat kbdrep_s;
+       /*
+        * This ioctl is defined in <linux/kd.h> but is not
+        * implemented anywhere - must be in some m68k patches.
+        * Since 2.4.9 also on i386.
+        */
+       struct my_kbd_repeat kbdrep_s;
 
        /* don't change, just test */
-       kbdrep_s.rate = -1;
+       kbdrep_s.period = -1;
        kbdrep_s.delay = -1;
        if (ioctl( 0, KDKBDREP, &kbdrep_s )) {
-               if (errno == EINVAL)
+               if (errno == EINVAL || errno == ENOTTY)
                        return 0;
                perror( "ioctl(KDKBDREP)" );
                exit( 1 );
        }
 
+#if 0
+       printf("old delay %d, period %d\n",
+              kbdrep_s.delay, kbdrep_s.period);
+#endif
+
        /* do the change */
-       if (rate == 0)                          /* switch repeat off */
-               kbdrep_s.rate = 0;
+       if (rate == 0)                            /* switch repeat off */
+               kbdrep_s.period = 0;
        else
-               kbdrep_s.rate  = 1000.0 / rate; /* convert cps to msec */
-       if (kbdrep_s.rate < 1)
-               kbdrep_s.rate = 1;
+               kbdrep_s.period  = 1000.0 / rate; /* convert cps to msec */
+       if (kbdrep_s.period < 1)
+               kbdrep_s.period = 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);
+       }
+
+       /* report */
+       if (kbdrep_s.period == 0)
+               rate = 0;
+       else
+               rate = 1000.0 / (double) kbdrep_s.period;
+
+       if (!silent)
+               printf( _("Typematic Rate set to %.1f cps (delay = %d ms)\n"),
+                       rate, kbdrep_s.delay );
+
+       kbdrep_s.period = -1;
+       kbdrep_s.delay = -1;
        if (ioctl( 0, KDKBDREP, &kbdrep_s )) {
+               if (errno == EINVAL)
+                       return 0;
                perror( "ioctl(KDKBDREP)" );
                exit( 1 );
        }
-
-       /* report */
-       if (kbdrep_s.rate == 0)
+       printf("old delay %d, period %d\n",
+              kbdrep_s.delay, kbdrep_s.period);
+       if (kbdrep_s.period == 0)
                rate = 0;
        else
-               rate = 1000.0 / (double) kbdrep_s.rate;
+               rate = 1000.0 / (double) kbdrep_s.period;
 
        if (!silent)
                printf( _("Typematic Rate set to %.1f cps (delay = %d ms)\n"),
                        rate, kbdrep_s.delay );
 
        return 1;                       /* success! */
-
-#else /* no KDKBDREP */
-       return 0;
-#endif /* KDKBDREP */
 }
 
+#ifndef KIOCSRATE
+#define arg_state attr_unused
+#else
+#define arg_state
+#endif
+
 static int
-KIOCSRATE_ioctl_ok(double rate, int delay, int silent) {
+KIOCSRATE_ioctl_ok(arg_state double rate, arg_state int delay, arg_state int silent) {
 #ifdef KIOCSRATE
        struct kbd_rate kbdrate_s;
        int fd;
@@ -179,8 +216,14 @@ KIOCSRATE_ioctl_ok(double rate, int delay, int silent) {
 #endif /* KIOCSRATE */
 }
 
-int main( int argc, char **argv )
-{
+static void
+sigalrmhandler( attr_unused int sig ) {
+       fprintf( stderr, "kbdrate: Failed waiting for kbd controller!\n" );
+       raise( SIGINT );
+}
+
+int
+main( int argc, char **argv ) {
 #ifdef __sparc__
        double      rate = 5.0;      /* Default rate */
        int         delay = 200;     /* Default delay */
@@ -189,21 +232,22 @@ int main( int argc, char **argv )
        int         delay = 250;     /* Default delay */
 #endif
        int         value = 0x7f;    /* Maximum delay with slowest rate */
-                                /* DO NOT CHANGE this value */
+                                    /* DO NOT CHANGE this value */
        int         silent = 0;
        int         fd;
        char        data;
        int         c;
-       int         i;
+       unsigned int i;
        extern char *optarg;
 
        set_progname(argv[0]);
 
        setlocale(LC_ALL, "");
-       bindtextdomain(PACKAGE, LOCALEDIR);
-       textdomain(PACKAGE);
+       bindtextdomain(PACKAGE_NAME, LOCALEDIR);
+       textdomain(PACKAGE_NAME);
 
-       if (argc == 2 && !strcmp(argv[1], "-V"))
+       if (argc == 2 &&
+           (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")))
                print_version_and_exit();
 
        while ( (c = getopt( argc, argv, "r:d:sv" )) != EOF ) {
@@ -217,9 +261,10 @@ int main( int argc, char **argv )
                case 's':
                        silent = 1;
                        break;
-               case 'v':
-                       fprintf(stderr, "kbdrate from kbd-%s\n", VERSION);
-                       exit(0);
+               default:
+                       fprintf(stderr,
+                               _("Usage: kbdrate [-V] [-s] [-r rate] [-d delay]\n"));
+                       exit(1);
                }
        }
 
@@ -252,23 +297,40 @@ int main( int argc, char **argv )
                exit( 1 );
        }
 
+       signal( SIGALRM, sigalrmhandler );
+       alarm( 3 );
+
        do {
                lseek( fd, 0x64, 0 );
-               read( fd, &data, 1 );
+               if (read( fd, &data, 1 ) == -1) {
+                       perror( "read" );
+                       exit( 1 );
+               }
        } while ((data & 2) == 2 );  /* wait */
 
        lseek( fd, 0x60, 0 );
        data = 0xf3;                 /* set typematic rate */
-       write( fd, &data, 1 );
+       if (write( fd, &data, 1 ) == -1) {
+               perror( "write" );
+               exit( 1 );
+       }
 
        do {
                lseek( fd, 0x64, 0 );
-               read( fd, &data, 1 );
+               if (read( fd, &data, 1 ) == -1) {
+                       perror( "read" );
+                       exit( 1 );
+               }
        } while ((data & 2) == 2 );  /* wait */
 
+       alarm( 0 );
+
        lseek( fd, 0x60, 0 );
        sleep( 1 );
-       write( fd, &value, 1 );
+       if (write( fd, &value, 1 ) == -1) {
+               perror( "write" );
+               exit( 1 );
+       }
 
        close( fd );