3 # Copyright (c) March 1995 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
15 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 # kbdmap/vidfont - front end for syscons
29 # $FreeBSD: src/usr.sbin/kbdmap/kbdmap.pl,v 1.10.2.2 2001/03/05 13:08:47 ru Exp $
30 # $DragonFly: src/usr.sbin/kbdmap/Attic/kbdmap.pl,v 1.2 2003/06/17 04:29:55 dillon Exp $
33 # simple test if syscons works
34 $x11 = system("kbdcontrol -d >/dev/null");
36 warn "You are not on a virtual console - " .
37 "expect certain strange side-effects\n";
41 sub variables_static {
42 $lang_default = "en"; # set default language
43 $lang = $ENV{'LC_ALL'} || $ENV{'LC_CTYPE'} || $ENV{'LANG'} || $lang_default;
45 $program = $0; $program =~ s|.*/||; $program =~ s/\.(pl|perl)$//;
46 $keymapdir = "/usr/share/syscons/keymaps";
47 $fontdir = "/usr/share/syscons/fonts";
48 $sysconfig = "/etc/rc.conf";
51 #$keymapdir = "/tmp/kbdmap/syscons/keymaps";
52 #$fontdir = "/tmp/kbdmap/syscons/fonts";
54 # read current font from rc.conf
55 $font_default = "cp437-8x16.fnt";
56 $font_current = &font_current($font_default);
58 if ($program eq "kbdmap") {
64 @langsupport = ('MENU', 'FONT'); # lang depended variables
65 $show = 0; # show which languages currently supported
66 $index = "INDEX"; # Keyboard language database
74 #$lang =~ s/_.*//; # strip country and font
75 $lang =~ s/^(C)$/en/; # aliases
76 #$lang =~ s/^(..).*/$1/; # use only first to characters
85 open(F, "$sysconfig") || warn "$sysconfig: $!\n";
89 if (/^\s*font[0-9]+x[0-9]+\s*=\s*\"?([^\s\"]+)\"?/) {
90 $font_current = $1 if $1 ne "NO";
95 return $font_current if $font_current;
102 return $x11 if $x11; # syscons test failed
104 if ($font =~ /.*([0-9]+x[0-9]+)(\.fnt)?$/) {
105 warn "vidcontrol -f $1 $font\n" if $verbose;
106 return system("vidcontrol -f $1 $font");
108 warn "Which font size? ``$font''\n";
114 local($e,@a,$mark,$ext);
115 local($keym, $lg, $dialect, $desc);
116 local(@langlist) = $lang_default;
118 $ext = $dir; $ext =~ s|.*/||;
119 # en_US.ISO8859-1 -> en_..\.ISO8859-1
120 ($dialect = $lang) =~ s/^(..)_..(.+)$/$1_..$2/;
121 # en_US.ISO8859-1 -> en
122 ($lang_abk = $lang) =~ s/^(..)_.*$/$1/;
124 # read index database
125 open(I, "$dir/$index.$ext") || warn "$dir/$index.$ext: $!\n";
127 # skip blank lines and comments
133 ($keym, $lg, $desc) = split(/:/);
134 if (! -r "$keym" && ! -r "$dir/$keym" &&
135 !grep(/$keym/, @langsupport)) {
136 warn "$keym not found!\n" if $verbose;
140 # set empty language to default language
141 $lg = $lang_default if $lg eq "";
145 foreach $e (split(/,/, $lg)) {
146 push(@langlist, $e) if !grep($_ eq $e, @langlist);
150 # 4) your choise if exist
151 # 3) long match e.g. en_GB.ISO8859-1 is equal to en_..\.ISO8859-1
152 # 2) short match 'de'
153 # 1) default langlist 'en'
156 # language may be a kommalist
157 # higher match overwrite lower
158 # last entry overwrite previous if exist twice in database
160 # found your favorite language :-)
161 if ($lg =~ /^(.+,)?$lang(,.+)?$/) {
162 $keymap{$keym} = $desc;
164 } elsif ($mark{$keym} <= 3 && $lg =~ /^(.+,)?$dialect(,.+)?$/) {
166 $keymap{$keym} = $desc;
168 } elsif ($mark{$keym} <= 2 && $lg =~ /^(.+,)?$lang_abk(,.+)?$/) {
170 $keymap{$keym} = $desc;
172 } elsif ($mark{$keym} <= 1 && $lg =~ /^(.+,)?$lang_default(,.+)?$/) {
174 $keymap{$keym} = $desc;
176 } elsif ($mark{$keym} <= 0) {
178 $keymap{$keym} = $desc;
185 @langlist = sort(@langlist);
186 print "Currently supported languages: @langlist\n";
190 # remove variables from list
192 foreach $e (@langsupport) {
193 ($ee = $e) =~ y/A-Z/a-z/;
194 eval "\$$ee = \"$keymap{$e}\"";
195 #warn "$e \$$ee = \"$keymap{$e}\"";
198 #warn "$font $font_default $font_current\n";
201 # look for keymaps which are not in database
202 opendir(D, "$dir") || warn "$dir: $!\n";
203 foreach $e (readdir(D)) {
204 if ($e =~ /^[a-z].*(kbd|fnt)$/ && !$keymap{$e}) {
205 warn "$e not in database\n" if $verbose;
207 $keymap{$e} =~ s/\.(kbd|fnt)$//;
212 # sort menu, font 8x8 is less than 8x14 and 8x16
213 foreach $e (sort(keys %keymap)) {
215 push(@a, "\"$keymap{$e}\" \"\"");
219 grep(s/8x8/8x08/, @a);
221 grep(s/8x08/8x8/, @a);
237 local($tmp) = "/tmp/_kbd_lang" . rand(9999);
239 $dialog = "/usr/bin/dialog \\
241 --title \"Keyboard Menu\" \\
245 ## *always* start right font, don't believe that your current font
246 ## is equal with default font in /etc/rc.conf
247 ## see also at end of this function
250 # start right font, assume that current font is equal
251 # to default font in /etc/rc.conf
253 # $font is the font which require the language $lang; e.g.
254 # russian *need* a koi8 font
255 # $font_current is the current font from /etc/rc.conf
256 if ($font && $font ne $font_current) {
261 system("$dialog @argv 2> $tmp");
264 $choise = `cat $tmp`;
265 foreach $e (keys %keymap) {
266 if ($keymap{$e} eq $choise) {
267 if ($program eq "kbdmap") {
268 system("kbdcontrol -l $dir/$e\n") unless $x11;
269 print "keymap=$e", "\n";
271 &vidcontrol("$dir/$e");
273 if (/^.*\-(.*)\.fnt/) {
275 } else { $font="unknown" }
276 print "font$font=$e", "\n";
282 } elsif ($font && $font ne $font_current) {
283 # cancel, restore old font
284 &vidcontrol($font_current);
292 usage: $program\t[-K] [-V] [-d|-default] [-h|-help] [-l|-lang language]
293 \t\t[-p|-print] [-r|-restore] [-s|-show] [-v|-verbose]
302 while($_ = $argv[0], /^-/) {
305 if (/^--?(h|help|\?)$/) { &usage; }
306 elsif (/^-(v|verbose)$/) { $verbose = 1; }
307 elsif (/^-(l|lang)$/) { $lang = &lang($argv[0]); shift @argv; }
308 elsif (/^-(d|default)$/) { $lang = $lang_default }
309 elsif (/^-(s|show)$/) { $show = 1 }
310 elsif (/^-(p|print)$/) { $print = 1 }
311 elsif (/^-(r|restore)$/) { &vidcontrol($font_current); exit(0) }
312 elsif (/^-K$/) { $dir = $keymapdir; }
313 elsif (/^-V$/) { $dir = $fontdir; }
319 &variables_static; # read variables
320 &parse(@ARGV); # parse arguments
321 &dialog(&menu_read); # start dialog and kbdcontrol/vidcontrol