[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: console-setup fetching data from xkb-data?



Ok, now I'm subscribed to debian-boot since people seem assume I am :)

Christian Perrier wrote:
> If I understand well, the strings used by console-setup for keymap
> names are indeed used from an XML file...that's built by
> xkeyboard-config, where these strings are translatable through PO
> files.

Yes.

> If that's right, it means that a main blocker for the swith to
> console-setup does not really exist and we could re-consider this more
> carefully.
> 
> Am I right?

Well, the blocker just becomes "how to merge two POs" :)

BTW, I've roughly finished a patch that does "parse base.xml to generate
locale/country -> layout/variant default choice", I have attached
it to this mail for review.  I have checked for differences between
the manual statement and the generated statement, and filed bugs on
bugzilla.freedesktop.org for the few discrepancies.  Appart from those,
going to the generated form fixes a bunch of bugs and provides much
better coverage :)

Samuel
Index: debian/control
===================================================================
--- debian/control	(révision 57439)
+++ debian/control	(copie de travail)
@@ -3,7 +3,7 @@
 Priority: optional
 Maintainer: Debian Install System Team <debian-boot@lists.debian.org>
 Uploaders: Anton Zinoviev <zinoviev@debian.org>, Christian Perrier <bubulle@debian.org>
-Build-Depends-Indep: perl, libxml-parser-perl, xkb-data (>= 0.9)
+Build-Depends-Indep: perl, libxml-parser-perl, xkb-data (>= 0.9), iso-codes
 Build-Depends: debhelper (>= 5), po-debconf
 Standards-Version: 3.7.3
 Vcs-Svn: svn://svn.debian.org/d-i/trunk/packages/console-setup
Index: debian/rules
===================================================================
--- debian/rules	(révision 57439)
+++ debian/rules	(copie de travail)
@@ -34,6 +34,10 @@
     printf "'\''"; \
     next; \
 } \
+/## *CHOOSER *##/ { \
+    system("cd Keyboard && ./chooser-maker MyKeyboardNames.pl"); \
+    next; \
+} \
 { \
    print; \
 }' debian/config.proto >$@
Index: debian/config.proto
===================================================================
--- debian/config.proto	(révision 57439)
+++ debian/config.proto	(copie de travail)
@@ -702,238 +702,7 @@
 default_layout=''
 default_variant=''
 layout_priority=critical
-case "$locale" in
-    # Keyboards for countries
-    *_AL*)
-	default_layout=al  # Albania
-	;;
-    *_AZ*)
-	default_layout=az  # Azerbaijan
-	;;
-    *_BD*)
-	default_layout=bd  # Bangladesh
-	;;
-    *_BE*)
-	default_layout=be  # Belgium
-	;;
-    *_BG*)
-	default_layout=bg  # Bulgaria
-	layout_priority=critical
-	;;
-    *_BR*)
-	default_layout=br  # Brazil
-	;;
-    *_BY*)
-	default_layout=by  # Belarus
-	;;
-    fr_CA*)
-	default_layout=ca  # Canada
-	;;
-    *_CA*)
-	default_layout=us  # U.S. English
-	;;
-    fr_CH*)
-	default_layout=ch  # Switzerland
-	default_variant=fr # French
-	;;
-    *_CH*)
-	default_layout=ch  # Switzerland
-	layout_priority=critical
-	;;
-    *_CZ*)
-	default_layout=cz  # Czechia
-	layout_priority=critical
-	;;
-    *_DK*)
-	default_layout=dk  # Denmark
-	;;
-    *_EE*)
-	default_layout=ee  # Estonia
-	;;
-    *_ES*)
-	default_layout=es  # Spain
-	;;
-    se_FI*)
-	default_layout=fi  # Finland
-	default_variant=smi # Northern Saami
-	;;
-    *_FI*)
-	default_layout=fi  # Finland
-	default_variant=fi # Finland
-	;;
-    *_GB*)
-	default_layout=gb  # United Kingdom
-	;;
-    *_HU*)
-	default_layout=hu  # Hungary
-	;;
-    *_IE*)
-	default_layout=ie  # Ireland
-	;;
-    *_IL*)
-	default_layout=il  # Israel
-	layout_priority=critical
-	;;
-    *_IR*)
-	default_layout=ir  # Iran
-	;;
-    *_IS*)
-	default_layout=is  # Iceland
-	;;
-    *_IT*)
-	default_layout=it  # Italy
-	;;
-    *_JP*)
-	default_layout=jp  # Japan
-	;;
-    *_LT*)
-	default_layout=lt  # Lithuania
-	layout_priority=critical
-	;;
-    *_LV*)
-	default_layout=lv  # Latvia
-	;;
-    *_MK*)
-	default_layout=mk  # Macedonia
-	;;
-    *_NL*)
-	default_layout=nl  # Netherlands
-	;;
-    *_MN*)
-	default_layout=mn  # Mongolia
-	;;
-    *_MT*)
-	default_layout=mt  # Malta
-	layout_priority=critical
-	;;
-    se_NO*)
-	default_layout=no  # Norway
-	default_variant=smi # Northern Saami
-	;;
-    *_NO*)
-	default_layout=no  # Norway (se_NO is not in this case)
-	;;
-    *_PL*)
-	default_layout=pl  # Poland
-	;;
-    *_PT*)
-	default_layout=pt  # Portugal
-	;;
-    *_RO*)
-	default_layout=ro  # Romania
-	;;
-    *_RU*)
-	default_layout=ru  # Russia
-	layout_priority=critical
-	;;
-    se_SE*)
-	default_layout=se  # Sweden
-	default_variant=smi # Northern Saami
-	;;
-    *_SK*)
-	default_layout=sk  # Slovakia
-	;;
-    *_SI*)
-	default_layout=si  # Slovenia
-	;;
-    *_TJ*)
-	default_layout=tj  # Tajikistan
-	;;
-    *_TH*)
-	default_layout=th  # Thailand
-	layout_priority=critical
-	;;
-    *_TR*)
-	default_layout=tr  # Turkish
-	layout_priority=critical
-	;;
-    *_UA*)
-	default_layout=ua  # Ukraine
-	;;
-    en_US*)
-	default_layout=us  # U.S. English
-	;;
-    *_VN*)
-	default_layout=vn  # Vietnam
-	;;
-    # Keyboards for specific languages and international keyboards:
-    # TODO: Is the following list correct?
-    *_AR*|*_BO*|*_CL*|*_CO*|*_CR*|*_DO*|*_EC*|*_GT*|*_HN*|*_MX*|*_NI*|*_PA*|*_PE*|es_PR*|*_PY*|*_SV*|es_US*|*_UY*|*_VE*)
-	default_layout=latam # Latin American
-	;;
-    ar_*)
-	default_layout=ara # Arabic
-	;;
-    bs_*)
-	default_layout=ba  # Bosnia and Herzegovina
-	;;
-    de_*)
-	default_layout=de  # Germany
-	;;
-    el_*)
-	default_layout=gr  # Greece
-	;;
-    eo|eo.*|eo_*|eo\@*)
-	default_layout=epo  # Esperanto
-	;;
-    fr_*)
-	default_layout=fr  # France
-	layout_priority=critical
-	;;
-    gu_*)
-	default_layout=in  # India
-	default_variant=guj # Gujarati
-	;;
-    hi_*)
-	default_layout=in  # India
-	default_variant=deva # Devanagari
-	;;
-    hr_*)
-	default_layout=hr  # Croatia
-	;;
-    hy_*)
-	default_layout=am  # Armenia
-	;;
-    ka_*)
-	default_layout=ge  # Georgia
-	layout_priority=critical
-	;;
-    kn_*)
-	default_layout=in  # India
-	default_variant=kan # Kannada
-	;;
-    lo_*)
-	default_layout=la  # Laos
-	;;
-    ml_*)
-	default_layout=in  # India
-	default_variant=mal # Malayalam
-	;;
-    pa_*)
-	default_layout=in  # India
-	default_variant=guru # Gurmukhi
-	;;
-    sr_*)
-	default_layout=cs  # Serbia and Montenegro
-	layout_priority=critical
-	;;
-    sv_*)
-	default_layout=se  # Sweden
-	default_variant=basic
-	;;
-    ta_*)
-	default_layout=in  # India
-	default_variant=tam # Tamil
-	;;
-    te_*)
-	default_layout=in  # India
-	default_variant=tel # Telugu
-	;;
-    # Fallback
-    *)
-	default_layout=us
-	;;
-esac
+## CHOOSER ## Will be replaced by case "$locale"
 
 if \
     [ -d /lib/debian-installer ] \
Index: Keyboard/xmlreader
===================================================================
--- Keyboard/xmlreader	(révision 57439)
+++ Keyboard/xmlreader	(copie de travail)
@@ -20,6 +20,8 @@
 use warnings 'all';
 use strict;
 use encoding 'utf8';
+my $iso_639_3_xml_file = "/usr/share/xml/iso-codes/iso_639_3.xml";
+my $iso_639_xml_file = "/usr/share/xml/iso-codes/iso_639.xml";
 
 my $file;
 if ($ARGV[0]) {
@@ -66,10 +68,142 @@
 
 my $tree = $parser->parsefile ($file);
 
+my %iso639tolocale;
+
+sub addiso639tolocale {
+    my $code3 = $_[0];
+    my $code2 = $_[1];
+
+    if (!$code3) {
+	return;
+    }
+    if (!$code2) {
+	$code2 = $code3;
+    }
+
+    my $prevcode2 = $iso639tolocale{$code3};
+
+    if ($prevcode2) {
+	if ($code2 ne $prevcode2) {
+	    printf STDERR "previous 2-letter code for ISO 639 $code3 was $prevcode2, now trying to set $code2!\n";
+	    exit 1;
+	}
+    } else {
+	$iso639tolocale{$code3} = $code2;
+    }
+}
+
+my $iso639 = $parser->parsefile ($iso_639_xml_file);
+my $list = @{$iso639}[1];
+my $i;
+
+for ($i = 4; $i < $#{$list}; $i += 4) {
+    my $element = @{$list}[$i];
+    my $details = @{$element}[0];
+    my $iso_639_1_code = $details->{"iso_639_1_code"};
+    my $iso_639_2B_code = $details->{"iso_639_2B_code"};
+    my $iso_639_2T_code = $details->{"iso_639_2T_code"};
+    addiso639tolocale($iso_639_2B_code, $iso_639_1_code);
+    addiso639tolocale($iso_639_2T_code, $iso_639_1_code);
+}
+
+my $iso639_3 = $parser->parsefile ($iso_639_3_xml_file);
+$list = @{$iso639_3}[1];
+
+for ($i = 4; $i < $#{$list}; $i += 4) {
+    my $element = @{$list}[$i];
+    my $details = @{$element}[0];
+    my $id = $details->{"id"};
+    my $part1_code = $details->{"part1_code"};
+    my $part2_code = $details->{"part2_code"};
+    addiso639tolocale($id, $part1_code);
+    addiso639tolocale($part2_code, $part1_code);
+}
+
+# TODO: add support for iso639-5 language families
+
+sub iso639tolocale {
+    my $code = $_[0];
+    my $code2;
+
+    if (length($code) == 2) {
+	return $code;
+    }
+
+    if (length($code) != 3) {
+	print STDERR "non-ISO code $code";
+	exit 1;
+    }
+
+    $code2 = $iso639tolocale{$code};
+    if (!$code2) {
+	debug "could not find $code in $iso_639_xml_file or $iso_639_3_xml_file\n";
+	return $code;
+    }
+    return $code2;
+}
+
 my %models;
 my %layouts;
 my %variants;
+my %locales_keyboards;
+my %countries_keyboards;
+my %languages_keyboards;
 
+sub add_keyboard {
+    my $layout = $_[0];
+    my $variant = $_[1];
+    my $countries = $_[2];
+    my $languages = $_[3];
+    my @countries = @{$countries};
+    my @languages = @{$languages};
+
+    # if a keyboard already exactly matches,
+    # - if it's just a new variant of the same layout, ignore it
+    # - if it's a variant of another layout and we are the default variant of
+    # the currently parsed layout, replace it.
+    # - else ignore it but set ambiguous.
+
+    if (@languages && @countries) {
+	for my $country (@countries) {
+	    for my $language (@languages) {
+		my $existing = $locales_keyboards{$country}{$language};
+		if ($existing && !($existing->{"variant"} && !$variant)) {
+		    if ($existing->{"layout"} ne $layout) {
+			$locales_keyboards{$country}{$language}->{"ambiguous"} = 1;
+		    }
+		} else {
+		    $locales_keyboards{$country}{$language} = { 'layout' => $layout, 'variant' => $variant };
+		}
+	    }
+	}
+    }
+    if (@countries) {
+	for my $country (@countries) {
+	    my $existing = $countries_keyboards{$country};
+	    if ($existing && !($existing->{"variant"} && !$variant)) {
+		if ($existing->{"layout"} ne $layout) {
+		    $countries_keyboards{$country}->{"ambiguous"} = 1;
+		}
+	    } else {
+		$countries_keyboards{$country} = { 'layout' => $layout, 'variant' => $variant };
+	    }
+	}
+    }
+    if (@languages) {
+	for my $language (@languages) {
+	    my $existing = $languages_keyboards{$language};
+	    if ($existing && !($existing->{"variant"} && !$variant)) {
+		if ($existing->{"layout"} ne $layout) {
+		    $languages_keyboards{$language}->{"ambiguous"} = 1;
+		}
+	    } else {
+		$languages_keyboards{$language} = { 'layout' => $layout, 'variant' => $variant };
+	    }
+	}
+    }
+}
+
 sub parse_text {
     my $tree = $_[0];
     my $contents = '';
@@ -86,11 +220,50 @@
     return $contents;
 }
 
+
+sub parse_countryList {
+    my $tree = $_[0];
+    shift @{$tree};
+    my @countries = ();
+    while (@{$tree}) {
+	my $tag = shift @{$tree};
+	my $arg = shift @{$tree};
+	if ($tag eq 'iso3166Id') {
+	    push(@countries, parse_text $arg);
+	} elsif ($tag eq 0) {
+	    warning "countryList: Garbage in countryList: $arg.\n" if ($arg !~ /^\s*$/);
+	} else {
+	    warning "countryList: Unknown tag $tag, arg=$arg\n";
+	}
+    }
+    return (@countries);
+}
+
+sub parse_languageList {
+    my $tree = $_[0];
+    shift @{$tree};
+    my @languages = ();
+    while (@{$tree}) {
+	my $tag = shift @{$tree};
+	my $arg = shift @{$tree};
+	if ($tag eq 'iso639Id') {
+	    push(@languages, iso639tolocale(parse_text $arg));
+	} elsif ($tag eq 0) {
+	    warning "languageList: Garbage in languageList: $arg.\n" if ($arg !~ /^\s*$/);
+	} else {
+	    warning "languageList: Unknown tag $tag, arg=$arg\n";
+	}
+    }
+    return (@languages);
+}
+
 sub parse_configItem {
     my $tree = $_[0];
     shift @{$tree};
     my $name;
     my $description;
+    my @countries = ();
+    my @languages = ();
     while (@{$tree}) {
 	my $tag = shift @{$tree};
 	my $arg = shift @{$tree};
@@ -100,6 +273,10 @@
 	    if (! %{$arg->[0]}) {
 		$description = parse_text $arg;
 	    }
+	} elsif ($tag eq 'countryList') {
+	    @countries = parse_countryList $arg;
+	} elsif ($tag eq 'languageList') {
+	    @languages = parse_languageList $arg;
 	} elsif ($tag =~ /^(shortDescription|_description
                            |vendor|languageList|countryList)$/x) {
 	} elsif ($tag eq 0) {
@@ -110,7 +287,7 @@
     }
     $name = '' unless ($name);
     $description = $name unless ($description);
-    return ($name, $description);
+    return ($name, $description, \@countries, \@languages);
 }
 
 sub parse_model {
@@ -120,7 +297,7 @@
 	my $tag = shift @{$tree};
 	my $arg = shift @{$tree};
 	if ($tag eq 'configItem') {
-	    my ($name, $description) = parse_configItem $arg;
+	    my ($name, $description, $countries, $languages) = parse_configItem $arg;
 	    if ($name ne '') {
 		$models{$description} = $name;
 	    }
@@ -151,16 +328,29 @@
 sub parse_variant {
     my $layout = $_[0];
     my $tree = $_[1];
+    my $layout_countries = $_[2];
+    my $layout_languages = $_[3];
     shift @{$tree};
     my $name;
     my $description;
+    my ($countries, @countries, @variant_countries);
+    my ($languages, @languages, @variant_languages);
     while (@{$tree}) {
 	my $tag = shift @{$tree};
 	my $arg = shift @{$tree};
 	if ($tag eq 'configItem') {
-	    ($name, $description) = parse_configItem $arg;
+	    ($name, $description, $countries, $languages) = parse_configItem $arg;
+	    @countries = @variant_countries = @{$countries};
+	    @languages = @variant_languages = @{$languages};
+	    @countries = @{$layout_countries} unless (@countries);
+	    @languages = @{$layout_languages} unless (@languages);
 	    if ($layout ne '' && $name ne '') {
 		$variants{$layout}{$description} = $name;
+		if (@variant_countries || @variant_languages) {
+		    # This variant has specific countries or languages, add
+		    # them
+		    add_keyboard($layout, $name, \@countries, \@languages);
+		}
 	    }
 	} elsif ($tag eq 0) {
 	    warning "variant: Garbage in variant: $arg.\n" if ($arg !~ /^\s*$/);
@@ -173,12 +363,14 @@
 sub parse_variantList {
     my $name = $_[0];
     my $tree = $_[1];
+    my $countries = $_[2];
+    my $languages = $_[3];
     shift @{$tree};
     while (@{$tree}) {
 	my $tag = shift @{$tree};
 	my $arg = shift @{$tree};
 	if ($tag eq 'variant') {
-	    parse_variant $name, $arg;
+	    parse_variant $name, $arg, $countries, $languages;
 	} elsif ($tag eq 0) {
 	    warning "variantList: Garbage in variantList: $arg.\n" if ($arg !~ /^\s*$/);
 	} else {
@@ -194,20 +386,37 @@
     shift @{$tree};
     my $name;
     my $description;
+    my $countries;
+    my @countries = ();
+    my $languages;
+    my @languages = ();
     while (@{$tree}) {
 	my $tag = shift @{$tree};
 	my $arg = shift @{$tree};
 	if ($tag eq 'configItem') {
-	    ($name, $description) = parse_configItem $arg;
+	    ($name, $description, $countries, $languages) = parse_configItem $arg;
+	    @countries = @{$countries};
+	    @languages = @{$languages};
+	    if (length($name) == 2) {
+		# two-character names of layouts are countries
+		push(@countries,uc($name));
+	    } elsif (length($name) == 3) {
+		# three-character names of layouts are languages
+		push(@languages,iso639tolocale($name));
+	    }
 	    if ($name ne "") {
 		$layouts{$description} = $name;
+		# ignore deprecated keyboards
+		if ($name ne "nec_vndr/jp") {
+		    add_keyboard($name,"",\@countries,\@languages);
+		}
 	    }
 	} elsif ($tag eq 'variantList') {
 	    if (! $name) {
 		warning "layout: variantList before configItem\n";
 		next;
 	    }
-	    parse_variantList $name, $arg;
+	    parse_variantList $name, $arg, \@countries, \@languages;
 	} elsif ($tag eq 0) {
 	    warning "layout: Garbage in model: $arg.\n" if ($arg !~ /^\s*$/);
 	} else {
@@ -315,4 +524,54 @@
 }
 print ");\n\n";
 
+print "%locales_keyboards = (\n";
+for my $x (sort keys %locales_keyboards) {
+    my $y = $locales_keyboards{$x};
+    print "    '$x' => {\n";
+    for my $z (sort keys %{$y}) {
+	my $t = $y->{$z};
+	my %t = %{$t};
+	print "	'$z' => { 'layout' => '".$t->{"layout"}."'";
+	if ($t{'variant'}) {
+	    print ", 'variant' => '".$t->{"variant"}."'";
+	}
+	if ($t{'ambiguous'}) {
+	    print ", 'ambiguous' => 1";
+	}
+	print " },\n";
+    }
+    print "    },\n";
+}
+print ");\n\n";
+
+print "%countries_keyboards = (\n";
+for my $x (sort keys %countries_keyboards) {
+    my $t = $countries_keyboards{$x};
+    my %t = %{$t};
+    print "    '$x' => { 'layout' => '".$t->{"layout"}."'";
+    if ($t{'variant'}) {
+	print ", 'variant' => '".$t->{"variant"}."'";
+    }
+    if ($t{'ambiguous'}) {
+	print ", 'ambiguous' => 1";
+    }
+    print " },\n";
+}
+print ");\n\n";
+
+print "%languages_keyboards = (\n";
+for my $x (sort keys %languages_keyboards) {
+    my $t = $languages_keyboards{$x};
+    my %t = %{$t};
+    print "    '$x' => { 'layout' => '".$t->{"layout"}."'";
+    if ($t{'variant'}) {
+	print ", 'variant' => '".$t->{"variant"}."'";
+    }
+    if ($t{'ambiguous'}) {
+	print ", 'ambiguous' => 1";
+    }
+    print " },\n";
+}
+print ");\n\n";
+
 print "1;\n";
Index: Keyboard/KeyboardNames.pl
===================================================================
--- Keyboard/KeyboardNames.pl	(révision 57439)
+++ Keyboard/KeyboardNames.pl	(copie de travail)
@@ -69,6 +69,7 @@
     'Genius Comfy KB-16M / Genius MM Keyboard KWD-910' => 'genius',
     'Genius Comfy KB-21e-Scroll' => 'geniuscomfy2',
     'Genius KB-19e NB' => 'geniuskb19e',
+    'Genius KKB-2050HS' => 'geniuskkb2050hs',
     'Gyration' => 'gyration',
     'Happy Hacking Keyboard' => 'hhk',
     'Happy Hacking Keyboard for Mac' => 'macintosh_hhk',
@@ -319,6 +320,7 @@
 	'Multilingual, first part' => 'multi',
 	'Multilingual, second part' => 'multi-2gr',
 	'Secwepemctsin' => 'shs',
+	'U.S.' => 'us',
     },
     'ch' => {
 	'French' => 'fr',
@@ -694,4 +696,616 @@
     },
 );
 
+%locales_keyboards = (
+    'AD' => {
+	'ca' => { 'layout' => 'ad' },
+    },
+    'AE' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'AF' => {
+	'ps' => { 'layout' => 'af', 'variant' => 'ps' },
+	'uz' => { 'layout' => 'af', 'variant' => 'uz' },
+    },
+    'AL' => {
+	'sq' => { 'layout' => 'al' },
+    },
+    'AM' => {
+	'hy' => { 'layout' => 'am' },
+    },
+    'AR' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'AZ' => {
+	'az' => { 'layout' => 'az' },
+    },
+    'BA' => {
+	'bs' => { 'layout' => 'ba' },
+    },
+    'BD' => {
+	'bn' => { 'layout' => 'bd' },
+    },
+    'BE' => {
+	'de' => { 'layout' => 'be' },
+	'fr' => { 'layout' => 'be' },
+    },
+    'BG' => {
+	'bg' => { 'layout' => 'bg' },
+    },
+    'BH' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'BO' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'BR' => {
+	'eo' => { 'layout' => 'br', 'variant' => 'nativo-epo' },
+	'pt' => { 'layout' => 'br' },
+    },
+    'BT' => {
+	'dz' => { 'layout' => 'bt' },
+    },
+    'BY' => {
+	'be' => { 'layout' => 'by' },
+    },
+    'CA' => {
+	'en' => { 'layout' => 'ca', 'variant' => 'us' },
+	'fr' => { 'layout' => 'ca' },
+	'iu' => { 'layout' => 'ca', 'variant' => 'ike' },
+    },
+    'CD' => {
+	'fr' => { 'layout' => 'cd' },
+    },
+    'CH' => {
+	'de' => { 'layout' => 'ch' },
+	'fr' => { 'layout' => 'ch', 'variant' => 'fr' },
+	'gsw' => { 'layout' => 'ch' },
+    },
+    'CL' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'CN' => {
+	'bo' => { 'layout' => 'cn', 'variant' => 'tib' },
+	'zh' => { 'layout' => 'cn' },
+    },
+    'CO' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'CR' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'CU' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'CZ' => {
+	'cs' => { 'layout' => 'cz' },
+    },
+    'DE' => {
+	'de' => { 'layout' => 'de' },
+    },
+    'DK' => {
+	'da' => { 'layout' => 'dk' },
+    },
+    'DO' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'DZ' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'EC' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'EE' => {
+	'et' => { 'layout' => 'ee' },
+    },
+    'EG' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'EH' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'ES' => {
+	'ast' => { 'layout' => 'es', 'variant' => 'ast' },
+	'ca' => { 'layout' => 'es', 'variant' => 'cat' },
+	'es' => { 'layout' => 'es' },
+    },
+    'ET' => {
+	'am' => { 'layout' => 'et' },
+    },
+    'FI' => {
+	'fi' => { 'layout' => 'fi' },
+	'smi' => { 'layout' => 'fi', 'variant' => 'smi' },
+    },
+    'FO' => {
+	'fo' => { 'layout' => 'fo' },
+    },
+    'FR' => {
+	'fr' => { 'layout' => 'fr' },
+	'ka' => { 'layout' => 'fr', 'variant' => 'geo' },
+    },
+    'GB' => {
+	'en' => { 'layout' => 'gb' },
+    },
+    'GE' => {
+	'ka' => { 'layout' => 'ge' },
+	'os' => { 'layout' => 'ge', 'variant' => 'os' },
+	'ru' => { 'layout' => 'ge', 'variant' => 'ru' },
+    },
+    'GH' => {
+	'ak' => { 'layout' => 'gh', 'variant' => 'akan' },
+	'ee' => { 'layout' => 'gh', 'variant' => 'ewe' },
+	'en' => { 'layout' => 'gh' },
+	'ff' => { 'layout' => 'gh', 'variant' => 'fula' },
+	'gaa' => { 'layout' => 'gh', 'variant' => 'ga' },
+	'ha' => { 'layout' => 'gh', 'variant' => 'hausa' },
+    },
+    'GN' => {
+	'fr' => { 'layout' => 'gn' },
+    },
+    'GR' => {
+	'el' => { 'layout' => 'gr' },
+    },
+    'GT' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'HN' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'HR' => {
+	'hr' => { 'layout' => 'hr' },
+    },
+    'HT' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'HU' => {
+	'hu' => { 'layout' => 'hu' },
+    },
+    'IE' => {
+	'en' => { 'layout' => 'ie' },
+	'gd' => { 'layout' => 'ie', 'variant' => 'CloGaelach' },
+    },
+    'IL' => {
+	'he' => { 'layout' => 'il' },
+    },
+    'IN' => {
+	'bn' => { 'layout' => 'in', 'variant' => 'ben' },
+	'gu' => { 'layout' => 'in', 'variant' => 'guj' },
+	'hi' => { 'layout' => 'in', 'variant' => 'bolnagri' },
+	'kn' => { 'layout' => 'in', 'variant' => 'kan' },
+	'ml' => { 'layout' => 'in', 'variant' => 'mal' },
+	'or' => { 'layout' => 'in', 'variant' => 'ori' },
+	'pa' => { 'layout' => 'in', 'variant' => 'guru' },
+	'ta' => { 'layout' => 'in', 'variant' => 'tam_unicode' },
+	'te' => { 'layout' => 'in', 'variant' => 'tel' },
+	'ur' => { 'layout' => 'in', 'variant' => 'urd' },
+    },
+    'IQ' => {
+	'ar' => { 'layout' => 'iq' },
+	'ku' => { 'layout' => 'iq' },
+    },
+    'IR' => {
+	'fa' => { 'layout' => 'ir' },
+	'ku' => { 'layout' => 'ir', 'variant' => 'ku' },
+    },
+    'IS' => {
+	'is' => { 'layout' => 'is' },
+    },
+    'IT' => {
+	'it' => { 'layout' => 'it' },
+	'ka' => { 'layout' => 'it', 'variant' => 'geo' },
+    },
+    'JO' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'JP' => {
+	'ja' => { 'layout' => 'jp' },
+    },
+    'KG' => {
+	'ky' => { 'layout' => 'kg' },
+    },
+    'KH' => {
+	'km' => { 'layout' => 'kh' },
+    },
+    'KR' => {
+	'ko' => { 'layout' => 'kr' },
+    },
+    'KW' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'KZ' => {
+	'kk' => { 'layout' => 'kz' },
+	'ru' => { 'layout' => 'kz', 'variant' => 'ruskaz' },
+    },
+    'LA' => {
+	'lo' => { 'layout' => 'la' },
+    },
+    'LB' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'LK' => {
+	'si' => { 'layout' => 'lk' },
+	'ta' => { 'layout' => 'lk', 'variant' => 'tam_unicode' },
+    },
+    'LT' => {
+	'lt' => { 'layout' => 'lt' },
+    },
+    'LV' => {
+	'lv' => { 'layout' => 'lv' },
+    },
+    'LY' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'MA' => {
+	'ar' => { 'layout' => 'ara' },
+	'ber' => { 'layout' => 'ma', 'variant' => 'tifinagh' },
+	'fr' => { 'layout' => 'ma', 'variant' => 'french' },
+    },
+    'ME' => {
+	'sr' => { 'layout' => 'me' },
+    },
+    'MK' => {
+	'mk' => { 'layout' => 'mk' },
+    },
+    'MM' => {
+	'my' => { 'layout' => 'mm' },
+    },
+    'MN' => {
+	'mng' => { 'layout' => 'mn' },
+    },
+    'MR' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'MT' => {
+	'mt' => { 'layout' => 'mt' },
+    },
+    'MV' => {
+	'dv' => { 'layout' => 'mv' },
+    },
+    'MX' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'NG' => {
+	'en' => { 'layout' => 'ng' },
+	'ha' => { 'layout' => 'ng', 'variant' => 'hausa' },
+	'ig' => { 'layout' => 'ng', 'variant' => 'igbo' },
+	'yo' => { 'layout' => 'ng', 'variant' => 'yoruba' },
+    },
+    'NI' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'NL' => {
+	'nl' => { 'layout' => 'nl' },
+    },
+    'NO' => {
+	'no' => { 'layout' => 'no' },
+	'se' => { 'layout' => 'no', 'variant' => 'smi' },
+    },
+    'NP' => {
+	'ne' => { 'layout' => 'np' },
+    },
+    'OM' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'PA' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'PE' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'PK' => {
+	'ar' => { 'layout' => 'pk', 'variant' => 'ara' },
+	'ur' => { 'layout' => 'pk' },
+    },
+    'PL' => {
+	'csb' => { 'layout' => 'pl', 'variant' => 'csb' },
+	'pl' => { 'layout' => 'pl' },
+	'ru' => { 'layout' => 'pl', 'variant' => 'ru_phonetic_dvorak' },
+    },
+    'PR' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'PS' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'PT' => {
+	'eo' => { 'layout' => 'pt', 'variant' => 'nativo-epo' },
+	'pt' => { 'layout' => 'pt' },
+    },
+    'PY' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'QA' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'RO' => {
+	'ro' => { 'layout' => 'ro' },
+    },
+    'RS' => {
+	'sr' => { 'layout' => 'rs' },
+    },
+    'RU' => {
+	'cv' => { 'layout' => 'ru', 'variant' => 'cv' },
+	'kv' => { 'layout' => 'ru', 'variant' => 'kom' },
+	'os' => { 'layout' => 'ru', 'variant' => 'os_legacy' },
+	'ru' => { 'layout' => 'ru' },
+	'tt' => { 'layout' => 'ru', 'variant' => 'tt' },
+	'udm' => { 'layout' => 'ru', 'variant' => 'udm' },
+    },
+    'SA' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'SD' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'SE' => {
+	'ru' => { 'layout' => 'se', 'variant' => 'rus' },
+	'se' => { 'layout' => 'se', 'variant' => 'smi' },
+	'sv' => { 'layout' => 'se' },
+    },
+    'SI' => {
+	'sl' => { 'layout' => 'si' },
+    },
+    'SK' => {
+	'sk' => { 'layout' => 'sk' },
+    },
+    'SY' => {
+	'ar' => { 'layout' => 'ara' },
+	'ku' => { 'layout' => 'sy', 'variant' => 'ku' },
+	'syr' => { 'layout' => 'sy' },
+    },
+    'TH' => {
+	'th' => { 'layout' => 'th' },
+    },
+    'TJ' => {
+	'tg' => { 'layout' => 'tj' },
+    },
+    'TN' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'TR' => {
+	'ku' => { 'layout' => 'tr', 'variant' => 'ku' },
+	'tr' => { 'layout' => 'tr' },
+    },
+    'UA' => {
+	'uk' => { 'layout' => 'ua' },
+    },
+    'US' => {
+	'de' => { 'layout' => 'us', 'variant' => 'altgr-intl' },
+	'en' => { 'layout' => 'us' },
+	'fr' => { 'layout' => 'us', 'variant' => 'altgr-intl' },
+    },
+    'UY' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'UZ' => {
+	'uz' => { 'layout' => 'uz' },
+    },
+    'VE' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    'VN' => {
+	'vi' => { 'layout' => 'vn' },
+    },
+    'YE' => {
+	'ar' => { 'layout' => 'ara' },
+    },
+    'ZA' => {
+	'en' => { 'layout' => 'za' },
+    },
+);
+
+%countries_keyboards = (
+    'AD' => { 'layout' => 'ad' },
+    'AE' => { 'layout' => 'ara' },
+    'AF' => { 'layout' => 'af' },
+    'AL' => { 'layout' => 'al' },
+    'AM' => { 'layout' => 'am' },
+    'AR' => { 'layout' => 'latam' },
+    'AZ' => { 'layout' => 'az' },
+    'BA' => { 'layout' => 'ba' },
+    'BD' => { 'layout' => 'bd' },
+    'BE' => { 'layout' => 'be' },
+    'BG' => { 'layout' => 'bg' },
+    'BH' => { 'layout' => 'ara' },
+    'BO' => { 'layout' => 'latam' },
+    'BR' => { 'layout' => 'br' },
+    'BT' => { 'layout' => 'bt' },
+    'BY' => { 'layout' => 'by' },
+    'CA' => { 'layout' => 'ca' },
+    'CD' => { 'layout' => 'cd' },
+    'CH' => { 'layout' => 'ch' },
+    'CL' => { 'layout' => 'latam' },
+    'CN' => { 'layout' => 'cn' },
+    'CO' => { 'layout' => 'latam' },
+    'CR' => { 'layout' => 'latam' },
+    'CU' => { 'layout' => 'latam' },
+    'CZ' => { 'layout' => 'cz' },
+    'DE' => { 'layout' => 'de' },
+    'DK' => { 'layout' => 'dk' },
+    'DO' => { 'layout' => 'latam' },
+    'DZ' => { 'layout' => 'ara' },
+    'EC' => { 'layout' => 'latam' },
+    'EE' => { 'layout' => 'ee' },
+    'EG' => { 'layout' => 'ara' },
+    'EH' => { 'layout' => 'ara' },
+    'ES' => { 'layout' => 'es' },
+    'ET' => { 'layout' => 'et' },
+    'FI' => { 'layout' => 'fi' },
+    'FO' => { 'layout' => 'fo' },
+    'FR' => { 'layout' => 'fr' },
+    'GB' => { 'layout' => 'gb' },
+    'GE' => { 'layout' => 'ge' },
+    'GH' => { 'layout' => 'gh' },
+    'GN' => { 'layout' => 'gn' },
+    'GR' => { 'layout' => 'gr' },
+    'GT' => { 'layout' => 'latam' },
+    'HN' => { 'layout' => 'latam' },
+    'HR' => { 'layout' => 'hr' },
+    'HT' => { 'layout' => 'latam' },
+    'HU' => { 'layout' => 'hu' },
+    'IE' => { 'layout' => 'ie' },
+    'IL' => { 'layout' => 'il' },
+    'IN' => { 'layout' => 'in' },
+    'IQ' => { 'layout' => 'iq' },
+    'IR' => { 'layout' => 'ir' },
+    'IS' => { 'layout' => 'is' },
+    'IT' => { 'layout' => 'it' },
+    'JO' => { 'layout' => 'ara' },
+    'JP' => { 'layout' => 'jp' },
+    'KG' => { 'layout' => 'kg' },
+    'KH' => { 'layout' => 'kh' },
+    'KR' => { 'layout' => 'kr' },
+    'KW' => { 'layout' => 'ara' },
+    'KZ' => { 'layout' => 'kz' },
+    'LA' => { 'layout' => 'la' },
+    'LB' => { 'layout' => 'ara' },
+    'LK' => { 'layout' => 'lk' },
+    'LT' => { 'layout' => 'lt' },
+    'LV' => { 'layout' => 'lv' },
+    'LY' => { 'layout' => 'ara' },
+    'MA' => { 'layout' => 'ara', 'ambiguous' => 1 },
+    'ME' => { 'layout' => 'me' },
+    'MK' => { 'layout' => 'mk' },
+    'MM' => { 'layout' => 'mm' },
+    'MN' => { 'layout' => 'mn' },
+    'MR' => { 'layout' => 'ara' },
+    'MT' => { 'layout' => 'mt' },
+    'MV' => { 'layout' => 'mv' },
+    'MX' => { 'layout' => 'latam' },
+    'NG' => { 'layout' => 'ng' },
+    'NI' => { 'layout' => 'latam' },
+    'NL' => { 'layout' => 'nl' },
+    'NO' => { 'layout' => 'no' },
+    'NP' => { 'layout' => 'np' },
+    'OM' => { 'layout' => 'ara' },
+    'PA' => { 'layout' => 'latam' },
+    'PE' => { 'layout' => 'latam' },
+    'PK' => { 'layout' => 'pk' },
+    'PL' => { 'layout' => 'pl' },
+    'PR' => { 'layout' => 'latam' },
+    'PS' => { 'layout' => 'ara' },
+    'PT' => { 'layout' => 'pt' },
+    'PY' => { 'layout' => 'latam' },
+    'QA' => { 'layout' => 'ara' },
+    'RO' => { 'layout' => 'ro' },
+    'RS' => { 'layout' => 'rs' },
+    'RU' => { 'layout' => 'ru' },
+    'SA' => { 'layout' => 'ara' },
+    'SD' => { 'layout' => 'ara' },
+    'SE' => { 'layout' => 'se' },
+    'SI' => { 'layout' => 'si' },
+    'SK' => { 'layout' => 'sk' },
+    'SY' => { 'layout' => 'ara', 'ambiguous' => 1 },
+    'TH' => { 'layout' => 'th' },
+    'TJ' => { 'layout' => 'tj' },
+    'TN' => { 'layout' => 'ara' },
+    'TR' => { 'layout' => 'tr' },
+    'UA' => { 'layout' => 'ua' },
+    'US' => { 'layout' => 'us' },
+    'UY' => { 'layout' => 'latam' },
+    'UZ' => { 'layout' => 'uz' },
+    'VE' => { 'layout' => 'latam' },
+    'VN' => { 'layout' => 'vn' },
+    'YE' => { 'layout' => 'ara' },
+    'ZA' => { 'layout' => 'za' },
+);
+
+%languages_keyboards = (
+    'ak' => { 'layout' => 'gh', 'variant' => 'akan' },
+    'am' => { 'layout' => 'et' },
+    'ar' => { 'layout' => 'ara', 'ambiguous' => 1 },
+    'ast' => { 'layout' => 'es', 'variant' => 'ast' },
+    'az' => { 'layout' => 'az' },
+    'be' => { 'layout' => 'by' },
+    'ber' => { 'layout' => 'ma', 'variant' => 'tifinagh' },
+    'bg' => { 'layout' => 'bg' },
+    'bn' => { 'layout' => 'bd', 'ambiguous' => 1 },
+    'bo' => { 'layout' => 'cn', 'variant' => 'tib' },
+    'bs' => { 'layout' => 'ba' },
+    'ca' => { 'layout' => 'ad', 'ambiguous' => 1 },
+    'cs' => { 'layout' => 'cz' },
+    'csb' => { 'layout' => 'pl', 'variant' => 'csb' },
+    'cv' => { 'layout' => 'ru', 'variant' => 'cv' },
+    'da' => { 'layout' => 'dk' },
+    'de' => { 'layout' => 'be', 'ambiguous' => 1 },
+    'dv' => { 'layout' => 'mv' },
+    'dz' => { 'layout' => 'bt' },
+    'ee' => { 'layout' => 'gh', 'variant' => 'ewe' },
+    'el' => { 'layout' => 'gr' },
+    'en' => { 'layout' => 'us', 'ambiguous' => 1 },
+    'eo' => { 'layout' => 'epo' },
+    'es' => { 'layout' => 'latam', 'ambiguous' => 1 },
+    'et' => { 'layout' => 'ee' },
+    'fa' => { 'layout' => 'ir' },
+    'ff' => { 'layout' => 'gh', 'variant' => 'fula' },
+    'fi' => { 'layout' => 'fi' },
+    'fo' => { 'layout' => 'fo' },
+    'fr' => { 'layout' => 'be', 'ambiguous' => 1 },
+    'gaa' => { 'layout' => 'gh', 'variant' => 'ga' },
+    'gd' => { 'layout' => 'ie', 'variant' => 'CloGaelach' },
+    'gsw' => { 'layout' => 'ch' },
+    'gu' => { 'layout' => 'in', 'variant' => 'guj' },
+    'ha' => { 'layout' => 'gh', 'variant' => 'hausa', 'ambiguous' => 1 },
+    'he' => { 'layout' => 'il' },
+    'hi' => { 'layout' => 'in', 'variant' => 'bolnagri' },
+    'hr' => { 'layout' => 'hr' },
+    'hu' => { 'layout' => 'hu' },
+    'hy' => { 'layout' => 'am' },
+    'ig' => { 'layout' => 'ng', 'variant' => 'igbo' },
+    'is' => { 'layout' => 'is' },
+    'it' => { 'layout' => 'it' },
+    'iu' => { 'layout' => 'ca', 'variant' => 'ike' },
+    'ja' => { 'layout' => 'jp' },
+    'ka' => { 'layout' => 'ge', 'ambiguous' => 1 },
+    'kk' => { 'layout' => 'kz' },
+    'km' => { 'layout' => 'kh' },
+    'kn' => { 'layout' => 'in', 'variant' => 'kan' },
+    'ko' => { 'layout' => 'kr' },
+    'ku' => { 'layout' => 'iq', 'ambiguous' => 1 },
+    'kv' => { 'layout' => 'ru', 'variant' => 'kom' },
+    'ky' => { 'layout' => 'kg' },
+    'lo' => { 'layout' => 'la' },
+    'lt' => { 'layout' => 'lt' },
+    'lv' => { 'layout' => 'lv' },
+    'mi' => { 'layout' => 'mao' },
+    'mk' => { 'layout' => 'mk' },
+    'ml' => { 'layout' => 'in', 'variant' => 'mal' },
+    'mng' => { 'layout' => 'mn' },
+    'mt' => { 'layout' => 'mt' },
+    'my' => { 'layout' => 'mm' },
+    'ne' => { 'layout' => 'np' },
+    'nl' => { 'layout' => 'nl' },
+    'no' => { 'layout' => 'no' },
+    'or' => { 'layout' => 'in', 'variant' => 'ori' },
+    'os' => { 'layout' => 'ge', 'variant' => 'os', 'ambiguous' => 1 },
+    'pa' => { 'layout' => 'in', 'variant' => 'guru' },
+    'pl' => { 'layout' => 'pl' },
+    'ps' => { 'layout' => 'af', 'variant' => 'ps' },
+    'pt' => { 'layout' => 'br', 'ambiguous' => 1 },
+    'ro' => { 'layout' => 'ro' },
+    'ru' => { 'layout' => 'ru', 'ambiguous' => 1 },
+    'se' => { 'layout' => 'no', 'variant' => 'smi', 'ambiguous' => 1 },
+    'si' => { 'layout' => 'lk' },
+    'sk' => { 'layout' => 'sk' },
+    'sl' => { 'layout' => 'si' },
+    'smi' => { 'layout' => 'fi', 'variant' => 'smi' },
+    'sq' => { 'layout' => 'al' },
+    'sr' => { 'layout' => 'me', 'ambiguous' => 1 },
+    'sv' => { 'layout' => 'se' },
+    'syr' => { 'layout' => 'sy' },
+    'ta' => { 'layout' => 'in', 'variant' => 'tam_unicode', 'ambiguous' => 1 },
+    'te' => { 'layout' => 'in', 'variant' => 'tel' },
+    'tg' => { 'layout' => 'tj' },
+    'th' => { 'layout' => 'th' },
+    'tr' => { 'layout' => 'tr' },
+    'tt' => { 'layout' => 'ru', 'variant' => 'tt' },
+    'udm' => { 'layout' => 'ru', 'variant' => 'udm' },
+    'uk' => { 'layout' => 'ua' },
+    'ur' => { 'layout' => 'pk' },
+    'uz' => { 'layout' => 'uz' },
+    'vi' => { 'layout' => 'vn' },
+    'yo' => { 'layout' => 'ng', 'variant' => 'yoruba' },
+    'zh' => { 'layout' => 'cn' },
+);
+
 1;
Index: Keyboard/chooser-maker
===================================================================
--- Keyboard/chooser-maker	(révision 0)
+++ Keyboard/chooser-maker	(révision 0)
@@ -0,0 +1,141 @@
+#!/usr/bin/perl -w
+
+use warnings 'all';
+use strict;
+
+use Data::Dumper;
+
+BEGIN {
+    my $file;
+    if ($ARGV[0]) {
+	$file = $ARGV[0];
+    } else {
+	$file = 'KeyboardNames.pl';
+    }
+    do "$file";
+}
+
+my %rev_locales_keyboards;
+
+# Add some more ambiguity flags
+# Ideally these ambiguities should be expressed in base.xml instead
+$KeyboardNames::countries_keyboards{"BG"}->{"ambiguous"} = 1;
+$KeyboardNames::countries_keyboards{"CZ"}->{"ambiguous"} = 1;
+$KeyboardNames::countries_keyboards{"IL"}->{"ambiguous"} = 1;
+$KeyboardNames::countries_keyboards{"LT"}->{"ambiguous"} = 1;
+$KeyboardNames::countries_keyboards{"MT"}->{"ambiguous"} = 1;
+$KeyboardNames::countries_keyboards{"TH"}->{"ambiguous"} = 1;
+
+print "case \"\$locale\" in\n";
+
+print "    # Keyboards for full locales\n";
+for my $country (sort keys %KeyboardNames::locales_keyboards) {
+    my $localeKeyboards = $KeyboardNames::locales_keyboards{$country};
+    for my $language (keys %{$localeKeyboards}) {
+	my $keyboard = ${$localeKeyboards}{$language};
+	$rev_locales_keyboards{$language}{$country} = $keyboard;
+
+	my %keyboard = %{$keyboard};
+	my $layout = $keyboard->{"layout"};
+	my $variant = $keyboard->{"variant"};
+	my $ambiguous = $keyboard->{"ambiguous"};
+
+	my $country_keyboard = $KeyboardNames::countries_keyboards{$country};
+	my $country_layout = $country_keyboard->{"layout"};
+	my $country_variant = $country_keyboard->{"variant"};
+	my $country_ambiguous = $country_keyboard->{"ambiguous"};
+	if ($country_keyboard) {
+	    if ($layout eq $country_layout
+	     && ((!$variant && !$country_variant) || ($variant && $country_variant && $variant eq $country_variant))) {
+		# this locale will already be catched by keyboard countries, no need to bloat the script
+		next;
+	    }
+	}
+
+	print "    ${language}_$country*)\n";
+	print "	default_layout=$layout\n";
+	if ($variant) {
+	    print "	default_variant=$variant\n";
+	}
+	if ($ambiguous) {
+	    print "	layout_priority=critical\n";
+	}
+	print "	;;\n";
+    }
+}
+
+print "    # Keyboards for countries\n";
+for my $country (sort keys %KeyboardNames::countries_keyboards) {
+    my $keyboard = $KeyboardNames::countries_keyboards{$country};
+    my %keyboard = %{$keyboard};
+    my $layout = $keyboard->{"layout"};
+    my $variant = $keyboard->{"variant"};
+    my $ambiguous = $keyboard->{"ambiguous"};
+    print "    *_$country*)\n";
+    print "	default_layout=$layout\n";
+    if ($variant) {
+	print "	default_variant=$variant\n";
+    }
+    my $locales_keyboards = $KeyboardNames::locales_keyboards{$country};
+    if ($locales_keyboards) {
+	if (keys %{$locales_keyboards} >= 2) {
+	    $ambiguous = 1;
+	} elsif (keys %{$locales_keyboards} == 1) {
+	    my $locale_keyboard = ${$locales_keyboards}{(keys %{$locales_keyboards})[0]};
+	    my %locale_keyboard = %{$locale_keyboard};
+	    my $locale_layout = $locale_keyboard->{"layout"};
+	    my $locale_variant = $locale_keyboard->{"variant"};
+	    my $locale_ambiguous = $locale_keyboard->{"ambiguous"};
+	    if ($locale_layout ne $layout
+	     || !((!$locale_layout && !$layout) || ($locale_layout && $layout && $locale_layout eq $layout))
+	     || $locale_ambiguous) {
+	        $ambiguous = 1;
+	    }
+	}
+    }
+    if ($ambiguous) {
+	print "	layout_priority=critical\n";
+    }
+    print "	;;\n";
+}
+
+print "    # Keyboards for specific languages\n";
+for my $language (sort keys %KeyboardNames::languages_keyboards) {
+    my $keyboard = $KeyboardNames::languages_keyboards{$language};
+    my %keyboard = %{$keyboard};
+    my $layout = $keyboard->{"layout"};
+    my $variant = $keyboard->{"variant"};
+    my $ambiguous = $keyboard->{"ambiguous"};
+    print "    ${language}_*)\n";
+    print "	default_layout=$layout\n";
+    if ($variant) {
+	print "	default_variant=$variant\n";
+    }
+    my $rev = $rev_locales_keyboards{$language};
+    if ($rev) {
+	if (keys %{$rev} >= 2) {
+	    $ambiguous = 1;
+	} elsif (keys %{$rev} == 1) {
+	    my $locale_keyboard = ${$rev}{(keys %{$rev})[0]};
+	    my %locale_keyboard = %{$locale_keyboard};
+	    my $locale_layout = $locale_keyboard->{"layout"};
+	    my $locale_variant = $locale_keyboard->{"variant"};
+	    my $locale_ambiguous = $locale_keyboard->{"ambiguous"};
+	    if ($locale_layout ne $layout
+	     || !((!$locale_layout && !$layout) || ($locale_layout && $layout && $locale_layout eq $layout))
+	     || $locale_ambiguous) {
+	        $ambiguous = 1;
+	    }
+	}
+    }
+    if ($ambiguous) {
+	print "	layout_priority=critical\n";
+    }
+    print "	;;\n";
+}
+
+print "    # Fallback\n";
+print "    *)\n";
+print "	default_layout=us\n";
+print "	;;\n";
+print "esac\n";

Modification de propriétés sur Keyboard/chooser-maker
___________________________________________________________________
Ajouté : svn:executable
   + *


Reply to: