1#!/usr/bin/perl 2 3eval { use bytes; }; 4eval { binmode STDOUT; }; 5 6$DEFAULT_MAP = "us"; 7$DEFAULT_EXT = ".kmap"; 8 9sub 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 19while ($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]; 26load_map("def",defined $ARGV[1] ? $ARGV[0] : undef); 27load_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"); 30for ($i = 0; $i < 256; $i++) { 31 printf("%c",$table[$i] ? $table[$i] : $i) || die "print: $!"; 32} 33close STDOUT || die "close: $!"; 34 35 36sub 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 69sub 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