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 <zinov...@debian.org>, Christian Perrier 
<bubu...@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_*|e...@*)
-       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 via email to