From 3f05a82fec6223a49df300a9cbf80c6245c3f99e Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 6 Feb 2022 19:33:20 +0000 Subject: [console] Update genkeymap to work with current databases Rewrite genkeymap.pl in Python with added sanity checks, and update the list of keyboard mappings to remove those no longer supported by the underlying "loadkeys" tool. Signed-off-by: Michael Brown --- src/util/genkeymap.pl | 238 -------------------------------------------------- 1 file changed, 238 deletions(-) delete mode 100755 src/util/genkeymap.pl (limited to 'src/util/genkeymap.pl') diff --git a/src/util/genkeymap.pl b/src/util/genkeymap.pl deleted file mode 100755 index 7a5024bf8..000000000 --- a/src/util/genkeymap.pl +++ /dev/null @@ -1,238 +0,0 @@ -#!/usr/bin/perl -w -# -# Copyright (C) 2011 Michael Brown . -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -=head1 NAME - -genkeymap.pl - -=head1 SYNOPSIS - -genkeymap.pl [options] - -Options: - - -f,--from= Set BIOS keymap name (default "us") - -h,--help Display brief help message - -v,--verbose Increase verbosity - -q,--quiet Decrease verbosity - -=cut - -# With reference to: -# -# http://gunnarwrobel.de/wiki/Linux-and-the-keyboard.html - -use Getopt::Long; -use Pod::Usage; -use strict; -use warnings; - -use constant BIOS_KEYMAP => "us"; -use constant BKEYMAP_MAGIC => "bkeymap"; -use constant MAX_NR_KEYMAPS => 256; -use constant NR_KEYS => 128; -use constant KG_SHIFT => 0; -use constant KG_ALTGR => 1; -use constant KG_CTRL => 2; -use constant KG_ALT => 3; -use constant KG_SHIFTL => 4; -use constant KG_KANASHIFT => 4; -use constant KG_SHIFTR => 5; -use constant KG_CTRLL => 6; -use constant KG_CTRLR => 7; -use constant KG_CAPSSHIFT => 8; -use constant KT_LATIN => 0; -use constant KT_FN => 1; -use constant KT_SPEC => 2; -use constant KT_PAD => 3; -use constant KT_DEAD => 4; -use constant KT_CONS => 5; -use constant KT_CUR => 6; -use constant KT_SHIFT => 7; -use constant KT_META => 8; -use constant KT_ASCII => 9; -use constant KT_LOCK => 10; -use constant KT_LETTER => 11; -use constant KT_SLOCK => 12; -use constant KT_SPKUP => 14; - -my $verbosity = 1; -my $from_name = BIOS_KEYMAP; - -# Read named keymaps using "loadkeys -b" -# -sub read_keymaps { - my $name = shift; - my $keymaps = []; - - # Generate binary keymap - open my $pipe, "-|", "loadkeys", "-b", $name - or die "Could not load keymap \"".$name."\": $!\n"; - - # Check magic - read $pipe, my $magic, length BKEYMAP_MAGIC - or die "Could not read from \"".$name."\": $!\n"; - die "Bad magic value from \"".$name."\"\n" - unless $magic eq BKEYMAP_MAGIC; - - # Read list of included keymaps - read $pipe, my $included, MAX_NR_KEYMAPS - or die "Could not read from \"".$name."\": $!\n"; - my @included = unpack ( "C*", $included ); - die "Missing or truncated keymap list from \"".$name."\"\n" - unless @included == MAX_NR_KEYMAPS; - - # Read each keymap in turn - for ( my $keymap = 0 ; $keymap < MAX_NR_KEYMAPS ; $keymap++ ) { - if ( $included[$keymap] ) { - read $pipe, my $keysyms, ( NR_KEYS * 2 ) - or die "Could not read from \"".$name."\": $!\n"; - my @keysyms = unpack ( "S*", $keysyms ); - die "Missing or truncated keymap ".$keymap." from \"".$name."\"\n" - unless @keysyms == NR_KEYS; - push @$keymaps, \@keysyms; - } else { - push @$keymaps, undef; - } - } - - close $pipe; - return $keymaps; -} - -# Translate keysym value to ASCII -# -sub keysym_to_ascii { - my $keysym = shift; - - # Non-existent keysyms have no ASCII equivalent - return unless $keysym; - - # Sanity check - if ( $keysym & 0xf000 ) { - warn "Unexpected keysym ".sprintf ( "0x%04x", $keysym )."\n"; - return; - } - - # Extract type and value - my $type = ( $keysym >> 8 ); - my $value = ( $keysym & 0xff ); - - # Non-simple types have no ASCII equivalent - return unless ( ( $type == KT_LATIN ) || ( $type == KT_ASCII ) || - ( $type == KT_LETTER ) ); - - # High-bit-set characters cannot be generated on a US keyboard - return if $value & 0x80; - - return $value; -} - -# Translate ASCII to descriptive name -# -sub ascii_to_name { - my $ascii = shift; - - if ( $ascii == 0x5c ) { - return "'\\\\'"; - } elsif ( $ascii == 0x27 ) { - return "'\\\''"; - } elsif ( ( $ascii >= 0x20 ) && ( $ascii <= 0x7e ) ) { - return sprintf ( "'%c'", $ascii ); - } elsif ( $ascii <= 0x1a ) { - return sprintf ( "Ctrl-%c", ( 0x40 + $ascii ) ); - } else { - return sprintf ( "0x%02x", $ascii ); - } -} - -# Produce translation table between two keymaps -# -sub translate_keymaps { - my $from = shift; - my $to = shift; - my $map = {}; - - foreach my $keymap ( 0, 1 << KG_SHIFT, 1 << KG_CTRL ) { - for ( my $keycode = 0 ; $keycode < NR_KEYS ; $keycode++ ) { - my $from_ascii = keysym_to_ascii ( $from->[$keymap]->[$keycode] ) - or next; - my $to_ascii = keysym_to_ascii ( $to->[$keymap]->[$keycode] ) - or next; - my $new_map = ( ! exists $map->{$from_ascii} ); - my $update_map = - ( $new_map || ( $keycode < $map->{$from_ascii}->{keycode} ) ); - if ( ( $verbosity > 1 ) && - ( ( $from_ascii != $to_ascii ) || - ( $update_map && ! $new_map ) ) ) { - printf STDERR "In keymap %d: %s => %s%s\n", $keymap, - ascii_to_name ( $from_ascii ), ascii_to_name ( $to_ascii ), - ( $update_map ? ( $new_map ? "" : " (override)" ) - : " (ignored)" ); - } - if ( $update_map ) { - $map->{$from_ascii} = { - to_ascii => $to_ascii, - keycode => $keycode, - }; - } - } - } - return { map { $_ => $map->{$_}->{to_ascii} } keys %$map }; -} - -# Parse command-line options -Getopt::Long::Configure ( 'bundling', 'auto_abbrev' ); -GetOptions ( - 'verbose|v+' => sub { $verbosity++; }, - 'quiet|q+' => sub { $verbosity--; }, - 'from|f=s' => sub { shift; $from_name = shift; }, - 'help|h' => sub { pod2usage ( 1 ); }, -) or die "Could not parse command-line options\n"; -pod2usage ( 1 ) unless @ARGV == 1; -my $to_name = shift; - -# Read and translate keymaps -my $from = read_keymaps ( $from_name ); -my $to = read_keymaps ( $to_name ); -my $map = translate_keymaps ( $from, $to ); - -# Generate output -( my $to_name_c = $to_name ) =~ s/\W/_/g; -printf "/** \@file\n"; -printf " *\n"; -printf " * \"".$to_name."\" keyboard mapping\n"; -printf " *\n"; -printf " * This file is automatically generated; do not edit\n"; -printf " *\n"; -printf " */\n"; -printf "\n"; -printf "FILE_LICENCE ( PUBLIC_DOMAIN );\n"; -printf "\n"; -printf "#include \n"; -printf "\n"; -printf "/** \"".$to_name."\" keyboard mapping */\n"; -printf "struct key_mapping ".$to_name_c."_mapping[] __keymap = {\n"; -foreach my $from_sym ( sort { $a <=> $b } keys %$map ) { - my $to_sym = $map->{$from_sym}; - next if $from_sym == $to_sym; - printf "\t{ 0x%02x, 0x%02x },\t/* %s => %s */\n", $from_sym, $to_sym, - ascii_to_name ( $from_sym ), ascii_to_name ( $to_sym ); -} -printf "};\n"; -- cgit v1.2.3-55-g7522