Merge "Port Emulator keymaps."
diff --git a/data/keyboards/Android.mk b/data/keyboards/Android.mk
new file mode 100644
index 0000000..8cba52d
--- /dev/null
+++ b/data/keyboards/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This makefile performs build time validation of framework keymap files.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(LOCAL_PATH)/common.mk
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 682584c..24b485d 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -22,6 +22,8 @@
 
 type FULL
 
+### Basic QWERTY keys ###
+
 key A {
     label:                              'A'
     base:                               'a'
@@ -369,6 +371,8 @@
     ctrl, alt, meta:                    none
 }
 
+### Numeric keypad ###
+
 key NUMPAD_0 {
     label, number:                      '0'
     base:                               fallback INSERT
@@ -499,3 +503,25 @@
     base:                               '\n' fallback ENTER
     ctrl, alt, meta:                    none fallback ENTER
 }
+
+### Special keys on phones ###
+
+key AT {
+    label, number:                      '@'
+    base:                               '@'
+}
+
+key STAR {
+    label, number:                      '*'
+    base:                               '*'
+}
+
+key POUND {
+    label, number:                      '#'
+    base:                               '#'
+}
+
+key PLUS {
+    label, number:                      '+'
+    base:                               '+'
+}
diff --git a/data/keyboards/Virtual.kcm b/data/keyboards/Virtual.kcm
index 9ada86a..8d3c7ac 100644
--- a/data/keyboards/Virtual.kcm
+++ b/data/keyboards/Virtual.kcm
@@ -19,6 +19,8 @@
 
 type FULL
 
+### Basic QWERTY keys ###
+
 key A {
     label:                              'A'
     base:                               'a'
@@ -366,6 +368,8 @@
     ctrl, alt, meta:                    none
 }
 
+### Numeric keypad ###
+
 key NUMPAD_0 {
     label, number:                      '0'
     base:                               fallback INSERT
@@ -496,3 +500,25 @@
     base:                               '\n' fallback ENTER
     ctrl, alt, meta:                    none fallback ENTER
 }
+
+### Special keys on phones ###
+
+key AT {
+    label, number:                      '@'
+    base:                               '@'
+}
+
+key STAR {
+    label, number:                      '*'
+    base:                               '*'
+}
+
+key POUND {
+    label, number:                      '#'
+    base:                               '#'
+}
+
+key PLUS {
+    label, number:                      '+'
+    base:                               '+'
+}
diff --git a/data/keyboards/common.mk b/data/keyboards/common.mk
new file mode 100644
index 0000000..3f05edb
--- /dev/null
+++ b/data/keyboards/common.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is the list of framework provided keylayouts and key character maps to include.
+# Used by Android.mk and keyboards.mk.
+
+keylayouts := \
+    AVRCP.kl \
+    Generic.kl \
+    Motorola_Bluetooth_Wireless_Keyboard.kl \
+    qwerty.kl \
+    qwerty2.kl
+
+keycharmaps := \
+    Generic.kcm \
+    Virtual.kcm \
+    Motorola_Bluetooth_Wireless_Keyboard.kcm \
+    qwerty.kcm \
+    qwerty2.kcm
diff --git a/data/keyboards/keyboards.mk b/data/keyboards/keyboards.mk
index 3a0a553..b32e436 100644
--- a/data/keyboards/keyboards.mk
+++ b/data/keyboards/keyboards.mk
@@ -14,15 +14,7 @@
 
 # Warning: this is actually a product definition, to be inherited from
 
-keylayouts := \
-    AVRCP.kl \
-    Generic.kl \
-    Motorola_Bluetooth_Wireless_Keyboard.kl
-
-keycharmaps := \
-    Generic.kcm \
-    Virtual.kcm \
-    Motorola_Bluetooth_Wireless_Keyboard.kcm
+include $(LOCAL_PATH)/common.mk
 
 PRODUCT_COPY_FILES := $(foreach file,$(keylayouts),\
     frameworks/base/data/keyboards/$(file):system/usr/keylayout/$(file))
@@ -30,4 +22,4 @@
 PRODUCT_COPY_FILES += $(foreach file,$(keycharmaps),\
     frameworks/base/data/keyboards/$(file):system/usr/keychars/$(file))
 
-PRODUCT_PACKAGES := $(keycharmaps)
+PRODUCT_PACKAGES := $(keylayouts) $(keycharmaps)
diff --git a/data/keyboards/qwerty.kcm b/data/keyboards/qwerty.kcm
new file mode 100644
index 0000000..f31333e
--- /dev/null
+++ b/data/keyboards/qwerty.kcm
@@ -0,0 +1,508 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Emulator keyboard character map #1.
+#
+# This file is no longer used as the platform's default keyboard character map.
+# Refer to Generic.kcm and Virtual.kcm instead.
+#
+
+type ALPHA
+
+key A {
+    label:                              'A'
+    number:                             '2'
+    base:                               'a'
+    shift, capslock:                    'A'
+    alt:                                '#'
+    shift+alt, capslock+alt:            none
+}
+
+key B {
+    label:                              'B'
+    number:                             '2'
+    base:                               'b'
+    shift, capslock:                    'B'
+    alt:                                '<'
+    shift+alt, capslock+alt:            none
+}
+
+key C {
+    label:                              'C'
+    number:                             '2'
+    base:                               'c'
+    shift, capslock:                    'C'
+    alt:                                '9'
+    shift+alt, capslock+alt:            '\u00e7'
+}
+
+key D {
+    label:                              'D'
+    number:                             '3'
+    base:                               'd'
+    shift, capslock:                    'D'
+    alt:                                '5'
+    shift+alt, capslock+alt:            none
+}
+
+key E {
+    label:                              'E'
+    number:                             '3'
+    base:                               'e'
+    shift, capslock:                    'E'
+    alt:                                '2'
+    shift+alt, capslock+alt:            '\u0301'
+}
+
+key F {
+    label:                              'F'
+    number:                             '3'
+    base:                               'f'
+    shift, capslock:                    'F'
+    alt:                                '6'
+    shift+alt, capslock+alt:            '\u00a5'
+}
+
+key G {
+    label:                              'G'
+    number:                             '4'
+    base:                               'g'
+    shift, capslock:                    'G'
+    alt:                                '-'
+    shift+alt, capslock+alt:            '_'
+}
+
+key H {
+    label:                              'H'
+    number:                             '4'
+    base:                               'h'
+    shift, capslock:                    'H'
+    alt:                                '['
+    shift+alt, capslock+alt:            '{'
+}
+
+key I {
+    label:                              'I'
+    number:                             '4'
+    base:                               'i'
+    shift, capslock:                    'I'
+    alt:                                '$'
+    shift+alt, capslock+alt:            '\u0302'
+}
+
+key J {
+    label:                              'J'
+    number:                             '5'
+    base:                               'j'
+    shift, capslock:                    'J'
+    alt:                                ']'
+    shift+alt, capslock+alt:            '}'
+}
+
+key K {
+    label:                              'K'
+    number:                             '5'
+    base:                               'k'
+    shift, capslock:                    'K'
+    alt:                                '"'
+    shift+alt, capslock+alt:            '~'
+}
+
+key L {
+    label:                              'L'
+    number:                             '5'
+    base:                               'l'
+    shift, capslock:                    'L'
+    alt:                                '\''
+    shift+alt, capslock+alt:            '`'
+}
+
+key M {
+    label:                              'M'
+    number:                             '6'
+    base:                               'm'
+    shift, capslock:                    'M'
+    alt:                                '!'
+    shift+alt, capslock+alt:            none
+}
+
+key N {
+    label:                              'N'
+    number:                             '6'
+    base:                               'n'
+    shift, capslock:                    'N'
+    alt:                                '>'
+    shift+alt, capslock+alt:            '\u0303'
+}
+
+key O {
+    label:                              'O'
+    number:                             '6'
+    base:                               'o'
+    shift, capslock:                    'O'
+    alt:                                '('
+    shift+alt, capslock+alt:            none
+}
+
+key P {
+    label:                              'P'
+    number:                             '7'
+    base:                               'p'
+    shift, capslock:                    'P'
+    alt:                                ')'
+    shift+alt, capslock+alt:            none
+}
+
+key Q {
+    label:                              'Q'
+    number:                             '7'
+    base:                               'q'
+    shift, capslock:                    'Q'
+    alt:                                '*'
+    shift+alt, capslock+alt:            '\u0300'
+}
+
+key R {
+    label:                              'R'
+    number:                             '7'
+    base:                               'r'
+    shift, capslock:                    'R'
+    alt:                                '3'
+    shift+alt, capslock+alt:            '\u20ac'
+}
+
+key S {
+    label:                              'S'
+    number:                             '7'
+    base:                               's'
+    shift, capslock:                    'S'
+    alt:                                '4'
+    shift+alt, capslock+alt:            '\u00df'
+}
+
+key T {
+    label:                              'T'
+    number:                             '8'
+    base:                               't'
+    shift, capslock:                    'T'
+    alt:                                '+'
+    shift+alt, capslock+alt:            '\u00a3'
+}
+
+key U {
+    label:                              'U'
+    number:                             '8'
+    base:                               'u'
+    shift, capslock:                    'U'
+    alt:                                '&'
+    shift+alt, capslock+alt:            '\u0308'
+}
+
+key V {
+    label:                              'V'
+    number:                             '8'
+    base:                               'v'
+    shift, capslock:                    'V'
+    alt:                                '='
+    shift+alt, capslock+alt:            '^'
+}
+
+key W {
+    label:                              'W'
+    number:                             '9'
+    base:                               'w'
+    shift, capslock:                    'W'
+    alt:                                '1'
+    shift+alt, capslock+alt:            none
+}
+
+key X {
+    label:                              'X'
+    number:                             '9'
+    base:                               'x'
+    shift, capslock:                    'X'
+    alt:                                '8'
+    shift+alt, capslock+alt:            '\uef00'
+}
+
+key Y {
+    label:                              'Y'
+    number:                             '9'
+    base:                               'y'
+    shift, capslock:                    'Y'
+    alt:                                '%'
+    shift+alt, capslock+alt:            '\u00a1'
+}
+
+key Z {
+    label:                              'Z'
+    number:                             '9'
+    base:                               'z'
+    shift, capslock:                    'Z'
+    alt:                                '7'
+    shift+alt, capslock+alt:            none
+}
+
+key COMMA {
+    label:                              ','
+    number:                             ','
+    base:                               ','
+    shift, capslock:                    ';'
+    alt:                                ';'
+    shift+alt, capslock+alt:            '|'
+}
+
+key PERIOD {
+    label:                              '.'
+    number:                             '.'
+    base:                               '.'
+    shift:                              ':'
+    alt:                                ':'
+    shift+alt:                          '\u2026'
+}
+
+key AT {
+    label:                              '@'
+    number:                             '0'
+    base:                               '@'
+    shift:                              '0'
+    alt:                                '0'
+    shift+alt:                          '\u2022'
+}
+
+key SLASH {
+    label:                              '/'
+    number:                             '/'
+    base:                               '/'
+    shift:                              '?'
+    alt:                                '?'
+    shift+alt:                          '\\'
+}
+
+key SPACE {
+    label:                              ' '
+    number:                             ' '
+    base:                               ' '
+    shift:                              ' '
+    alt:                                '\uef01'
+    shift+alt:                          '\uef01'
+}
+
+key ENTER {
+    label:                              '\n'
+    number:                             '\n'
+    base:                               '\n'
+    shift:                              '\n'
+    alt:                                '\n'
+    shift+alt:                          '\n'
+}
+
+key TAB {
+    label:                              '\t'
+    number:                             '\t'
+    base:                               '\t'
+    shift:                              '\t'
+    alt:                                '\t'
+    shift+alt:                          '\t'
+}
+
+key 0 {
+    label:                              '0'
+    number:                             '0'
+    base:                               '0'
+    shift:                              ')'
+    alt:                                ')'
+    shift+alt:                          ')'
+}
+
+key 1 {
+    label:                              '1'
+    number:                             '1'
+    base:                               '1'
+    shift:                              '!'
+    alt:                                '!'
+    shift+alt:                          '!'
+}
+
+key 2 {
+    label:                              '2'
+    number:                             '2'
+    base:                               '2'
+    shift:                              '@'
+    alt:                                '@'
+    shift+alt:                          '@'
+}
+
+key 3 {
+    label:                              '3'
+    number:                             '3'
+    base:                               '3'
+    shift:                              '#'
+    alt:                                '#'
+    shift+alt:                          '#'
+}
+
+key 4 {
+    label:                              '4'
+    number:                             '4'
+    base:                               '4'
+    shift:                              '$'
+    alt:                                '$'
+    shift+alt:                          '$'
+}
+
+key 5 {
+    label:                              '5'
+    number:                             '5'
+    base:                               '5'
+    shift:                              '%'
+    alt:                                '%'
+    shift+alt:                          '%'
+}
+
+key 6 {
+    label:                              '6'
+    number:                             '6'
+    base:                               '6'
+    shift:                              '^'
+    alt:                                '^'
+    shift+alt:                          '^'
+}
+
+key 7 {
+    label:                              '7'
+    number:                             '7'
+    base:                               '7'
+    shift:                              '&'
+    alt:                                '&'
+    shift+alt:                          '&'
+}
+
+key 8 {
+    label:                              '8'
+    number:                             '8'
+    base:                               '8'
+    shift:                              '*'
+    alt:                                '*'
+    shift+alt:                          '*'
+}
+
+key 9 {
+    label:                              '9'
+    number:                             '9'
+    base:                               '9'
+    shift:                              '('
+    alt:                                '('
+    shift+alt:                          '('
+}
+
+key GRAVE {
+    label:                              '`'
+    number:                             '`'
+    base:                               '`'
+    shift:                              '~'
+    alt:                                '`'
+    shift+alt:                          '~'
+}
+
+key MINUS {
+    label:                              '-'
+    number:                             '-'
+    base:                               '-'
+    shift:                              '_'
+    alt:                                '-'
+    shift+alt:                          '_'
+}
+
+key EQUALS {
+    label:                              '='
+    number:                             '='
+    base:                               '='
+    shift:                              '+'
+    alt:                                '='
+    shift+alt:                          '+'
+}
+
+key LEFT_BRACKET {
+    label:                              '['
+    number:                             '['
+    base:                               '['
+    shift:                              '{'
+    alt:                                '['
+    shift+alt:                          '{'
+}
+
+key RIGHT_BRACKET {
+    label:                              ']'
+    number:                             ']'
+    base:                               ']'
+    shift:                              '}'
+    alt:                                ']'
+    shift+alt:                          '}'
+}
+
+key BACKSLASH {
+    label:                              '\\'
+    number:                             '\\'
+    base:                               '\\'
+    shift:                              '|'
+    alt:                                '\\'
+    shift+alt:                          '|'
+}
+
+key SEMICOLON {
+    label:                              ';'
+    number:                             ';'
+    base:                               ';'
+    shift:                              ':'
+    alt:                                ';'
+    shift+alt:                          ':'
+}
+
+key APOSTROPHE {
+    label:                              '\''
+    number:                             '\''
+    base:                               '\''
+    shift:                              '"'
+    alt:                                '\''
+    shift+alt:                          '"'
+}
+
+key STAR {
+    label:                              '*'
+    number:                             '*'
+    base:                               '*'
+    shift:                              '*'
+    alt:                                '*'
+    shift+alt:                          '*'
+}
+
+key POUND {
+    label:                              '#'
+    number:                             '#'
+    base:                               '#'
+    shift:                              '#'
+    alt:                                '#'
+    shift+alt:                          '#'
+}
+
+key PLUS {
+    label:                              '+'
+    number:                             '+'
+    base:                               '+'
+    shift:                              '+'
+    alt:                                '+'
+    shift+alt:                          '+'
+}
diff --git a/data/keyboards/qwerty.kl b/data/keyboards/qwerty.kl
new file mode 100644
index 0000000..f1caacd
--- /dev/null
+++ b/data/keyboards/qwerty.kl
@@ -0,0 +1,112 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Emulator keyboard layout #1.
+#
+# This file is no longer used as the platform's default keyboard layout.
+# Refer to Generic.kl instead.
+#
+
+key 399   GRAVE
+key 2     1
+key 3     2
+key 4     3
+key 5     4
+key 6     5
+key 7     6
+key 8     7
+key 9     8
+key 10    9
+key 11    0
+key 158   BACK              WAKE_DROPPED
+key 230   SOFT_RIGHT        WAKE
+key 60    SOFT_RIGHT        WAKE
+key 107   ENDCALL           WAKE_DROPPED
+key 62    ENDCALL           WAKE_DROPPED
+key 229   MENU              WAKE_DROPPED
+key 139   MENU              WAKE_DROPPED
+key 59    MENU              WAKE_DROPPED
+key 127   SEARCH            WAKE_DROPPED
+key 217   SEARCH            WAKE_DROPPED
+key 228   POUND
+key 227   STAR
+key 231   CALL              WAKE_DROPPED
+key 61    CALL              WAKE_DROPPED
+key 232   DPAD_CENTER       WAKE_DROPPED
+key 108   DPAD_DOWN         WAKE_DROPPED
+key 103   DPAD_UP           WAKE_DROPPED
+key 102   HOME              WAKE
+key 105   DPAD_LEFT         WAKE_DROPPED
+key 106   DPAD_RIGHT        WAKE_DROPPED
+key 115   VOLUME_UP         WAKE
+key 114   VOLUME_DOWN       WAKE
+key 116   POWER             WAKE
+key 212   CAMERA
+
+key 16    Q
+key 17    W
+key 18    E
+key 19    R
+key 20    T
+key 21    Y
+key 22    U
+key 23    I
+key 24    O
+key 25    P
+key 26    LEFT_BRACKET
+key 27    RIGHT_BRACKET
+key 43    BACKSLASH
+
+key 30    A
+key 31    S
+key 32    D
+key 33    F
+key 34    G
+key 35    H
+key 36    J
+key 37    K
+key 38    L
+key 39    SEMICOLON
+key 40    APOSTROPHE
+key 14    DEL
+        
+key 44    Z
+key 45    X
+key 46    C
+key 47    V
+key 48    B
+key 49    N
+key 50    M
+key 51    COMMA
+key 52    PERIOD
+key 53    SLASH
+key 28    ENTER
+        
+key 56    ALT_LEFT
+key 100   ALT_RIGHT
+key 42    SHIFT_LEFT
+key 54    SHIFT_RIGHT
+key 15    TAB
+key 57    SPACE
+key 150   EXPLORER
+key 155   ENVELOPE        
+
+key 12    MINUS
+key 13    EQUALS
+key 215   AT
+
+# On an AT keyboard: ESC, F10
+key 1     BACK              WAKE_DROPPED
+key 68    MENU              WAKE_DROPPED
diff --git a/data/keyboards/qwerty2.kcm b/data/keyboards/qwerty2.kcm
new file mode 100644
index 0000000..d96914f
--- /dev/null
+++ b/data/keyboards/qwerty2.kcm
@@ -0,0 +1,505 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Emulator keyboard character map #2.
+#
+
+type ALPHA
+
+key A {
+    label:                              'A'
+    number:                             '2'
+    base:                               'a'
+    shift, capslock:                    'A'
+    alt:                                'a'
+    shift+alt, capslock+alt:            'A'
+}
+
+key B {
+    label:                              'B'
+    number:                             '2'
+    base:                               'b'
+    shift, capslock:                    'B'
+    alt:                                'b'
+    shift+alt, capslock+alt:            'B'
+}
+
+key C {
+    label:                              'C'
+    number:                             '2'
+    base:                               'c'
+    shift, capslock:                    'C'
+    alt:                                '\u00e7'
+    shift+alt, capslock+alt:            '\u00e7'
+}
+
+key D {
+    label:                              'D'
+    number:                             '3'
+    base:                               'd'
+    shift, capslock:                    'D'
+    alt:                                '\''
+    shift+alt, capslock+alt:            '\''
+}
+
+key E {
+    label:                              'E'
+    number:                             '3'
+    base:                               'e'
+    shift, capslock:                    'E'
+    alt:                                '"'
+    shift+alt, capslock+alt:            '\u0301'
+}
+
+key F {
+    label:                              'F'
+    number:                             '3'
+    base:                               'f'
+    shift, capslock:                    'F'
+    alt:                                '['
+    shift+alt, capslock+alt:            '['
+}
+
+key G {
+    label:                              'G'
+    number:                             '4'
+    base:                               'g'
+    shift, capslock:                    'G'
+    alt:                                ']'
+    shift+alt, capslock+alt:            ']'
+}
+
+key H {
+    label:                              'H'
+    number:                             '4'
+    base:                               'h'
+    shift, capslock:                    'H'
+    alt:                                '<'
+    shift+alt, capslock+alt:            '<'
+}
+
+key I {
+    label:                              'I'
+    number:                             '4'
+    base:                               'i'
+    shift, capslock:                    'I'
+    alt:                                '-'
+    shift+alt, capslock+alt:            '\u0302'
+}
+
+key J {
+    label:                              'J'
+    number:                             '5'
+    base:                               'j'
+    shift, capslock:                    'J'
+    alt:                                '>'
+    shift+alt, capslock+alt:            '>'
+}
+
+key K {
+    label:                              'K'
+    number:                             '5'
+    base:                               'k'
+    shift, capslock:                    'K'
+    alt:                                ';'
+    shift+alt, capslock+alt:            '~'
+}
+
+key L {
+    label:                              'L'
+    number:                             '5'
+    base:                               'l'
+    shift, capslock:                    'L'
+    alt:                                ':'
+    shift+alt, capslock+alt:            '`'
+}
+
+key M {
+    label:                              'M'
+    number:                             '6'
+    base:                               'm'
+    shift, capslock:                    'M'
+    alt:                                '%'
+    shift+alt, capslock+alt:            none
+}
+
+key N {
+    label:                              'N'
+    number:                             '6'
+    base:                               'n'
+    shift, capslock:                    'N'
+    alt:                                none
+    shift+alt, capslock+alt:            '\u0303'
+}
+
+key O {
+    label:                              'O'
+    number:                             '6'
+    base:                               'o'
+    shift, capslock:                    'O'
+    alt:                                '+'
+    shift+alt, capslock+alt:            '+'
+}
+
+key P {
+    label:                              'P'
+    number:                             '7'
+    base:                               'p'
+    shift, capslock:                    'P'
+    alt:                                '='
+    shift+alt, capslock+alt:            '\u00a5'
+}
+
+key Q {
+    label:                              'Q'
+    number:                             '7'
+    base:                               'q'
+    shift, capslock:                    'Q'
+    alt:                                '|'
+    shift+alt, capslock+alt:            '\u0300'
+}
+
+key R {
+    label:                              'R'
+    number:                             '7'
+    base:                               'r'
+    shift, capslock:                    'R'
+    alt:                                '`'
+    shift+alt, capslock+alt:            '\u20ac'
+}
+
+key S {
+    label:                              'S'
+    number:                             '7'
+    base:                               's'
+    shift, capslock:                    'S'
+    alt:                                '\\'
+    shift+alt, capslock+alt:            '\u00df'
+}
+
+key T {
+    label:                              'T'
+    number:                             '8'
+    base:                               't'
+    shift, capslock:                    'T'
+    alt:                                '{'
+    shift+alt, capslock+alt:            '\u00a3'
+}
+
+key U {
+    label:                              'U'
+    number:                             '8'
+    base:                               'u'
+    shift, capslock:                    'U'
+    alt:                                '_'
+    shift+alt, capslock+alt:            '\u0308'
+}
+
+key V {
+    label:                              'V'
+    number:                             '8'
+    base:                               'v'
+    shift, capslock:                    'V'
+    alt:                                'v'
+    shift+alt, capslock+alt:            'V'
+}
+
+key W {
+    label:                              'W'
+    number:                             '9'
+    base:                               'w'
+    shift, capslock:                    'W'
+    alt:                                '~'
+    shift+alt, capslock+alt:            '~'
+}
+
+key X {
+    label:                              'X'
+    number:                             '9'
+    base:                               'x'
+    shift, capslock:                    'X'
+    alt:                                'x'
+    shift+alt, capslock+alt:            '\uef00'
+}
+
+key Y {
+    label:                              'Y'
+    number:                             '9'
+    base:                               'y'
+    shift, capslock:                    'Y'
+    alt:                                '}'
+    shift+alt, capslock+alt:            '\u00a1'
+}
+
+key Z {
+    label:                              'Z'
+    number:                             '9'
+    base:                               'z'
+    shift, capslock:                    'Z'
+    alt:                                'z'
+    shift+alt, capslock+alt:            'Z'
+}
+
+key COMMA {
+    label:                              ','
+    number:                             ','
+    base:                               ','
+    shift:                              '<'
+    alt:                                ','
+    shift+alt:                          ','
+}
+
+key PERIOD {
+    label:                              '.'
+    number:                             '.'
+    base:                               '.'
+    shift:                              '>'
+    alt:                                '.'
+    shift+alt:                          '\u2026'
+}
+
+key AT {
+    label:                              '@'
+    number:                             '@'
+    base:                               '@'
+    shift:                              '@'
+    alt:                                '@'
+    shift+alt:                          '\u2022'
+}
+
+key SLASH {
+    label:                              '/'
+    number:                             '/'
+    base:                               '/'
+    shift:                              '?'
+    alt:                                '?'
+    shift+alt:                          '?'
+}
+
+key SPACE {
+    label:                              ' '
+    number:                             ' '
+    base:                               ' '
+    shift:                              ' '
+    alt:                                '\uef01'
+    shift+alt:                          '\uef01'
+}
+
+key ENTER {
+    label:                              '\n'
+    number:                             '\n'
+    base:                               '\n'
+    shift:                              '\n'
+    alt:                                '\n'
+    shift+alt:                          '\n'
+}
+
+key TAB {
+    label:                              '\t'
+    number:                             '\t'
+    base:                               '\t'
+    shift:                              '\t'
+    alt:                                '\t'
+    shift+alt:                          '\t'
+}
+
+key 0 {
+    label:                              '0'
+    number:                             '0'
+    base:                               '0'
+    shift:                              ')'
+    alt:                                ')'
+    shift+alt:                          ')'
+}
+
+key 1 {
+    label:                              '1'
+    number:                             '1'
+    base:                               '1'
+    shift:                              '!'
+    alt:                                '!'
+    shift+alt:                          '!'
+}
+
+key 2 {
+    label:                              '2'
+    number:                             '2'
+    base:                               '2'
+    shift:                              '@'
+    alt:                                '@'
+    shift+alt:                          '@'
+}
+
+key 3 {
+    label:                              '3'
+    number:                             '3'
+    base:                               '3'
+    shift:                              '#'
+    alt:                                '#'
+    shift+alt:                          '#'
+}
+
+key 4 {
+    label:                              '4'
+    number:                             '4'
+    base:                               '4'
+    shift:                              '$'
+    alt:                                '$'
+    shift+alt:                          '$'
+}
+
+key 5 {
+    label:                              '5'
+    number:                             '5'
+    base:                               '5'
+    shift:                              '%'
+    alt:                                '%'
+    shift+alt:                          '%'
+}
+
+key 6 {
+    label:                              '6'
+    number:                             '6'
+    base:                               '6'
+    shift:                              '^'
+    alt:                                '^'
+    shift+alt:                          '^'
+}
+
+key 7 {
+    label:                              '7'
+    number:                             '7'
+    base:                               '7'
+    shift:                              '&'
+    alt:                                '&'
+    shift+alt:                          '&'
+}
+
+key 8 {
+    label:                              '8'
+    number:                             '8'
+    base:                               '8'
+    shift:                              '*'
+    alt:                                '*'
+    shift+alt:                          '*'
+}
+
+key 9 {
+    label:                              '9'
+    number:                             '9'
+    base:                               '9'
+    shift:                              '('
+    alt:                                '('
+    shift+alt:                          '('
+}
+
+key GRAVE {
+    label:                              '`'
+    number:                             '`'
+    base:                               '`'
+    shift:                              '~'
+    alt:                                '`'
+    shift+alt:                          '~'
+}
+
+key MINUS {
+    label:                              '-'
+    number:                             '-'
+    base:                               '-'
+    shift:                              '_'
+    alt:                                '-'
+    shift+alt:                          '_'
+}
+
+key EQUALS {
+    label:                              '='
+    number:                             '='
+    base:                               '='
+    shift:                              '+'
+    alt:                                '='
+    shift+alt:                          '+'
+}
+
+key LEFT_BRACKET {
+    label:                              '['
+    number:                             '['
+    base:                               '['
+    shift:                              '{'
+    alt:                                '['
+    shift+alt:                          '{'
+}
+
+key RIGHT_BRACKET {
+    label:                              ']'
+    number:                             ']'
+    base:                               ']'
+    shift:                              '}'
+    alt:                                ']'
+    shift+alt:                          '}'
+}
+
+key BACKSLASH {
+    label:                              '\\'
+    number:                             '\\'
+    base:                               '\\'
+    shift:                              '|'
+    alt:                                '\\'
+    shift+alt:                          '|'
+}
+
+key SEMICOLON {
+    label:                              ';'
+    number:                             ';'
+    base:                               ';'
+    shift:                              ':'
+    alt:                                ';'
+    shift+alt:                          ':'
+}
+
+key APOSTROPHE {
+    label:                              '\''
+    number:                             '\''
+    base:                               '\''
+    shift:                              '"'
+    alt:                                '\''
+    shift+alt:                          '"'
+}
+
+key STAR {
+    label:                              '*'
+    number:                             '*'
+    base:                               '*'
+    shift:                              '*'
+    alt:                                '*'
+    shift+alt:                          '*'
+}
+
+key POUND {
+    label:                              '#'
+    number:                             '#'
+    base:                               '#'
+    shift:                              '#'
+    alt:                                '#'
+    shift+alt:                          '#'
+}
+
+key PLUS {
+    label:                              '+'
+    number:                             '+'
+    base:                               '+'
+    shift:                              '+'
+    alt:                                '+'
+    shift+alt:                          '+'
+}
diff --git a/data/keyboards/qwerty2.kl b/data/keyboards/qwerty2.kl
new file mode 100644
index 0000000..863a258
--- /dev/null
+++ b/data/keyboards/qwerty2.kl
@@ -0,0 +1,109 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Emulator keyboard layout #2.
+#
+
+key 399   GRAVE
+key 2     1
+key 3     2
+key 4     3
+key 5     4
+key 6     5
+key 7     6
+key 8     7
+key 9     8
+key 10    9
+key 11    0
+key 158   BACK              WAKE_DROPPED
+key 230   SOFT_RIGHT        WAKE
+key 60    SOFT_RIGHT        WAKE
+key 107   ENDCALL           WAKE_DROPPED
+key 62    ENDCALL           WAKE_DROPPED
+key 229   MENU              WAKE_DROPPED
+key 139   MENU              WAKE_DROPPED
+key 59    MENU              WAKE_DROPPED
+key 127   SEARCH            WAKE_DROPPED
+key 217   SEARCH            WAKE_DROPPED
+key 228   POUND
+key 227   STAR
+key 231   CALL              WAKE_DROPPED
+key 61    CALL              WAKE_DROPPED
+key 232   DPAD_CENTER       WAKE_DROPPED
+key 108   DPAD_DOWN         WAKE_DROPPED
+key 103   DPAD_UP           WAKE_DROPPED
+key 102   HOME              WAKE
+key 105   DPAD_LEFT         WAKE_DROPPED
+key 106   DPAD_RIGHT        WAKE_DROPPED
+key 115   VOLUME_UP         WAKE
+key 114   VOLUME_DOWN       WAKE
+key 116   POWER             WAKE
+key 212   CAMERA
+
+key 16    Q
+key 17    W
+key 18    E
+key 19    R
+key 20    T
+key 21    Y
+key 22    U
+key 23    I
+key 24    O
+key 25    P
+key 26    LEFT_BRACKET
+key 27    RIGHT_BRACKET
+key 43    BACKSLASH
+
+key 30    A
+key 31    S
+key 32    D
+key 33    F
+key 34    G
+key 35    H
+key 36    J
+key 37    K
+key 38    L
+key 39    SEMICOLON
+key 40    APOSTROPHE
+key 14    DEL
+        
+key 44    Z
+key 45    X
+key 46    C
+key 47    V
+key 48    B
+key 49    N
+key 50    M
+key 51    COMMA
+key 52    PERIOD
+key 53    SLASH
+key 28    ENTER
+        
+key 56    ALT_LEFT
+key 100   ALT_RIGHT
+key 42    SHIFT_LEFT
+key 54    SHIFT_RIGHT
+key 15    TAB
+key 57    SPACE
+key 150   EXPLORER
+key 155   ENVELOPE        
+
+key 12    MINUS
+key 13    EQUALS
+key 215   AT
+
+# On an AT keyboard: ESC, F10
+key 1     BACK              WAKE_DROPPED
+key 68    MENU              WAKE_DROPPED
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 61d8abd..5948e04 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -1,7 +1,46 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 LOCAL_PATH:= $(call my-dir)
+
+# libui is partially built for the host (used by build time keymap validation tool)
+# These files are common to host and target builds.
+commonSources:= \
+	Input.cpp \
+	Keyboard.cpp \
+	KeyLayoutMap.cpp \
+	KeyCharacterMap.cpp \
+
+# For the host
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(commonSources)
+
+LOCAL_MODULE:= libui
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+# For the device
+# =====================================================
+
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
+	$(commonSources) \
 	EGLUtils.cpp \
 	EventHub.cpp \
 	EventRecurrence.cpp \
@@ -10,10 +49,6 @@
 	GraphicBufferAllocator.cpp \
 	GraphicBufferMapper.cpp \
 	GraphicLog.cpp \
-	Keyboard.cpp \
-	KeyLayoutMap.cpp \
-	KeyCharacterMap.cpp \
-	Input.cpp \
 	InputDispatcher.cpp \
 	InputManager.cpp \
 	InputReader.cpp \
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
index 890cc3f..e689c4b 100644
--- a/libs/ui/KeyCharacterMap.cpp
+++ b/libs/ui/KeyCharacterMap.cpp
@@ -733,6 +733,7 @@
             }
 
             combinedMeta |= metaState;
+            start = cur + 1;
 
             if (ch == '\0') {
                 break;
diff --git a/tools/validatekeymaps/Android.mk b/tools/validatekeymaps/Android.mk
new file mode 100644
index 0000000..90979e1
--- /dev/null
+++ b/tools/validatekeymaps/Android.mk
@@ -0,0 +1,34 @@
+#
+# Copyright 2010 The Android Open Source Project
+#
+# Keymap validation tool.
+#
+
+# This tool is prebuilt if we're doing an app-only build.
+ifeq ($(TARGET_BUILD_APPS),)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	Main.cpp
+
+LOCAL_CFLAGS := -Wall -Werror
+
+#LOCAL_C_INCLUDES +=
+
+LOCAL_STATIC_LIBRARIES := \
+	libui \
+	libutils \
+	libcutils
+
+ifeq ($(HOST_OS),linux)
+LOCAL_LDLIBS += -lpthread
+endif
+
+LOCAL_MODULE := validatekeymaps
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_EXECUTABLE)
+
+endif # TARGET_BUILD_APPS
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
new file mode 100644
index 0000000..f0d2fee
--- /dev/null
+++ b/tools/validatekeymaps/Main.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ui/KeyCharacterMap.h>
+#include <ui/KeyLayoutMap.h>
+#include <utils/String8.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+using namespace android;
+
+static const char* gProgName = "validatekeymaps";
+
+enum FileType {
+    FILETYPE_UNKNOWN,
+    FILETYPE_KEYLAYOUT,
+    FILETYPE_KEYCHARACTERMAP,
+};
+
+
+static void usage() {
+    fprintf(stderr, "Keymap Validation Tool\n\n");
+    fprintf(stderr, "Usage:\n");
+    fprintf(stderr,
+        " %s [FILENAME.kl] [FILENAME.kcm] [...]\n"
+        "   Validates the specified key layout and/or key character map files.\n\n", gProgName);
+}
+
+static FileType getFileType(const char* filename) {
+    char *extension = strrchr(filename, '.');
+    if (extension) {
+        if (strcmp(extension, ".kl") == 0) {
+            return FILETYPE_KEYLAYOUT;
+        }
+        if (strcmp(extension, ".kcm") == 0) {
+            return FILETYPE_KEYCHARACTERMAP;
+        }
+    }
+    return FILETYPE_UNKNOWN;
+}
+
+static bool validateFile(const char* filename) {
+    fprintf(stdout, "Validating file '%s'...\n", filename);
+
+    FileType fileType = getFileType(filename);
+    switch (fileType) {
+    case FILETYPE_UNKNOWN:
+        fprintf(stderr, "File extension must be .kl or .kcm.\n\n");
+        return false;
+
+    case FILETYPE_KEYLAYOUT: {
+        KeyLayoutMap* map;
+        status_t status = KeyLayoutMap::load(String8(filename), &map);
+        if (status) {
+            fprintf(stderr, "Error %d parsing key layout file.\n\n", status);
+            return false;
+        }
+        break;
+    }
+
+    case FILETYPE_KEYCHARACTERMAP: {
+        KeyCharacterMap* map;
+        status_t status = KeyCharacterMap::load(String8(filename), &map);
+        if (status) {
+            fprintf(stderr, "Error %d parsing key character map file.\n\n", status);
+            return false;
+        }
+        break;
+    }
+    }
+
+    fputs("No errors.\n\n", stdout);
+    return true;
+}
+
+int main(int argc, const char** argv) {
+    if (argc < 2) {
+        usage();
+        return 1;
+    }
+
+    int result = 0;
+    for (int i = 1; i < argc; i++) {
+        if (!validateFile(argv[i])) {
+            result = 1;
+        }
+    }
+
+    if (result) {
+        fputs("Failed!\n", stderr);
+    } else {
+        fputs("Success.\n", stdout);
+    }
+    return result;
+}