http://qs1969.pair.com?node_id=271673
Category: Miscellaneous
Author/Contact Info Curtis "Mr_Person" Hawthorne
Description:

While working on a project, I was trying to find a way to get the status of numlock and preferably be able to tell when it was pressed. belg4mit pointed out that it was possible to get the scan code for Numlock using the showkey program. I took a look at the showkey source and found out that it does several things to the keyboard mode that allows it to capture raw scan codes. The first part is pretty much the same as saying ReadMode 4; with Term::ReadKey, but the last part I hadn't seen before and it set the keyboard to "MEDIUMRAW" mode. On closer inspection, it used an ioctl call to the current filehandle with some constants from the kd.h header file in the Linux kernel sources. It then does a bitwise AND with each character and 0x7f to get the scancode and also tests if a bitwise AND with 0x80 is true in which case the key was released, false it was pressed.

This program just uses the hard coded values taken from the kd.h file instead of including it like showkey does. There's probably a better way to do this, but I didn't know of one that would work easily. It also doesn't include as much error checking as showkey to make sure your keyboard gets back to how it should be or as many options for output.

#!/usr/bin/perl

use Term::ReadKey;

use strict;
use warnings;

use constant KDSKBMODE          => 0x4B45;
use constant K_XLATE            => 0x01;
use constant K_MEDIUMRAW        => 0x02;

$SIG{ALRM} = sub {
        ioctl(STDIN, KDSKBMODE, K_XLATE); # Return to XLATE
        ReadMode 0;
        exit;
};

ReadMode 4;

ioctl(STDIN, KDSKBMODE, K_MEDIUMRAW); # Set keyboard to MEDIUMRAW

while(1) {
        my $char = getc(STDIN);
        print "keycode ", (ord($char) & 0x7f), (ord($char) & 0x80) ? "
+ release" : " press", "\n";
        alarm(10);
}
Replies are listed 'Best First'.
Re: Simple "showkey" in Perl
by Coruscate (Sexton) on Jul 06, 2003 at 03:40 UTC

    Do the codes depend on the keyboard or OS type? This snippet doesn't catch numlock/caps key for me. Does block ctrl+z. Thanks for throwing the alarm in :)


    If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, please reply to this node or /msg me to inform me as to what is wrong with the post, so that I may update the node to the best of my ability.

      Unfortunately I don't have a full understanding of how the code works, just that it works for me :-) I'm guessing it depends on the operating system because the codes I used come from constants in the Linux kernel includes that don't change based on what kind of keyboard you have. The mode I set it to is MEDIUMRAW, you might try just plain RAW which is 0x00, or perhaps a different ReadMode.
      The management of the keyboard it's competence of the kernel.
      So, it's difficult (impossible, imho) to make a script OS independent.
      ----------
      kral
      (sorry for my english)