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

[PATCH,RFC] parse base.xml to generate locale/country -> layout/variant default choice



Hello,

Attached is a patch that implements using xbk-data's base.xml to
generate the part of config that selects the default choice based on
locale/country.  The idea is to just parse base.xml, mix a bit to see
which cases have ambiguities and in such cases raise the priority.  I
have attached to this mail the diff between what was hardcoded and what
would now be auto-generated.  One can see that a few bugs get fixed,
and there is much better coverage.  There are however a few non-trivial
changes:

- now canadian keyboards are assumed to be 'ca' by default,
unless speaking english. That however also suits the needs of
https://bugs.launchpad.net/ubuntu/+bug/64418 which was the reason for
the introduction of a special rule.

- See:
     fr_*)
-     default_layout=fr
+     default_layout=be
      layout_priority=critical
It isn't strictly a problem as we set the priority to critical anyway
since there are several possibilities, but still.  The issue here is
that nothing in xkb says that french-speaking people (fr) are usually
mostly found in France (FR) and so my script is just taking the first
country that matches, which happens to be Belgium.  Same for german
(de) and Germany (DE) etc.  Ideally that kind of information should be
integrated to xkb but we could as well have our own fixup table.


Also, there is this:
+# 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;

I don't know why the layout priority was set to critical for those.
Those lines should be replaced by entries in base.xml that tell which
other keyboards could be seen in those countries, and then my patch will
detect the ambiguity automatically.

Samuel
Index: debian/rules
===================================================================
--- debian/rules	(révision 58021)
+++ 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 58021)
+++ debian/config.proto	(copie de travail)
@@ -732,238 +732,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 58021)
+++ 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 58021)
+++ Keyboard/KeyboardNames.pl	(copie de travail)
@@ -26,6 +26,7 @@
     'BTC 9000A' => 'btc9000a',
     'BTC 9001AH' => 'btc9001ah',
     'BTC 9019U' => 'btc9019u',
+    'BTC 9116U Mini Wireless Internet and Gaming' => 'btc9116u',
     'BenQ X-Touch' => 'benqx',
     'BenQ X-Touch 730' => 'benqx730',
     'BenQ X-Touch 800' => 'benqx800',
@@ -34,11 +35,13 @@
     'Cherry Blue Line CyBo@rd' => 'cherryblue',
     'Cherry Blue Line CyBo@rd (alternate option)' => 'cherrybluea',
     'Cherry CyBo@rd USB-Hub' => 'cherrycyboard',
+    'Cherry CyMotion Expert' => 'cherrycmexpert',
     'Cherry CyMotion Master Linux' => 'cymotionlinux',
     'Cherry CyMotion Master XPress' => 'cherryblueb',
     'Chicony Internet Keyboard' => 'chicony',
     'Chicony KB-9885' => 'chicony9885',
     'Chicony KU-0108' => 'chicony0108',
+    'Chicony KU-0420' => 'chicony0420',
     'Classmate PC' => 'classmate',
     'Compaq Easy Access Keyboard' => 'compaqeak8',
     'Compaq Internet Keyboard (13 keys)' => 'compaqik13',
@@ -54,13 +57,14 @@
     'Dell Precision M65' => 'dellm65',
     'Dell SK-8125' => 'dellsk8125',
     'Dell SK-8135' => 'dellsk8135',
-    'Dell USB Multimedia Keybard' => 'dellusbmm',
+    'Dell USB Multimedia Keyboard' => 'dellusbmm',
     'Dexxa Wireless Desktop Keyboard' => 'dexxa',
     'Diamond 9801 / 9802 series' => 'diamond',
     'Ennyah DKB-1008' => 'ennyah_dkb1008',
     'Evdev-managed keyboard' => 'evdev',
     'Everex STEPnote' => 'everex',
-    'Fujitsu-Siemens Computers AMILO A1667G laptop' => 'fscaa1667g',
+    'FL90' => 'compalfl90',
+    'Fujitsu-Siemens Computers AMILO laptop' => 'fscaa1667g',
     'Generic 101-key PC' => 'pc101',
     'Generic 102-key (Intl) PC' => 'pc102',
     'Generic 104-key PC' => 'pc104',
@@ -73,8 +77,6 @@
     'Happy Hacking Keyboard' => 'hhk',
     'Happy Hacking Keyboard for Mac' => 'macintosh_hhk',
     'Hewlett-Packard Internet Keyboard' => 'hpi6',
-    'Hewlett-Packard Internet Keyboard 5181' => 'hp5181',
-    'Hewlett-Packard Internet Keyboard 5185' => 'hp5185',
     'Hewlett-Packard Omnibook 500 FA' => 'hp500fa',
     'Hewlett-Packard Omnibook 5xx' => 'hp5xx',
     'Hewlett-Packard Omnibook 6000/6100' => 'hp6000',
@@ -82,16 +84,17 @@
     'Hewlett-Packard Omnibook XE3 GF' => 'hpxe3gf',
     'Hewlett-Packard Omnibook XT1000' => 'hpxt1000',
     'Hewlett-Packard Pavilion ZT11xx' => 'hpzt11xx',
-    'Hewlett-Packard SK-2501 Multimedia Keyboard' => 'hp2501',
-    'Hewlett-Packard SK-2505 Internet Keyboard' => 'hp2505',
+    'Hewlett-Packard Pavilion dv5' => 'hpdv5',
+    'Hewlett-Packard SK-250x Multimedia Keyboard' => 'hp250x',
     'Hewlett-Packard nx9020' => 'hpnx9020',
     'Honeywell Euroboard' => 'honeywell_euroboard',
     'IBM Rapid Access' => 'rapidaccess',
     'IBM Rapid Access II' => 'rapidaccess2',
-    'IBM Rapid Access II (alternate option)' => 'rapidaccess2a',
+    'IBM Space Saver' => 'ibm_spacesaver',
     'IBM ThinkPad 560Z/600/600E/A22E' => 'thinkpad',
     'IBM ThinkPad 560Z/600/600E/A22E, Intl' => 'thinkpadintl',
-    'IBM ThinkPad R60/T60/Z60m/Z60t/R61/T61/Z61m/Z61t' => 'thinkpad60',
+    'IBM ThinkPad R60/T60/R61/T61' => 'thinkpad60',
+    'IBM ThinkPad Z60m/Z60t/Z61m/Z61t' => 'thinkpadz60',
     'Japanese 106-key' => 'jp106',
     'Keytronic FlexPro' => 'flexpro',
     'Korean 106-key' => 'kr106',
@@ -129,6 +132,7 @@
     'Memorex MX1998' => 'mx1998',
     'Memorex MX2500 EZ-Access Keyboard' => 'mx2500',
     'Memorex MX2750' => 'mx2750',
+    'Microsoft Comfort Curve Keyboard 2000' => 'microsoftccurve2k',
     'Microsoft Internet Keyboard' => 'microsoftinet',
     'Microsoft Internet Keyboard Pro, Swedish' => 'microsoftprose',
     'Microsoft Natural' => 'microsoft',
@@ -136,6 +140,7 @@
     'Microsoft Natural Keyboard Pro / Microsoft Internet Keyboard Pro' => 'microsoftpro',
     'Microsoft Natural Keyboard Pro OEM' => 'microsoftprooem',
     'Microsoft Natural Keyboard Pro USB / Microsoft Internet Keyboard Pro' => 'microsoftprousb',
+    'Microsoft Natural Wireless Ergonomic Keyboard 7000' => 'microsoft7000',
     'Microsoft Office Keyboard' => 'microsoftoffice',
     'Microsoft Wireless Multimedia Keyboard 1.0A' => 'microsoftmult',
     'Northgate OmniKey 101' => 'omnikey101',
@@ -150,6 +155,7 @@
     'SK-6200' => 'sk6200',
     'SK-7100' => 'sk7100',
     'SVEN Ergonomic 2500' => 'sven',
+    'SVEN Slim 303' => 'sven303',
     'Samsung SDM 4500P' => 'samsung4500',
     'Samsung SDM 4510P' => 'samsung4510',
     'Sun Type 4' => 'sun4',
@@ -157,9 +163,11 @@
     'Sun Type 5/6' => 'sun6',
     'Super Power Multimedia Keyboard' => 'sp_inet',
     'Symplon PaceBook (tablet PC)' => 'symplon',
+    'Targa Visionary 811' => 'targa_v811',
     'Toshiba Satellite S3000' => 'toshiba_s3000',
     'Trust Direct Access Keyboard' => 'trustda',
     'Trust Wireless Keyboard Classic' => 'trust',
+    'Unitek KB-1925' => 'unitekkb1925',
     'ViewSonic KU-306 Internet Keyboard' => 'vsonku306',
     'Winbook Model XP5' => 'winbook',
     'Yahoo! Internet Keyboard' => 'yahoo',
@@ -287,6 +295,9 @@
 	'Probhat' => 'probhat',
     },
     'be' => {
+	'Alternative' => 'oss',
+	'Alternative, Sun dead keys' => 'oss_sundeadkeys',
+	'Alternative, latin-9 only' => 'oss_latin9',
 	'Eliminate dead keys' => 'nodeadkeys',
 	'ISO Alternate' => 'iso-alternate',
 	'Sun dead keys' => 'sundeadkeys',
@@ -301,7 +312,6 @@
 	'Nativo' => 'nativo',
 	'Nativo for Esperanto' => 'nativo-epo',
 	'Nativo for USA keyboards' => 'nativo-us',
-	'Thinkpad' => 'thinkpad',
     },
     'braille' => {
 	'Left hand' => 'left_hand',
@@ -312,9 +322,11 @@
 	'Winkeys' => 'winkeys',
     },
     'ca' => {
+	'English' => 'eng',
 	'French (legacy)' => 'fr-legacy',
 	'French Dvorak' => 'fr-dvorak',
 	'Inuktitut' => 'ike',
+	'Ktunaxa' => 'kut',
 	'Multilingual' => 'multix',
 	'Multilingual, first part' => 'multi',
 	'Multilingual, second part' => 'multi-2gr',
@@ -334,6 +346,7 @@
 	'Tibetan (with ASCII numerals)' => 'tib_asciinum',
     },
     'cz' => {
+	'UCW layout (accented letters only)' => 'ucw',
 	'With <\|> key' => 'bksl',
 	'qwerty' => 'qwerty',
 	'qwerty, extended Backslash' => 'qwerty_bksl',
@@ -343,12 +356,15 @@
 	'Dead grave acute' => 'deadgraveacute',
 	'Dvorak' => 'dvorak',
 	'Eliminate dead keys' => 'nodeadkeys',
+	'Lower Sorbian' => 'dsb',
+	'Lower Sorbian (qwertz)' => 'dsb_qwertz',
 	'Macintosh' => 'mac',
 	'Macintosh, eliminate dead keys' => 'mac_nodeadkeys',
-	'Neostyle' => 'neo',
+	'Neo 2' => 'neo',
 	'Romanian keyboard with German letters' => 'ro',
 	'Romanian keyboard with German letters, eliminate dead keys' => 'ro_nodeadkeys',
 	'Sun dead keys' => 'sundeadkeys',
+	'qwerty' => 'qwerty',
     },
     'dk' => {
 	'Dvorak' => 'dvorak',
@@ -369,6 +385,7 @@
 	'Catalan variant with middle-dot L' => 'cat',
 	'Dvorak' => 'dvorak',
 	'Eliminate dead keys' => 'nodeadkeys',
+	'Include dead tilde' => 'deadtilde',
 	'Macintosh' => 'mac',
 	'Sun dead keys' => 'sundeadkeys',
     },
@@ -385,20 +402,23 @@
 	'(Legacy) Alternative' => 'latin9',
 	'(Legacy) Alternative, Sun dead keys' => 'latin9_sundeadkeys',
 	'(Legacy) Alternative, eliminate dead keys' => 'latin9_nodeadkeys',
-	'(Legacy) Dvorak' => 'dvorak',
 	'Alternative' => 'oss',
 	'Alternative, Sun dead keys' => 'oss_sundeadkeys',
 	'Alternative, eliminate dead keys' => 'oss_nodeadkeys',
 	'Alternative, latin-9 only' => 'oss_latin9',
 	'Bepo, ergonomic, Dvorak way' => 'bepo',
 	'Bepo, ergonomic, Dvorak way, latin-9 only' => 'bepo_latin9',
+	'Breton' => 'bre',
+	'Dvorak' => 'dvorak',
 	'Eliminate dead keys' => 'nodeadkeys',
 	'Georgian AZERTY Tskapo' => 'geo',
 	'Macintosh' => 'mac',
 	'Sun dead keys' => 'sundeadkeys',
     },
     'gb' => {
+	'Colemak' => 'colemak',
 	'Dvorak' => 'dvorak',
+	'Dvorak (UK Punctuation)' => 'dvorakukp',
 	'International (with dead keys)' => 'intl',
 	'Macintosh' => 'mac',
     },
@@ -420,6 +440,7 @@
 	'Eliminate dead keys' => 'nodeadkeys',
 	'Extended' => 'extended',
 	'Polytonic' => 'polytonic',
+	'Simple' => 'simple',
     },
     'hr' => {
 	'US keyboard with Croatian digraphs' => 'unicodeus',
@@ -475,7 +496,9 @@
 	'Tamil TSCII Typewriter' => 'tam_TSCII',
 	'Tamil Unicode' => 'tam_unicode',
 	'Telugu' => 'tel',
-	'Urdu' => 'urd',
+	'Urdu, Alternative phonetic' => 'urd-phonetic3',
+	'Urdu, Phonetic' => 'urd-phonetic',
+	'Urdu, Winkeys' => 'urd-winkeys',
     },
     'iq' => {
 	'Kurdish, (F)' => 'ku_f',
@@ -493,6 +516,7 @@
 	'Pro Keypad' => 'pro_keypad',
     },
     'is' => {
+	'Dvorak' => 'dvorak',
 	'Eliminate dead keys' => 'nodeadkeys',
 	'Macintosh' => 'mac',
 	'Sun dead keys' => 'Sundeadkeys',
@@ -515,6 +539,7 @@
     },
     'latam' => {
 	'Eliminate dead keys' => 'nodeadkeys',
+	'Include dead tilde' => 'deadtilde',
 	'Sun dead keys' => 'sundeadkeys',
     },
     'lk' => {
@@ -522,7 +547,6 @@
 	'Tamil Unicode' => 'tam_unicode',
     },
     'lt' => {
-	'Baltic+' => 'balticplus',
 	'IBM (LST 1205-92)' => 'ibm',
 	'LEKP' => 'lekp',
 	'LEKPa' => 'lekpa',
@@ -578,6 +602,8 @@
     },
     'pk' => {
 	'Arabic' => 'ara',
+	'CRULP' => 'urd-crulp',
+	'NLA' => 'urd-nla',
     },
     'pl' => {
 	'Dvorak' => 'dvorak',
@@ -615,6 +641,7 @@
     'ru' => {
 	'Chuvash' => 'cv',
 	'Chuvash Latin' => 'cv_latin',
+	'Kalmyk' => 'xal',
 	'Komi' => 'kom',
 	'Legacy' => 'legacy',
 	'Ossetian, Winkeys' => 'os_winkeys',
@@ -623,6 +650,7 @@
 	'Tatar' => 'tt',
 	'Typewriter' => 'typewriter',
 	'Udmurt' => 'udm',
+	'Yakut' => 'sah',
     },
     'se' => {
 	'Dvorak' => 'dvorak',
@@ -655,6 +683,9 @@
 	'Pattachote' => 'pat',
 	'TIS-820.2538' => 'tis',
     },
+    'tj' => {
+	'Legacy' => 'legacy',
+    },
     'tr' => {
 	'(F)' => 'f',
 	'Alt-Q' => 'alt',
@@ -675,6 +706,7 @@
     },
     'us' => {
 	'Alternative international (former us_intl)' => 'alt-intl',
+	'Cherokee' => 'chr',
 	'Classic Dvorak' => 'dvorak-classic',
 	'Colemak' => 'colemak',
 	'Dvorak' => 'dvorak',
@@ -694,4 +726,630 @@
     },
 );
 
+%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' => 'eng' },
+	'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' },
+	'dsb' => { 'layout' => 'de', 'variant' => 'dsb' },
+    },
+    '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' },
+	'se' => { 'layout' => 'fi', 'variant' => 'smi' },
+	'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-phonetic' },
+    },
+    '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' },
+	'sah' => { 'layout' => 'ru', 'variant' => 'sah' },
+	'tt' => { 'layout' => 'ru', 'variant' => 'tt' },
+	'udm' => { 'layout' => 'ru', 'variant' => 'udm' },
+	'xal' => { 'layout' => 'ru', 'variant' => 'xal' },
+    },
+    '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' },
+    },
+    'SV' => {
+	'es' => { 'layout' => 'latam' },
+    },
+    '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' => {
+	'chr' => { 'layout' => 'us', 'variant' => 'chr' },
+	'de' => { 'layout' => 'us', 'variant' => 'altgr-intl' },
+	'en' => { 'layout' => 'us' },
+	'es' => { 'layout' => 'latam' },
+	'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' },
+    'SV' => { 'layout' => 'latam' },
+    'SY' => { 'layout' => 'ara', 'ambiguous' => 1 },
+    'TH' => { 'layout' => 'th' },
+    'TJ' => { 'layout' => 'tj' },
+    'TN' => { 'layout' => 'ara' },
+    'TR' => { 'layout' => 'tr' },
+    'UA' => { 'layout' => 'ua' },
+    'US' => { 'layout' => 'us', 'ambiguous' => 1 },
+    '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 },
+    'chr' => { 'layout' => 'us', 'variant' => 'chr' },
+    'cs' => { 'layout' => 'cz' },
+    'csb' => { 'layout' => 'pl', 'variant' => 'csb' },
+    'cv' => { 'layout' => 'ru', 'variant' => 'cv' },
+    'da' => { 'layout' => 'dk' },
+    'de' => { 'layout' => 'be', 'ambiguous' => 1 },
+    'dsb' => { 'layout' => 'de', 'variant' => 'dsb' },
+    '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 },
+    'sah' => { 'layout' => 'ru', 'variant' => 'sah' },
+    'se' => { 'layout' => 'fi', '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' },
+    'xal' => { 'layout' => 'ru', 'variant' => 'xal' },
+    '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
   + *

--- config.proto.tinkered	2009-01-31 00:59:49.000000000 +0100
+++ console-setup.config	2009-02-03 02:35:42.000000000 +0100
@@ -1,94 +1,465 @@
 case "$locale" in
-    fr_CA*)
+    # Keyboards for full locales
+    uz_AF*)
+	default_layout=af
+	default_variant=uz
+	;;
+    ps_AF*)
+	default_layout=af
+	default_variant=ps
+	;;
+    eo_BR*)
+	default_layout=br
+	default_variant=nativo-epo
+	;;
+    en_CA*)
 	default_layout=ca
+	default_variant=eng
+	;;
+    iu_CA*)
+	default_layout=ca
+	default_variant=ike
 	;;
     fr_CH*)
 	default_layout=ch
 	default_variant=fr
 	;;
+    bo_CN*)
+	default_layout=cn
+	default_variant=tib
+	;;
+    dsb_DE*)
+	default_layout=de
+	default_variant=dsb
+	;;
+    ca_ES*)
+	default_layout=es
+	default_variant=cat
+	;;
+    ast_ES*)
+	default_layout=es
+	default_variant=ast
+	;;
     se_FI*)
 	default_layout=fi
 	default_variant=smi
 	;;
+    smi_FI*)
+	default_layout=fi
+	default_variant=smi
+	;;
+    ka_FR*)
+	default_layout=fr
+	default_variant=geo
+	;;
+    ru_GE*)
+	default_layout=ge
+	default_variant=ru
+	;;
+    os_GE*)
+	default_layout=ge
+	default_variant=os
+	;;
+    gaa_GH*)
+	default_layout=gh
+	default_variant=ga
+	;;
+    ak_GH*)
+	default_layout=gh
+	default_variant=akan
+	;;
+    ff_GH*)
+	default_layout=gh
+	default_variant=fula
+	;;
+    ha_GH*)
+	default_layout=gh
+	default_variant=hausa
+	;;
+    ee_GH*)
+	default_layout=gh
+	default_variant=ewe
+	;;
+    gd_IE*)
+	default_layout=ie
+	default_variant=CloGaelach
+	;;
+    ur_IN*)
+	default_layout=in
+	default_variant=urd-phonetic
+	;;
+    hi_IN*)
+	default_layout=in
+	default_variant=bolnagri
+	;;
+    te_IN*)
+	default_layout=in
+	default_variant=tel
+	;;
+    ml_IN*)
+	default_layout=in
+	default_variant=mal
+	;;
+    kn_IN*)
+	default_layout=in
+	default_variant=kan
+	;;
+    pa_IN*)
+	default_layout=in
+	default_variant=guru
+	;;
+    or_IN*)
+	default_layout=in
+	default_variant=ori
+	;;
+    bn_IN*)
+	default_layout=in
+	default_variant=ben
+	;;
+    ta_IN*)
+	default_layout=in
+	default_variant=tam_unicode
+	;;
+    gu_IN*)
+	default_layout=in
+	default_variant=guj
+	;;
+    ku_IR*)
+	default_layout=ir
+	default_variant=ku
+	;;
+    ka_IT*)
+	default_layout=it
+	default_variant=geo
+	;;
+    ru_KZ*)
+	default_layout=kz
+	default_variant=ruskaz
+	;;
+    ta_LK*)
+	default_layout=lk
+	default_variant=tam_unicode
+	;;
+    fr_MA*)
+	default_layout=ma
+	default_variant=french
+	;;
+    ber_MA*)
+	default_layout=ma
+	default_variant=tifinagh
+	;;
+    yo_NG*)
+	default_layout=ng
+	default_variant=yoruba
+	;;
+    ha_NG*)
+	default_layout=ng
+	default_variant=hausa
+	;;
+    ig_NG*)
+	default_layout=ng
+	default_variant=igbo
+	;;
     se_NO*)
 	default_layout=no
 	default_variant=smi
 	;;
+    ar_PK*)
+	default_layout=pk
+	default_variant=ara
+	;;
+    ru_PL*)
+	default_layout=pl
+	default_variant=ru_phonetic_dvorak
+	;;
+    csb_PL*)
+	default_layout=pl
+	default_variant=csb
+	;;
+    eo_PT*)
+	default_layout=pt
+	default_variant=nativo-epo
+	;;
+    cv_RU*)
+	default_layout=ru
+	default_variant=cv
+	;;
+    xal_RU*)
+	default_layout=ru
+	default_variant=xal
+	;;
+    tt_RU*)
+	default_layout=ru
+	default_variant=tt
+	;;
+    os_RU*)
+	default_layout=ru
+	default_variant=os_legacy
+	;;
+    udm_RU*)
+	default_layout=ru
+	default_variant=udm
+	;;
+    sah_RU*)
+	default_layout=ru
+	default_variant=sah
+	;;
+    kv_RU*)
+	default_layout=ru
+	default_variant=kom
+	;;
     se_SE*)
 	default_layout=se
 	default_variant=smi
 	;;
+    ru_SE*)
+	default_layout=se
+	default_variant=rus
+	;;
+    syr_SY*)
+	default_layout=sy
+	;;
+    ku_SY*)
+	default_layout=sy
+	default_variant=ku
+	;;
+    ku_TR*)
+	default_layout=tr
+	default_variant=ku
+	;;
+    fr_US*)
+	default_layout=us
+	default_variant=altgr-intl
+	;;
+    de_US*)
+	default_layout=us
+	default_variant=altgr-intl
+	;;
+    chr_US*)
+	default_layout=us
+	default_variant=chr
+	;;
+    es_US*)
+	default_layout=latam
+	;;
+    # Keyboards for countries
+    *_AD*)
+	default_layout=ad
+	;;
+    *_AE*)
+	default_layout=ara
+	;;
+    *_AF*)
+	default_layout=af
+	layout_priority=critical
+	;;
     *_AL*)
 	default_layout=al
 	;;
+    *_AM*)
+	default_layout=am
+	;;
+    *_AR*)
+	default_layout=latam
+	;;
     *_AZ*)
 	default_layout=az
 	;;
+    *_BA*)
+	default_layout=ba
+	;;
     *_BD*)
 	default_layout=bd
 	;;
     *_BE*)
 	default_layout=be
+	layout_priority=critical
 	;;
     *_BG*)
 	default_layout=bg
 	layout_priority=critical
 	;;
+    *_BH*)
+	default_layout=ara
+	;;
+    *_BO*)
+	default_layout=latam
+	;;
     *_BR*)
 	default_layout=br
+	layout_priority=critical
+	;;
+    *_BT*)
+	default_layout=bt
 	;;
     *_BY*)
 	default_layout=by
 	;;
     *_CA*)
-	default_layout=us
+	default_layout=ca
+	layout_priority=critical
+	;;
+    *_CD*)
+	default_layout=cd
 	;;
     *_CH*)
 	default_layout=ch
 	layout_priority=critical
 	;;
+    *_CL*)
+	default_layout=latam
+	;;
+    *_CN*)
+	default_layout=cn
+	layout_priority=critical
+	;;
+    *_CO*)
+	default_layout=latam
+	;;
+    *_CR*)
+	default_layout=latam
+	;;
+    *_CU*)
+	default_layout=latam
+	;;
     *_CZ*)
 	default_layout=cz
 	layout_priority=critical
 	;;
+    *_DE*)
+	default_layout=de
+	layout_priority=critical
+	;;
     *_DK*)
 	default_layout=dk
 	;;
+    *_DO*)
+	default_layout=latam
+	;;
+    *_DZ*)
+	default_layout=ara
+	;;
+    *_EC*)
+	default_layout=latam
+	;;
     *_EE*)
 	default_layout=ee
 	;;
+    *_EG*)
+	default_layout=ara
+	;;
+    *_EH*)
+	default_layout=ara
+	;;
     *_ES*)
 	default_layout=es
+	layout_priority=critical
+	;;
+    *_ET*)
+	default_layout=et
 	;;
     *_FI*)
 	default_layout=fi
-	default_variant=fi
+	layout_priority=critical
+	;;
+    *_FO*)
+	default_layout=fo
+	;;
+    *_FR*)
+	default_layout=fr
+	layout_priority=critical
 	;;
     *_GB*)
 	default_layout=gb
 	;;
+    *_GE*)
+	default_layout=ge
+	layout_priority=critical
+	;;
+    *_GH*)
+	default_layout=gh
+	layout_priority=critical
+	;;
+    *_GN*)
+	default_layout=gn
+	;;
+    *_GR*)
+	default_layout=gr
+	;;
+    *_GT*)
+	default_layout=latam
+	;;
+    *_HN*)
+	default_layout=latam
+	;;
+    *_HR*)
+	default_layout=hr
+	;;
+    *_HT*)
+	default_layout=latam
+	;;
     *_HU*)
 	default_layout=hu
 	;;
     *_IE*)
 	default_layout=ie
+	layout_priority=critical
 	;;
     *_IL*)
 	default_layout=il
 	layout_priority=critical
 	;;
+    *_IN*)
+	default_layout=in
+	layout_priority=critical
+	;;
+    *_IQ*)
+	default_layout=iq
+	layout_priority=critical
+	;;
     *_IR*)
 	default_layout=ir
+	layout_priority=critical
 	;;
     *_IS*)
 	default_layout=is
 	;;
     *_IT*)
 	default_layout=it
+	layout_priority=critical
+	;;
+    *_JO*)
+	default_layout=ara
 	;;
     *_JP*)
 	default_layout=jp
 	;;
+    *_KG*)
+	default_layout=kg
+	;;
+    *_KH*)
+	default_layout=kh
+	;;
+    *_KR*)
+	default_layout=kr
+	;;
+    *_KW*)
+	default_layout=ara
+	;;
+    *_KZ*)
+	default_layout=kz
+	layout_priority=critical
+	;;
+    *_LA*)
+	default_layout=la
+	;;
+    *_LB*)
+	default_layout=ara
+	;;
+    *_LK*)
+	default_layout=lk
+	layout_priority=critical
+	;;
     *_LT*)
 	default_layout=lt
 	layout_priority=critical
@@ -96,41 +467,121 @@
     *_LV*)
 	default_layout=lv
 	;;
+    *_LY*)
+	default_layout=ara
+	;;
+    *_MA*)
+	default_layout=ara
+	layout_priority=critical
+	;;
+    *_ME*)
+	default_layout=me
+	;;
     *_MK*)
 	default_layout=mk
 	;;
+    *_MM*)
+	default_layout=mm
+	;;
     *_MN*)
 	default_layout=mn
 	;;
+    *_MR*)
+	default_layout=ara
+	;;
     *_MT*)
 	default_layout=mt
 	layout_priority=critical
 	;;
+    *_MV*)
+	default_layout=mv
+	;;
+    *_MX*)
+	default_layout=latam
+	;;
+    *_NG*)
+	default_layout=ng
+	layout_priority=critical
+	;;
+    *_NI*)
+	default_layout=latam
+	;;
     *_NL*)
 	default_layout=nl
 	;;
     *_NO*)
 	default_layout=no
+	layout_priority=critical
+	;;
+    *_NP*)
+	default_layout=np
+	;;
+    *_OM*)
+	default_layout=ara
+	;;
+    *_PA*)
+	default_layout=latam
+	;;
+    *_PE*)
+	default_layout=latam
+	;;
+    *_PK*)
+	default_layout=pk
+	layout_priority=critical
 	;;
     *_PL*)
 	default_layout=pl
+	layout_priority=critical
+	;;
+    *_PR*)
+	default_layout=latam
+	;;
+    *_PS*)
+	default_layout=ara
 	;;
     *_PT*)
 	default_layout=pt
+	layout_priority=critical
+	;;
+    *_PY*)
+	default_layout=latam
+	;;
+    *_QA*)
+	default_layout=ara
 	;;
     *_RO*)
 	default_layout=ro
 	;;
+    *_RS*)
+	default_layout=rs
+	;;
     *_RU*)
 	default_layout=ru
 	layout_priority=critical
 	;;
+    *_SA*)
+	default_layout=ara
+	;;
+    *_SD*)
+	default_layout=ara
+	;;
+    *_SE*)
+	default_layout=se
+	layout_priority=critical
+	;;
     *_SI*)
 	default_layout=si
 	;;
     *_SK*)
 	default_layout=sk
 	;;
+    *_SV*)
+	default_layout=latam
+	;;
+    *_SY*)
+	default_layout=ara
+	layout_priority=critical
+	;;
     *_TH*)
 	default_layout=th
 	layout_priority=critical
@@ -138,6 +589,9 @@
     *_TJ*)
 	default_layout=tj
 	;;
+    *_TN*)
+	default_layout=ara
+	;;
     *_TR*)
 	default_layout=tr
 	layout_priority=critical
@@ -145,86 +599,379 @@
     *_UA*)
 	default_layout=ua
 	;;
-    en_US*)
+    *_US*)
 	default_layout=us
+	layout_priority=critical
+	;;
+    *_UY*)
+	default_layout=latam
+	;;
+    *_UZ*)
+	default_layout=uz
+	;;
+    *_VE*)
+	default_layout=latam
 	;;
     *_VN*)
 	default_layout=vn
 	;;
-  
-  
-    *_AR*|*_BO*|*_CL*|*_CO*|*_CR*|*_DO*|*_EC*|*_GT*|*_HN*|*_MX*|*_NI*|*_PA*|*_PE*|es_PR*|*_PY*|*_SV*|es_US*|*_UY*|*_VE*)
-	default_layout=latam
+    *_YE*)
+	default_layout=ara
+	;;
+    *_ZA*)
+	default_layout=za
+	;;
+    # Keyboards for specific languages
+    ak_*)
+	default_layout=gh
+	default_variant=akan
+	;;
+    am_*)
+	default_layout=et
 	;;
     ar_*)
 	default_layout=ara
+	layout_priority=critical
+	;;
+    ast_*)
+	default_layout=es
+	default_variant=ast
+	;;
+    az_*)
+	default_layout=az
+	;;
+    be_*)
+	default_layout=by
+	;;
+    ber_*)
+	default_layout=ma
+	default_variant=tifinagh
+	;;
+    bg_*)
+	default_layout=bg
+	;;
+    bn_*)
+	default_layout=bd
+	layout_priority=critical
+	;;
+    bo_*)
+	default_layout=cn
+	default_variant=tib
 	;;
     bs_*)
 	default_layout=ba
 	;;
+    ca_*)
+	default_layout=ad
+	layout_priority=critical
+	;;
+    chr_*)
+	default_layout=us
+	default_variant=chr
+	;;
+    cs_*)
+	default_layout=cz
+	;;
+    csb_*)
+	default_layout=pl
+	default_variant=csb
+	;;
+    cv_*)
+	default_layout=ru
+	default_variant=cv
+	;;
+    da_*)
+	default_layout=dk
+	;;
     de_*)
+	default_layout=be
+	layout_priority=critical
+	;;
+    dsb_*)
 	default_layout=de
+	default_variant=dsb
+	;;
+    dv_*)
+	default_layout=mv
+	;;
+    dz_*)
+	default_layout=bt
+	;;
+    ee_*)
+	default_layout=gh
+	default_variant=ewe
 	;;
     el_*)
 	default_layout=gr
 	;;
-    eo|eo.*|eo_*|eo\@*)
+    en_*)
+	default_layout=us
+	layout_priority=critical
+	;;
+    eo_*)
 	default_layout=epo
+	layout_priority=critical
+	;;
+    es_*)
+	default_layout=latam
+	layout_priority=critical
+	;;
+    et_*)
+	default_layout=ee
+	;;
+    fa_*)
+	default_layout=ir
+	;;
+    ff_*)
+	default_layout=gh
+	default_variant=fula
+	;;
+    fi_*)
+	default_layout=fi
+	;;
+    fo_*)
+	default_layout=fo
 	;;
     fr_*)
-	default_layout=fr
+	default_layout=be
 	layout_priority=critical
 	;;
+    gaa_*)
+	default_layout=gh
+	default_variant=ga
+	;;
+    gd_*)
+	default_layout=ie
+	default_variant=CloGaelach
+	;;
+    gsw_*)
+	default_layout=ch
+	;;
     gu_*)
 	default_layout=in
 	default_variant=guj
 	;;
+    ha_*)
+	default_layout=gh
+	default_variant=hausa
+	layout_priority=critical
+	;;
+    he_*)
+	default_layout=il
+	;;
     hi_*)
 	default_layout=in
-	default_variant=deva
+	default_variant=bolnagri
 	;;
     hr_*)
 	default_layout=hr
 	;;
+    hu_*)
+	default_layout=hu
+	;;
     hy_*)
 	default_layout=am
 	;;
+    ig_*)
+	default_layout=ng
+	default_variant=igbo
+	;;
+    is_*)
+	default_layout=is
+	;;
+    it_*)
+	default_layout=it
+	;;
+    iu_*)
+	default_layout=ca
+	default_variant=ike
+	;;
+    ja_*)
+	default_layout=jp
+	;;
     ka_*)
 	default_layout=ge
 	layout_priority=critical
 	;;
+    kk_*)
+	default_layout=kz
+	;;
+    km_*)
+	default_layout=kh
+	;;
     kn_*)
 	default_layout=in
 	default_variant=kan
 	;;
+    ko_*)
+	default_layout=kr
+	;;
+    ku_*)
+	default_layout=iq
+	layout_priority=critical
+	;;
+    kv_*)
+	default_layout=ru
+	default_variant=kom
+	;;
+    ky_*)
+	default_layout=kg
+	;;
     lo_*)
 	default_layout=la
 	;;
+    lt_*)
+	default_layout=lt
+	;;
+    lv_*)
+	default_layout=lv
+	;;
+    mi_*)
+	default_layout=mao
+	;;
+    mk_*)
+	default_layout=mk
+	;;
     ml_*)
 	default_layout=in
 	default_variant=mal
 	;;
+    mng_*)
+	default_layout=mn
+	;;
+    mt_*)
+	default_layout=mt
+	;;
+    my_*)
+	default_layout=mm
+	;;
+    ne_*)
+	default_layout=np
+	;;
+    nl_*)
+	default_layout=nl
+	;;
+    no_*)
+	default_layout=no
+	;;
+    or_*)
+	default_layout=in
+	default_variant=ori
+	;;
+    os_*)
+	default_layout=ge
+	default_variant=os
+	layout_priority=critical
+	;;
     pa_*)
 	default_layout=in
 	default_variant=guru
 	;;
+    pl_*)
+	default_layout=pl
+	;;
+    ps_*)
+	default_layout=af
+	default_variant=ps
+	;;
+    pt_*)
+	default_layout=br
+	layout_priority=critical
+	;;
+    ro_*)
+	default_layout=ro
+	;;
+    ru_*)
+	default_layout=ru
+	layout_priority=critical
+	;;
+    sah_*)
+	default_layout=ru
+	default_variant=sah
+	;;
+    se_*)
+	default_layout=fi
+	default_variant=smi
+	layout_priority=critical
+	;;
+    si_*)
+	default_layout=lk
+	;;
+    sk_*)
+	default_layout=sk
+	;;
+    sl_*)
+	default_layout=si
+	;;
+    smi_*)
+	default_layout=fi
+	default_variant=smi
+	;;
+    sq_*)
+	default_layout=al
+	;;
     sr_*)
-	default_layout=cs
+	default_layout=me
 	layout_priority=critical
 	;;
     sv_*)
 	default_layout=se
-	default_variant=basic
+	;;
+    syr_*)
+	default_layout=sy
 	;;
     ta_*)
 	default_layout=in
-	default_variant=tam
+	default_variant=tam_unicode
+	layout_priority=critical
 	;;
     te_*)
 	default_layout=in
 	default_variant=tel
 	;;
-  
+    tg_*)
+	default_layout=tj
+	;;
+    th_*)
+	default_layout=th
+	;;
+    tr_*)
+	default_layout=tr
+	;;
+    tt_*)
+	default_layout=ru
+	default_variant=tt
+	;;
+    udm_*)
+	default_layout=ru
+	default_variant=udm
+	;;
+    uk_*)
+	default_layout=ua
+	;;
+    ur_*)
+	default_layout=pk
+	layout_priority=critical
+	;;
+    uz_*)
+	default_layout=uz
+	layout_priority=critical
+	;;
+    vi_*)
+	default_layout=vn
+	;;
+    xal_*)
+	default_layout=ru
+	default_variant=xal
+	;;
+    yo_*)
+	default_layout=ng
+	default_variant=yoruba
+	;;
+    zh_*)
+	default_layout=cn
+	;;
+    # Fallback
     *)
 	default_layout=us
 	;;

Reply to: