1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
package keyboard;
use diagnostics;
use strict;
use vars qw($KMAP_MAGIC %defaultKeyboards %loadKeymap);
use common qw(:system :file);
use run_program;
use log;
use c;
$KMAP_MAGIC = 0x8B39C07F;
%defaultKeyboards = (
"de" => "de-latin1",
"fr" => "fr-latin1",
"fi" => "fi-latin1",
"se" => "se-latin1",
"no" => "no-latin1",
"cs" => "cz-lat2",
"tr" => "trq",
);
1;
sub load($) {
my ($keymap) = @_;
my ($magic, @keymaps) = unpack "I i" . c::MAX_NR_KEYMAPS() . "a*", $keymap;
$keymap = pop @keymaps;
$magic != $KMAP_MAGIC and die "failed to read kmap magic";
local *F;
sysopen F, "/dev/console", 2 or die "failed to open /dev/console: $!";
my $count = 0;
foreach (0 .. c::MAX_NR_KEYMAPS() - 1) {
$keymaps[$_] or next;
my @keymap = unpack "s" . c::NR_KEYS() . "a*", $keymap;
$keymap = pop @keymap;
my $key = -1;
foreach my $value (@keymap) {
$key++;
c::KTYP($value) != c::KT_SPEC() or next;
ioctl(F, c::KDSKBENT(), pack("CCS", $_, $key, $value)) or die "keymap ioctl failed ($_ $key $value): $!";
}
$count++;
}
log::l("loaded $count keymap tables");
}
sub setup(;$) {
my ($defkbd) = @_;
my $t;
$defkbd ||= $defaultKeyboards{$ENV{LANG}} || "us";
my $file = "/usr/share/keymaps/$defkbd.kmap";
if (-e $file) {
log::l("loading keymap $defkbd");
load(cat_($file));
}
# local *F;
# open F, "/usr/etc/keymaps" or die "cannot open /usr/etc/keymaps: $!";
#
# my $format = "i2";
# read F, $t, psizeof($format) or die "failed to read keymaps header: $!";
# my ($magic, $numEntries) = unpack $format, $t;
#
# log::l("%d keymaps are available", $numEntries);
#
# my @infoTable;
# my $format2 = "i Z40";
# foreach (1..$numEntries) {
# read F, $t, psizeof($format2) or die "failed to read keymap information: $!";
# push @infoTable, [ unpack $format2, $t ];
# }
#
# foreach (@infoTable) {
# read F, $t, $_->[0] or die "error reading keymap data: $!";
#
# if ($defkbd eq $_->[1]) {
# log::l("using keymap $_->[1]");
# load($t);
# &write("/tmp", $_->[1]);
# return;
# }
# }
# die "keyboard $defkbd not found in /usr/etc/keymaps";
}
sub write($$) {
my ($prefix, $keymap) = @_;
local *F;
open F, ">$prefix/etc/sysconfig/keyboard" or die "failed to create keyboard configuration: $!";
print F "KEYTABLE=$keymap\n" or die "failed to write keyboard configuration: $!";
run_program::rooted($prefix, "dumpkeys > /etc/sysconfig/console/default.kmap") or die "dumpkeys failed";
}
sub read($) {
my ($file) = @_;
local *F;
open F, "$file" or die "failed to read keyboard configuration";
foreach (<F>) {
($_) = /^KEYTABLE=(.*)/ or log::l("unrecognized entry in keyboard configuration file ($_)"), next;
s/\"//g;
s/\.[^.]*//; # remove extension
return basename($_);
}
die "empty keyboard configuration file";
}
|