Home | History | Annotate | Download | only in utils
      1 #!/usr/bin/perl
      2 
      3 eval { use bytes; };
      4 eval { binmode STDOUT; };
      5 
      6 $DEFAULT_MAP = "us";
      7 $DEFAULT_EXT = ".kmap";
      8 
      9 sub usage
     10 {
     11     print STDERR
     12       "usage: $0 [ -p old_code=new_code ] ...\n".
     13       (" "x(8+length $0))."[path]default_layout[.kmap] ] ".
     14       "[path]kbd_layout[.kmap]\n";
     15     exit 1;
     16 }
     17 
     18 
     19 while ($ARGV[0] eq "-p") {
     20     shift(@ARGV);
     21     &usage unless $ARGV[0] =~ /=/;
     22     $table[eval($`)] = eval($');
     23     shift(@ARGV);
     24 }
     25 &usage unless defined $ARGV[0];
     26 load_map("def",defined $ARGV[1] ? $ARGV[0] : undef);
     27 load_map("kbd",defined $ARGV[1] ? $ARGV[1] : $ARGV[0]);
     28 &build_table("plain","shift","ctrl","altgr","shift_ctrl",
     29   "altgr_ctrl","alt","shift_alt","ctrl_alt");
     30 for ($i = 0; $i < 256; $i++) {
     31     printf("%c",$table[$i] ? $table[$i] : $i) || die "print: $!";
     32 }
     33 close STDOUT || die "close: $!";
     34 
     35 
     36 sub load_map
     37 {
     38     local ($pfx,$map) = @_;
     39     local ($empty,$current);
     40 
     41     $map = $DEFAULT_MAP unless defined $map;
     42     $map .= $DEFAULT_EXT unless $map =~ m|/[^/]+\.[^/]+$|;
     43     if (!open(FILE,"loadkeys -m $map |")) {
     44 	print STDERR "loadkeys -m $map: $!\n";
     45 	exit 1;
     46     }
     47     undef $current;
     48     $empty = 1;
     49     while (<FILE>) {
     50 	chop;
     51 	if (/^(static\s+)?u_short\s+(\S+)_map\[\S*\]\s+=\s+{\s*$/) {
     52 	    die "active at beginning of map" if defined $current;
     53 	    $current = $pfx.":".$2;
     54 	    next;
     55 	}
     56 	undef $current if /^};\s*$/;
     57 	next unless defined $current;
     58 	s/\s//g;
     59 	$map{$current} .= $_;
     60 	$empty = 0;
     61     }
     62     close FILE;
     63     return unless $empty;
     64     print STDERR "Keymap is empty\n";
     65     exit 1;
     66 }
     67 
     68 
     69 sub build_table
     70 {
     71     local (@maps) = @_;
     72     local (@tmp);
     73 
     74     $set = 0;
     75     for $map (@maps) {
     76 	$code = $set;
     77 	for (split(",",$map{"def:".$map})) {
     78 	    die "bad map entry $_ (def, map $map)" unless /^0x\S\S(\S\S)$/;
     79 	    $tmp[$code] = hex $1 unless $tmp[$code];
     80 	    $code++;
     81 	}
     82 	$set += 256;
     83     }
     84     $set = 0;
     85     for $map (@maps) {
     86 	$code = $set;
     87 	for (split(",",$map{"kbd:".$map})) {
     88 	    die "bad map entry $_ (kbd, map $map)" unless /^0x\S\S(\S\S)$/;
     89 	    $table[$tmp[$code]] = hex $1 unless $table[$tmp[$code]];
     90 	    $code++;
     91 	}
     92 	$set += 256;
     93     }
     94     $table[0] = 0;
     95 }
     96