// input-kbd-rpt.c // Utility to set the keyboard auto-repeat parameters for a USB keyboard that's using the // Linux input system. // By Phil Endecott, 2007. // I hereby place this code in the public domain. // You can get the latest version of this code from // http://svn.chezphil.org/utils/trunk/input-kbd-rpt.c // // It's very odd that there doesn't already seem to be a utility to do this. As far as I can // see, the kbdrate program is not for USB devices, and the input-utils package doesn't have // control for the auto-repeat rate. Maybe there is a program out there somewhere. I spent a // long time looking and decided eventually that it would be quicker to write my own, since // all you have to do is one ioctl. // // It seems that the ability to change the repeat rate using an ioctl has not existed forever. // You might like to grep for EVIOCSREP in your /usr/include/linux/input.h before going much // further. Specifically, it's not present in 2.6.13 but it is present in 2.6.18. // // Compile this program like this: // gcc --std=c99 -Os -o input-kbd-rpt input-kdb-rpt.c #include #include #include #include #include #include #include #include #include static void usage(void) { fprintf(stderr,"Usage: input-kdb-rpt /dev/input/event - get\n"); fprintf(stderr," input-kdb-rpt /dev/input/event - set\n"); fprintf(stderr," input-kdb-rpt /dev/input/event off - disable auto-repeat\n"); } int main(int argc, char* argv[]) { if (argc>4 || argc<2) { usage(); exit(1); } if (geteuid()!=0) { fprintf(stderr,"Warning: you probably need to be root to run this. Trying anyway...\n"); } char* fn = argv[1]; int fd = open(fn,O_RDWR); if (fd==-1) { perror("open()"); exit(1); } if (argc==2) { int ioctl_params[2]; int rc = ioctl(fd,EVIOCGREP,ioctl_params); if (rc==-1) { perror("ioctl(EVIOCGREP)"); exit(1); } int delay = ioctl_params[0]; int interval = ioctl_params[1]; fprintf(stdout,"delay = %d ms, interval = %d ms\n", delay, interval); } else { int delay, interval; if (argc==3) { if (strcmp(argv[2],"off")==0) { delay = interval = 0; } else { usage(); exit(1); } } else { char* delay_str = argv[2]; char* interval_str = argv[3]; char* endptr; delay = strtol(delay_str,&endptr,10); if (*delay_str==0 || *endptr!=0) { fprintf(stderr,"Error: %s is not a number\n",delay_str); exit(1); } interval = strtol(interval_str,&endptr,10); if (*interval_str==0 || *endptr!=0) { fprintf(stderr,"Error: %s is not a number\n",interval_str); exit(1); } } int ioctl_params[2]; ioctl_params[0] = delay; ioctl_params[1] = interval; int rc = ioctl(fd,EVIOCSREP,ioctl_params); if (rc==-1) { perror("ioctl(EVIOCSREP)"); exit(1); } } exit(0); }