s.a.c. redesign, first checkin

Change-Id: I4dead2f18bc5e4a38f204c92198a267c286e775d
diff --git a/src/devices/tech/input/dumpsys.jd b/src/devices/tech/input/dumpsys.jd
new file mode 100644
index 0000000..a37584f
--- /dev/null
+++ b/src/devices/tech/input/dumpsys.jd
@@ -0,0 +1,344 @@
+page.title=Dumpsys
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>The <code>dumpsys</code> tool runs on the device and dumps interesting information
+about the status of system services.</p>
+<h2 id="usage">Usage</h2>
+<p>The input system is part of the window manager.  To dump its state,
+run the following command.</p>
+<pre><code>$ adb shell su -- dumpsys window
+
+WINDOW MANAGER INPUT (dumpsys window input)
+Event Hub State:
+  BuiltInKeyboardId: -1
+  Devices:
+...
+</code></pre>
+<p>The set of information that is reported varies depending on the version of Android.</p>
+<h3 id="event-hub-state">Event Hub State</h3>
+<p>The <code>EventHub</code> component is responsible for communicating with the kernel device
+drivers and identifying device capabilities.  Accordingly, its state shows
+information about how devices are configured.</p>
+<pre><code>Event Hub State:
+  BuiltInKeyboardId: -1
+  Devices:
+    3: tuna-gpio-keypad
+      Classes: 0x00000001
+      Path: /dev/input/event2
+      Location:
+      UniqueId:
+      Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000
+      KeyLayoutFile: /system/usr/keylayout/tuna-gpio-keypad.kl
+      KeyCharacterMapFile: /system/usr/keychars/tuna-gpio-keypad.kcm
+      ConfigurationFile:
+    5: Tuna Headset Jack
+      Classes: 0x00000080
+      Path: /dev/input/event5
+      Location: ALSA
+      UniqueId:
+      Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000
+      KeyLayoutFile:
+      KeyCharacterMapFile:
+      ConfigurationFile:
+    6: Melfas MMSxxx Touchscreen
+      Classes: 0x00000014
+      Path: /dev/input/event1
+      Location: 3-0048/input0
+      UniqueId:
+      Identifier: bus=0x0018, vendor=0x0000, product=0x0000, version=0x0000
+      KeyLayoutFile:
+      KeyCharacterMapFile:
+      ConfigurationFile: /system/usr/idc/Melfas_MMSxxx_Touchscreen.idc
+    7: Motorola Bluetooth Wireless Keyboard
+      Classes: 0x8000000b
+      Path: /dev/input/event6
+      Location: 0C:DF:A4:B3:2D:BA
+      UniqueId: 00:0F:F6:80:02:CD
+      Identifier: bus=0x0005, vendor=0x22b8, product=0x093d, version=0x0288
+      KeyLayoutFile: /system/usr/keylayout/Vendor_22b8_Product_093d.kl
+      KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
+      ConfigurationFile:
+</code></pre>
+<h4 id="things-to-look-for">Things To Look For</h4>
+<ol>
+<li>
+<p>All of the expected input devices are present.</p>
+</li>
+<li>
+<p>Each input device has an appropriate key layout file, key character map file
+    and input device configuration file.  If the files are missing or contain
+    syntax errors, then they will not be loaded.</p>
+</li>
+<li>
+<p>Each input device is being classified correctly.  The bits in the <code>Classes</code>
+    field correspond to flags in <code>EventHub.h</code> such as <code>INPUT_DEVICE_CLASS_TOUCH_MT</code>.</p>
+</li>
+<li>
+<p>The <code>BuiltInKeyboardId</code> is correct.  If the device does not have a built-in keyboard,
+    then the id must be <code>-1</code>, otherwise it should be the id of the built-in keyboard.</p>
+<p>If you observe that the <code>BuiltInKeyboardId</code> is not <code>-1</code> but it should be, then
+you are missing a key character map file for a special function keypad somewhere.
+Special function keypad devices should have key character map files that contain
+just the line <code>type SPECIAL_FUNCTION</code> (that's what in the <code>tuna-gpio-keykad.kcm</code>
+file we see mentioned above).</p>
+</li>
+</ol>
+<h3 id="input-reader-state">Input Reader State</h3>
+<p>The <code>InputReader</code> is responsible for decoding input events from the kernel.
+Its state dump shows information about how each input device is configured
+and recent state changes that occurred, such as key presses or touches on
+the touch screen.</p>
+<p>This is what a special function keypad looks like:</p>
+<pre><code>Input Reader State:
+  Device 3: tuna-gpio-keypad
+    IsExternal: false
+    Sources: 0x00000101
+    KeyboardType: 1
+    Keyboard Input Mapper:
+      Parameters:
+        AssociatedDisplayId: -1
+        OrientationAware: false
+      KeyboardType: 1
+      Orientation: 0
+      KeyDowns: 0 keys currently down
+      MetaState: 0x0
+      DownTime: 75816923828000
+</code></pre>
+<p>Here is a touch screen.  Notice all of the information about the resolution of
+the device and the calibration parameters that were used.</p>
+<pre><code>  Device 6: Melfas MMSxxx Touchscreen
+    IsExternal: false
+    Sources: 0x00001002
+    KeyboardType: 0
+    Motion Ranges:
+      X: source=0x00001002, min=0.000, max=719.001, flat=0.000, fuzz=0.999
+      Y: source=0x00001002, min=0.000, max=1279.001, flat=0.000, fuzz=0.999
+      PRESSURE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000
+      SIZE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000
+      TOUCH_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
+      TOUCH_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
+      TOOL_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
+      TOOL_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
+    Touch Input Mapper:
+      Parameters:
+        GestureMode: spots
+        DeviceType: touchScreen
+        AssociatedDisplay: id=0, isExternal=false
+        OrientationAware: true
+      Raw Touch Axes:
+        X: min=0, max=720, flat=0, fuzz=0, resolution=0
+        Y: min=0, max=1280, flat=0, fuzz=0, resolution=0
+        Pressure: min=0, max=255, flat=0, fuzz=0, resolution=0
+        TouchMajor: min=0, max=30, flat=0, fuzz=0, resolution=0
+        TouchMinor: unknown range
+        ToolMajor: unknown range
+        ToolMinor: unknown range
+        Orientation: unknown range
+        Distance: unknown range
+        TiltX: unknown range
+        TiltY: unknown range
+        TrackingId: min=0, max=65535, flat=0, fuzz=0, resolution=0
+        Slot: min=0, max=9, flat=0, fuzz=0, resolution=0
+      Calibration:
+        touch.size.calibration: diameter
+        touch.size.scale: 10.000
+        touch.size.bias: 0.000
+        touch.size.isSummed: false
+        touch.pressure.calibration: amplitude
+        touch.pressure.scale: 0.005
+        touch.orientation.calibration: none
+        touch.distance.calibration: none
+      SurfaceWidth: 720px
+      SurfaceHeight: 1280px
+      SurfaceOrientation: 0
+      Translation and Scaling Factors:
+        XScale: 0.999
+        YScale: 0.999
+        XPrecision: 1.001
+        YPrecision: 1.001
+        GeometricScale: 0.999
+        PressureScale: 0.005
+        SizeScale: 0.033
+        OrientationCenter: 0.000
+        OrientationScale: 0.000
+        DistanceScale: 0.000
+        HaveTilt: false
+        TiltXCenter: 0.000
+        TiltXScale: 0.000
+        TiltYCenter: 0.000
+        TiltYScale: 0.000
+      Last Button State: 0x00000000
+      Last Raw Touch: pointerCount=0
+      Last Cooked Touch: pointerCount=0
+</code></pre>
+<p>Here is an external keyboard / mouse combo HID device.  (This device doesn't actually
+have a mouse but its HID descriptor says it does.)</p>
+<pre><code>  Device 7: Motorola Bluetooth Wireless Keyboard
+    IsExternal: true
+    Sources: 0x00002103
+    KeyboardType: 2
+    Motion Ranges:
+      X: source=0x00002002, min=0.000, max=719.000, flat=0.000, fuzz=0.000
+      Y: source=0x00002002, min=0.000, max=1279.000, flat=0.000, fuzz=0.000
+      PRESSURE: source=0x00002002, min=0.000, max=1.000, flat=0.000, fuzz=0.000
+      VSCROLL: source=0x00002002, min=-1.000, max=1.000, flat=0.000, fuzz=0.000
+    Keyboard Input Mapper:
+      Parameters:
+        AssociatedDisplayId: -1
+        OrientationAware: false
+      KeyboardType: 2
+      Orientation: 0
+      KeyDowns: 0 keys currently down
+      MetaState: 0x0
+      DownTime: 75868832946000
+    Cursor Input Mapper:
+      Parameters:
+        AssociatedDisplayId: 0
+        Mode: pointer
+        OrientationAware: false
+      XScale: 1.000
+      YScale: 1.000
+      XPrecision: 1.000
+      YPrecision: 1.000
+      HaveVWheel: true
+      HaveHWheel: false
+      VWheelScale: 1.000
+      HWheelScale: 1.000
+      Orientation: 0
+      ButtonState: 0x00000000
+      Down: false
+      DownTime: 0
+</code></pre>
+<p>Here is a joystick.  Notice how all of the axes have been scaled to a normalized
+range.  The axis mapping can be configured using key layout files.</p>
+<pre><code>Device 18: Logitech Logitech Cordless RumblePad 2
+    IsExternal: true
+    Sources: 0x01000511
+    KeyboardType: 1
+    Motion Ranges:
+      X: source=0x01000010, min=-1.000, max=1.000, flat=0.118, fuzz=0.000
+      Y: source=0x01000010, min=-1.000, max=1.000, flat=0.118, fuzz=0.000
+      Z: source=0x01000010, min=-1.000, max=1.000, flat=0.118, fuzz=0.000
+      RZ: source=0x01000010, min=-1.000, max=1.000, flat=0.118, fuzz=0.000
+      HAT_X: source=0x01000010, min=-1.000, max=1.000, flat=0.000, fuzz=0.000
+      HAT_Y: source=0x01000010, min=-1.000, max=1.000, flat=0.000, fuzz=0.000
+    Keyboard Input Mapper:
+      Parameters:
+        AssociatedDisplayId: -1
+        OrientationAware: false
+      KeyboardType: 1
+      Orientation: 0
+      KeyDowns: 0 keys currently down
+      MetaState: 0x0
+      DownTime: 675270841000
+    Joystick Input Mapper:
+      Axes:
+        X: min=-1.00000, max=1.00000, flat=0.11765, fuzz=0.00000
+          scale=0.00784, offset=-1.00000, highScale=0.00784, highOffset=-1.00000
+          rawAxis=0, rawMin=0, rawMax=255, rawFlat=15, rawFuzz=0, rawResolution=0
+        Y: min=-1.00000, max=1.00000, flat=0.11765, fuzz=0.00000
+          scale=0.00784, offset=-1.00000, highScale=0.00784, highOffset=-1.00000
+          rawAxis=1, rawMin=0, rawMax=255, rawFlat=15, rawFuzz=0, rawResolution=0
+        Z: min=-1.00000, max=1.00000, flat=0.11765, fuzz=0.00000
+          scale=0.00784, offset=-1.00000, highScale=0.00784, highOffset=-1.00000
+          rawAxis=2, rawMin=0, rawMax=255, rawFlat=15, rawFuzz=0, rawResolution=0
+        RZ: min=-1.00000, max=1.00000, flat=0.11765, fuzz=0.00000
+          scale=0.00784, offset=-1.00000, highScale=0.00784, highOffset=-1.00000
+          rawAxis=5, rawMin=0, rawMax=255, rawFlat=15, rawFuzz=0, rawResolution=0
+        HAT_X: min=-1.00000, max=1.00000, flat=0.00000, fuzz=0.00000
+          scale=1.00000, offset=0.00000, highScale=1.00000, highOffset=0.00000
+          rawAxis=16, rawMin=-1, rawMax=1, rawFlat=0, rawFuzz=0, rawResolution=0
+        HAT_Y: min=-1.00000, max=1.00000, flat=0.00000, fuzz=0.00000
+          scale=1.00000, offset=0.00000, highScale=1.00000, highOffset=0.00000
+          rawAxis=17, rawMin=-1, rawMax=1, rawFlat=0, rawFuzz=0, rawResolution=0
+</code></pre>
+<p>At the end of the input reader dump there is some information about global configuration
+parameters such as the mouse pointer speed.</p>
+<pre><code>  Configuration:
+    ExcludedDeviceNames: []
+    VirtualKeyQuietTime: 0.0ms
+    PointerVelocityControlParameters: scale=1.000, lowThreshold=500.000, highThreshold=3000.000, acceleration=3.000
+    WheelVelocityControlParameters: scale=1.000, lowThreshold=15.000, highThreshold=50.000, acceleration=4.000
+    PointerGesture:
+      Enabled: true
+      QuietInterval: 100.0ms
+      DragMinSwitchSpeed: 50.0px/s
+      TapInterval: 150.0ms
+      TapDragInterval: 300.0ms
+      TapSlop: 20.0px
+      MultitouchSettleInterval: 100.0ms
+      MultitouchMinDistance: 15.0px
+      SwipeTransitionAngleCosine: 0.3
+      SwipeMaxWidthRatio: 0.2
+      MovementSpeedRatio: 0.8
+      ZoomSpeedRatio: 0.3
+</code></pre>
+<h4 id="things-to-look-for_1">Things To Look For</h4>
+<ol>
+<li>
+<p>All of the expected input devices are present.</p>
+</li>
+<li>
+<p>Each input device has been configured appropriately.  Especially check the
+    touch screen and joystick axes.</p>
+</li>
+</ol>
+<h3 id="input-dispatcher-state">Input Dispatcher State</h3>
+<p>The <code>InputDispatcher</code> is responsible for sending input events to applications.
+Its state dump shows information about which window is being touched, the
+state of the input queue, whether an ANR is in progress, and so on.</p>
+<pre><code>Input Dispatcher State:
+  DispatchEnabled: 1
+  DispatchFrozen: 0
+  FocusedApplication: name='AppWindowToken{41b03a10 token=Token{41bdcf78 ActivityRecord{418ab728 com.android.settings/.Settings}}}', dispatchingTimeout=5000.000ms
+  FocusedWindow: name='Window{41908458 Keyguard paused=false}'
+  TouchDown: false
+  TouchSplit: false
+  TouchDeviceId: -1
+  TouchSource: 0x00000000
+  TouchedWindows: &lt;none&gt;
+  Windows:
+    0: name='Window{41bd5b18 NavigationBar paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x05800068, type=0x000007e3, layer=181000, frame=[0,1184][720,1280], scale=1.000000, touchableRegion=[0,1184][720,1280], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+    1: name='Window{41a19770 RecentsPanel paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01820100, type=0x000007de, layer=151000, frame=[0,0][720,1184], scale=1.000000, touchableRegion=[0,0][720,1184], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+    2: name='Window{41a78768 StatusBar paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x00800048, type=0x000007d0, layer=141000, frame=[0,0][720,50], scale=1.000000, touchableRegion=[0,0][720,50], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+    3: name='Window{41877570 StatusBarExpanded paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x01811328, type=0x000007e1, layer=131005, frame=[0,-1184][720,-114], scale=1.000000, touchableRegion=[0,-1184][720,-114], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+    4: name='Window{41bedf20 TrackingView paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01020300, type=0x000007e1, layer=131000, frame=[0,-1032][720,102], scale=1.000000, touchableRegion=[0,-1032][720,102], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+    5: name='Window{41908458 Keyguard paused=false}', paused=false, hasFocus=true, hasWallpaper=false, visible=true, canReceiveKeys=true, flags=0x15120800, type=0x000007d4, layer=111000, frame=[0,50][720,1184], scale=1.000000, touchableRegion=[0,50][720,1184], inputFeatures=0x00000000, ownerPid=205, ownerUid=1000, dispatchingTimeout=5000.000ms
+    6: name='Window{4192cc30 com.android.phasebeam.PhaseBeamWallpaper paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x00000308, type=0x000007dd, layer=21010, frame=[0,0][720,1184], scale=1.000000, touchableRegion=[0,0][720,1184], inputFeatures=0x00000000, ownerPid=429, ownerUid=10046, dispatchingTimeout=5000.000ms
+    7: name='Window{41866c00 com.android.settings/com.android.settings.Settings paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01810100, type=0x00000001, layer=21005, frame=[0,0][720,1184], scale=1.000000, touchableRegion=[0,0][720,1184], inputFeatures=0x00000000, ownerPid=19000, ownerUid=1000, dispatchingTimeout=5000.000ms
+    8: name='Window{4197c858 com.android.launcher/com.android.launcher2.Launcher paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01910100, type=0x00000001, layer=21000, frame=[0,0][720,1184], scale=1.000000, touchableRegion=[0,0][720,1184], inputFeatures=0x00000000, ownerPid=515, ownerUid=10032, dispatchingTimeout=5000.000ms
+  MonitoringChannels: &lt;none&gt;
+  InboundQueue: length=0
+  ActiveConnections: &lt;none&gt;
+  AppSwitch: not pending
+  Configuration:
+    MaxEventsPerSecond: 90
+    KeyRepeatDelay: 50.0ms
+    KeyRepeatTimeout: 500.0ms
+</code></pre>
+<h4 id="things-to-look-for_2">Things To Look For</h4>
+<ol>
+<li>
+<p>In general, all input events are being processed as expected.</p>
+</li>
+<li>
+<p>If you touch the touch screen and run dumpsys at the same time, then the <code>TouchedWindows</code>
+    line should show the window that you are touching.</p>
+</li>
+</ol>
+
diff --git a/src/devices/tech/input/getevent.jd b/src/devices/tech/input/getevent.jd
new file mode 100644
index 0000000..19499d1
--- /dev/null
+++ b/src/devices/tech/input/getevent.jd
@@ -0,0 +1,103 @@
+page.title=Getevent
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>The <code>getevent</code> tool runs on the device and provides information about input
+devices and a live dump of kernel input events.</p>
+<p>It is very useful tool for ensuring that device drivers are reporing the
+expected set of capabilities for each input device and are generating the
+desired stream of input events.</p>
+<h2 id="usage">Usage</h2>
+<h3 id="showing-device-capabilities">Showing Device Capabilities</h3>
+<p>It is often quite useful to see all of the keys and axes that a device reports.
+Use the <code>-p</code> option to do that.</p>
+<p>Here is a list of all of the Linux key codes and other events that a
+particular keyboard says it supports.</p>
+<pre><code>$ adb shell su -- getevent -p
+
+  name:     "Motorola Bluetooth Wireless Keyboard"
+  events:
+    KEY (0001): 0001  0002  0003  0004  0005  0006  0007  0008 
+                0009  000a  000b  000c  000d  000e  000f  0010 
+                0011  0012  0013  0014  0015  0016  0017  0018 
+                0019  001a  001b  001c  001d  001e  001f  0020 
+                0021  0022  0023  0024  0025  0026  0027  0028 
+                0029  002a  002b  002c  002d  002e  002f  0030 
+                0031  0032  0033  0034  0035  0036  0037  0038 
+                0039  003a  003b  003c  003d  003e  003f  0040 
+                0041  0042  0043  0044  0045  0046  0047  0048 
+                0049  004a  004b  004c  004d  004e  004f  0050 
+                0051  0052  0053  0055  0056  0057  0058  0059 
+                005a  005b  005c  005d  005e  005f  0060  0061 
+                0062  0063  0064  0066  0067  0068  0069  006a 
+                006b  006c  006d  006e  006f  0071  0072  0073 
+                0074  0075  0077  0079  007a  007b  007c  007d 
+                007e  007f  0080  0081  0082  0083  0084  0085 
+                0086  0087  0088  0089  008a  008c  008e  0090 
+                0096  0098  009b  009c  009e  009f  00a1  00a3 
+                00a4  00a5  00a6  00ab  00ac  00ad  00b0  00b1 
+                00b2  00b3  00b4  00b7  00b8  00b9  00ba  00bb 
+                00bc  00bd  00be  00bf  00c0  00c1  00c2  00d9 
+                00f0  0110  0111  0112  01ba 
+    REL (0002): 0000  0001  0008 
+    ABS (0003): 0028  : value 223, min 0, max 255, fuzz 0, flat 0, resolution 0
+                0029  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+                002a  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+                002b  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+    MSC (0004): 0004 
+    LED (0011): 0000  0001  0002  0003  0004 
+  input props:
+    &lt;none&gt;
+</code></pre>
+<p>The <code>-i</code> option shows even more information than <code>-p</code>, including HID mapping tables
+and debugging information.</p>
+<p>The <code>-l</code> option uses textual labels for all event codes, which is handy.</p>
+<pre><code>$ adb shell su -- getevent -lp /dev/input/event1
+
+  name:     "Melfas MMSxxx Touchscreen"
+  events:
+    ABS (0003): ABS_MT_SLOT           : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
+                ABS_MT_TOUCH_MAJOR    : value 0, min 0, max 30, fuzz 0, flat 0, resolution 0
+                ABS_MT_POSITION_X     : value 0, min 0, max 720, fuzz 0, flat 0, resolution 0
+                ABS_MT_POSITION_Y     : value 0, min 0, max 1280, fuzz 0, flat 0, resolution 0
+                ABS_MT_TRACKING_ID    : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
+                ABS_MT_PRESSURE       : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+  input props:
+    INPUT_PROP_DIRECT
+</code></pre>
+<h3 id="showing-live-events">Showing Live Events</h3>
+<p>This is what a two finger multitouch gesture looks like for a touch screen
+that is using the Linux multitouch input protocol "B".  We use the <code>-l</code> option
+to show textual labels and <code>-t</code> to show timestamps.</p>
+<pre><code>$ adb shell su -- getevent -lt /dev/input/event1
+
+[   78826.389007] EV_ABS       ABS_MT_TRACKING_ID   0000001f
+[   78826.389038] EV_ABS       ABS_MT_PRESSURE      000000ab
+[   78826.389038] EV_ABS       ABS_MT_POSITION_X    000000ab
+[   78826.389068] EV_ABS       ABS_MT_POSITION_Y    0000025b
+[   78826.389068] EV_ABS       ABS_MT_SLOT          00000001
+[   78826.389068] EV_ABS       ABS_MT_TRACKING_ID   00000020
+[   78826.389068] EV_ABS       ABS_MT_PRESSURE      000000b9
+[   78826.389099] EV_ABS       ABS_MT_POSITION_X    0000019e
+[   78826.389099] EV_ABS       ABS_MT_POSITION_Y    00000361
+[   78826.389099] EV_SYN       SYN_REPORT           00000000
+[   78826.468688] EV_ABS       ABS_MT_SLOT          00000000
+[   78826.468688] EV_ABS       ABS_MT_TRACKING_ID   ffffffff
+[   78826.468719] EV_ABS       ABS_MT_SLOT          00000001
+[   78826.468719] EV_ABS       ABS_MT_TRACKING_ID   ffffffff
+[   78826.468719] EV_SYN       SYN_REPORT           00000000
+</code></pre>
diff --git a/src/devices/tech/input/index.jd b/src/devices/tech/input/index.jd
new file mode 100644
index 0000000..80cc997
--- /dev/null
+++ b/src/devices/tech/input/index.jd
@@ -0,0 +1,22 @@
+page.title=Input Technical Information
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>The Android input subsystem supports many different device classes,
+including keyboard, joystick, trackball, mouse and touch screen.</p>
+<p>The documentation in this section describes how to configure,
+calibrate, test, and write drivers for input devices.</p>
\ No newline at end of file
diff --git a/src/devices/tech/input/input-device-configuration-files.jd b/src/devices/tech/input/input-device-configuration-files.jd
new file mode 100644
index 0000000..e5629c3
--- /dev/null
+++ b/src/devices/tech/input/input-device-configuration-files.jd
@@ -0,0 +1,127 @@
+page.title=Input Device Configuration Files
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>Input device configuration files (<code>.idc</code> files) contain device-specific
+configuration properties that affect the behavior of input devices.</p>
+<p>Input device configuration files are typically not necessary for standard
+peripherals such as HID keyboards and mice since the default system behavior
+usually ensures that they will work out of the box.  On the other hand,
+built-in embedded devices, particularly touch screens, almost always
+require input device configuration files to specify their behavior.</p>
+<h2 id="rationale">Rationale</h2>
+<p>Android automatically detects and configures most input device capabilities
+based on the event types and properties that are reported by the associated
+Linux kernel input device driver.</p>
+<p>For example, if an input device supports the <code>EV_REL</code> event type and codes
+<code>REL_X</code> and <code>REL_Y</code> as well as the <code>EV_KEY</code> event type and <code>BTN_MOUSE</code>,
+then Android will classify the input device as a mouse.  The default behavior
+for a mouse is to present an on-screen cursor which tracks the mouse's movements
+and simulates touches when the mouse is clicked.  Although the mouse can
+be configured differently, the default behavior is usually sufficient for
+standard mouse peripherals.</p>
+<p>Certain classes of input devices are more ambiguous.  For example, multi-touch
+touch screens and touch pads both support the <code>EV_ABS</code> event type and codes
+<code>ABS_MT_POSITION_X</code> and <code>ABS_MT_POSITION_Y</code> at a minimum.  However, the intended
+uses of these devices are quite different and cannot always be determined
+automatically.  Also, additional information is required to make sense of the
+pressure and size information reported by touch devices.  Hence touch devices,
+especially built-in touch screens, usually need IDC files.</p>
+<h2 id="location">Location</h2>
+<p>Input device configuration files are located by USB vendor, product (and
+optionally version) id or by input device name.</p>
+<p>The following paths are consulted in order.</p>
+<ul>
+<li><code>/system/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc</code></li>
+<li><code>/system/usr/idc/Vendor_XXXX_Product_XXXX.idc</code></li>
+<li><code>/system/usr/idc/DEVICE_NAME.idc</code></li>
+<li><code>/data/system/devices/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc</code></li>
+<li><code>/data/system/devices/idc/Vendor_XXXX_Product_XXXX.idc</code></li>
+<li><code>/data/system/devices/idc/DEVICE_NAME.idc</code></li>
+</ul>
+<p>When constructing a file path that contains the device name, all characters
+in the device name other than '0'-'9', 'a'-'z', 'A'-'Z', '-' or '_' are replaced by '_'.</p>
+<h2 id="syntax">Syntax</h2>
+<p>An input device configuration file is a plain text file consisting of property
+assignments and comments.</p>
+<h3 id="properties">Properties</h3>
+<p>Property assignments each consist of a property name, an <code>=</code>, a property value,
+and a new line.  Like this:</p>
+<pre><code>property = value
+</code></pre>
+<p>Property names are non-empty literal text identifiers.  They must not contain
+whitespace.  Each components of the input system defines a set of properties
+that are used to configure its function.</p>
+<p>Property values are non-empty string literals, integers or floating point numbers.
+They must not contain whitespace or the reserved characters <code>\</code> or <code>"</code>.</p>
+<p>Property names and values are case-sensitive.</p>
+<h3 id="comments">Comments</h3>
+<p>Comment lines begin with '#' and continue to the end of the line.  Like this:</p>
+<pre><code># A comment!
+</code></pre>
+<p>Blank lines are ignored.</p>
+<h3 id="example">Example</h3>
+<pre><code># This is an example of an input device configuration file.
+# It might be used to describe the characteristics of a built-in touch screen.
+
+# This is an internal device, not an external peripheral attached to the USB
+# or Bluetooth bus.
+device.internal = 1
+
+# The device should behave as a touch screen, which uses the same orientation
+# as the built-in display.
+touch.deviceType = touchScreen
+touch.orientationAware = 1
+
+# Additional calibration properties...
+# etc...
+</code></pre>
+<h2 id="common-properties">Common Properties</h2>
+<p>The following properties are common to all input device classes.</p>
+<p>Refer to the documentation of each input device class for information about the
+special properties used by each class.</p>
+<h4 id="deviceinternal"><code>device.internal</code></h4>
+<p><em>Definition:</em> <code>device.internal</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the input device is an internal built-in component as opposed to an
+externally attached (most likely removable) peripheral.</p>
+<ul>
+<li>
+<p>If the value is <code>0</code>, the device is external.</p>
+</li>
+<li>
+<p>If the value is <code>1</code>, the device is internal.</p>
+</li>
+<li>
+<p>If the value is not specified, the default value is <code>0</code> for all devices on the
+    USB (BUS_USB) or Bluetooth (BUS_BLUETOOTH) bus, <code>1</code> otherwise.</p>
+</li>
+</ul>
+<p>This property determines default policy decisions regarding wake events.</p>
+<p>Internal input devices generally do not wake the display from sleep unless explicitly
+configured to do so in the key layout file or in a hardcoded policy rule.  This
+distinction prevents key presses and touches from spuriously waking up your phone
+when it is in your pocket.  Usually there are only a small handful of wake keys defined.</p>
+<p>Conversely, external input devices usually wake the device more aggressively because
+they are assumed to be turned off or not plugged in during transport.  For example,
+pressing any key on an external keyboard is a good indicator that the user wants the
+device to wake up and respond.</p>
+<p>It is important to ensure that the value of the <code>device.internal</code> property is set
+correctly for all internal input devices.</p>
+<h2 id="validation">Validation</h2>
+<p>Make sure to validate your input device configuration files using the
+<a href="/tech/input/validate-keymaps.html">Validate Keymaps</a> tool.</p>
+
diff --git a/src/devices/tech/input/key-character-map-files.jd b/src/devices/tech/input/key-character-map-files.jd
new file mode 100644
index 0000000..7b1ac5b
--- /dev/null
+++ b/src/devices/tech/input/key-character-map-files.jd
@@ -0,0 +1,425 @@
+page.title=Key Character Map Files
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>Key character map files (<code>.kcm</code> files) are responsible for mapping combinations
+of Android key codes with modifiers to Unicode characters.</p>
+<p>Device-specific key layout files are <em>required</em> for all internal (built-in)
+input devices that have keys, if only to tell the system that the device
+is special purpose only (not a full keyboard).</p>
+<p>Device-specific key layout files are <em>optional</em> for external keyboards, and
+often aren't needed at all.  The system provides a generic key character map
+that is suitable for many external keyboards.</p>
+<p>If no device-specific key layout file is available, then the system will
+choose a default instead.</p>
+<h2 id="location">Location</h2>
+<p>Key character map files are located by USB vendor, product (and optionally version)
+id or by input device name.</p>
+<p>The following paths are consulted in order.</p>
+<ul>
+<li><code>/system/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm</code></li>
+<li><code>/system/usr/keychars/Vendor_XXXX_Product_XXXX.kcm</code></li>
+<li><code>/system/usr/keychars/DEVICE_NAME.kcm</code></li>
+<li><code>/data/system/devices/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm</code></li>
+<li><code>/data/system/devices/keychars/Vendor_XXXX_Product_XXXX.kcm</code></li>
+<li><code>/data/system/devices/keychars/DEVICE_NAME.kcm</code></li>
+<li><code>/system/usr/keychars/Generic.kcm</code></li>
+<li><code>/data/system/devices/keychars/Generic.kcm</code></li>
+<li><code>/system/usr/keychars/Virtual.kcm</code></li>
+<li><code>/data/system/devices/keychars/Virtual.kcm</code></li>
+</ul>
+<p>When constructing a file path that contains the device name, all characters
+in the device name other than '0'-'9', 'a'-'z', 'A'-'Z', '-' or '<em>' are replaced by '</em>'.</p>
+<h2 id="generic-key-character-map-file">Generic Key Character Map File</h2>
+<p>The system provides a special built-in key character map file called <code>Generic.kcm</code>.
+This key character map is intended to support a variety of standard external
+keyboards.</p>
+<p><em>Do not modify the generic key character map!</em></p>
+<h2 id="virtual-key-character-map-file">Virtual Key Character Map File</h2>
+<p>The system provides a special built-in key character map file called <code>Virtual.kcm</code>
+that is used by the virtual keyboard devices.</p>
+<p>The virtual keyboard device is a synthetic input device whose id is -1
+(see <code>KeyCharacterMap.VIRTUAL_KEYBOARD</code>).  It is present on all Android devices
+beginning with Android Honeycomb 3.0.  The purpose of the virtual keyboard device
+is to provide a known built-in input device that can be used for injecting
+keystokes into applications by the IME or by test instrumentation, even
+for devices that do not have built-in keyboards.</p>
+<p>The virtual keyboard is assumed to have a full QWERTY layout that is the
+same on all devices.  This makes it possible for applications to inject
+keystrokes using the virtual keyboard device and always get the same results.</p>
+<p><em>Do not modify the virtual key character map!</em></p>
+<h2 id="syntax">Syntax</h2>
+<p>A key character map file is a plain text file consisting of a keyboard type
+declaration and a set of key declarations.</p>
+<h3 id="keyboard-type-declaration">Keyboard Type Declaration</h3>
+<p>A keyboard type declaration describes the overall behavior of the keyboard.
+A character map file must contain a keyboard type declaration.  For clarity,
+it is often placed at the top of the file.</p>
+<pre><code>type FULL
+</code></pre>
+<p>The following keyboard types are recognized:</p>
+<ul>
+<li>
+<p><code>NUMERIC</code>: A numeric (12-key) keyboard.</p>
+<p>A numeric keyboard supports text entry using a multi-tap approach.
+It may be necessary to tap a key multiple times to generate the desired letter or symbol.</p>
+<p>This type of keyboard is generally designed for thumb typing.</p>
+<p>Corresponds to <code>KeyCharacterMap.NUMERIC</code>.</p>
+</li>
+<li>
+<p><code>PREDICTIVE</code>: A keyboard with all the letters, but with more than one letter per key.</p>
+<p>This type of keyboard is generally designed for thumb typing.</p>
+<p>Corresponds to <code>KeyCharacterMap.PREDICTIVE</code>.</p>
+</li>
+<li>
+<p><code>ALPHA</code>: A keyboard with all the letters, and maybe some numbers.</p>
+<p>An alphabetic keyboard supports text entry directly but may have a condensed
+layout with a small form factor.  In contrast to a <code>FULL</code> keyboard, some
+symbols may only be accessible using special on-screen character pickers.
+In addition, to improve typing speed and accuracy, the framework provides
+special affordances for alphabetic keyboards such as auto-capitalization
+and toggled / locked SHIFT and ALT keys.</p>
+<p>This type of keyboard is generally designed for thumb typing.</p>
+</li>
+<li>
+<p><code>FULL</code>: A full PC-style keyboard.</p>
+<p>A full keyboard behaves like a PC keyboard.  All symbols are accessed directly
+by pressing keys on the keyboard without on-screen support or affordances such
+as auto-capitalization.</p>
+<p>This type of keyboard is generally designed for full two hand typing.</p>
+</li>
+<li>
+<p><code>SPECIAL_FUNCTION</code>: A keyboard that is only used to perform system control functions
+    rather than for typing.</p>
+<p>A special function keyboard consists only of non-printing keys such as
+HOME and POWER that are not actually used for typing.</p>
+</li>
+</ul>
+<p>The <code>Generic.kcm</code> and <code>Virtual.kcm</code> key character maps are both <code>FULL</code> keyboards.</p>
+<h3 id="key-declarations">Key Declarations</h3>
+<p>Key declarations each consist of the keyword <code>key</code> followed by an Android key code
+name, an open curly brace, a set of properties and behaviors and a close curly brace.</p>
+<pre><code>key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+    ctrl, alt, meta:                    none
+}
+</code></pre>
+<h4 id="properties">Properties</h4>
+<p>Each key property establishes a mapping from a key to a behavior.  To make the
+key character map files more compact, several properties can be mapped to the
+same behavior by separating them with a comma.</p>
+<p>In the above example, the <code>label</code> property is assigned the <code>'A'</code> behavior.
+Likewise, the <code>ctrl</code>, <code>alt</code> and <code>meta</code> properties are all simultaneously assigned
+the <code>none</code> behavior.</p>
+<p>The following properties are recognized:</p>
+<ul>
+<li>
+<p><code>label</code>: Specifies the label that is physically printed on the key, when it
+    consists of a single character.  This is the value that is returned by
+    the <code>KeyCharacterMap.getDisplayLabel</code> method.</p>
+</li>
+<li>
+<p><code>number</code>: Specifies the behavior (character that should be typed) when a numeric
+    text view has focus, such as when the user is typing a phone number.</p>
+<p>Compact keyboards often combine multiple symbols into a single key, such that
+the same key might be used to type <code>'1'</code> and <code>'a'</code> or <code>'#'</code> and <code>'q'</code>, perhaps.
+For these keys, the <code>number</code> property should be set to indicate which symbol
+should be typed in a numeric context, if any.</p>
+<p>Some typical "numeric" symbols are digits <code>'0'</code> through <code>'9'</code>, <code>'#'</code>, <code>'+'</code>,
+<code>'('</code>, <code>')'</code>, <code>','</code>, and <code>'.'</code>.</p>
+</li>
+<li>
+<p><code>base</code>: Specifies the behavior (character that should be typed) when no modifiers
+    are pressed.</p>
+</li>
+<li>
+<p>&lt;modifier&gt; or &lt;modifier1&gt;<code>+</code>&lt;modifier2&gt;<code>+</code>...: Specifies the
+    behavior (character that should be typed) when the key is pressed and all of the
+    specified modifiers are active.</p>
+<p>For example, the modifier property <code>shift</code> specifies a behavior that applies when
+the either the LEFT SHIFT or RIGHT SHIFT modifier is pressed.</p>
+<p>Similarly, the modifier property <code>rshift+ralt</code> specifies a behavior that applies
+when the both RIGHT SHIFT and RIGHT ALT modifiers are pressed together.</p>
+</li>
+</ul>
+<p>The following modifiers are recognized in modifier properties:</p>
+<ul>
+<li><code>shift</code>: Applies when either the LEFT SHIFT or RIGHT SHIFT modifier is pressed.</li>
+<li><code>lshift</code>: Applies when the LEFT SHIFT modifier is pressed.</li>
+<li><code>rshift</code>: Applies when the RIGHT SHIFT modifier is pressed.</li>
+<li><code>alt</code>: Applies when either the LEFT ALT or RIGHT ALT modifier is pressed.</li>
+<li><code>lalt</code>: Applies when the LEFT ALT modifier is pressed.</li>
+<li><code>ralt</code>: Applies when the RIGHT ALT modifier is pressed.</li>
+<li><code>ctrl</code>: Applies when either the LEFT CONTROL or RIGHT CONTROL modifier is pressed.</li>
+<li><code>lctrl</code>: Applies when the LEFT CONTROL modifier is pressed.</li>
+<li><code>rctrl</code>: Applies when the RIGHT CONTROL modifier is pressed.</li>
+<li><code>meta</code>: Applies when either the LEFT META or RIGHT META modifier is pressed.</li>
+<li><code>lmeta</code>: Applies when the LEFT META modifier is pressed.</li>
+<li><code>rmeta</code>: Applies when the RIGHT META modifier is pressed.</li>
+<li><code>sym</code>: Applies when the SYMBOL modifier is pressed.</li>
+<li><code>fn</code>: Applies when the FUNCTION modifier is pressed.</li>
+<li><code>capslock</code>: Applies when the CAPS LOCK modifier is locked.</li>
+<li><code>numlock</code>: Applies when the NUM LOCK modifier is locked.</li>
+<li><code>scrolllock</code>: Applies when the SCROLL LOCK modifier is locked.</li>
+</ul>
+<p>The order in which the properties are listed is significant.  When mapping a key to
+a behavior, the system scans all relevant properties in order and returns the last
+applicable behavior that it found.</p>
+<p>Consequently, properties that are specified later override properties that are
+specified earlier for a given key.</p>
+<h4 id="behaviors">Behaviors</h4>
+<p>Each property maps to a behavior.  The most common behavior is typing a character
+but there are others.</p>
+<p>The following behaviors are recognized:</p>
+<ul>
+<li>
+<p><code>none</code>: Don't type a character.</p>
+<p>This behavior is the default when no character is specified.  Specifying <code>none</code>
+is optional but it improves clarity.</p>
+</li>
+<li>
+<p><code>'X'</code>: Type the specified character literal.</p>
+<p>This behavior causes the specified character to be entered into the focused
+text view.  The character literal may be any ASCII character, or one of the
+following escape sequences:</p>
+<ul>
+<li><code>'\\'</code>: Type a backslash character.</li>
+<li><code>'\n'</code>: Type a new line character (use this for ENTER / RETURN).</li>
+<li><code>'\t'</code>: Type a TAB character.</li>
+<li><code>'\''</code>: Type an apostrophe character.</li>
+<li><code>'\"'</code>: Type a quote character.</li>
+<li><code>'\uXXXX'</code>: Type the Unicode character whose code point is given in hex by XXXX.</li>
+</ul>
+</li>
+<li>
+<p><code>fallback</code> &lt;Android key code name&gt;: Perform a default action if the key is not
+    handled by the application.</p>
+<p>This behavior causes the system to simulate a different key press when an application
+does not handle the specified key natively.  It is used to support default behavior
+for new keys that not all applications know how to handle, such as ESCAPE or
+numeric keypad keys (when numlock is not pressed).</p>
+<p>When a fallback behavior is performed, the application will receive two key presses:
+one for the original key and another for the fallback key that was selected.
+If the application handles the original key during key up, then the fallback key
+event will be canceled (<code>KeyEvent.isCanceled</code> will return <code>true</code>).</p>
+</li>
+</ul>
+<p>The system reserves two Unicode characters to perform special functions:</p>
+<ul>
+<li>
+<p><code>'\uef00'</code>: When this behavior is performed, the text view consumes and removes the
+    four characters preceding the cursor, interprets them as hex digits, and inserts the
+    corresponding Unicode code point.</p>
+</li>
+<li>
+<p><code>'\uef01'</code>: When this behavior is performed, the text view displays a
+    character picker dialog that contains miscellaneous symbols.</p>
+</li>
+</ul>
+<p>The system recognizes the following Unicode characters as combining diacritical dead
+key characters:</p>
+<ul>
+<li><code>'\u0300'</code>: Grave accent.</li>
+<li><code>'\u0301'</code>: Acute accent.</li>
+<li><code>'\u0302'</code>: Circumflex accent.</li>
+<li><code>'\u0303'</code>: Tilde accent.</li>
+<li><code>'\u0308'</code>: Umlaut accent.</li>
+</ul>
+<p>When a dead key is typed followed by another character, the dead key and the following
+characters are composed.  For example, when the user types a grave accent dead
+key followed by the letter 'a', the result is '&agrave;'.</p>
+<p>Refer to <code>KeyCharacterMap.getDeadChar</code> for more information about dead key handling.</p>
+<h3 id="comments">Comments</h3>
+<p>Comment lines begin with '#' and continue to the end of the line.  Like this:</p>
+<pre><code># A comment!
+</code></pre>
+<p>Blank lines are ignored.</p>
+<h3 id="how-key-combinations-are-mapped-to-behaviors">How Key Combinations are Mapped to Behaviors</h3>
+<p>When the user presses a key, the system looks up the behavior associated with
+the combination of that key press and the currently pressed modifiers.</p>
+<h4 id="shift-a">SHIFT + A</h4>
+<p>Suppose the user pressed A and SHIFT together.  The system first locates
+the set of properties and behaviors associated with <code>KEYCODE_A</code>.</p>
+<pre><code>key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+    ctrl, alt, meta:                    none
+}
+</code></pre>
+<p>The system scans the properties from first to last and left to right, ignoring
+the <code>label</code> and <code>number</code> properties, which are special.</p>
+<p>The first property encountered is <code>base</code>.  The <code>base</code> property always applies to
+a key, no matter what modifiers are pressed.  It essentially specifies the default
+behavior for the key unless it is overridden by following properties.
+Since the <code>base</code> property applies to this key press, the system makes note
+of the fact that its behavior is <code>'a'</code> (type the character <code>a</code>).</p>
+<p>The system then continues to scan subsequent properties in case any of them
+are more specific than <code>base</code> and override it.  It encounters <code>shift</code> which
+also applies to the key press SHIFT + A.  So the system decides to ignore
+the <code>base</code> property's behavior and chooses the behavior associated with
+the <code>shift</code> property, which is <code>'A'</code> (type the character <code>A</code>).</p>
+<p>It then continues to scan the table, however no other properties apply to this
+key press (CAPS LOCK is not locked, neither CONTROL key is pressed, neither
+ALT key is pressed and neither META key is pressed).</p>
+<p>So the resulting behavior for the key combination SHIFT + A is <code>'A'</code>.</p>
+<h4 id="control-a">CONTROL + A</h4>
+<p>Now consider what would happen if the user pressed A and CONTROL together.</p>
+<p>As before, the system would scan the table of properties.  It would notice
+that the <code>base</code> property applied but would also continue scanning until
+it eventually reached the <code>control</code> property.  As it happens, the <code>control</code>
+property appears after <code>base</code> so its behavior overrides the <code>base</code> behavior.</p>
+<p>So the resulting behavior for the key combination CONTROL + A is <code>none</code>.</p>
+<h4 id="escape">ESCAPE</h4>
+<p>Now suppose the user pressed ESCAPE.</p>
+<pre><code>key ESCAPE {
+    base:                               fallback BACK
+    alt, meta:                          fallback HOME
+    ctrl:                               fallback MENU
+}
+</code></pre>
+<p>This time the system obtains the behavior <code>fallback BACK</code>, a fallback behavior.
+Because no character literal appears, no character will be typed.</p>
+<p>When processing the key, the system will first deliver <code>KEYCODE_ESCAPE</code> to the
+application.  If the application does not handle it, then the system will try
+again but this time it will deliver <code>KEYCODE_BACK</code> to the application as
+requested by the fallback behavior.</p>
+<p>So applications that recognize and support <code>KEYCODE_ESCAPE</code> have the
+opportunity to handle it as is, but other applications that do not can instead
+perform the fallback action of treating the key as if it were <code>KEYCODE_BACK</code>.</p>
+<h4 id="numpad_0-with-or-without-num-lock">NUMPAD_0 with or without NUM LOCK</h4>
+<p>The numeric keypad keys have very different interpretations depending on whether
+the NUM LOCK key is locked.</p>
+<p>The following key declaration ensures that <code>KEYCODE_NUMPAD_0</code> types <code>0</code>
+when NUM LOCK is pressed.  When NUM LOCK is not pressed, the key is delivered
+to the application as usual, and if it is not handled, then the fallback
+key <code>KEYCODE_INSERT</code> is delivered instead.</p>
+<pre><code>key NUMPAD_0 {
+    label, number:                      '0'
+    base:                               fallback INSERT
+    numlock:                            '0'
+    ctrl, alt, meta:                    none
+}
+</code></pre>
+<p>As we can see, fallback key declarations greatly improve compatibility
+with older applications that do not recognize or directly support all of the keys
+that are present on a full PC style keyboard.</p>
+<h3 id="examples">Examples</h3>
+<h4 id="full-keyboard">Full Keyboard</h4>
+<pre><code># This is an example of part of a key character map file for a full keyboard
+# include a few fallback behaviors for special keys that few applications
+# handle themselves.
+
+type FULL
+
+key C {
+    label:                              'C'
+    base:                               'c'
+    shift, capslock:                    'C'
+    alt:                                '\u00e7'
+    shift+alt:                          '\u00c7'
+    ctrl, meta:                         none
+}
+
+key SPACE {
+    label:                              ' '
+    base:                               ' '
+    ctrl:                               none
+    alt, meta:                          fallback SEARCH
+}
+
+key NUMPAD_9 {
+    label, number:                      '9'
+    base:                               fallback PAGE_UP
+    numlock:                            '9'
+    ctrl, alt, meta:                    none
+}
+</code></pre>
+<h4 id="alphanumeric-keyboard">Alphanumeric Keyboard</h4>
+<pre><code># This is an example of part of a key character map file for an alphanumeric
+# thumb keyboard.  Some keys are combined, such as `A` and `2`.  Here we
+# specify `number` labels to tell the system what to do when the user is
+# typing a number into a dial pad.
+#
+# Also note the special character '\uef01' mapped to ALT+SPACE.
+# Pressing this combination of keys invokes an on-screen character picker.
+
+type ALPHA
+
+key A {
+    label:                              'A'
+    number:                             '2'
+    base:                               'a'
+    shift, capslock:                    'A'
+    alt:                                '#'
+    shift+alt, capslock+alt:            none
+}
+
+key SPACE {
+    label:                              ' '
+    number:                             ' '
+    base:                               ' '
+    shift:                              ' '
+    alt:                                '\uef01'
+    shift+alt:                          '\uef01'
+}
+</code></pre>
+<h4 id="game-pad">Game Pad</h4>
+<pre><code># This is an example of part of a key character map file for a game pad.
+# It defines fallback actions that enable the user to navigate the user interface
+# by pressing buttons.
+
+type SPECIAL_FUNCTION
+
+key BUTTON_A {
+    base:                               fallback BACK
+}
+
+key BUTTON_X {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_START {
+    base:                               fallback HOME
+}
+
+key BUTTON_SELECT {
+    base:                               fallback MENU
+}
+</code></pre>
+<h2 id="compatibility-note">Compatibility Note</h2>
+<p>Prior to Android Honeycomb 3.0, the Android key character map was specified
+using a very different syntax and was compiled into a binary file format
+(<code>.kcm.bin</code>) at build time.</p>
+<p>Although the new format uses the same extension <code>.kcm</code>, the syntax is quite
+different (and much more powerful).</p>
+<p>As of Android Honeycomb 3.0, all Android key character map files must use
+the new syntax and plain text file format that is described in this document.
+The old syntax is not supported and the old <code>.kcm.bin</code> files are not recognized
+by the system.</p>
+<h2 id="language-note">Language Note</h2>
+<p>Android does not currently support multilingual keyboards.  Moreover, the
+built-in generic key character map assumes a US English keyboard layout.</p>
+<p>OEMs are encouraged to provide custom key character maps for their keyboards
+if they are designed for other languages.</p>
+<p>Future versions of Android may provide better support for multilingual keyboards
+or user-selectable keyboard layouts.</p>
+<h2 id="validation">Validation</h2>
+<p>Make sure to validate your key character map files using the
+<a href="/tech/input/validate-keymaps.html">Validate Keymaps</a> tool.</p>
diff --git a/src/devices/tech/input/key-layout-files.jd b/src/devices/tech/input/key-layout-files.jd
new file mode 100644
index 0000000..d416341
--- /dev/null
+++ b/src/devices/tech/input/key-layout-files.jd
@@ -0,0 +1,277 @@
+page.title=Key Layout Files
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>Key layout files (<code>.kl</code> files) are responsible for mapping Linux key codes
+and axis codes to Android key codes and axis codes and specifying associated
+policy flags.</p>
+<p>Device-specific key layout files are <em>required</em> for all internal (built-in)
+input devices that have keys, including special keys such as volume, power
+and headset media keys.</p>
+<p>Device-specific key layout files are <em>optional</em> for other input devices but
+they are <em>recommended</em> for special-purpose keyboards and joysticks.</p>
+<p>If no device-specific key layout file is available, then the system will
+choose a default instead.</p>
+<h2 id="location">Location</h2>
+<p>Key layout files are located by USB vendor, product (and optionally version)
+id or by input device name.</p>
+<p>The following paths are consulted in order.</p>
+<ul>
+<li><code>/system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl</code></li>
+<li><code>/system/usr/keylayout/Vendor_XXXX_Product_XXXX.kl</code></li>
+<li><code>/system/usr/keylayout/DEVICE_NAME.kl</code></li>
+<li><code>/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl</code></li>
+<li><code>/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX.kl</code></li>
+<li><code>/data/system/devices/keylayout/DEVICE_NAME.kl</code></li>
+<li><code>/system/usr/keylayout/Generic.kl</code></li>
+<li><code>/data/system/devices/keylayout/Generic.kl</code></li>
+</ul>
+<p>When constructing a file path that contains the device name, all characters
+in the device name other than '0'-'9', 'a'-'z', 'A'-'Z', '-' or '<em>' are replaced by '</em>'.</p>
+<h2 id="generic-key-layout-file">Generic Key Layout File</h2>
+<p>The system provides a special built-in generic key layout file called <code>Generic.kl</code>.
+This key layout is intended to support a variety of standard external
+keyboards and joysticks.</p>
+<p><em>Do not modify the generic key layout!</em></p>
+<h2 id="syntax">Syntax</h2>
+<p>A key layout file is a plain text file consisting of key or axis declarations
+and flags.</p>
+<h3 id="key-declarations">Key Declarations</h3>
+<p>Key declarations each consist of the keyword <code>key</code> followed by a Linux key code
+number, an Android key code name, and optional set of whitespace delimited policy flags.</p>
+<pre><code>key 1     ESCAPE
+key 114   VOLUME_DOWN       WAKE
+key 16    Q                 VIRTUAL     WAKE
+</code></pre>
+<p>The following policy flags are recognized:</p>
+<ul>
+<li><code>WAKE</code>: The key should wake the device when it is asleep.  For historical reasons,
+    this flag behaves in the same manner as <code>WAKE_DROPPED</code> below.</li>
+<li><code>WAKE_DROPPED</code>: The key should wake the device when it is asleep but the key itself
+    should be dropped when the wake-up occurs.  In a sense, the key's action was to
+    wake the device, but the key itself is not processed.</li>
+<li><code>SHIFT</code>: The key should be interpreted as if the SHIFT key were also pressed.</li>
+<li><code>CAPS_LOCK</code>: The key should be interpreted as if the CAPS LOCK key were also pressed.</li>
+<li><code>ALT</code>: The key should be interpreted as if the ALT key were also pressed.</li>
+<li><code>ALT_GR</code>: The key should be interpreted as if the RIGHT ALT key were also pressed.</li>
+<li><code>FUNCTION</code>: The key should be interpreted as if the FUNCTION key were also pressed.</li>
+<li><code>VIRTUAL</code>: The key is a virtual soft key (capacitive button) that is adjacent to
+    the main touch screen.  This causes special debouncing logic to be enabled, see below.</li>
+<li><code>MENU</code>: Deprecated.  Do not use.</li>
+<li><code>LAUNCHER</code>: Deprecated.  Do not use.</li>
+</ul>
+<h3 id="axis-declarations">Axis Declarations</h3>
+<p>Axis declarations each consist of the keyword <code>axis</code> followed by a Linux axis code
+number, and qualifiers that control the behavior of the axis including at least
+one Android axis code name.</p>
+<h4 id="basic-axes">Basic Axes</h4>
+<p>A basic axis simply maps a Linux axis code to an Android axis code name.</p>
+<p>The following declaration maps <code>ABS_X</code> (indicated by <code>0x00</code>) to <code>AXIS_X</code> (indicated by <code>X</code>).</p>
+<pre><code>axis 0x00 X
+</code></pre>
+<p>In the above example, if the value of <code>ABS_X</code> is <code>5</code> then <code>AXIS_X</code> will be set to <code>5</code>.</p>
+<h4 id="split-axes">Split Axes</h4>
+<p>A split axis maps a Linux axis code to two Android axis code names, such that
+values less than or greater than a threshold are split across two different axes when
+mapped.  This mapping is useful when a single physical axis reported by the device
+encodes two different mutually exclusive logical axes.</p>
+<p>The following declaration maps values of the <code>ABS_Y</code> axis (indicated by <code>0x01</code>) to
+<code>AXIS_GAS</code> when less than <code>0x7f</code> or to <code>AXIS_BRAKE</code> when greater than <code>0x7f</code>.</p>
+<pre><code>axis 0x01 split 0x7f GAS BRAKE
+</code></pre>
+<p>In the above example, if the value of <code>ABS_Y</code> is <code>0x7d</code> then <code>AXIS_GAS</code> is set
+to <code>2</code> (<code>0x7f - 0x7d</code>) and <code>AXIS_BRAKE</code> is set to <code>0</code>.  Conversely, if the value of
+<code>ABS_Y</code> is <code>0x83</code> then <code>AXIS_GAS</code> is set to <code>0</code> and <code>AXIS_BRAKE</code> is set to <code>4</code>
+(<code>0x83 - 0x7f</code>).  Finally, if the value of <code>ABS_Y</code> equals the split value of <code>0x7f</code>
+then both <code>AXIS_GAS</code> and <code>AXIS_BRAKE</code> are set to <code>0</code>.</p>
+<h4 id="inverted-axes">Inverted Axes</h4>
+<p>An inverted axis inverts the sign of the axis value.</p>
+<p>The following declaration maps <code>ABS_RZ</code> (indicated by <code>0x05</code>) to <code>AXIS_BRAKE</code>
+(indicated by <code>BRAKE</code>), and inverts the output by negating it.</p>
+<pre><code>axis 0x05 invert AXIS_RZ
+</code></pre>
+<p>In the above example, if the value of <code>ABS_RZ</code> is <code>2</code> then <code>AXIS_RZ</code> is set to <code>-2</code>.</p>
+<h4 id="center-flat-position-option">Center Flat Position Option</h4>
+<p>The Linux input protocol provides a way for input device drivers to specify the
+center flat position of joystick axes but not all of them do and some of them
+provide incorrect values.</p>
+<p>The center flat position is the neutral position of the axis, such as when
+a directional pad is in the very middle of its range and the user is not
+touching it.</p>
+<p>To resolve this issue, an axis declaration may be followed by a <code>flat</code>
+option that specifies the value of the center flat position for the axis.</p>
+<pre><code>axis 0x03 Z flat 4096
+</code></pre>
+<p>In the above example, the center flat position is set to <code>4096</code>.</p>
+<h3 id="comments">Comments</h3>
+<p>Comment lines begin with '#' and continue to the end of the line.  Like this:</p>
+<pre><code># A comment!
+</code></pre>
+<p>Blank lines are ignored.</p>
+<h3 id="examples">Examples</h3>
+<h4 id="keyboard">Keyboard</h4>
+<pre><code># This is an example of a key layout file for a keyboard.
+
+key 1     ESCAPE
+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 12    MINUS
+key 13    EQUALS
+key 14    DEL
+
+# etc...
+</code></pre>
+<h4 id="system-controls">System Controls</h4>
+<pre><code># This is an example of a key layout file for basic system controls, such as
+# volume and power keys which are typically implemented as GPIO pins that
+# the device decodes into key presses.
+
+key 114   VOLUME_DOWN       WAKE
+key 115   VOLUME_UP         WAKE
+key 116   POWER             WAKE
+</code></pre>
+<h4 id="capacitive-buttons">Capacitive Buttons</h4>
+<pre><code># This is an example of a key layout file for a touch device with capacitive buttons.
+
+key 139    MENU           VIRTUAL
+key 102    HOME           VIRTUAL
+key 158    BACK           VIRTUAL
+key 217    SEARCH         VIRTUAL
+</code></pre>
+<h4 id="headset-jack-media-controls">Headset Jack Media Controls</h4>
+<pre><code># This is an example of a key layout file for headset mounted media controls.
+# A typical headset jack interface might have special control wires or detect known
+# resistive loads as corresponding to media functions or volume controls.
+# This file assumes that the driver decodes these signals and reports media
+# controls as key presses.
+
+key 163   MEDIA_NEXT        WAKE
+key 165   MEDIA_PREVIOUS    WAKE
+key 226   HEADSETHOOK       WAKE
+</code></pre>
+<h4 id="joystick">Joystick</h4>
+<pre><code># This is an example of a key layout file for a joystick.
+
+# These are the buttons that the joystick supports, represented as keys.
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+key 314   BUTTON_SELECT
+key 315   BUTTON_START
+key 316   BUTTON_MODE
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Left and right stick.
+# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick actually
+# settles in a flat range of +/- 4096 or so.  We override it here.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x03 Z flat 4096
+axis 0x04 RZ flat 4096
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+</code></pre>
+<h2 id="wake-keys">Wake Keys</h2>
+<p>Wake keys are special keys that wake the device from sleep, such as the power key.</p>
+<p>By default, for internal keyboard devices, no key is a wake key.  For external
+keyboard device, all keys are wake keys.</p>
+<p>To make a key be a wake key, set the <code>WAKE_DROPPED</code> flag in the key layout file
+for the keyboard device.</p>
+<p>Note that the <code>WindowManagerPolicy</code> component is responsible for implementing wake
+key behavior.  Moreover, the key guard may prevent certain keys from functioning
+as wake keys.  A good place to start understanding wake key behavior is
+<code>PhoneWindowManager.interceptKeyBeforeQueueing</code>.</p>
+<h2 id="virtual-soft-keys">Virtual Soft Keys</h2>
+<p>The input system provides special features for implementing virtual soft keys.</p>
+<p>There are three cases:</p>
+<ol>
+<li>
+<p>If the virtual soft keys are displayed graphically on the screen, as on the
+    Galaxy Nexus, then they are implemented by the Navigation Bar component in
+    the System UI package.</p>
+<p>Because graphical virtual soft keys are implemented at a high layer in the
+system, key layout files are not involved and the following information does
+not apply.</p>
+</li>
+<li>
+<p>If the virtual soft keys are implemented as an extended touchable region
+    that is part of the main touch screen, as on the Nexus One, then the
+    input system uses a virtual key map file to translate X / Y touch coordinates
+    into Linux key codes, then uses the key layout file to translate
+    Linux key codes into Android key codes.</p>
+<p>Refer to the section on <a href="/tech/input/touch-devices.html">Touch Devices</a>
+for more details about virtual key map files.</p>
+<p>The key layout file for the touch screen input device must specify the
+appropriate key mapping and include the <code>VIRTUAL</code> flag for each key.</p>
+</li>
+<li>
+<p>If the virtual soft keys are implemented as capacitive buttons that are
+    separate from the main touch screen, as on the Nexus S, then the kernel
+    device driver or firmware is responsible for translating touches into
+    Linux key codes which the input system then translates into Android
+    key codes using the key layout file.</p>
+<p>The key layout file for the capacitive button input device must specify the
+appropriate key mapping and include the <code>VIRTUAL</code> flag for each key.</p>
+</li>
+</ol>
+<p>When virtual soft key are located within or in close physical proximity of the
+touch screen, it is easy for the user to accidentally press one of the buttons
+when touching near the bottom of the screen or when sliding a finger from top
+to bottom or from bottom to top on the screen.</p>
+<p>To prevent this from happening, the input system applies a little debouncing
+such that virtual soft key presses are ignored for a brief period of time
+after the most recent touch on the touch screen.  The delay is called the
+virtual key quiet time.</p>
+<p>To enable virtual soft key debouncing, we must do two things.</p>
+<p>First, we provide a key layout file for the touch screen or capacitive button
+input device with the <code>VIRTUAL</code> flag set for each key.</p>
+<pre><code>key 139    MENU           VIRTUAL
+key 102    HOME           VIRTUAL
+key 158    BACK           VIRTUAL
+key 217    SEARCH         VIRTUAL
+</code></pre>
+<p>Then, we set the value of the virtual key quiet time in a resource overlay
+for the framework <code>config.xml</code> resource.</p>
+<pre><code>&lt;!-- Specifies the amount of time to disable virtual keys after the screen is touched
+     in order to filter out accidental virtual key presses due to swiping gestures
+     or taps near the edge of the display.  May be 0 to disable the feature.
+     It is recommended that this value be no more than 250 ms.
+     This feature should be disabled for most devices. --&gt;
+&lt;integer name="config_virtualKeyQuietTimeMillis"&gt;250&lt;/integer&gt;
+</code></pre>
+<h2 id="validation">Validation</h2>
+<p>Make sure to validate your key layout files using the
+<a href="/tech/input/validate-keymaps.html">Validate Keymaps</a> tool.</p>
diff --git a/src/devices/tech/input/keyboard-devices.jd b/src/devices/tech/input/keyboard-devices.jd
new file mode 100644
index 0000000..aa968ac
--- /dev/null
+++ b/src/devices/tech/input/keyboard-devices.jd
@@ -0,0 +1,6438 @@
+page.title=Keyboard Devices
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>Android supports a variety of keyboard devices including special function
+keypads (volume and power controls), compact embedded QWERTY keyboards,
+and fully featured PC-style external keyboards.</p>
+<p>This document decribes physical keyboards only.  Refer to the Android SDK
+for information about soft keyboards (Input Method Editors).</p>
+<h2 id="keyboard-classification">Keyboard Classification</h2>
+<p>An input device is classified as a keyboard if either of the following
+conditions hold:</p>
+<ul>
+<li>
+<p>The input device reports the presence of any Linux key codes used on keyboards
+    including <code>0</code> through <code>0xff</code> or <code>KEY_OK</code> through <code>KEY_MAX</code>.</p>
+</li>
+<li>
+<p>The input device reports the presence of any Linux key codes used on joysticks
+    and gamepads including <code>BTN_0</code> through <code>BTN_9</code>, <code>BTN_TRIGGER</code> through <code>BTN_DEAD</code>,
+    or <code>BTN_A</code> through <code>BTN_THUMBR</code>.</p>
+</li>
+</ul>
+<p>Joysticks are currently classified as keyboards because joystick and gamepad buttons
+are reported by <code>EV_KEY</code> events in the same way keyboard keys are reported.  Thus
+joysticks and gamepads also make use of key map files for configuration.
+Refer to the section on <a href="/tech/input/joystick-devices.html">Joystick Devices</a> for
+more information.</p>
+<p>Once an input device has been classified as a keyboard, the system loads the
+input device configuration file and keyboard layout for the keyboard.</p>
+<p>The system then tries to determine additional characteristics of the device.</p>
+<ul>
+<li>
+<p>If the input device has any keys that are mapped to <code>KEYCODE_Q</code>, then the
+    device is considered to have an alphabetic keypad (as opposed to numeric).
+    The alphabetic keypad capability is reported in the resource <code>Configuration</code>
+    object as <code>KEYBOARD_QWERTY</code>.</p>
+</li>
+<li>
+<p>If the input device has any keys that are mapped to <code>KEYCODE_DPAD_UP</code>,
+    <code>KEYCODE_DPAD_DOWN</code>, <code>KEYCODE_DPAD_LEFT</code>, <code>KEYCODE_DPAD_RIGHT</code>, and
+    <code>KEYCODE_DPAD_CENTER</code> (all must be present), then the device is considered
+    to have a directional keypad.
+    The directional keypad capability is reported in the resource <code>Configuration</code>
+    object as <code>NAVIGATION_DPAD</code>.</p>
+</li>
+<li>
+<p>If the input device has any keys that are mapped to <code>KEYCODE_BUTTON_A</code>
+    or other gamepad related keys, then the device is considered to have a gamepad.</p>
+</li>
+</ul>
+<h2 id="keyboard-driver-requirements">Keyboard Driver Requirements</h2>
+<ol>
+<li>
+<p>Keyboard drivers should only register key codes for the keys that they
+    actually support.  Registering excess key codes may confuse the device
+    classification algorithm or cause the system to incorrectly detect
+    the supported keyboard capabilities of the device.</p>
+</li>
+<li>
+<p>Keyboard drivers should use <code>EV_KEY</code> to report key presses, using a value
+    of <code>0</code> to indicate that a key is released, a value of <code>1</code> to indicate that
+    a key is pressed, and a value greater than or equal to <code>2</code> to indicate that
+    the key is being repeated automatically.</p>
+</li>
+<li>
+<p>Android performs its own keyboard repeating.  Auto-repeat functionality
+    should be disabled in the driver.</p>
+</li>
+<li>
+<p>Keyboard drivers may optionally indicate the HID usage or low-level scan
+    code by sending <code>EV_MSC</code> with <code>MSC_SCANCODE</code> and a valud indicating the usage
+    or scan code when the key is pressed.  This information is not currently
+    used by Android.</p>
+</li>
+<li>
+<p>Keyboard drivers should support setting LED states when <code>EV_LED</code> is written
+    to the device.  The <code>hid-input</code> driver handles this automatically.
+    At the time of this writing, Android uses <code>LED_CAPSLOCK</code>, <code>LED_SCROLLLOCK</code>,
+    and <code>LED_NUMLOCK</code>.  These LEDs only need to be supported when the
+    keyboard actually has the associated indicator lights.</p>
+</li>
+<li>
+<p>Keyboard drivers for embedded keypads (for example, using a GPIO matrix)
+    should make sure to send <code>EV_KEY</code> events with a value of <code>0</code> for any keys that
+    are still pressed when the device is going to sleep.  Otherwise keys might
+    get stuck down and will auto-repeat forever.</p>
+</li>
+</ol>
+<h2 id="keyboard-operation">Keyboard Operation</h2>
+<p>The following is a brief summary of the keyboard operation on Android.</p>
+<ol>
+<li>
+<p>The <code>EventHub</code> reads raw events from the <code>evdev</code> driver and maps Linux key codes
+    (sometimes referred to as scan codes) into Android key codes using the
+    keyboard's key layout map.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> consumes the raw events and updates the meta key state.
+    For example, if the left shift key is pressed or released, the reader will
+    set or reset the <code>META_SHIFT_LEFT_ON</code> and <code>META_SHIFT_ON</code> bits accordingly.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> notifies the <code>InputDispatcher</code> about the key event.</p>
+</li>
+<li>
+<p>The <code>InputDispatcher</code> asks the <code>WindowManagerPolicy</code> what to do with the key
+    event by calling <code>WindowManagerPolicy.interceptKeyBeforeQueueing</code>.  This method
+    is part of a critical path that is responsible for waking the device when
+    certain keys are pressed.  The <code>EventHub</code> effectively holds a wake lock
+    along this critical path to ensure that it will run to completion.</p>
+</li>
+<li>
+<p>If an <code>InputFilter</code> is currently in use, the <code>InputDispatcher</code> gives it a
+    chance to consume or transform the key.  The <code>InputFilter</code> may be used to implement
+    low-level system-wide accessibility policies.</p>
+</li>
+<li>
+<p>The <code>InputDispatcher</code> enqueues the key for processing on the dispatch thread.</p>
+</li>
+<li>
+<p>When the <code>InputDispatcher</code> dequeues the key, it gives the <code>WindowManagerPolicy</code>
+    a second chance to intercept the key event by calling
+    <code>WindowManagerPolicy.interceptKeyBeforeDispatching</code>.  This method handles system
+    shortcuts and other functions.</p>
+</li>
+<li>
+<p>The <code>InputDispatcher</code> then identifies the key event target (the focused window)
+    and waits for them to become ready.  Then, the <code>InputDispatcher</code> delivers the
+    key event to the application.</p>
+</li>
+<li>
+<p>Inside the application, the key event propagates down the view hierarchy to
+    the focused view for pre-IME key dispatch.</p>
+</li>
+<li>
+<p>If the key event is not handled in the pre-IME dispatch and an IME is in use, the
+    key event is delivered to the IME.</p>
+</li>
+<li>
+<p>If the key event was not consumed by the IME, then the key event propagates
+    down the view hierarchy to the focused view for standard key dispatch.</p>
+</li>
+<li>
+<p>The application reports back to the <code>InputDispatcher</code> as to whether the key
+    event was consumed.  If the event was not consumed, the <code>InputDispatcher</code>
+    calls <code>WindowManagerPolicy.dispatchUnhandledKey</code> to apply "fallback" behavior.
+    Depending on the fallback action, the key event dispatch cycle may be restarted
+    using a different key code.  For example, if an application does not handle
+    <code>KEYCODE_ESCAPE</code>, the system may redispatch the key event as <code>KEYCODE_BACK</code> instead.</p>
+</li>
+</ol>
+<h2 id="keyboard-configuration">Keyboard Configuration</h2>
+<p>Keyboard behavior is determined by the keyboard's key layout, key character
+map and input device configuration.</p>
+<p>Refer to the following sections for more details about the files that
+participate in keyboard configuration:</p>
+<ul>
+<li><a href="/tech/input/key-layout-files.html">Key Layout Files</a></li>
+<li><a href="/tech/input/key-character-map-files.html">Key Character Map Files</a></li>
+<li><a href="/tech/input/input-device-configuration-files.html">Input Device Configuration Files</a></li>
+</ul>
+<h3 id="properties">Properties</h3>
+<p>The following input device configuration properties are used for keyboards.</p>
+<h4 id="keyboardlayout"><code>keyboard.layout</code></h4>
+<p><em>Definition:</em> <code>keyboard.layout</code> = &lt;name&gt;</p>
+<p>Specifies the name of the key layout file associated with the input device,
+excluding the <code>.kl</code> extension.  If this file is not found, the input system
+will use the default key layout instead.</p>
+<p>Spaces in the name are converted to underscores during lookup.</p>
+<p>Refer to the key layout file documentation for more details.</p>
+<h4 id="keyboardcharactermap"><code>keyboard.characterMap</code></h4>
+<p><em>Definition:</em> <code>keyboard.characterMap</code> = &lt;name&gt;</p>
+<p>Specifies the name of the key character map file associated with the input device,
+excluding the <code>.kcm</code> extension.  If this file is not found, the input system
+will use the default key character map instead.</p>
+<p>Spaces in the name are converted to underscores during lookup.</p>
+<p>Refer to the key character map file documentation for more details.</p>
+<h4 id="keyboardorientationaware"><code>keyboard.orientationAware</code></h4>
+<p><em>Definition:</em> <code>keyboard.orientationAware</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the keyboard should react to display orientation changes.</p>
+<ul>
+<li>
+<p>If the value is <code>1</code>, the directional keypad keys are rotated when the
+    associated display orientation changes.</p>
+</li>
+<li>
+<p>If the value is <code>0</code>, the keyboard is immune to display orientation changes.</p>
+</li>
+</ul>
+<p>The default value is <code>0</code>.</p>
+<p>Orientation awareness is used to support rotation of directional keypad keys,
+such as on the Motorola Droid.  For example, when the device is rotated
+clockwise 90 degrees from its natural orientation, <code>KEYCODE_DPAD_UP</code> is
+remapped to produce <code>KEYCODE_DPAD_RIGHT</code> since the 'up' key ends up pointing
+'right' when the device is held in that orientation.</p>
+<h4 id="keyboardbuiltin"><code>keyboard.builtIn</code></h4>
+<p><em>Definition:</em> <code>keyboard.builtIn</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the keyboard is the built-in (physically attached)
+keyboard.</p>
+<p>The default value is <code>1</code> if the device name ends with <code>-keypad</code>, <code>0</code> otherwise.</p>
+<p>The built-in keyboard is always assigned a device id of <code>0</code>.  Other keyboards
+that are not built-in are assigned unique non-zero device ids.</p>
+<p>Using an id of <code>0</code> for the built-in keyboard is important for maintaining
+compatibility with the <code>KeyCharacterMap.BUILT_IN_KEYBOARD</code> field, which specifies
+the id of the built-in keyboard and has a value of <code>0</code>.  This field has been
+deprecated in the API but older applications might still be using it.</p>
+<p>A special-function keyboard (one whose key character map specifies a
+type of <code>SPECIAL_FUNCTION</code>) will never be registered as the built-in keyboard,
+regardless of the setting of this property.  This is because a special-function
+keyboard is by definition not intended to be used for general purpose typing.</p>
+<h3 id="example-configurations">Example Configurations</h3>
+<pre><code># This is an example input device configuration file for a built-in
+# keyboard that has a DPad.
+
+# The keyboard is internal because it is part of the device.
+device.internal = 1
+
+# The keyboard is the default built-in keyboard so it should be assigned
+# an id of 0.
+keyboard.builtIn = 1
+
+# The keyboard includes a DPad which is mounted on the device.  As the device
+# is rotated the orientation of the DPad rotates along with it, so the DPad must
+# be aware of the display orientation.  This ensures that pressing 'up' on the
+# DPad always means 'up' from the perspective of the user, even when the entire
+# device has been rotated.
+keyboard.orientationAware = 1
+</code></pre>
+<h3 id="compatibility-notes">Compatibility Notes</h3>
+<p>Prior to Honeycomb, the keyboard input mapper did not use any configuration properties.
+All keyboards were assumed to be physically attached and orientation aware.  The default
+key layout and key character map was named <code>qwerty</code> instead of <code>Generic</code>.  The key
+character map format was also very different and the framework did not support
+PC-style full keyboards or external keyboards.</p>
+<p>When upgrading devices to Honeycomb, make sure to create or update the necessary
+configuration and key map files.</p>
+<h2 id="hid-usages-linux-key-codes-and-android-key-codes">HID Usages, Linux Key Codes and Android Key Codes</h2>
+<p>The system refers to keys using several different identifiers, depending on the
+layer of abstraction.</p>
+<p>For HID devices, each key has an associated HID usage.  The Linux <code>hid-input</code>
+driver and related vendor and device-specific HID drivers are responsible
+for parsing HID reports and mapping HID usages to Linux key codes.</p>
+<p>As Android reads <code>EV_KEY</code> events from the Linux kernel, it translates each
+Linux key code into its corresponding Android key code according to the
+key layout file of the device.</p>
+<p>When the key event is dispatched to an application, the <code>android.view.KeyEvent</code>
+instance reports the Linux key code as the value of <code>getScanCode()</code> and the
+Android key code as the value of <code>getKeyCode()</code>.  For the purposes of the
+framework, only the value of <code>getKeyCode()</code> is important.</p>
+<p>Note that the HID usage information is not used by Android itself or
+passed to applications.</p>
+<h2 id="code-tables">Code Tables</h2>
+<p>The following tables show how HID usages, Linux key codes and Android
+key codes are related to one another.</p>
+<p>The LKC column specifies the Linux key code in hexadecimal.</p>
+<p>The AKC column specifies the Android key code in hexadecimal.</p>
+<p>The Notes column refers to notes that are posted after the table.</p>
+<p>The Version column specifies the first version of the Android platform
+to have included this key in its default key map.  Multiple rows are
+shown in cases where the default key map has changed between versions.
+The oldest version indicated is 1.6.</p>
+<ul>
+<li>
+<p>In Gingerbread (2.3) and earlier releases, the default key map was
+    <code>qwerty.kl</code>. This key map was only intended for use with the Android
+    Emulator and was not intended to be used to support arbitrary
+    external keyboards.  Nevertheless, a few OEMs added Bluetooth
+    keyboard support to the platform and relied on <code>qwerty.kl</code> to
+    provide the necessary keyboard mappings.  Consequently these
+    older mappings may be of interest to OEMs who are building
+    peripherals for these particular devices.  Note that the mappings
+    are substantially different from the current ones, particularly
+    with respect to the treatment of the <code>HOME</code> key.  It is recommended
+    that all new peripherals be developed according to the Honeycomb or more
+    recent key maps (ie. standard HID).</p>
+</li>
+<li>
+<p>As of Honeycomb (3.0), the default key map is <code>Generic.kl</code>.
+    This key map was designed to support full PC style keyboards.
+    Most functionality of standard HID keyboards should just work out
+    of the box.</p>
+</li>
+</ul>
+<p>The key code mapping may vary across versions of the Linux kernel and Android.
+When changes are known to have occurred in the Android default key maps,
+they are indicated in the version column.</p>
+<p>Device-specific HID drivers and key maps may apply different mappings
+than are indicated here.</p>
+<h3 id="hid-keyboard-and-keypad-page-0x07">HID Keyboard and Keypad Page (0x07)</h3>
+<table>
+<thead>
+<tr>
+<th>HID Usage</th>
+<th>HID Usage Name</th>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x07 0x0001</td>
+<td>Keyboard Error Roll Over</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0002</td>
+<td>Keyboard POST Fail</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0003</td>
+<td>Keyboard Error Undefined</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0004</td>
+<td>Keyboard a and A</td>
+<td>0x001e</td>
+<td>KEY_A</td>
+<td>1.6</td>
+<td>0x001d</td>
+<td>KEYCODE_A</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0005</td>
+<td>Keyboard b and B</td>
+<td>0x0030</td>
+<td>KEY_B</td>
+<td>1.6</td>
+<td>0x001e</td>
+<td>KEYCODE_B</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0006</td>
+<td>Keyboard c and C</td>
+<td>0x002e</td>
+<td>KEY_C</td>
+<td>1.6</td>
+<td>0x001f</td>
+<td>KEYCODE_C</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0007</td>
+<td>Keyboard d and D</td>
+<td>0x0020</td>
+<td>KEY_D</td>
+<td>1.6</td>
+<td>0x0020</td>
+<td>KEYCODE_D</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0008</td>
+<td>Keyboard e and E</td>
+<td>0x0012</td>
+<td>KEY_E</td>
+<td>1.6</td>
+<td>0x0021</td>
+<td>KEYCODE_E</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0009</td>
+<td>Keyboard f and F</td>
+<td>0x0021</td>
+<td>KEY_F</td>
+<td>1.6</td>
+<td>0x0022</td>
+<td>KEYCODE_F</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000a</td>
+<td>Keyboard g and G</td>
+<td>0x0022</td>
+<td>KEY_G</td>
+<td>1.6</td>
+<td>0x0023</td>
+<td>KEYCODE_G</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000b</td>
+<td>Keyboard h and H</td>
+<td>0x0023</td>
+<td>KEY_H</td>
+<td>1.6</td>
+<td>0x0024</td>
+<td>KEYCODE_H</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000c</td>
+<td>Keyboard i and I</td>
+<td>0x0017</td>
+<td>KEY_I</td>
+<td>1.6</td>
+<td>0x0025</td>
+<td>KEYCODE_I</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000d</td>
+<td>Keyboard j and J</td>
+<td>0x0024</td>
+<td>KEY_J</td>
+<td>1.6</td>
+<td>0x0026</td>
+<td>KEYCODE_J</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000e</td>
+<td>Keyboard k and K</td>
+<td>0x0025</td>
+<td>KEY_K</td>
+<td>1.6</td>
+<td>0x0027</td>
+<td>KEYCODE_K</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000f</td>
+<td>Keyboard l and L</td>
+<td>0x0026</td>
+<td>KEY_L</td>
+<td>1.6</td>
+<td>0x0028</td>
+<td>KEYCODE_L</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0010</td>
+<td>Keyboard m and M</td>
+<td>0x0032</td>
+<td>KEY_M</td>
+<td>1.6</td>
+<td>0x0029</td>
+<td>KEYCODE_M</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0011</td>
+<td>Keyboard n and N</td>
+<td>0x0031</td>
+<td>KEY_N</td>
+<td>1.6</td>
+<td>0x002a</td>
+<td>KEYCODE_N</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0012</td>
+<td>Keyboard o and O</td>
+<td>0x0018</td>
+<td>KEY_O</td>
+<td>1.6</td>
+<td>0x002b</td>
+<td>KEYCODE_O</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0013</td>
+<td>Keyboard p and P</td>
+<td>0x0019</td>
+<td>KEY_P</td>
+<td>1.6</td>
+<td>0x002c</td>
+<td>KEYCODE_P</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0014</td>
+<td>Keyboard q and Q</td>
+<td>0x0010</td>
+<td>KEY_Q</td>
+<td>1.6</td>
+<td>0x002d</td>
+<td>KEYCODE_Q</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0015</td>
+<td>Keyboard r and R</td>
+<td>0x0013</td>
+<td>KEY_R</td>
+<td>1.6</td>
+<td>0x002e</td>
+<td>KEYCODE_R</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0016</td>
+<td>Keyboard s and S</td>
+<td>0x001f</td>
+<td>KEY_S</td>
+<td>1.6</td>
+<td>0x002f</td>
+<td>KEYCODE_S</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0017</td>
+<td>Keyboard t and T</td>
+<td>0x0014</td>
+<td>KEY_T</td>
+<td>1.6</td>
+<td>0x0030</td>
+<td>KEYCODE_T</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0018</td>
+<td>Keyboard u and U</td>
+<td>0x0016</td>
+<td>KEY_U</td>
+<td>1.6</td>
+<td>0x0031</td>
+<td>KEYCODE_U</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0019</td>
+<td>Keyboard v and V</td>
+<td>0x002f</td>
+<td>KEY_V</td>
+<td>1.6</td>
+<td>0x0032</td>
+<td>KEYCODE_V</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001a</td>
+<td>Keyboard w and W</td>
+<td>0x0011</td>
+<td>KEY_W</td>
+<td>1.6</td>
+<td>0x0033</td>
+<td>KEYCODE_W</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001b</td>
+<td>Keyboard x and X</td>
+<td>0x002d</td>
+<td>KEY_X</td>
+<td>1.6</td>
+<td>0x0034</td>
+<td>KEYCODE_X</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001c</td>
+<td>Keyboard y and Y</td>
+<td>0x0015</td>
+<td>KEY_Y</td>
+<td>1.6</td>
+<td>0x0035</td>
+<td>KEYCODE_Y</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001d</td>
+<td>Keyboard z and Z</td>
+<td>0x002c</td>
+<td>KEY_Z</td>
+<td>1.6</td>
+<td>0x0036</td>
+<td>KEYCODE_Z</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001e</td>
+<td>Keyboard 1 and !</td>
+<td>0x0002</td>
+<td>KEY_1</td>
+<td>1.6</td>
+<td>0x0008</td>
+<td>KEYCODE_1</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001f</td>
+<td>Keyboard 2 and @</td>
+<td>0x0003</td>
+<td>KEY_2</td>
+<td>1.6</td>
+<td>0x0009</td>
+<td>KEYCODE_2</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0020</td>
+<td>Keyboard 3 and #</td>
+<td>0x0004</td>
+<td>KEY_3</td>
+<td>1.6</td>
+<td>0x000a</td>
+<td>KEYCODE_3</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0021</td>
+<td>Keyboard 4 and $</td>
+<td>0x0005</td>
+<td>KEY_4</td>
+<td>1.6</td>
+<td>0x000b</td>
+<td>KEYCODE_4</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0022</td>
+<td>Keyboard 5 and %</td>
+<td>0x0006</td>
+<td>KEY_5</td>
+<td>1.6</td>
+<td>0x000c</td>
+<td>KEYCODE_5</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0023</td>
+<td>Keyboard 6 and ^</td>
+<td>0x0007</td>
+<td>KEY_6</td>
+<td>1.6</td>
+<td>0x000d</td>
+<td>KEYCODE_6</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0024</td>
+<td>Keyboard 7 and &amp;</td>
+<td>0x0008</td>
+<td>KEY_7</td>
+<td>1.6</td>
+<td>0x000e</td>
+<td>KEYCODE_7</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0025</td>
+<td>Keyboard 8 and *</td>
+<td>0x0009</td>
+<td>KEY_8</td>
+<td>1.6</td>
+<td>0x000f</td>
+<td>KEYCODE_8</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0026</td>
+<td>Keyboard 9 and (</td>
+<td>0x000a</td>
+<td>KEY_9</td>
+<td>1.6</td>
+<td>0x0010</td>
+<td>KEYCODE_9</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0027</td>
+<td>Keyboard 0 and )</td>
+<td>0x000b</td>
+<td>KEY_0</td>
+<td>1.6</td>
+<td>0x0007</td>
+<td>KEYCODE_0</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0028</td>
+<td>Keyboard Return (ENTER)</td>
+<td>0x001c</td>
+<td>KEY_ENTER</td>
+<td>1.6</td>
+<td>0x0042</td>
+<td>KEYCODE_ENTER</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0029</td>
+<td>Keyboard ESCAPE</td>
+<td>0x0001</td>
+<td>KEY_ESC</td>
+<td>3.0</td>
+<td>0x006f</td>
+<td>KEYCODE_ESCAPE</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>2.3</td>
+<td>0x0004</td>
+<td>KEYCODE_BACK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x002a</td>
+<td>Keyboard DELETE (Backspace)</td>
+<td>0x000e</td>
+<td>KEY_BACKSPACE</td>
+<td>1.6</td>
+<td>0x0043</td>
+<td>KEYCODE_DEL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x002b</td>
+<td>Keyboard Tab</td>
+<td>0x000f</td>
+<td>KEY_TAB</td>
+<td>1.6</td>
+<td>0x003d</td>
+<td>KEYCODE_TAB</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x002c</td>
+<td>Keyboard Spacebar</td>
+<td>0x0039</td>
+<td>KEY_SPACE</td>
+<td>1.6</td>
+<td>0x003e</td>
+<td>KEYCODE_SPACE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x002d</td>
+<td>Keyboard - and _</td>
+<td>0x000c</td>
+<td>KEY_MINUS</td>
+<td>1.6</td>
+<td>0x0045</td>
+<td>KEYCODE_MINUS</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x002e</td>
+<td>Keyboard = and +</td>
+<td>0x000d</td>
+<td>KEY_EQUAL</td>
+<td>1.6</td>
+<td>0x0046</td>
+<td>KEYCODE_EQUALS</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x002f</td>
+<td>Keyboard [ and {</td>
+<td>0x001a</td>
+<td>KEY_LEFTBRACE</td>
+<td>1.6</td>
+<td>0x0047</td>
+<td>KEYCODE_LEFT_BRACKET</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0030</td>
+<td>Keyboard ] and }</td>
+<td>0x001b</td>
+<td>KEY_RIGHTBRACE</td>
+<td>1.6</td>
+<td>0x0048</td>
+<td>KEYCODE_RIGHT_BRACKET</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0031</td>
+<td>Keyboard \ and &#124;</td>
+<td>0x002b</td>
+<td>KEY_BACKSLASH</td>
+<td>1.6</td>
+<td>0x0049</td>
+<td>KEYCODE_BACKSLASH</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0032</td>
+<td>Keyboard Non-US # and ~</td>
+<td>0x002b</td>
+<td>KEY_BACKSLASH</td>
+<td>1.6</td>
+<td>0x0049</td>
+<td>KEYCODE_BACKSLASH</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0033</td>
+<td>Keyboard ; and :</td>
+<td>0x0027</td>
+<td>KEY_SEMICOLON</td>
+<td>1.6</td>
+<td>0x004a</td>
+<td>KEYCODE_SEMICOLON</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0034</td>
+<td>Keyboard ' and "</td>
+<td>0x0028</td>
+<td>KEY_APOSTROPHE</td>
+<td>1.6</td>
+<td>0x004b</td>
+<td>KEYCODE_APOSTROPHE</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0035</td>
+<td>Keyboard ` and ~</td>
+<td>0x0029</td>
+<td>KEY_GRAVE</td>
+<td>3.0</td>
+<td>0x0044</td>
+<td>KEYCODE_GRAVE</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0036</td>
+<td>Keyboard , and &lt;</td>
+<td>0x0033</td>
+<td>KEY_COMMA</td>
+<td>1.6</td>
+<td>0x0037</td>
+<td>KEYCODE_COMMA</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0037</td>
+<td>Keyboard . and &gt;</td>
+<td>0x0034</td>
+<td>KEY_DOT</td>
+<td>1.6</td>
+<td>0x0038</td>
+<td>KEYCODE_PERIOD</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0038</td>
+<td>Keyboard / and ?</td>
+<td>0x0035</td>
+<td>KEY_SLASH</td>
+<td>1.6</td>
+<td>0x004c</td>
+<td>KEYCODE_SLASH</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0039</td>
+<td>Keyboard Caps Lock</td>
+<td>0x003a</td>
+<td>KEY_CAPSLOCK</td>
+<td>3.0</td>
+<td>0x0073</td>
+<td>KEYCODE_CAPS_LOCK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003a</td>
+<td>Keyboard F1</td>
+<td>0x003b</td>
+<td>KEY_F1</td>
+<td>3.0</td>
+<td>0x0083</td>
+<td>KEYCODE_F1</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003b</td>
+<td>Keyboard F2</td>
+<td>0x003c</td>
+<td>KEY_F2</td>
+<td>3.0</td>
+<td>0x0084</td>
+<td>KEYCODE_F2</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0002</td>
+<td>KEYCODE_SOFT_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003c</td>
+<td>Keyboard F3</td>
+<td>0x003d</td>
+<td>KEY_F3</td>
+<td>3.0</td>
+<td>0x0085</td>
+<td>KEYCODE_F3</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0005</td>
+<td>KEYCODE_CALL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003d</td>
+<td>Keyboard F4</td>
+<td>0x003e</td>
+<td>KEY_F4</td>
+<td>3.0</td>
+<td>0x0086</td>
+<td>KEYCODE_F4</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0006</td>
+<td>KEYCODE_ENDCALL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003e</td>
+<td>Keyboard F5</td>
+<td>0x003f</td>
+<td>KEY_F5</td>
+<td>3.0</td>
+<td>0x0087</td>
+<td>KEYCODE_F5</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003f</td>
+<td>Keyboard F6</td>
+<td>0x0040</td>
+<td>KEY_F6</td>
+<td>3.0</td>
+<td>0x0088</td>
+<td>KEYCODE_F6</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0040</td>
+<td>Keyboard F7</td>
+<td>0x0041</td>
+<td>KEY_F7</td>
+<td>3.0</td>
+<td>0x0089</td>
+<td>KEYCODE_F7</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0041</td>
+<td>Keyboard F8</td>
+<td>0x0042</td>
+<td>KEY_F8</td>
+<td>3.0</td>
+<td>0x008a</td>
+<td>KEYCODE_F8</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0042</td>
+<td>Keyboard F9</td>
+<td>0x0043</td>
+<td>KEY_F9</td>
+<td>3.0</td>
+<td>0x008b</td>
+<td>KEYCODE_F9</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0043</td>
+<td>Keyboard F10</td>
+<td>0x0044</td>
+<td>KEY_F10</td>
+<td>3.0</td>
+<td>0x008c</td>
+<td>KEYCODE_F10</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>2.3</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0044</td>
+<td>Keyboard F11</td>
+<td>0x0057</td>
+<td>KEY_F11</td>
+<td>3.0</td>
+<td>0x008d</td>
+<td>KEYCODE_F11</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0045</td>
+<td>Keyboard F12</td>
+<td>0x0058</td>
+<td>KEY_F12</td>
+<td>3.0</td>
+<td>0x008e</td>
+<td>KEYCODE_F12</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0046</td>
+<td>Keyboard Print Screen</td>
+<td>0x0063</td>
+<td>KEY_SYSRQ</td>
+<td>3.0</td>
+<td>0x0078</td>
+<td>KEYCODE_SYSRQ</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0047</td>
+<td>Keyboard Scroll Lock</td>
+<td>0x0046</td>
+<td>KEY_SCROLLLOCK</td>
+<td>3.0</td>
+<td>0x0074</td>
+<td>KEYCODE_SCROLL_LOCK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0048</td>
+<td>Keyboard Pause</td>
+<td>0x0077</td>
+<td>KEY_PAUSE</td>
+<td>3.0</td>
+<td>0x0079</td>
+<td>KEYCODE_BREAK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0049</td>
+<td>Keyboard Insert</td>
+<td>0x006e</td>
+<td>KEY_INSERT</td>
+<td>3.0</td>
+<td>0x007c</td>
+<td>KEYCODE_INSERT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004a</td>
+<td>Keyboard Home</td>
+<td>0x0066</td>
+<td>KEY_HOME</td>
+<td>3.0</td>
+<td>0x007a</td>
+<td>KEYCODE_MOVE_HOME</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0003</td>
+<td>KEYCODE_HOME</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004b</td>
+<td>Keyboard Page Up</td>
+<td>0x0068</td>
+<td>KEY_PAGEUP</td>
+<td>3.0</td>
+<td>0x005c</td>
+<td>KEYCODE_PAGE_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004c</td>
+<td>Keyboard Delete Forward</td>
+<td>0x006f</td>
+<td>KEY_DELETE</td>
+<td>3.0</td>
+<td>0x0070</td>
+<td>KEYCODE_FORWARD_DEL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004d</td>
+<td>Keyboard End</td>
+<td>0x006b</td>
+<td>KEY_END</td>
+<td>3.0</td>
+<td>0x007b</td>
+<td>KEYCODE_MOVE_END</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0006</td>
+<td>KEYCODE_ENDCALL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004e</td>
+<td>Keyboard Page Down</td>
+<td>0x006d</td>
+<td>KEY_PAGEDOWN</td>
+<td>3.0</td>
+<td>0x005d</td>
+<td>KEYCODE_PAGE_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004f</td>
+<td>Keyboard Right Arrow</td>
+<td>0x006a</td>
+<td>KEY_RIGHT</td>
+<td>1.6</td>
+<td>0x0016</td>
+<td>KEYCODE_DPAD_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0050</td>
+<td>Keyboard Left Arrow</td>
+<td>0x0069</td>
+<td>KEY_LEFT</td>
+<td>1.6</td>
+<td>0x0015</td>
+<td>KEYCODE_DPAD_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0051</td>
+<td>Keyboard Down Arrow</td>
+<td>0x006c</td>
+<td>KEY_DOWN</td>
+<td>1.6</td>
+<td>0x0014</td>
+<td>KEYCODE_DPAD_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0052</td>
+<td>Keyboard Up Arrow</td>
+<td>0x0067</td>
+<td>KEY_UP</td>
+<td>1.6</td>
+<td>0x0013</td>
+<td>KEYCODE_DPAD_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0053</td>
+<td>Keyboard Num Lock and Clear</td>
+<td>0x0045</td>
+<td>KEY_NUMLOCK</td>
+<td>3.0</td>
+<td>0x008f</td>
+<td>KEYCODE_NUM_LOCK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0054</td>
+<td>Keypad /</td>
+<td>0x0062</td>
+<td>KEY_KPSLASH</td>
+<td>3.0</td>
+<td>0x009a</td>
+<td>KEYCODE_NUMPAD_DIVIDE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0055</td>
+<td>Keypad *</td>
+<td>0x0037</td>
+<td>KEY_KPASTERISK</td>
+<td>3.0</td>
+<td>0x009b</td>
+<td>KEYCODE_NUMPAD_MULTIPLY</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0056</td>
+<td>Keypad -</td>
+<td>0x004a</td>
+<td>KEY_KPMINUS</td>
+<td>3.0</td>
+<td>0x009c</td>
+<td>KEYCODE_NUMPAD_SUBTRACT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0057</td>
+<td>Keypad +</td>
+<td>0x004e</td>
+<td>KEY_KPPLUS</td>
+<td>3.0</td>
+<td>0x009d</td>
+<td>KEYCODE_NUMPAD_ADD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0058</td>
+<td>Keypad ENTER</td>
+<td>0x0060</td>
+<td>KEY_KPENTER</td>
+<td>3.0</td>
+<td>0x00a0</td>
+<td>KEYCODE_NUMPAD_ENTER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0059</td>
+<td>Keypad 1 and End</td>
+<td>0x004f</td>
+<td>KEY_KP1</td>
+<td>3.0</td>
+<td>0x0091</td>
+<td>KEYCODE_NUMPAD_1</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005a</td>
+<td>Keypad 2 and Down Arrow</td>
+<td>0x0050</td>
+<td>KEY_KP2</td>
+<td>3.0</td>
+<td>0x0092</td>
+<td>KEYCODE_NUMPAD_2</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005b</td>
+<td>Keypad 3 and PageDn</td>
+<td>0x0051</td>
+<td>KEY_KP3</td>
+<td>3.0</td>
+<td>0x0093</td>
+<td>KEYCODE_NUMPAD_3</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005c</td>
+<td>Keypad 4 and Left Arrow</td>
+<td>0x004b</td>
+<td>KEY_KP4</td>
+<td>3.0</td>
+<td>0x0094</td>
+<td>KEYCODE_NUMPAD_4</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005d</td>
+<td>Keypad 5</td>
+<td>0x004c</td>
+<td>KEY_KP5</td>
+<td>3.0</td>
+<td>0x0095</td>
+<td>KEYCODE_NUMPAD_5</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005e</td>
+<td>Keypad 6 and Right Arrow</td>
+<td>0x004d</td>
+<td>KEY_KP6</td>
+<td>3.0</td>
+<td>0x0096</td>
+<td>KEYCODE_NUMPAD_6</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005f</td>
+<td>Keypad 7 and Home</td>
+<td>0x0047</td>
+<td>KEY_KP7</td>
+<td>3.0</td>
+<td>0x0097</td>
+<td>KEYCODE_NUMPAD_7</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0060</td>
+<td>Keypad 8 and Up Arrow</td>
+<td>0x0048</td>
+<td>KEY_KP8</td>
+<td>3.0</td>
+<td>0x0098</td>
+<td>KEYCODE_NUMPAD_8</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0061</td>
+<td>Keypad 9 and Page Up</td>
+<td>0x0049</td>
+<td>KEY_KP9</td>
+<td>3.0</td>
+<td>0x0099</td>
+<td>KEYCODE_NUMPAD_9</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0062</td>
+<td>Keypad 0 and Insert</td>
+<td>0x0052</td>
+<td>KEY_KP0</td>
+<td>3.0</td>
+<td>0x0090</td>
+<td>KEYCODE_NUMPAD_0</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0063</td>
+<td>Keypad . and Delete</td>
+<td>0x0053</td>
+<td>KEY_KPDOT</td>
+<td>3.0</td>
+<td>0x009e</td>
+<td>KEYCODE_NUMPAD_DOT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0064</td>
+<td>Keyboard Non-US \ and &#124;</td>
+<td>0x0056</td>
+<td>KEY_102ND</td>
+<td>4.0</td>
+<td>0x0049</td>
+<td>KEYCODE_BACKSLASH</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0065</td>
+<td>Keyboard Application</td>
+<td>0x007f</td>
+<td>KEY_COMPOSE</td>
+<td>3.0</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0054</td>
+<td>KEYCODE_SEARCH</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0066</td>
+<td>Keyboard Power</td>
+<td>0x0074</td>
+<td>KEY_POWER</td>
+<td>1.6</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0067</td>
+<td>Keypad =</td>
+<td>0x0075</td>
+<td>KEY_KPEQUAL</td>
+<td>3.0</td>
+<td>0x00a1</td>
+<td>KEYCODE_NUMPAD_EQUALS</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0068</td>
+<td>Keyboard F13</td>
+<td>0x00b7</td>
+<td>KEY_F13</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0069</td>
+<td>Keyboard F14</td>
+<td>0x00b8</td>
+<td>KEY_F14</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006a</td>
+<td>Keyboard F15</td>
+<td>0x00b9</td>
+<td>KEY_F15</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006b</td>
+<td>Keyboard F16</td>
+<td>0x00ba</td>
+<td>KEY_F16</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006c</td>
+<td>Keyboard F17</td>
+<td>0x00bb</td>
+<td>KEY_F17</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006d</td>
+<td>Keyboard F18</td>
+<td>0x00bc</td>
+<td>KEY_F18</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006e</td>
+<td>Keyboard F19</td>
+<td>0x00bd</td>
+<td>KEY_F19</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006f</td>
+<td>Keyboard F20</td>
+<td>0x00be</td>
+<td>KEY_F20</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0070</td>
+<td>Keyboard F21</td>
+<td>0x00bf</td>
+<td>KEY_F21</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0071</td>
+<td>Keyboard F22</td>
+<td>0x00c0</td>
+<td>KEY_F22</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0072</td>
+<td>Keyboard F23</td>
+<td>0x00c1</td>
+<td>KEY_F23</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0073</td>
+<td>Keyboard F24</td>
+<td>0x00c2</td>
+<td>KEY_F24</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0074</td>
+<td>Keyboard Execute</td>
+<td>0x0086</td>
+<td>KEY_OPEN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0075</td>
+<td>Keyboard Help</td>
+<td>0x008a</td>
+<td>KEY_HELP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0076</td>
+<td>Keyboard Menu</td>
+<td>0x0082</td>
+<td>KEY_PROPS</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0077</td>
+<td>Keyboard Select</td>
+<td>0x0084</td>
+<td>KEY_FRONT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0078</td>
+<td>Keyboard Stop</td>
+<td>0x0080</td>
+<td>KEY_STOP</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0079</td>
+<td>Keyboard Again</td>
+<td>0x0081</td>
+<td>KEY_AGAIN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007a</td>
+<td>Keyboard Undo</td>
+<td>0x0083</td>
+<td>KEY_UNDO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007b</td>
+<td>Keyboard Cut</td>
+<td>0x0089</td>
+<td>KEY_CUT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007c</td>
+<td>Keyboard Copy</td>
+<td>0x0085</td>
+<td>KEY_COPY</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007d</td>
+<td>Keyboard Paste</td>
+<td>0x0087</td>
+<td>KEY_PASTE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007e</td>
+<td>Keyboard Find</td>
+<td>0x0088</td>
+<td>KEY_FIND</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007f</td>
+<td>Keyboard Mute</td>
+<td>0x0071</td>
+<td>KEY_MUTE</td>
+<td>3.0</td>
+<td>0x00a4</td>
+<td>KEYCODE_VOLUME_MUTE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0080</td>
+<td>Keyboard Volume Up</td>
+<td>0x0073</td>
+<td>KEY_VOLUMEUP</td>
+<td>1.6</td>
+<td>0x0018</td>
+<td>KEYCODE_VOLUME_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0081</td>
+<td>Keyboard Volume Down</td>
+<td>0x0072</td>
+<td>KEY_VOLUMEDOWN</td>
+<td>1.6</td>
+<td>0x0019</td>
+<td>KEYCODE_VOLUME_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0082</td>
+<td>Keyboard Locking Caps Lock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0083</td>
+<td>Keyboard Locking Num Lock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0084</td>
+<td>Keyboard Locking Scroll Lock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0085</td>
+<td>Keypad Comma</td>
+<td>0x0079</td>
+<td>KEY_KPCOMMA</td>
+<td>3.0</td>
+<td>0x009f</td>
+<td>KEYCODE_NUMPAD_COMMA</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0086</td>
+<td>Keypad Equal Sign</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0087</td>
+<td>Keyboard International1</td>
+<td>0x0059</td>
+<td>KEY_RO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0088</td>
+<td>Keyboard International2</td>
+<td>0x005d</td>
+<td>KEY_KATAKANAHIRAGANA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0089</td>
+<td>Keyboard International3</td>
+<td>0x007c</td>
+<td>KEY_YEN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008a</td>
+<td>Keyboard International4</td>
+<td>0x005c</td>
+<td>KEY_HENKAN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008b</td>
+<td>Keyboard International5</td>
+<td>0x005e</td>
+<td>KEY_MUHENKAN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008c</td>
+<td>Keyboard International6</td>
+<td>0x005f</td>
+<td>KEY_KPJPCOMMA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008d</td>
+<td>Keyboard International7</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008e</td>
+<td>Keyboard International8</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008f</td>
+<td>Keyboard International9</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0090</td>
+<td>Keyboard LANG1</td>
+<td>0x007a</td>
+<td>KEY_HANGEUL</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0091</td>
+<td>Keyboard LANG2</td>
+<td>0x007b</td>
+<td>KEY_HANJA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0092</td>
+<td>Keyboard LANG3</td>
+<td>0x005a</td>
+<td>KEY_KATAKANA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0093</td>
+<td>Keyboard LANG4</td>
+<td>0x005b</td>
+<td>KEY_HIRAGANA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0094</td>
+<td>Keyboard LANG5</td>
+<td>0x0055</td>
+<td>KEY_ZENKAKUHANKAKU</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0095</td>
+<td>Keyboard LANG6</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0096</td>
+<td>Keyboard LANG7</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0097</td>
+<td>Keyboard LANG8</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0098</td>
+<td>Keyboard LANG9</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0099</td>
+<td>Keyboard Alternate Erase</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009a</td>
+<td>Keyboard SysReq/Attention</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009b</td>
+<td>Keyboard Cancel</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009c</td>
+<td>Keyboard Clear</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009d</td>
+<td>Keyboard Prior</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009e</td>
+<td>Keyboard Return</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009f</td>
+<td>Keyboard Separator</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a0</td>
+<td>Keyboard Out</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a1</td>
+<td>Keyboard Oper</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a2</td>
+<td>Keyboard Clear/Again</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a3</td>
+<td>Keyboard CrSel/Props</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a4</td>
+<td>Keyboard ExSel</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b0</td>
+<td>Keypad 00</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b1</td>
+<td>Keypad 000</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b2</td>
+<td>Thousands Separator</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b3</td>
+<td>Decimal Separator</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b4</td>
+<td>Currency Unit</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b5</td>
+<td>Currency Sub-unit</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b6</td>
+<td>Keypad (</td>
+<td>0x00b3</td>
+<td>KEY_KPLEFTPAREN</td>
+<td>3.0</td>
+<td>0x00a2</td>
+<td>KEYCODE_NUMPAD_LEFT_PAREN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b7</td>
+<td>Keypad )</td>
+<td>0x00b4</td>
+<td>KEY_KPRIGHTPAREN</td>
+<td>3.0</td>
+<td>0x00a3</td>
+<td>KEYCODE_NUMPAD_RIGHT_PAREN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b8</td>
+<td>Keypad {</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b9</td>
+<td>Keypad }</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ba</td>
+<td>Keypad Tab</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00bb</td>
+<td>Keypad Backspace</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00bc</td>
+<td>Keypad A</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00bd</td>
+<td>Keypad B</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00be</td>
+<td>Keypad C</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00bf</td>
+<td>Keypad D</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c0</td>
+<td>Keypad E</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c1</td>
+<td>Keypad F</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c2</td>
+<td>Keypad XOR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c3</td>
+<td>Keypad ^</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c4</td>
+<td>Keypad %</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c5</td>
+<td>Keypad &lt;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c6</td>
+<td>Keypad &gt;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c7</td>
+<td>Keypad &amp;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c8</td>
+<td>Keypad &amp;&amp;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c9</td>
+<td>Keypad &#124;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ca</td>
+<td>Keypad &#124;&#124;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00cb</td>
+<td>Keypad :</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00cc</td>
+<td>Keypad #</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00cd</td>
+<td>Keypad Space</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ce</td>
+<td>Keypad @</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00cf</td>
+<td>Keypad !</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d0</td>
+<td>Keypad Memory Store</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d1</td>
+<td>Keypad Memory Recall</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d2</td>
+<td>Keypad Memory Clear</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d3</td>
+<td>Keypad Memory Add</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d4</td>
+<td>Keypad Memory Subtract</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d5</td>
+<td>Keypad Memory Multiply</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d6</td>
+<td>Keypad Memory Divide</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d7</td>
+<td>Keypad +/-</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d8</td>
+<td>Keypad Clear</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d9</td>
+<td>Keypad Clear Entry</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00da</td>
+<td>Keypad Binary</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00db</td>
+<td>Keypad Octal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00dc</td>
+<td>Keypad Decimal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00dd</td>
+<td>Keypad Hexadecimal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e0</td>
+<td>Keyboard Left Control</td>
+<td>0x001d</td>
+<td>KEY_LEFTCTRL</td>
+<td>3.0</td>
+<td>0x0071</td>
+<td>KEYCODE_CTRL_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e1</td>
+<td>Keyboard Left Shift</td>
+<td>0x002a</td>
+<td>KEY_LEFTSHIFT</td>
+<td>1.6</td>
+<td>0x003b</td>
+<td>KEYCODE_SHIFT_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e2</td>
+<td>Keyboard Left Alt</td>
+<td>0x0038</td>
+<td>KEY_LEFTALT</td>
+<td>1.6</td>
+<td>0x0039</td>
+<td>KEYCODE_ALT_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e3</td>
+<td>Keyboard Left GUI</td>
+<td>0x007d</td>
+<td>KEY_LEFTMETA</td>
+<td>3.0</td>
+<td>0x0075</td>
+<td>KEYCODE_META_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e4</td>
+<td>Keyboard Right Control</td>
+<td>0x0061</td>
+<td>KEY_RIGHTCTRL</td>
+<td>3.0</td>
+<td>0x0072</td>
+<td>KEYCODE_CTRL_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e5</td>
+<td>Keyboard Right Shift</td>
+<td>0x0036</td>
+<td>KEY_RIGHTSHIFT</td>
+<td>1.6</td>
+<td>0x003c</td>
+<td>KEYCODE_SHIFT_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e6</td>
+<td>Keyboard Right Alt</td>
+<td>0x0064</td>
+<td>KEY_RIGHTALT</td>
+<td>1.6</td>
+<td>0x003a</td>
+<td>KEYCODE_ALT_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e7</td>
+<td>Keyboard Right GUI</td>
+<td>0x007e</td>
+<td>KEY_RIGHTMETA</td>
+<td>3.0</td>
+<td>0x0076</td>
+<td>KEYCODE_META_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e8</td>
+<td></td>
+<td>0x00a4</td>
+<td>KEY_PLAYPAUSE</td>
+<td>3.0</td>
+<td>0x0055</td>
+<td>KEYCODE_MEDIA_PLAY_PAUSE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e9</td>
+<td></td>
+<td>0x00a6</td>
+<td>KEY_STOPCD</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ea</td>
+<td></td>
+<td>0x00a5</td>
+<td>KEY_PREVIOUSSONG</td>
+<td>3.0</td>
+<td>0x0058</td>
+<td>KEYCODE_MEDIA_PREVIOUS</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00eb</td>
+<td></td>
+<td>0x00a3</td>
+<td>KEY_NEXTSONG</td>
+<td>3.0</td>
+<td>0x0057</td>
+<td>KEYCODE_MEDIA_NEXT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ec</td>
+<td></td>
+<td>0x00a1</td>
+<td>KEY_EJECTCD</td>
+<td>3.0</td>
+<td>0x0081</td>
+<td>KEYCODE_MEDIA_EJECT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ed</td>
+<td></td>
+<td>0x0073</td>
+<td>KEY_VOLUMEUP</td>
+<td>1.6</td>
+<td>0x0018</td>
+<td>KEYCODE_VOLUME_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ee</td>
+<td></td>
+<td>0x0072</td>
+<td>KEY_VOLUMEDOWN</td>
+<td>1.6</td>
+<td>0x0019</td>
+<td>KEYCODE_VOLUME_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ef</td>
+<td></td>
+<td>0x0071</td>
+<td>KEY_MUTE</td>
+<td>3.0</td>
+<td>0x00a4</td>
+<td>KEYCODE_VOLUME_MUTE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f0</td>
+<td></td>
+<td>0x0096</td>
+<td>KEY_WWW</td>
+<td>1.6</td>
+<td>0x0040</td>
+<td>KEYCODE_EXPLORER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f1</td>
+<td></td>
+<td>0x009e</td>
+<td>KEY_BACK</td>
+<td>1.6</td>
+<td>0x0004</td>
+<td>KEYCODE_BACK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f2</td>
+<td></td>
+<td>0x009f</td>
+<td>KEY_FORWARD</td>
+<td>3.0</td>
+<td>0x007d</td>
+<td>KEYCODE_FORWARD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f3</td>
+<td></td>
+<td>0x0080</td>
+<td>KEY_STOP</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f4</td>
+<td></td>
+<td>0x0088</td>
+<td>KEY_FIND</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f5</td>
+<td></td>
+<td>0x00b1</td>
+<td>KEY_SCROLLUP</td>
+<td>3.0</td>
+<td>0x005c</td>
+<td>KEYCODE_PAGE_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f6</td>
+<td></td>
+<td>0x00b2</td>
+<td>KEY_SCROLLDOWN</td>
+<td>3.0</td>
+<td>0x005d</td>
+<td>KEYCODE_PAGE_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f7</td>
+<td></td>
+<td>0x00b0</td>
+<td>KEY_EDIT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f8</td>
+<td></td>
+<td>0x008e</td>
+<td>KEY_SLEEP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f9</td>
+<td></td>
+<td>0x0098</td>
+<td>KEY_COFFEE</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00fa</td>
+<td></td>
+<td>0x00ad</td>
+<td>KEY_REFRESH</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00fb</td>
+<td></td>
+<td>0x008c</td>
+<td>KEY_CALC</td>
+<td>4.0.3</td>
+<td>0x00d2</td>
+<td>KEYCODE_CALCULATOR</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h3 id="hid-generic-desktop-page-0x01">HID Generic Desktop Page (0x01)</h3>
+<table>
+<thead>
+<tr>
+<th>HID Usage</th>
+<th>HID Usage Name</th>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x01 0x0081</td>
+<td>System Power Down</td>
+<td>0x0074</td>
+<td>KEY_POWER</td>
+<td>1.6</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0082</td>
+<td>System Sleep</td>
+<td>0x008e</td>
+<td>KEY_SLEEP</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0083</td>
+<td>System Wake Up</td>
+<td>0x008f</td>
+<td>KEY_WAKEUP</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0084</td>
+<td>System Context Menu</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0085</td>
+<td>System Main Menu</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0086</td>
+<td>System App Menu</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0087</td>
+<td>System Menu Help</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0088</td>
+<td>System Menu Exit</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0089</td>
+<td>System Menu Select</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008a</td>
+<td>System Menu Right</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008b</td>
+<td>System Menu Left</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008c</td>
+<td>System Menu Up</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008d</td>
+<td>System Menu Down</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008e</td>
+<td>System Cold Restart</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008f</td>
+<td>System Warm Restart</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a0</td>
+<td>System Dock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a1</td>
+<td>System Undock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a2</td>
+<td>System Setup</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a3</td>
+<td>System Break</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a4</td>
+<td>System Debugger Break</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a5</td>
+<td>Application Break</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a6</td>
+<td>Application Debugger Break</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a7</td>
+<td>System Speaker Mute</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a8</td>
+<td>System Hibernate</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b0</td>
+<td>System Display Invert</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b1</td>
+<td>System Display Internal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b2</td>
+<td>System Display External</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b3</td>
+<td>System Display Both</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b4</td>
+<td>System Display Dual</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b5</td>
+<td>System Display Toggle Int/Ext</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b6</td>
+<td>System Display Swap Prim./Sec.</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b7</td>
+<td>System Display LCD Autoscale</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h3 id="hid-consumer-page-0x0c">HID Consumer Page (0x0c)</h3>
+<table>
+<thead>
+<tr>
+<th>HID Usage</th>
+<th>HID Usage Name</th>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x0c 0x0030</td>
+<td>Power</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0031</td>
+<td>Reset</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0032</td>
+<td>Sleep</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0033</td>
+<td>Sleep After</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0034</td>
+<td>Sleep Mode</td>
+<td>0x008e</td>
+<td>KEY_SLEEP</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0040</td>
+<td>Menu</td>
+<td>0x008b</td>
+<td>KEY_MENU</td>
+<td>1.6</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0041</td>
+<td>Menu Pick</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0042</td>
+<td>Menu Up</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0043</td>
+<td>Menu Down</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0044</td>
+<td>Menu Left</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0045</td>
+<td>Menu Right</td>
+<td>0x0181</td>
+<td>KEY_RADIO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0046</td>
+<td>Menu Escape</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0047</td>
+<td>Menu Value Increase</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0048</td>
+<td>Menu Value Decrease</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0081</td>
+<td>Assign Selection</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0082</td>
+<td>Mode Step</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0083</td>
+<td>Recall Last</td>
+<td>0x0195</td>
+<td>KEY_LAST</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0084</td>
+<td>Enter Channel</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0085</td>
+<td>Order Movie</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0088</td>
+<td>Media Select Computer</td>
+<td>0x0178</td>
+<td>KEY_PC</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0089</td>
+<td>Media Select TV</td>
+<td>0x0179</td>
+<td>KEY_TV</td>
+<td>3.0</td>
+<td>0x00aa</td>
+<td>KEYCODE_TV</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008a</td>
+<td>Media Select WWW</td>
+<td>0x0096</td>
+<td>KEY_WWW</td>
+<td>1.6</td>
+<td>0x0040</td>
+<td>KEYCODE_EXPLORER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008b</td>
+<td>Media Select DVD</td>
+<td>0x0185</td>
+<td>KEY_DVD</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008c</td>
+<td>Media Select Telephone</td>
+<td>0x00a9</td>
+<td>KEY_PHONE</td>
+<td>3.0</td>
+<td>0x0005</td>
+<td>KEYCODE_CALL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008d</td>
+<td>Media Select Program Guide</td>
+<td>0x016a</td>
+<td>KEY_PROGRAM</td>
+<td>3.0</td>
+<td>0x00ac</td>
+<td>KEYCODE_GUIDE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008e</td>
+<td>Media Select Video Phone</td>
+<td>0x01a0</td>
+<td>KEY_VIDEOPHONE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008f</td>
+<td>Media Select Games</td>
+<td>0x01a1</td>
+<td>KEY_GAMES</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0090</td>
+<td>Media Select Messages</td>
+<td>0x018c</td>
+<td>KEY_MEMO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0091</td>
+<td>Media Select CD</td>
+<td>0x017f</td>
+<td>KEY_CD</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0092</td>
+<td>Media Select VCR</td>
+<td>0x017b</td>
+<td>KEY_VCR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0093</td>
+<td>Media Select Tuner</td>
+<td>0x0182</td>
+<td>KEY_TUNER</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0094</td>
+<td>Quit</td>
+<td>0x00ae</td>
+<td>KEY_EXIT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0095</td>
+<td>Help</td>
+<td>0x008a</td>
+<td>KEY_HELP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0096</td>
+<td>Media Select Tape</td>
+<td>0x0180</td>
+<td>KEY_TAPE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0097</td>
+<td>Media Select Cable</td>
+<td>0x017a</td>
+<td>KEY_TV2</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0098</td>
+<td>Media Select Satellite</td>
+<td>0x017d</td>
+<td>KEY_SAT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0099</td>
+<td>Media Select Security</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x009a</td>
+<td>Media Select Home</td>
+<td>0x016e</td>
+<td>KEY_PVR</td>
+<td>3.0</td>
+<td>0x00ad</td>
+<td>KEYCODE_DVR</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x009c</td>
+<td>Channel Increment</td>
+<td>0x0192</td>
+<td>KEY_CHANNELUP</td>
+<td>3.0</td>
+<td>0x00a6</td>
+<td>KEYCODE_CHANNEL_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x009d</td>
+<td>Channel Decrement</td>
+<td>0x0193</td>
+<td>KEY_CHANNELDOWN</td>
+<td>3.0</td>
+<td>0x00a7</td>
+<td>KEYCODE_CHANNEL_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x009e</td>
+<td>Media Select SAP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a0</td>
+<td>VCR Plus</td>
+<td>0x017c</td>
+<td>KEY_VCR2</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a1</td>
+<td>Once</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a2</td>
+<td>Daily</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a3</td>
+<td>Weekly</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a4</td>
+<td>Monthly</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b0</td>
+<td>Play</td>
+<td>0x00cf</td>
+<td>KEY_PLAY</td>
+<td>3.0</td>
+<td>0x007e</td>
+<td>KEYCODE_MEDIA_PLAY</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b1</td>
+<td>Pause</td>
+<td>0x0077</td>
+<td>KEY_PAUSE</td>
+<td>3.0</td>
+<td>0x0079</td>
+<td>KEYCODE_BREAK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b2</td>
+<td>Record</td>
+<td>0x00a7</td>
+<td>KEY_RECORD</td>
+<td>3.0</td>
+<td>0x0082</td>
+<td>KEYCODE_MEDIA_RECORD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b3</td>
+<td>Fast Forward</td>
+<td>0x00d0</td>
+<td>KEY_FASTFORWARD</td>
+<td>3.0</td>
+<td>0x005a</td>
+<td>KEYCODE_MEDIA_FAST_FORWARD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b4</td>
+<td>Rewind</td>
+<td>0x00a8</td>
+<td>KEY_REWIND</td>
+<td>3.0</td>
+<td>0x0059</td>
+<td>KEYCODE_MEDIA_REWIND</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b5</td>
+<td>Scan Next Track</td>
+<td>0x00a3</td>
+<td>KEY_NEXTSONG</td>
+<td>3.0</td>
+<td>0x0057</td>
+<td>KEYCODE_MEDIA_NEXT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b6</td>
+<td>Scan Previous Track</td>
+<td>0x00a5</td>
+<td>KEY_PREVIOUSSONG</td>
+<td>3.0</td>
+<td>0x0058</td>
+<td>KEYCODE_MEDIA_PREVIOUS</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b7</td>
+<td>Stop</td>
+<td>0x00a6</td>
+<td>KEY_STOPCD</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b8</td>
+<td>Eject</td>
+<td>0x00a1</td>
+<td>KEY_EJECTCD</td>
+<td>3.0</td>
+<td>0x0081</td>
+<td>KEYCODE_MEDIA_EJECT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b9</td>
+<td>Random Play</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00ba</td>
+<td>Select Disc</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00bb</td>
+<td>Enter Disc</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00bc</td>
+<td>Repeat</td>
+<td>0x01b7</td>
+<td>KEY_MEDIA_REPEAT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00be</td>
+<td>Track Normal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c0</td>
+<td>Frame Forward</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c1</td>
+<td>Frame Back</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c2</td>
+<td>Mark</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c3</td>
+<td>Clear Mark</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c4</td>
+<td>Repeat From Mark</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c5</td>
+<td>Return To Mark</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c6</td>
+<td>Search Mark Forward</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c7</td>
+<td>Search Mark Backwards</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c8</td>
+<td>Counter Reset</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c9</td>
+<td>Show Counter</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00ca</td>
+<td>Tracking Increment</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00cb</td>
+<td>Tracking Decrement</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00cc</td>
+<td>Stop / Eject</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00cd</td>
+<td>Play / Pause</td>
+<td>0x00a4</td>
+<td>KEY_PLAYPAUSE</td>
+<td>3.0</td>
+<td>0x0055</td>
+<td>KEYCODE_MEDIA_PLAY_PAUSE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00ce</td>
+<td>Play / Skip</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e2</td>
+<td>Mute</td>
+<td>0x0071</td>
+<td>KEY_MUTE</td>
+<td>3.0</td>
+<td>0x00a4</td>
+<td>KEYCODE_VOLUME_MUTE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e5</td>
+<td>Bass Boost</td>
+<td>0x00d1</td>
+<td>KEY_BASSBOOST</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e6</td>
+<td>Surround Mode</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e7</td>
+<td>Loudness</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e8</td>
+<td>MPX</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e9</td>
+<td>Volume Increment</td>
+<td>0x0073</td>
+<td>KEY_VOLUMEUP</td>
+<td>1.6</td>
+<td>0x0018</td>
+<td>KEYCODE_VOLUME_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00ea</td>
+<td>Volume Decrement</td>
+<td>0x0072</td>
+<td>KEY_VOLUMEDOWN</td>
+<td>1.6</td>
+<td>0x0019</td>
+<td>KEYCODE_VOLUME_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0181</td>
+<td>AL Launch Button Config. Tool</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0182</td>
+<td>AL Programmable Button Config.</td>
+<td>0x009c</td>
+<td>KEY_BOOKMARKS</td>
+<td>3.0</td>
+<td>0x00ae</td>
+<td>KEYCODE_BOOKMARK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0183</td>
+<td>AL Consumer Control Config.</td>
+<td>0x00ab</td>
+<td>KEY_CONFIG</td>
+<td>4.0.3</td>
+<td>0x00d1</td>
+<td>KEYCODE_MUSIC</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0184</td>
+<td>AL Word Processor</td>
+<td>0x01a5</td>
+<td>KEY_WORDPROCESSOR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0185</td>
+<td>AL Text Editor</td>
+<td>0x01a6</td>
+<td>KEY_EDITOR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0186</td>
+<td>AL Spreadsheet</td>
+<td>0x01a7</td>
+<td>KEY_SPREADSHEET</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0187</td>
+<td>AL Graphics Editor</td>
+<td>0x01a8</td>
+<td>KEY_GRAPHICSEDITOR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0188</td>
+<td>AL Presentation App</td>
+<td>0x01a9</td>
+<td>KEY_PRESENTATION</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0189</td>
+<td>AL Database App</td>
+<td>0x01aa</td>
+<td>KEY_DATABASE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018a</td>
+<td>AL Email Reader</td>
+<td>0x009b</td>
+<td>KEY_MAIL</td>
+<td>1.6</td>
+<td>0x0041</td>
+<td>KEYCODE_ENVELOPE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018b</td>
+<td>AL Newsreader</td>
+<td>0x01ab</td>
+<td>KEY_NEWS</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018c</td>
+<td>AL Voicemail</td>
+<td>0x01ac</td>
+<td>KEY_VOICEMAIL</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018d</td>
+<td>AL Contacts / Address Book</td>
+<td>0x01ad</td>
+<td>KEY_ADDRESSBOOK</td>
+<td>4.0.3</td>
+<td>0x00cf</td>
+<td>KEYCODE_CONTACTS</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018e</td>
+<td>AL Calendar / Schedule</td>
+<td>0x018d</td>
+<td>KEY_CALENDAR</td>
+<td>4.0.3</td>
+<td>0x00d0</td>
+<td>KEYCODE_CALENDAR</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018f</td>
+<td>AL Task / Project Manager</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0190</td>
+<td>AL Log / Journal / Timecard</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0191</td>
+<td>AL Checkbook / Finance</td>
+<td>0x00db</td>
+<td>KEY_FINANCE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0192</td>
+<td>AL Calculator</td>
+<td>0x008c</td>
+<td>KEY_CALC</td>
+<td>4.0.3</td>
+<td>0x00d2</td>
+<td>KEYCODE_CALCULATOR</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0193</td>
+<td>AL A/V Capture / Playback</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0194</td>
+<td>AL Local Machine Browser</td>
+<td>0x0090</td>
+<td>KEY_FILE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0195</td>
+<td>AL LAN/WAN Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0196</td>
+<td>AL Internet Browser</td>
+<td>0x0096</td>
+<td>KEY_WWW</td>
+<td>1.6</td>
+<td>0x0040</td>
+<td>KEYCODE_EXPLORER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0197</td>
+<td>AL Remote Networking/ISP Connect</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0198</td>
+<td>AL Network Conference</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0199</td>
+<td>AL Network Chat</td>
+<td>0x00d8</td>
+<td>KEY_CHAT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019a</td>
+<td>AL Telephony / Dialer</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019b</td>
+<td>AL Logon</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019c</td>
+<td>AL Logoff</td>
+<td>0x01b1</td>
+<td>KEY_LOGOFF</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019d</td>
+<td>AL Logon / Logoff</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019e</td>
+<td>AL Terminal Lock / Screensaver</td>
+<td>0x0098</td>
+<td>KEY_COFFEE</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019f</td>
+<td>AL Control Panel</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a0</td>
+<td>AL Command Line Processor / Run</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a1</td>
+<td>AL Process / Task Manager</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a2</td>
+<td>AL Select Task / Application</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a3</td>
+<td>AL Next Task / Application</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a4</td>
+<td>AL Previous Task / Application</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a5</td>
+<td>AL Preemptive Halt Task / App.</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a6</td>
+<td>AL Integrated Help Center</td>
+<td>0x008a</td>
+<td>KEY_HELP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a7</td>
+<td>AL Documents</td>
+<td>0x00eb</td>
+<td>KEY_DOCUMENTS</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a8</td>
+<td>AL Thesaurus</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a9</td>
+<td>AL Dictionary</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01aa</td>
+<td>AL Desktop</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ab</td>
+<td>AL Spell Check</td>
+<td>0x01b0</td>
+<td>KEY_SPELLCHECK</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ac</td>
+<td>AL Grammar Check</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ad</td>
+<td>AL Wireless Status</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ae</td>
+<td>AL Keyboard Layout</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01af</td>
+<td>AL Virus Protection</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b0</td>
+<td>AL Encryption</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b1</td>
+<td>AL Screen Saver</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b2</td>
+<td>AL Alarms</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b3</td>
+<td>AL Clock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b4</td>
+<td>AL File Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b5</td>
+<td>AL Power Status</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b6</td>
+<td>AL Image Browser</td>
+<td>0x00e2</td>
+<td>KEY_MEDIA</td>
+<td>3.0</td>
+<td>0x004f</td>
+<td>KEYCODE_HEADSETHOOK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b7</td>
+<td>AL Audio Browser</td>
+<td>0x00d5</td>
+<td>KEY_SOUND</td>
+<td>4.0.3</td>
+<td>0x00d1</td>
+<td>KEYCODE_MUSIC</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b8</td>
+<td>AL Movie Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b9</td>
+<td>AL Digital Rights Manager</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ba</td>
+<td>AL Digital Wallet</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01bc</td>
+<td>AL Instant Messaging</td>
+<td>0x01ae</td>
+<td>KEY_MESSENGER</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01bd</td>
+<td>AL OEM Features / Tips Browser</td>
+<td>0x0166</td>
+<td>KEY_INFO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01be</td>
+<td>AL OEM Help</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01bf</td>
+<td>AL Online Community</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c0</td>
+<td>AL Entertainment Content Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c1</td>
+<td>AL Online Shopping Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c2</td>
+<td>AL SmartCard Information / Help</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c3</td>
+<td>AL Market / Finance Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c4</td>
+<td>AL Customized Corp. News Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c5</td>
+<td>AL Online Activity Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c6</td>
+<td>AL Research / Search Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c7</td>
+<td>AL Audio Player</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0201</td>
+<td>AC New</td>
+<td>0x00b5</td>
+<td>KEY_NEW</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0202</td>
+<td>AC Open</td>
+<td>0x0086</td>
+<td>KEY_OPEN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0203</td>
+<td>AC Close</td>
+<td>0x00ce</td>
+<td>KEY_CLOSE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0204</td>
+<td>AC Exit</td>
+<td>0x00ae</td>
+<td>KEY_EXIT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0205</td>
+<td>AC Maximize</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0206</td>
+<td>AC Minimize</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0207</td>
+<td>AC Save</td>
+<td>0x00ea</td>
+<td>KEY_SAVE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0208</td>
+<td>AC Print</td>
+<td>0x00d2</td>
+<td>KEY_PRINT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0209</td>
+<td>AC Properties</td>
+<td>0x0082</td>
+<td>KEY_PROPS</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021a</td>
+<td>AC Undo</td>
+<td>0x0083</td>
+<td>KEY_UNDO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021b</td>
+<td>AC Copy</td>
+<td>0x0085</td>
+<td>KEY_COPY</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021c</td>
+<td>AC Cut</td>
+<td>0x0089</td>
+<td>KEY_CUT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021d</td>
+<td>AC Paste</td>
+<td>0x0087</td>
+<td>KEY_PASTE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021e</td>
+<td>AC Select All</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021f</td>
+<td>AC Find</td>
+<td>0x0088</td>
+<td>KEY_FIND</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0220</td>
+<td>AC Find and Replace</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0221</td>
+<td>AC Search</td>
+<td>0x00d9</td>
+<td>KEY_SEARCH</td>
+<td>1.6</td>
+<td>0x0054</td>
+<td>KEYCODE_SEARCH</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0222</td>
+<td>AC Go To</td>
+<td>0x0162</td>
+<td>KEY_GOTO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0223</td>
+<td>AC Home</td>
+<td>0x00ac</td>
+<td>KEY_HOMEPAGE</td>
+<td>3.0</td>
+<td>0x0003</td>
+<td>KEYCODE_HOME</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0224</td>
+<td>AC Back</td>
+<td>0x009e</td>
+<td>KEY_BACK</td>
+<td>1.6</td>
+<td>0x0004</td>
+<td>KEYCODE_BACK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0225</td>
+<td>AC Forward</td>
+<td>0x009f</td>
+<td>KEY_FORWARD</td>
+<td>3.0</td>
+<td>0x007d</td>
+<td>KEYCODE_FORWARD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0226</td>
+<td>AC Stop</td>
+<td>0x0080</td>
+<td>KEY_STOP</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0227</td>
+<td>AC Refresh</td>
+<td>0x00ad</td>
+<td>KEY_REFRESH</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0228</td>
+<td>AC Previous Link</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0229</td>
+<td>AC Next Link</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022a</td>
+<td>AC Bookmarks</td>
+<td>0x009c</td>
+<td>KEY_BOOKMARKS</td>
+<td>3.0</td>
+<td>0x00ae</td>
+<td>KEYCODE_BOOKMARK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022b</td>
+<td>AC History</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022c</td>
+<td>AC Subscriptions</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022d</td>
+<td>AC Zoom In</td>
+<td>0x01a2</td>
+<td>KEY_ZOOMIN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022e</td>
+<td>AC Zoom Out</td>
+<td>0x01a3</td>
+<td>KEY_ZOOMOUT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022f</td>
+<td>AC Zoom</td>
+<td>0x01a4</td>
+<td>KEY_ZOOMRESET</td>
+<td></td>
+<td></td>
+<td></td>
+<td>2</td>
+</tr>
+<tr>
+<td>0x0c 0x0230</td>
+<td>AC Full Screen View</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0231</td>
+<td>AC Normal View</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0232</td>
+<td>AC View Toggle</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0233</td>
+<td>AC Scroll Up</td>
+<td>0x00b1</td>
+<td>KEY_SCROLLUP</td>
+<td>3.0</td>
+<td>0x005c</td>
+<td>KEYCODE_PAGE_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0234</td>
+<td>AC Scroll Down</td>
+<td>0x00b2</td>
+<td>KEY_SCROLLDOWN</td>
+<td>3.0</td>
+<td>0x005d</td>
+<td>KEYCODE_PAGE_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0236</td>
+<td>AC Pan Left</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0237</td>
+<td>AC Pan Right</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0239</td>
+<td>AC New Window</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023a</td>
+<td>AC Tile Horizontally</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023b</td>
+<td>AC Tile Vertically</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023c</td>
+<td>AC Format</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023d</td>
+<td>AC Edit</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023e</td>
+<td>AC Bold</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023f</td>
+<td>AC Italics</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0240</td>
+<td>AC Underline</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0241</td>
+<td>AC Strikethrough</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0242</td>
+<td>AC Subscript</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0243</td>
+<td>AC Superscript</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0244</td>
+<td>AC All Caps</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0245</td>
+<td>AC Rotate</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0246</td>
+<td>AC Resize</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0247</td>
+<td>AC Flip horizontal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0248</td>
+<td>AC Flip Vertical</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0249</td>
+<td>AC Mirror Horizontal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024a</td>
+<td>AC Mirror Vertical</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024b</td>
+<td>AC Font Select</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024c</td>
+<td>AC Font Color</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024d</td>
+<td>AC Font Size</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024e</td>
+<td>AC Justify Left</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024f</td>
+<td>AC Justify Center H</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0250</td>
+<td>AC Justify Right</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0251</td>
+<td>AC Justify Block H</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0252</td>
+<td>AC Justify Top</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0253</td>
+<td>AC Justify Center V</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0254</td>
+<td>AC Justify Bottom</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0255</td>
+<td>AC Justify Block V</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0256</td>
+<td>AC Indent Decrease</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0257</td>
+<td>AC Indent Increase</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0258</td>
+<td>AC Numbered List</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0259</td>
+<td>AC Restart Numbering</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025a</td>
+<td>AC Bulleted List</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025b</td>
+<td>AC Promote</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025c</td>
+<td>AC Demote</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025d</td>
+<td>AC Yes</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025e</td>
+<td>AC No</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025f</td>
+<td>AC Cancel</td>
+<td>0x00df</td>
+<td>KEY_CANCEL</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0260</td>
+<td>AC Catalog</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0261</td>
+<td>AC Buy / Checkout</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0262</td>
+<td>AC Add to Cart</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0263</td>
+<td>AC Expand</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0264</td>
+<td>AC Expand All</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0265</td>
+<td>AC Collapse</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0266</td>
+<td>AC Collapse All</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0267</td>
+<td>AC Print Preview</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0268</td>
+<td>AC Paste Special</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0269</td>
+<td>AC Insert Mode</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026a</td>
+<td>AC Delete</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026b</td>
+<td>AC Lock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026c</td>
+<td>AC Unlock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026d</td>
+<td>AC Protect</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026e</td>
+<td>AC Unprotect</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026f</td>
+<td>AC Attach Comment</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0270</td>
+<td>AC Delete Comment</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0271</td>
+<td>AC View Comment</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0272</td>
+<td>AC Select Word</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0273</td>
+<td>AC Select Sentence</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0274</td>
+<td>AC Select Paragraph</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0275</td>
+<td>AC Select Column</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0276</td>
+<td>AC Select Row</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0277</td>
+<td>AC Select Table</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0278</td>
+<td>AC Select Object</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0279</td>
+<td>AC Redo / Repeat</td>
+<td>0x00b6</td>
+<td>KEY_REDO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027a</td>
+<td>AC Sort</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027b</td>
+<td>AC Sort Ascending</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027c</td>
+<td>AC Sort Descending</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027d</td>
+<td>AC Filter</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027e</td>
+<td>AC Set Clock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027f</td>
+<td>AC View Clock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0280</td>
+<td>AC Select Time Zone</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0281</td>
+<td>AC Edit Time Zones</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0282</td>
+<td>AC Set Alarm</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0283</td>
+<td>AC Clear Alarm</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0284</td>
+<td>AC Snooze Alarm</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0285</td>
+<td>AC Reset Alarm</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0286</td>
+<td>AC Synchronize</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0287</td>
+<td>AC Send/Receive</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0288</td>
+<td>AC Send To</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0289</td>
+<td>AC Reply</td>
+<td>0x00e8</td>
+<td>KEY_REPLY</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028a</td>
+<td>AC Reply All</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028b</td>
+<td>AC Forward Msg</td>
+<td>0x00e9</td>
+<td>KEY_FORWARDMAIL</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028c</td>
+<td>AC Send</td>
+<td>0x00e7</td>
+<td>KEY_SEND</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028d</td>
+<td>AC Attach File</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028e</td>
+<td>AC Upload</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028f</td>
+<td>AC Download (Save Target As)</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0290</td>
+<td>AC Set Borders</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0291</td>
+<td>AC Insert Row</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0292</td>
+<td>AC Insert Column</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0293</td>
+<td>AC Insert File</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0294</td>
+<td>AC Insert Picture</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0295</td>
+<td>AC Insert Object</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0296</td>
+<td>AC Insert Symbol</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0297</td>
+<td>AC Save and Close</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0298</td>
+<td>AC Rename</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0299</td>
+<td>AC Merge</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x029a</td>
+<td>AC Split</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x029b</td>
+<td>AC Distribute Horizontally</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x029c</td>
+<td>AC Distribute Vertically</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h3 id="additional-non-hid-mappings">Additional non-HID Mappings</h3>
+<p>These mappings describe functions that do not appear in HID but for which Linux
+key codes exist.</p>
+<table>
+<thead>
+<tr>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x01d0</td>
+<td>KEY_FN</td>
+<td>3.0</td>
+<td>0x0077</td>
+<td>KEYCODE_FUNCTION</td>
+<td></td>
+</tr>
+<tr>
+<td>0x01d1</td>
+<td>KEY_FN_ESC</td>
+<td>3.0</td>
+<td>0x006f</td>
+<td>KEYCODE_ESCAPE</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d2</td>
+<td>KEY_FN_F1</td>
+<td>3.0</td>
+<td>0x0083</td>
+<td>KEYCODE_F1</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d3</td>
+<td>KEY_FN_F2</td>
+<td>3.0</td>
+<td>0x0084</td>
+<td>KEYCODE_F2</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d4</td>
+<td>KEY_FN_F3</td>
+<td>3.0</td>
+<td>0x0085</td>
+<td>KEYCODE_F3</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d5</td>
+<td>KEY_FN_F4</td>
+<td>3.0</td>
+<td>0x0086</td>
+<td>KEYCODE_F4</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d6</td>
+<td>KEY_FN_F5</td>
+<td>3.0</td>
+<td>0x0087</td>
+<td>KEYCODE_F5</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d7</td>
+<td>KEY_FN_F6</td>
+<td>3.0</td>
+<td>0x0088</td>
+<td>KEYCODE_F6</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d8</td>
+<td>KEY_FN_F7</td>
+<td>3.0</td>
+<td>0x0089</td>
+<td>KEYCODE_F7</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d9</td>
+<td>KEY_FN_F8</td>
+<td>3.0</td>
+<td>0x008a</td>
+<td>KEYCODE_F8</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01da</td>
+<td>KEY_FN_F9</td>
+<td>3.0</td>
+<td>0x008b</td>
+<td>KEYCODE_F9</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01db</td>
+<td>KEY_FN_F10</td>
+<td>3.0</td>
+<td>0x008c</td>
+<td>KEYCODE_F10</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01dc</td>
+<td>KEY_FN_F11</td>
+<td>3.0</td>
+<td>0x008d</td>
+<td>KEYCODE_F11</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01dd</td>
+<td>KEY_FN_F12</td>
+<td>3.0</td>
+<td>0x008e</td>
+<td>KEYCODE_F12</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01de</td>
+<td>KEY_FN_1</td>
+<td>3.0</td>
+<td>0x0008</td>
+<td>KEYCODE_1</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01df</td>
+<td>KEY_FN_2</td>
+<td>3.0</td>
+<td>0x0009</td>
+<td>KEYCODE_2</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e0</td>
+<td>KEY_FN_D</td>
+<td>3.0</td>
+<td>0x0020</td>
+<td>KEYCODE_D</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e1</td>
+<td>KEY_FN_E</td>
+<td>3.0</td>
+<td>0x0021</td>
+<td>KEYCODE_E</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e2</td>
+<td>KEY_FN_F</td>
+<td>3.0</td>
+<td>0x0022</td>
+<td>KEYCODE_F</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e3</td>
+<td>KEY_FN_S</td>
+<td>3.0</td>
+<td>0x002f</td>
+<td>KEYCODE_S</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e4</td>
+<td>KEY_FN_B</td>
+<td>3.0</td>
+<td>0x001e</td>
+<td>KEYCODE_B</td>
+<td>3</td>
+</tr>
+</tbody>
+</table>
+<h3 id="legacy-unsupported-keys">Legacy Unsupported Keys</h3>
+<p>These mappings appeared in previous versions of Android but were inconsistent with
+HID or used non-standard Linux key codes.  They are no longer supported.</p>
+<table>
+<thead>
+<tr>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x00db</td>
+<td>KEY_EMAIL</td>
+<td>1.6</td>
+<td>0x004d</td>
+<td>KEYCODE_AT</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e3</td>
+<td>KEY_STAR</td>
+<td>1.6</td>
+<td>0x0011</td>
+<td>KEYCODE_STAR</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e4</td>
+<td>KEY_SHARP</td>
+<td>1.6</td>
+<td>0x0012</td>
+<td>KEYCODE_POUND</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e5</td>
+<td>KEY_SOFT1</td>
+<td>1.6</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e6</td>
+<td>KEY_SOFT2</td>
+<td>1.6</td>
+<td>0x0002</td>
+<td>KEYCODE_SOFT_RIGHT</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e7</td>
+<td>KEY_SEND</td>
+<td>1.6</td>
+<td>0x0005</td>
+<td>KEYCODE_CALL</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e8</td>
+<td>KEY_CENTER</td>
+<td>1.6</td>
+<td>0x0017</td>
+<td>KEYCODE_DPAD_CENTER</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e9</td>
+<td>KEY_HEADSETHOOK</td>
+<td>1.6</td>
+<td>0x004f</td>
+<td>KEYCODE_HEADSETHOOK</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00ea</td>
+<td>KEY_0_5</td>
+<td>1.6</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00eb</td>
+<td>KEY_2_5</td>
+<td>1.6</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+</tbody>
+</table>
+<h3 id="notes">Notes</h3>
+<ol>
+<li>
+<p>The Android key code associated with common alphanumeric and symbolic
+    keys may vary based on the keyboard layout and language.
+    For historical reasons, the physical scan codes and HID usages
+    associated with keys on a keyboard are often defined positionally
+    even though the labels printed on those keys may vary from one
+    language to another.</p>
+<p>On a US English (QWERTY) keyboard, the top-left alphabetic key is
+labeled Q.  On a French (AZERTY) keyboard, the key in the same
+position is labeled A.  Despite the label, on both keyboards the
+top-left alphabetic key is referred to using the HID usage
+0x07 0x0014 which is mapped to the Linux key code KEY_Q.</p>
+<p>When Android is configured with a US English keyboard layout, then
+the Linux key code KEY_Q will be mapped to the Android key code
+KEYCODE_Q and will produce the characters 'Q' and 'q'.
+However, when Android is configured with a French keyboard layout,
+then the Linux key code KEY_Q will be mapped to the Android key code
+KEYCODE_A and will produce the characters 'A' and 'a'.</p>
+<p>The Android key code typically reflects the language-specific
+interpretation of the key, so a different Android key code may
+be used for different languages.</p>
+</li>
+<li>
+<p><code>0x0c 0x022f AC Zoom</code> is defined in the HID as a linear control but
+    the kernel maps it as a key, which is probably incorrect.</p>
+</li>
+<li>
+<p>The Linux function keys <code>KEY_FN_*</code> are mapped to simpler
+    key codes but are dispatched with the <code>META_FUNCTION</code> meta state
+    bit set to true.</p>
+</li>
+<li>
+<p>Prior to Android Ice Cream Sandwich 4.0, the default key layout
+    contained mappings for some extra key codes that were not defined
+    in the mainline Linux kernel headers.  These mappings have since
+    been removed because these previously undefined key codes have
+    since been assigned different meanings in more recent versions
+    of the Linux kernel.</p>
+</li>
+</ol>
+<h3 id="sources">Sources</h3>
+<ol>
+<li><a href="http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf">USB HID Usage Tables v1.12</a></li>
+<li>Linux 2.6.39 kernel: include/linux/input.h, drivers/hid/hid-input.c</li>
+<li>Android ICS: qwerty.kl, Generic.kl, KeyEvent.java</li>
+</ol>
diff --git a/src/devices/tech/input/migration-guide.jd b/src/devices/tech/input/migration-guide.jd
new file mode 100644
index 0000000..dbdf666
--- /dev/null
+++ b/src/devices/tech/input/migration-guide.jd
@@ -0,0 +1,55 @@
+page.title=Migration Guide
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>This document contains a few helpful tips when migrating to new Android releases.</p>
+<h2 id="migrating-to-android-gingerbread-23">Migrating to Android Gingerbread 2.3</h2>
+<p>In Gingerbread, we added the concept of input device configuration files
+(also referred to as input device calibration files in this release).</p>
+<p>Make sure to provide an input device configuration file for all touch screens.
+In particular, it is worth spending time providing a calibration reference for
+touch size information.</p>
+<h2 id="migrating-to-android-honeycomb-30">Migrating to Android Honeycomb 3.0</h2>
+<p>In Honeycomb, we revised the key character map file format and started making
+greater use of input device configuration files.  We also added support for full
+PC-style keyboards and introduced a new "Generic" key map, which
+replaced the older emulator-specific "qwerty" key map (which was never
+intended to be used as a general-purpose key map.)</p>
+<p>Make sure to update all of your key character map files to use the new syntax.</p>
+<p>If your peripherals relied on the old "qwerty" key map, then you
+may need to provide new device-specific key maps to emulate the old behavior.
+You should create a new key map for each device identified either by
+USB product id / vendor id or by device name.</p>
+<p>It is especially important to provide key character map files for all special
+function input devices.  These files should simple contain a line to set
+the keyboard type to <code>SPECIAL_FUNCTION</code>.</p>
+<p>A good way to ensure that all built-in input devices are appropriately configured
+is to run <a href="/tech/input/dumpsys.html">Dumpsys</a> and look for devices that
+are inappropriately using <code>Generic.kcm</code>.</p>
+<h2 id="migrating-to-android-honeycomb-32">Migrating to Android Honeycomb 3.2</h2>
+<p>In Honeycomb 3.2, we added support for joysticks and extended the key layout file
+format to enable joystick axis mapping.</p>
+<h2 id="migrating-to-android-ice-cream-sandwich-40">Migrating to Android Ice Cream Sandwich 4.0</h2>
+<p>In Ice Cream Sandwich 4.0, we changed the device driver requirements for touch screens
+to follow the standard Linux multitouch input protocol and added support for
+protocol "B".  We also support digitizer tablets and stylus-based touch devices.</p>
+<p>You will probably need to update your input device driver to implement the Linux
+multitouch input protocol correctly according to the standard.</p>
+<p>You will also need to update your input device configuration files because some
+properties have been changed to be simpler and more systematic.</p>
+<p>Refer to <a href="/tech/input/touch-devices.html">Touch Devices</a> for more details about
+driver requirements.</p>
\ No newline at end of file
diff --git a/src/devices/tech/input/overview.jd b/src/devices/tech/input/overview.jd
new file mode 100644
index 0000000..cbf86b9
--- /dev/null
+++ b/src/devices/tech/input/overview.jd
@@ -0,0 +1,237 @@
+page.title=Overview
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>The Android input subsystem nominally consists of an event pipeline
+that traverses multiple layers of the system.</p>
+<h2 id="input-pipeline">Input Pipeline</h2>
+<p>At the lowest layer, the physical input device produces signals that
+describe state changes such as key presses and touch contact points.
+The device firmware encodes and transmits these signals in some way
+such as by sending USB HID reports to the system or by producing
+interrupts on an I2C bus.</p>
+<p>The signals are then decoded by a device driver in the Linux kernel.
+The Linux kernel provides drivers for many standard peripherals,
+particularly those that adhere to the HID protocol.  However, an OEM
+must often provide custom drivers for embedded devices that are
+tightly integrated into the system at a low-level, such as touch screens.</p>
+<p>The input device drivers are responsible for translating device-specific
+signals into a standard input event format, by way of the Linux
+input protocol.  The Linux input protocol defines a standard set of
+event types and codes in the <code>linux/input.h</code> kernel header file.
+In this way, components outside the kernel do not need to care about
+the details such as physical scan codes, HID usages, I2C messages,
+GPIO pins, and the like.</p>
+<p>Next, the Android <code>EventHub</code> component reads input events from the kernel
+by opening the <code>evdev</code> driver associated with each input device.
+The Android InputReader component then decodes the input events
+according to the device class and produces a stream of Android input
+events.  As part of this process, the Linux input protocol event codes
+are translated into Android event codes according to the
+input device configuration, keyboard layout files, and various
+mapping tables.</p>
+<p>Finally, the <code>InputReader</code> sends input events to the InputDispatcher
+which forwards them to the appropriate window.</p>
+<h2 id="control-points">Control Points</h2>
+<p>There are several stages in the input pipeline which effect control
+over the behavior of the input device.</p>
+<h3 id="driver-and-firmware-configuration">Driver and Firmware Configuration</h3>
+<p>Input device drivers frequently configure the behavior of the input
+device by setting parameters in registers or even uploading the
+firmware itself.  This is particularly the case for embedded
+devices such as touch screens where a large part of the calibration
+process involves tuning these parameters or fixing the firmware
+to provide the desired accuracy and responsiveness and to suppress
+noise.</p>
+<p>Driver configuration options are often specified as module parameters
+in the kernel board support package (BSP) so that the same driver
+can support multiple different hardware implementations.</p>
+<p>This documentation does attempt to describe driver or firmware
+configuration, but it does offer guidance as to device calibration
+in general.</p>
+<h3 id="board-configuration-properties">Board Configuration Properties</h3>
+<p>The kernel board support package (BSP) may export board configuration
+properties via SysFS that are used by the Android InputReader component,
+such as the placement of virtual keys on a touch screen.</p>
+<p>Refer to the device class sections for details about how different
+devices use board configuration properties.</p>
+<h3 id="resource-overlays">Resource Overlays</h3>
+<p>A few input behaviors are configured by way of resource overlays
+in <code>config.xml</code> such as the operation of lid switch.</p>
+<p>Here are a few examples:</p>
+<ul>
+<li>
+<p><code>config_lidKeyboardAccessibility</code>: Specifies the effect of the
+    lid switch on whether the hardware keyboard is accessible or hidden.</p>
+</li>
+<li>
+<p><code>config_lidNavigationAccessibility</code>: Specifies the effect of the
+    lid switch on whether the trackpad is accessible or hidden.</p>
+</li>
+<li>
+<p><code>config_longPressOnPowerBehavior</code>: Specifies what should happen when
+    the user holds down the power button.</p>
+</li>
+<li>
+<p><code>config_lidOpenRotation</code>: Specifies the effect of the lid switch
+    on screen orientation.</p>
+</li>
+</ul>
+<p>Refer to the documentation within <code>frameworks/base/core/res/res/values/config.xml</code>
+for details about each configuration option.</p>
+<h3 id="key-maps">Key Maps</h3>
+<p>Key maps are used by the Android <code>EventHub</code> and <code>InputReader</code> components
+to configure the mapping from Linux event codes to Android event codes
+for keys, joystick buttons and joystick axes.  The mapping may
+be device or language dependent.</p>
+<p>Refer to the device class sections for details about how different
+devices use key maps.</p>
+<h3 id="input-device-configuration-files">Input Device Configuration Files</h3>
+<p>Input device configuration files are used by the Android <code>EventHub</code> and
+<code>InputReader</code> components to configure special device characteristics
+such as how touch size information is reported.</p>
+<p>Refer to the device class sections for details about how different
+devices use input device configuration maps.</p>
+<h2 id="understanding-hid-usages-and-event-codes">Understanding HID Usages and Event Codes</h2>
+<p>There are often several different identifiers used to refer to any
+given key on a keyboard, button on a game controller, joystick axis
+or other control.  The relationships between these identifiers
+are not always the same: they are dependent on a set of mapping tables,
+some of which are fixed, and some which vary based on characteristics
+of the device, the device driver, the current locale, the system
+configuration, user preferences and other factors.</p>
+<dl>
+<dt>Physical Scan Code</dt>
+<dd>
+<p>A physical scan code is a device-specific identifier that is associated
+with each key, button or other control.  Because physical scan codes
+often vary from one device to another, the firmware or device driver
+is responsible for mapping them to standard identifiers such as
+HID Usages or Linux key codes.</p>
+<p>Scan codes are mainly of interest for keyboards.  Other devices
+typically communicate at a low-level using GPIO pins, I2C messages
+or other means.  Consequently, the upper layers of the software
+stack rely on the device drivers to make sense of what is going on.</p>
+</dd>
+<dt>HID Usage</dt>
+<dd>
+<p>A HID usage is a standard identifier that is used to report the
+state of a control such as a keyboard key, joystick axis,
+mouse button, or touch contact point.  Most USB and Bluetooth
+input devices conform to the HID specification, which enables
+the system to interface with them in a uniform manner.</p>
+<p>The Android Framework relies on the Linux kernel HID drivers to
+translate HID usage codes into Linux key codes and other identifiers.
+Therefore HID usages are mainly of interest to peripheral manufacturers.</p>
+</dd>
+<dt>Linux Key Code</dt>
+<dd>
+<p>A Linux key code is a standard identifier for a key or button.
+Linux key codes are defined in the <code>linux/input.h</code> header file using
+constants that begin with the prefix <code>KEY_</code> or <code>BTN_</code>.  The Linux
+kernel input drivers are responsible for translating physical
+scan codes, HID usages and other device-specific signals into Linux
+key codes and delivering information about them as part of
+<code>EV_KEY</code> events.</p>
+<p>The Android API sometimes refers to the Linux key code associated
+with a key as its "scan code".  This is technically incorrect in
+but it helps to distinguish Linux key codes from Android key codes
+in the API.</p>
+</dd>
+<dt>Linux Relative or Absolute Axis Code</dt>
+<dd>
+<p>A Linux relative or absolute axis code is a standard identifier
+for reporting relative movements or absolute positions along an
+axis, such as the relative movements of a mouse along its X axis
+or the absolute position of a joystick along its X axis.
+Linux axis code are defined in the <code>linux/input.h</code> header file using
+constants that begin with the prefix <code>REL_</code> or <code>ABS_</code>.  The Linux
+kernel input drivers are responsible for translating HID usages
+and other device-specific signals into Linux axis codes and
+delivering information about them as part of <code>EV_REL</code> and
+<code>EV_ABS</code> events.</p>
+</dd>
+<dt>Linux Switch Code</dt>
+<dd>
+<p>A Linux switch code is a standard identifier for reporting the
+state of a switch on a device, such as a lid switch.  Linux
+switch codes are defined in the <code>linux/input.h</code> header file
+using constants that begin with the prefix <code>SW_</code>.  The Linux
+kernel input drivers report switch state changes as <code>EV_SW</code> events.</p>
+<p>Android applications generally do not receive events from switches,
+but the system may use them interally to control various
+device-specific functions.</p>
+</dd>
+<dt>Android Key Code</dt>
+<dd>
+<p>An Android key code is a standard identifier defined in the Android
+API for indicating a particular key such as 'HOME'.  Android key codes
+are defined by the <code>android.view.KeyEvent</code> class as constants that
+begin with the prefix <code>KEYCODE_</code>.</p>
+<p>The key layout specifies how Linux key codes are mapped to Android
+key codes.  Different key layouts may be used depending on the keyboard
+model, language, country, layout, or special functions.</p>
+<p>Combinations of Android key codes are transformed into character codes
+using a device and locale specific key character map.  For example,
+when the keys identified as <code>KEYCODE_SHIFT</code> and <code>KEYCODE_A</code> are both
+pressed together, the system looks up the combination in the key
+character map and finds the capital letter 'A', which is then inserted
+into the currently focused text widget.</p>
+</dd>
+<dt>Android Axis Code</dt>
+<dd>
+<p>An Android axis code is a standard identifier defined in the Android
+API for indicating a particular device axis.  Android axis codes are
+defined by the <code>android.view.MotionEvent</code> class as constants that
+begin with the prefix <code>AXIS_</code>.</p>
+<p>The key layout specifies how Linux Axis Codes are mapped to Android
+axis codes.  Different key layouts may be used depending on the device
+model, language, country, layout, or special functions.</p>
+</dd>
+<dt>Android Meta State</dt>
+<dd>
+<p>An Android meta state is a standard identifier defined in the Android
+API for indicating which modifier keys are pressed.  Android meta states
+are defined by the <code>android.view.KeyEvent</code> class as constants that
+begin with the prefix <code>META_</code>.</p>
+<p>The current meta state is determined by the Android InputReader
+component which monitors when modifier keys such as <code>KEYCODE_SHIFT_LEFT</code>
+are pressed / released and sets / resets the appropriate meta state flag.</p>
+<p>The relationship between modifier keys and meta states is hardcoded
+but the key layout can alter how the modifier keys themselves are
+mapped which in turns affects the meta states.</p>
+</dd>
+<dt>Android Button State</dt>
+<dd>
+<p>An Android button state is a standard identifier defined in the Android
+API for indicating which buttons (on a mouse or stylus) are pressed.
+Android button states are defined by the <code>android.view.MotionEvent</code>
+class as constants that begin with the prefix <code>BUTTON_</code>.</p>
+<p>The current button state is determined by the Android InputReader
+component which monitors when buttons (on a mouse or stylus) are
+pressed / released and sets / resets appropriate button state flag.</p>
+<p>The relationship between buttons and button states is hardcoded.</p>
+</dd>
+</dl>
+<h2 id="further-reading">Further Reading</h2>
+<ol>
+<li><a href="http://www.kernel.org/doc/Documentation/input/event-codes.txt">Linux input event codes</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt">Linux multi-touch protocol</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/input.txt">Linux input drivers</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/ff.txt">Linux force feedback</a></li>
+<li><a href="http://www.usb.org/developers/hidpage">HID information, including HID usage tables</a></li>
+</ol>
diff --git a/src/devices/tech/input/touch-devices.jd b/src/devices/tech/input/touch-devices.jd
new file mode 100644
index 0000000..21567d3
--- /dev/null
+++ b/src/devices/tech/input/touch-devices.jd
@@ -0,0 +1,1163 @@
+page.title=Touch Devices
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>Android supports a variety of touch screens and touch pads, including
+stylus-based digitizer tablets.</p>
+<p>Touch screens are touch devices that are associated with a display such that
+the user has the impression of directly manipulating items on screen.</p>
+<p>Touch pads are touch devices that are not associated with a display such as a
+digitizer tablet.  Touch pads are typically used for pointing or for
+absolute indirect positioning or gesture-based control of a user interface.</p>
+<p>Touch devices may have buttons whose functions are similar to mouse buttons.</p>
+<p>Touch devices can sometimes be manipulated using a variety of different tools
+such as fingers or a stylus depending on the underlying touch sensor technology.</p>
+<p>Touch devices are sometimes used to implement virtual keys.  For example, on
+some Android devices, the touch screen sensor area extends beyond the edge of
+the display and serves dual purpose as part of a touch sensitive key pad.</p>
+<p>Due to the great variety of touch devices, Android relies on a large number of
+configuration properties to describe the characteristics and desired behavior
+of each device.</p>
+<h2 id="touch-device-classification">Touch Device Classification</h2>
+<p>An input device is classified as a <em>multi-touch</em> device if both of
+the following conditions hold:</p>
+<ul>
+<li>
+<p>The input device reports the presence of the <code>ABS_MT_POSITION_X</code> and
+    <code>ABS_MT_POSITION_Y</code> absolute axes.</p>
+</li>
+<li>
+<p>The input device does not have any gamepad buttons.  This condition
+    resolves an ambiguity with certain gamepads that report axes with codes
+    that overlaps those of the MT axes.</p>
+</li>
+</ul>
+<p>An input device is classified as a <em>single-touch</em> device if both of the
+following conditions hold:</p>
+<ul>
+<li>
+<p>The input device is not classified as a multi-touch device.  An input device
+    is either classified as a single-touch device or as a multi-touch device,
+    never both.</p>
+</li>
+<li>
+<p>The input device reports the presence of the <code>ABS_X</code> and <code>ABS_Y</code> absolute
+    axes, and the presence of the <code>BTN_TOUCH</code> key code.</p>
+</li>
+</ul>
+<p>Once an input device has been classified as a touch device, the presence
+of virtual keys is determined by attempting to load the virtual key map file
+for the device.  If a virtual key map is available, then the key layout
+file for the device is also loaded.</p>
+<p>Refer to the section below about the location and format of virtual key map
+files.</p>
+<p>Next, the system loads the input device configuration file for the touch device.</p>
+<p><strong>All built-in touch devices should have input device configuration files.</strong>
+If no input device configuration file is present, the system will
+choose a default configuration that is appropriate for typical general-purpose
+touch peripherals such as external USB or Bluetooth HID touch screens
+or touch pads.  These defaults are not designed for built-in touch screens and
+will most likely result in incorrect behavior.</p>
+<p>After the input device configuration loaded, the system will classify the
+input device as a <em>touch screen</em>, <em>touch pad</em> or <em>pointer</em> device.</p>
+<ul>
+<li>
+<p>A <em>touch screen</em> device is used for direct manipulation of objects on the
+    screen.  Since the user is directly touching the screen, the system does
+    not require any additional affordances to indicate the objects being
+    manipulated.</p>
+</li>
+<li>
+<p>A <em>touch pad</em> device is used to provide absolute positioning information
+    to an application about touches on a given sensor area.  It may be useful
+    for digitizer tablets.</p>
+</li>
+<li>
+<p>A <em>pointer</em> device is used for indirect manipulation of objects on the
+    screen using a cursor.  Fingers are interpreted as multi-touch pointer
+    gestures.  Other tools, such as styluses, are interpreted using
+    absolute positions.</p>
+<p>See <a href="#indirect-multi-touch-pointer-gestures">Indirect Multi-touch Pointer Gestures</a>
+for more information.</p>
+</li>
+</ul>
+<p>The following rules are used to classify the input device as a <em>touch screen</em>,
+<em>touch pad</em> or <em>pointer</em> device.</p>
+<ul>
+<li>
+<p>If the <code>touch.deviceType</code> property is set, then the device type will be
+    set as indicated.</p>
+</li>
+<li>
+<p>If the input device reports the presence of the <code>INPUT_PROP_DIRECT</code>
+    input property (via the <code>EVIOCGPROP</code> ioctl), then the device type will
+    be set to <em>touch screen</em>.  This condition assumes that direct input touch
+    devices are attached to a display that is also connected.</p>
+</li>
+<li>
+<p>If the input device reports the presence of the <code>INPUT_PROP_POINTER</code>
+    input property (via the <code>EVIOCGPROP</code> ioctl), then the device type will
+    be set to <em>pointer</em>.</p>
+</li>
+<li>
+<p>If the input device reports the presence of the <code>REL_X</code> or <code>REL_Y</code> relative
+    axes, then the device type will be set to <em>touch pad</em>.  This condition
+    resolves an ambiguity for input devices that consist of both a mouse and
+    a touch pad.  In this case, the touch pad will not be used to control
+    the pointer because the mouse already controls it.</p>
+</li>
+<li>
+<p>Otherwise, the device type will be set to <em>pointer</em>.  This default ensures
+    that touch pads that have not been designated any other special purpose
+    will serve to control the pointer.</p>
+</li>
+</ul>
+<h2 id="buttons">Buttons</h2>
+<p>Buttons are <em>optional</em> controls that may be used by applications to perform
+additional functions.  Buttons on touch devices behave similarly to mouse
+buttons and are mainly of use with <em>pointer</em> type touch devices or with a
+stylus.</p>
+<p>The following buttons are supported:</p>
+<ul>
+<li>
+<p><code>BTN_LEFT</code>: mapped to <code>MotionEvent.BUTTON_PRIMARY</code>.</p>
+</li>
+<li>
+<p><code>BTN_RIGHT</code>: mapped to <code>MotionEvent.BUTTON_SECONDARY</code>.</p>
+</li>
+<li>
+<p><code>BTN_MIDDLE</code>: mapped to <code>MotionEvent.BUTTON_MIDDLE</code>.</p>
+</li>
+<li>
+<p><code>BTN_BACK</code> and <code>BTN_SIDE</code>: mapped to <code>MotionEvent.BUTTON_BACK</code>.
+    Pressing this button also synthesizes a key press with the key code
+    <code>KeyEvent.KEYCODE_BACK</code>.</p>
+</li>
+<li>
+<p><code>BTN_FORWARD</code> and <code>BTN_EXTRA</code>: mapped to <code>MotionEvent.BUTTON_FORWARD</code>.
+    Pressing this button also synthesizes a key press with the key code
+    <code>KeyEvent.KEYCODE_FORWARD</code>.</p>
+</li>
+<li>
+<p><code>BTN_STYLUS</code>: mapped to <code>MotionEvent.BUTTON_SECONDARY</code>.</p>
+</li>
+<li>
+<p><code>BTN_STYLUS2</code>: mapped to <code>MotionEvent.BUTTON_TERTIARY</code>.</p>
+</li>
+</ul>
+<h2 id="tools-and-tool-types">Tools and Tool Types</h2>
+<p>A <em>tool</em> is a finger, stylus or other apparatus that is used to interact with
+the touch device.  Some touch devices can distinguish between different
+types of tools.</p>
+<p>Elsewhere in Android, as in the <code>MotionEvent</code> API, a <em>tool</em> is often referred
+to as a <em>pointer</em>.</p>
+<p>The following tool types are supported:</p>
+<ul>
+<li>
+<p><code>BTN_TOOL_FINGER</code> and <code>MT_TOOL_FINGER</code>: mapped to <code>MotionEvent.TOOL_TYPE_FINGER</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_PEN</code> and <code>MT_TOOL_PEN</code>: mapped to <code>MotionEvent.TOOL_TYPE_STYLUS</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_RUBBER</code>: mapped to <code>MotionEvent.TOOL_TYPE_ERASER</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_BRUSH</code>: mapped to <code>MotionEvent.TOOL_TYPE_STYLUS</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_PENCIL</code>: mapped to <code>MotionEvent.TOOL_TYPE_STYLUS</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_AIRBRUSH</code>: mapped to <code>MotionEvent.TOOL_TYPE_STYLUS</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_MOUSE</code>: mapped to <code>MotionEvent.TOOL_TYPE_MOUSE</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_LENS</code>: mapped to <code>MotionEvent.TOOL_TYPE_MOUSE</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_DOUBLETAP</code>, <code>BTN_TOOL_TRIPLETAP</code>, and <code>BTN_TOOL_QUADTAP</code>:
+    mapped to <code>MotionEvent.TOOL_TYPE_FINGER</code>.</p>
+</li>
+</ul>
+<h2 id="hovering-vs-touching-tools">Hovering vs. Touching Tools</h2>
+<p>Tools can either be in contact with the touch device or in range and hovering
+above it.  Not all touch devices are able to sense the presence of a tool
+hovering above the touch device.  Those that do, such as RF-based stylus digitizers,
+can often detect when the tool is within a limited range of the digitizer.</p>
+<p>The <code>InputReader</code> component takes care to distinguish touching tools from hovering
+tools.  Likewise, touching tools and hovering tools are reported to applications
+in different ways.</p>
+<p>Touching tools are reported to applications as touch events
+using <code>MotionEvent.ACTION_DOWN</code>, <code>MotionEvent.ACTION_MOVE</code>, <code>MotionEvent.ACTION_DOWN</code>,
+<code>MotionEvent.ACTION_POINTER_DOWN</code> and <code>MotionEvent.ACTION_POINTER_UP</code>.</p>
+<p>Hovering tools are reported to applications as generic motion events using
+<code>MotionEvent.ACTION_HOVER_ENTER</code>, <code>MotionEvent.ACTION_HOVER_MOVE</code>
+and <code>MotionEvent.ACTION_HOVER_EXIT</code>.</p>
+<h2 id="touch-device-driver-requirements">Touch Device Driver Requirements</h2>
+<ol>
+<li>
+<p>Touch device drivers should only register axes and key codes for the axes
+    and buttons that they actually support.  Registering excess axes or key codes
+    may confuse the device classification algorithm or cause the system to incorrectly
+    detect the capabilities of the device.</p>
+<p>For example, if the device reports the <code>BTN_TOUCH</code> key code, the system will
+assume that <code>BTN_TOUCH</code> will always be used to indicate whether the tool is
+actually touching the screen or is merely in range and hovering.</p>
+</li>
+<li>
+<p>Single-touch devices use the following Linux input events:</p>
+<ul>
+<li>
+<p><code>ABS_X</code>: <em>(REQUIRED)</em> Reports the X coordinate of the tool.</p>
+</li>
+<li>
+<p><code>ABS_Y</code>: <em>(REQUIRED)</em> Reports the Y coordinate of the tool.</p>
+</li>
+<li>
+<p><code>ABS_PRESSURE</code>: <em>(optional)</em> Reports the physical pressure applied to the tip
+    of the tool or the signal strength of the touch contact.</p>
+</li>
+<li>
+<p><code>ABS_TOOL_WIDTH</code>: <em>(optional)</em> Reports the cross-sectional area or width of the
+    touch contact or of the tool itself.</p>
+</li>
+<li>
+<p><code>ABS_DISTANCE</code>: <em>(optional)</em> Reports the distance of the tool from the surface of
+    the touch device.</p>
+</li>
+<li>
+<p><code>ABS_TILT_X</code>: <em>(optional)</em> Reports the tilt of the tool from the surface of the
+    touch device along the X axis.</p>
+</li>
+<li>
+<p><code>ABS_TILT_Y</code>: <em>(optional)</em> Reports the tilt of the tool from the surface of the
+    touch device along the Y axis.</p>
+</li>
+<li>
+<p><code>BTN_TOUCH</code>: <em>(REQUIRED)</em> Indicates whether the tool is touching the device.</p>
+</li>
+<li>
+<p><code>BTN_LEFT</code>, <code>BTN_RIGHT</code>, <code>BTN_MIDDLE</code>, <code>BTN_BACK</code>, <code>BTN_SIDE</code>, <code>BTN_FORWARD</code>,
+    <code>BTN_EXTRA</code>, <code>BTN_STYLUS</code>, <code>BTN_STYLUS2</code>:
+    <em>(optional)</em> Reports <a href="#buttons">button</a> states.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_FINGER</code>, <code>BTN_TOOL_PEN</code>, <code>BTN_TOOL_RUBBER</code>, <code>BTN_TOOL_BRUSH</code>,
+    <code>BTN_TOOL_PENCIL</code>, <code>BTN_TOOL_AIRBRUSH</code>, <code>BTN_TOOL_MOUSE</code>, <code>BTN_TOOL_LENS</code>,
+    <code>BTN_TOOL_DOUBLETAP</code>, <code>BTN_TOOL_TRIPLETAP</code>, <code>BTN_TOOL_QUADTAP</code>:
+    <em>(optional)</em> Reports the <a href="#tools-and-tool-types">tool type</a>.</p>
+</li>
+</ul>
+</li>
+<li>
+<p>Multi-touch devices use the following Linux input events:</p>
+<ul>
+<li>
+<p><code>ABS_MT_POSITION_X</code>: <em>(REQUIRED)</em> Reports the X coordinate of the tool.</p>
+</li>
+<li>
+<p><code>ABS_MT_POSITION_Y</code>: <em>(REQUIRED)</em> Reports the Y coordinate of the tool.</p>
+</li>
+<li>
+<p><code>ABS_MT_PRESSURE</code>: <em>(optional)</em> Reports the physical pressure applied to the
+    tip of the tool or the signal strength of the touch contact.</p>
+</li>
+<li>
+<p><code>ABS_MT_TOUCH_MAJOR</code>: <em>(optional)</em> Reports the cross-sectional area of the
+    touch contact, or the length of the longer dimension of the touch contact.</p>
+</li>
+<li>
+<p><code>ABS_MT_TOUCH_MINOR</code>: <em>(optional)</em> Reports the length of the shorter dimension of the
+    touch contact.  This axis should not be used if <code>ABS_MT_TOUCH_MAJOR</code> is reporting an
+    area measurement.</p>
+</li>
+<li>
+<p><code>ABS_MT_WIDTH_MAJOR</code>: <em>(optional)</em> Reports the cross-sectional area of the tool itself,
+    or the length of the longer dimension of the tool itself.
+    This axis should not be used if the dimensions of the tool itself are unknown.</p>
+</li>
+<li>
+<p><code>ABS_MT_WIDTH_MINOR</code>: <em>(optional)</em> Reports the length of the shorter dimension of
+    the tool itself. This axis should not be used if <code>ABS_MT_WIDTH_MAJOR</code> is reporting
+    an area measurement or if the dimensions of the tool itself are unknown.</p>
+</li>
+<li>
+<p><code>ABS_MT_ORIENTATION</code>: <em>(optional)</em> Reports the orientation of the tool.</p>
+</li>
+<li>
+<p><code>ABS_MT_DISTANCE</code>: <em>(optional)</em> Reports the distance of the tool from the
+    surface of the touch device.</p>
+</li>
+<li>
+<p><code>ABS_MT_TOOL_TYPE</code>: <em>(optional)</em> Reports the <a href="#tools-and-tool-types">tool type</a> as
+    <code>MT_TOOL_FINGER</code> or <code>MT_TOOL_PEN</code>.</p>
+</li>
+<li>
+<p><code>ABS_MT_TRACKING_ID</code>: <em>(optional)</em> Reports the tracking id of the tool.
+    The tracking id is an arbitrary non-negative integer that is used to identify
+    and track each tool independently when multiple tools are active.  For example,
+    when multiple fingers are touching the device, each finger should be assigned a distinct
+    tracking id that is used as long as the finger remains in contact.  Tracking ids
+    may be reused when their associated tools move out of range.</p>
+</li>
+<li>
+<p><code>ABS_MT_SLOT</code>: <em>(optional)</em> Reports the slot id of the tool, when using the Linux
+    multi-touch protocol 'B'.  Refer to the Linux multi-touch protocol documentation
+    for more details.</p>
+</li>
+<li>
+<p><code>BTN_TOUCH</code>: <em>(REQUIRED)</em> Indicates whether the tool is touching the device.</p>
+</li>
+<li>
+<p><code>BTN_LEFT</code>, <code>BTN_RIGHT</code>, <code>BTN_MIDDLE</code>, <code>BTN_BACK</code>, <code>BTN_SIDE</code>, <code>BTN_FORWARD</code>,
+    <code>BTN_EXTRA</code>, <code>BTN_STYLUS</code>, <code>BTN_STYLUS2</code>:
+    <em>(optional)</em> Reports <a href="#buttons">button</a> states.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_FINGER</code>, <code>BTN_TOOL_PEN</code>, <code>BTN_TOOL_RUBBER</code>, <code>BTN_TOOL_BRUSH</code>,
+    <code>BTN_TOOL_PENCIL</code>, <code>BTN_TOOL_AIRBRUSH</code>, <code>BTN_TOOL_MOUSE</code>, <code>BTN_TOOL_LENS</code>,
+    <code>BTN_TOOL_DOUBLETAP</code>, <code>BTN_TOOL_TRIPLETAP</code>, <code>BTN_TOOL_QUADTAP</code>:
+    <em>(optional)</em> Reports the <a href="#tools-and-tool-types">tool type</a>.</p>
+</li>
+</ul>
+</li>
+<li>
+<p>If axes for both the single-touch and multi-touch protocol are defined, then
+    only the multi-touch axes will be used and the single-touch axes will be ignored.</p>
+</li>
+<li>
+<p>The minimum and maximum values of the <code>ABS_X</code>, <code>ABS_Y</code>, <code>ABS_MT_POSITION_X</code>
+    and <code>ABS_MT_POSITION_Y</code> axes define the bounds of the active area of the device
+    in device-specific surface units.  In the case of a touch screen, the active area
+    describes the part of the touch device that actually covers the display.</p>
+<p>For a touch screen, the system automatically interpolates the reported touch
+positions in surface units to obtain touch positions in display pixels according
+to the following calculation:</p>
+<pre><code>displayX = (x - minX) * displayWidth / (maxX - minX + 1)
+displayY = (y - minY) * displayHeight / (maxY - minY + 1)
+</code></pre>
+<p>A touch screen may report touches outside of the reported active area.</p>
+<p>Touches that are initiated outside the active area are not delivered to applications
+but may be used for virtual keys.</p>
+<p>Touches that are initiated inside the active area, or that enter and exit the display
+area are delivered to applications.  Consequently, if a touch starts within the
+bounds of an application and then moves outside of the active area, the application
+may receive touch events with display coordinates that are negative or beyond the
+bounds of the display.  This is expected behavior.</p>
+<p>A touch device should never clamp touch coordinates to the bounds of the active
+area.  If a touch exits the active area, it should be reported as being outside of
+the active area, or it should not be reported at all.</p>
+<p>For example, if the user's finger is touching near the top-left corner of the
+touch screen, it may report a coordinate of (minX, minY).  If the finger continues
+to move further outside of the active area, the touch screen should either start
+reporting coordinates with components less than minX and minY, such as
+(minX - 2, minY - 3), or it should stop reporting the touch altogether.
+In other words, the touch screen should <em>not</em> be reporting (minX, minY)
+when the user's finger is really touching outside of the active area.</p>
+<p>Clamping touch coordinates to the display edge creates an artificial
+hard boundary around the edge of the screen which prevents the system from
+smoothly tracking motions that enter or exit the bounds of the display area.</p>
+</li>
+<li>
+<p>The values reported by <code>ABS_PRESSURE</code> or <code>ABS_MT_PRESSURE</code>, if they
+    are reported at all, must be non-zero when the tool is touching the device
+    and zero otherwise to indicate that the tool is hovering.</p>
+<p>Reporting pressure information is <em>optional</em> but strongly recommended.
+Applications can use pressure information to implement pressure-sensitive drawing
+and other effects.</p>
+</li>
+<li>
+<p>The values reported by <code>ABS_TOOL_WIDTH</code>, <code>ABS_MT_TOUCH_MAJOR</code>, <code>ABS_MT_TOUCH_MINOR</code>,
+    <code>ABS_MT_WIDTH_MAJOR</code>, or <code>ABS_MT_WIDTH_MINOR</code> should be non-zero when the tool
+    is touching the device and zero otherwise, but this is not required.
+    For example, the touch device may be able to measure the size of finger touch
+    contacts but not stylus touch contacts.</p>
+<p>Reporting size information is <em>optional</em> but strongly recommended.
+Applications can use pressure information to implement size-sensitive drawing
+and other effects.</p>
+</li>
+<li>
+<p>The values reported by <code>ABS_DISTANCE</code> or <code>ABS_MT_DISTANCE</code> should approach
+    zero when the tool is touching the device.  The distance may remain non-zero
+    even when the tool is in direct contact.  The exact values reported depend
+    on the manner in which the hardware measures distance.</p>
+<p>Reporting distance information is <em>optional</em> but recommended for
+stylus devices.</p>
+</li>
+<li>
+<p>The values reported by <code>ABS_TILT_X</code> and <code>ABS_TILT_Y</code> should be zero when the
+    tool is perpendicular to the device.  A non-zero tilt is taken as an indication
+    that the tool is held at an incline.</p>
+<p>The tilt angles along the X and Y axes are assumed to be specified in degrees
+from perpendicular.  The center point (perfectly perpendicular) is given
+by <code>(max + min) / 2</code> for each axis.  Values smaller than the center point
+represent a tilt up or to the left, values larger than the center point
+represent a tilt down or to the right.</p>
+<p>The <code>InputReader</code> converts the X and Y tilt components into a perpendicular
+tilt angle ranging from 0 to <code>PI / 2</code> radians and a planar orientation angle
+ranging from <code>-PI</code> to <code>PI</code> radians.  This representation results in a
+description of orientation that is compatible with what is used to describe
+finger touches.</p>
+<p>Reporting tilt information is <em>optional</em> but recommended for stylus devices.</p>
+</li>
+<li>
+<p>If the tool type is reported by <code>ABS_MT_TOOL_TYPE</code>, it will supercede any tool
+    type information reported by <code>BTN_TOOL_*</code>.
+    If no tool type information is available at all, the tool type defaults to
+    <code>MotionEvent.TOOL_TYPE_FINGER</code>.</p>
+</li>
+<li>
+<p>A tool is determined to be active based on the following conditions:</p>
+<ul>
+<li>
+<p>When using the single-touch protocol, the tool is active if <code>BTN_TOUCH</code>,
+    or <code>BTN_TOOL_*</code> is 1.</p>
+<p>This condition implies that the <code>InputReader</code> needs to have at least some
+information about the nature of the tool, either whether it is touching,
+or at least its tool type.  If no information is available,
+then the tool is assumed to be inactive (out of range).</p>
+</li>
+<li>
+<p>When using the multi-touch protocol 'A', the tool is active whenever it
+    appears in the most recent sync report.  When the tool stops appearing in
+    sync reports, it ceases to exist.</p>
+</li>
+<li>
+<p>When using the multi-touch protocol 'B', the tool is active as long as
+    it has an active slot.  When the slot it cleared, the tool ceases to exist.</p>
+</li>
+</ul>
+</li>
+<li>
+<p>A tool is determined to be hovering based on the following conditions:</p>
+<ul>
+<li>
+<p>If the tool is <code>BTN_TOOL_MOUSE</code> or <code>BTN_TOOL_LENS</code>, then the tool
+    is not hovering, even if either of the following conditions are true.</p>
+</li>
+<li>
+<p>If the tool is active and the driver reports pressure information,
+    and the reported pressure is zero, then the tool is hovering.</p>
+</li>
+<li>
+<p>If the tool is active and the driver supports the <code>BTN_TOUCH</code> key code and
+    <code>BTN_TOUCH</code> has a value of zero, then the tool is hovering.</p>
+</li>
+</ul>
+</li>
+<li>
+<p>The <code>InputReader</code> supports both multi-touch protocol 'A' and 'B'.  New drivers
+    should use the 'B' protocol but either will work.</p>
+</li>
+<li>
+<p><strong>As of Android Ice Cream Sandwich 4.0, touch screen drivers may need to be changed
+    to comply with the Linux input protocol specification.</strong></p>
+<p>The following changes may be required:</p>
+<ul>
+<li>
+<p>When a tool becomes inactive (finger goes "up"), it should stop appearing
+    in subsequent multi-touch sync reports.  When all tools become inactive
+    (all fingers go "up"), the driver should send an empty sync report packet,
+    such as <code>SYN_MT_REPORT</code> followed by <code>SYN_REPORT</code>.</p>
+<p>Previous versions of Android expected "up" events to be reported by sending
+a pressure value of 0.  The old behavior was incompatible with the
+Linux input protocol specification and is no longer supported.</p>
+</li>
+<li>
+<p>Physical pressure or signal strength information should be reported using
+    <code>ABS_MT_PRESSURE</code>.</p>
+<p>Previous versions of Android retrieved pressure information from
+<code>ABS_MT_TOUCH_MAJOR</code>.  The old behavior was incompatible with the
+Linux input protocol specification and is no longer supported.</p>
+</li>
+<li>
+<p>Touch size information should be reported using <code>ABS_MT_TOUCH_MAJOR</code>.</p>
+<p>Previous versions of Android retrieved size information from
+<code>ABS_MT_TOOL_MAJOR</code>.  The old behavior was incompatible with the
+Linux input protocol specification and is no longer supported.</p>
+</li>
+</ul>
+<p>Touch device drivers no longer need Android-specific customizations.
+By relying on the standard Linux input protocol, Android can support a
+wider variety of touch peripherals, such as external HID multi-touch
+touch screens, using unmodified drivers.</p>
+</li>
+</ol>
+<h2 id="touch-device-operation">Touch Device Operation</h2>
+<p>The following is a brief summary of the touch device operation on Android.</p>
+<ol>
+<li>
+<p>The <code>EventHub</code> reads raw events from the <code>evdev</code> driver.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> consumes the raw events and updates internal state about
+    the position and other characteristics of each tool.  It also tracks
+    button states.</p>
+</li>
+<li>
+<p>If the BACK or FORWARD buttons were pressed or released, the <code>InputReader</code>
+    notifies the <code>InputDispatcher</code> about the key event.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> determines whether a virtual key press occurred.  If so,
+    it notifies the <code>InputDispatcher</code> about the key event.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> determines whether the touch was initiated within the
+    bounds of the display.  If so, it notifies the <code>InputDispatcher</code> about
+    the touch event.</p>
+</li>
+<li>
+<p>If there are no touching tools but there is at least one hovering tool,
+    the <code>InputReader</code> notifies the <code>InputDispatcher</code> about the hover event.</p>
+</li>
+<li>
+<p>If the touch device type is <em>pointer</em>, the <code>InputReader</code> performs pointer
+    gesture detection, moves the pointer and spots accordingly and notifies
+    the <code>InputDispatcher</code> about the pointer event.</p>
+</li>
+<li>
+<p>The <code>InputDispatcher</code> uses the <code>WindowManagerPolicy</code> to determine whether
+    the events should be dispatched and whether they should wake the device.
+    Then, the <code>InputDispatcher</code> delivers the events to the appropriate applications.</p>
+</li>
+</ol>
+<h2 id="touch-device-configuration">Touch Device Configuration</h2>
+<p>Touch device behavior is determined by the device's axes, buttons, input properties,
+input device configuration, virtual key map and key layout.</p>
+<p>Refer to the following sections for more details about the files that
+participate in keyboard configuration:</p>
+<ul>
+<li><a href="/tech/input/input-device-configuration-files.html">Input Device Configuration Files</a></li>
+<li><a href="#virtual-key-map-files">Virtual Key Map Files</a></li>
+</ul>
+<h3 id="properties">Properties</h3>
+<p>The system relies on many input device configuration properties to configure
+and calibrate touch device behavior.</p>
+<p>One reason for this is that the device drivers for touch devices often report
+the characteristics of touches using device-specific units.</p>
+<p>For example, many touch devices measure the touch contact area
+using an internal device-specific scale, such as the total number of
+sensor nodes that were triggered by the touch.  This raw size value would
+not be meaningful applications because they would need to know about the
+physical size and other characteristics of the touch device sensor nodes.</p>
+<p>The system uses calibration parameters encoded in input device configuration
+files to decode, transform, and normalize the values reported by the touch
+device into a simpler standard representation that applications can understand.</p>
+<h3 id="documentation-conventions">Documentation Conventions</h3>
+<p>For documentation purposes, we will use the following conventions to describe
+the values used by the system during the calibration process.</p>
+<h4 id="raw-axis-values">Raw Axis Values</h4>
+<p>The following expressions denote the raw values reported by the touch
+device driver as <code>EV_ABS</code> events.</p>
+<dl>
+<dt><code>raw.x</code></dt>
+<dd>The value of the <code>ABS_X</code> or <code>ABS_MT_POSITION_X</code> axis.</dd>
+<dt><code>raw.y</code></dt>
+<dd>The value of the <code>ABS_Y</code> or <code>ABS_MT_POSITION_Y</code> axis.</dd>
+<dt><code>raw.pressure</code></dt>
+<dd>The value of the <code>ABS_PRESSURE</code> or <code>ABS_MT_PRESSURE</code> axis, or 0 if not available.</dd>
+<dt><code>raw.touchMajor</code></dt>
+<dd>The value of the <code>ABS_MT_TOUCH_MAJOR</code> axis, or 0 if not available.</dd>
+<dt><code>raw.touchMinor</code></dt>
+<dd>The value of the <code>ABS_MT_TOUCH_MINOR</code> axis, or <code>raw.touchMajor</code> if not available.</dd>
+<dt><code>raw.toolMajor</code></dt>
+<dd>The value of the <code>ABS_TOOL_WIDTH</code> or <code>ABS_MT_WIDTH_MAJOR</code> axis, or 0 if not available.</dd>
+<dt><code>raw.toolMinor</code></dt>
+<dd>The value of the <code>ABS_MT_WIDTH_MINOR</code> axis, or <code>raw.toolMajor</code> if not available.</dd>
+<dt><code>raw.orientation</code></dt>
+<dd>The value of the <code>ABS_MT_ORIENTATION</code> axis, or 0 if not available.</dd>
+<dt><code>raw.distance</code></dt>
+<dd>The value of the <code>ABS_DISTANCE</code> or <code>ABS_MT_DISTANCE</code> axis, or 0 if not available.</dd>
+<dt><code>raw.tiltX</code></dt>
+<dd>The value of the <code>ABS_TILT_X</code> axis, or 0 if not available.</dd>
+<dt><code>raw.tiltY</code></dt>
+<dd>The value of the <code>ABS_TILT_Y</code> axis, or 0 if not available.</dd>
+</dl>
+<h4 id="raw-axis-ranges">Raw Axis Ranges</h4>
+<p>The following expressions denote the bounds of raw values.  They are obtained
+by calling <code>EVIOCGABS</code> ioctl for each axis.</p>
+<dl>
+<dt><code>raw.*.min</code></dt>
+<dd>The inclusive minimum value of the raw axis.</dd>
+<dt><code>raw.*.max</code></dt>
+<dd>The inclusive maximum value of the raw axis.</dd>
+<dt><code>raw.*.range</code></dt>
+<dd>Equivalent to <code>raw.*.max - raw.*.min</code>.</dd>
+<dt><code>raw.*.fuzz</code></dt>
+<dd>The accuracy of the raw axis.  eg. fuzz = 1 implies values are accurate to +/- 1 unit.</dd>
+<dt><code>raw.width</code></dt>
+<dd>The inclusive width of the touch area, equivalent to <code>raw.x.range + 1</code>.</dd>
+<dt><code>raw.height</code></dt>
+<dd>The inclusive height of the touch area, equivalent to <code>raw.y.range + 1</code>.</dd>
+</dl>
+<h4 id="output-ranges">Output Ranges</h4>
+<p>The following expressions denote the characteristics of the output coordinate system.
+The system uses linear interpolation to translate touch position information from
+the surface units used by the touch device into the output units that will
+be reported to applications such as display pixels.</p>
+<dl>
+<dt><code>output.width</code></dt>
+<dd>The output width.  For touch screens (associated with a display), this
+is the display width in pixels.  For touch pads (not associated with a display),
+the output width equals <code>raw.width</code>, indicating that no interpolation will
+be performed.</dd>
+<dt><code>output.height</code></dt>
+<dd>The output height.  For touch screens (associated with a display), this
+is the display height in pixels.  For touch pads (not associated with a display),
+the output height equals <code>raw.height</code>, indicating that no interpolation will
+be performed.</dd>
+<dt><code>output.diag</code></dt>
+<dd>The diagonal length of the output coordinate system, equivalent to
+<code>sqrt(output.width ^2 + output.height ^2)</code>.</dd>
+</dl>
+<h3 id="basic-configuration">Basic Configuration</h3>
+<p>The touch input mapper uses many configuration properties in the input device
+configuration file to specify calibration values.  The following table describes
+some general purpose configuration properties.  All other properties are described
+in the following sections along with the fields they are used to calibrate.</p>
+<h4 id="touchdevicetype"><code>touch.deviceType</code></h4>
+<p><em>Definition:</em> <code>touch.deviceType</code> = <code>touchScreen</code> | <code>touchPad</code> | <code>pointer</code> | <code>default</code></p>
+<p>Specifies the touch device type.</p>
+<ul>
+<li>
+<p>If the value is <code>touchScreen</code>, the touch device is a touch screen associated
+    with a display.</p>
+</li>
+<li>
+<p>If the value is <code>touchPad</code>, the touch device is a touch pad not associated
+    with a display.</p>
+</li>
+<li>
+<p>If the value is <code>pointer</code>, the touch device is a touch pad not associated
+    with a display, and its motions are used for
+    <a href="#indirect-multi-touch-pointer-gestures">indirect multi-touch pointer gestures</a>.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system automatically detects the device type
+    according to the classification algorithm.</p>
+</li>
+</ul>
+<p>Refer to the <a href="#touch-device-classification">Classification</a> section for more details
+about how the device type influences the behavior of the touch device.</p>
+<p>Prior to Honeycomb, all touch devices were assumed to be touch screens.</p>
+<h4 id="touchorientationaware"><code>touch.orientationAware</code></h4>
+<p><em>Definition:</em> <code>touch.orientationAware</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the touch device should react to display orientation changes.</p>
+<ul>
+<li>
+<p>If the value is <code>1</code>, touch positions reported by the touch device are rotated
+    whenever the display orientation changes.</p>
+</li>
+<li>
+<p>If the value is <code>0</code>, touch positions reported by the touch device are immune
+    to display orientation changes.</p>
+</li>
+</ul>
+<p>The default value is <code>1</code> if the device is a touch screen, <code>0</code> otherwise.</p>
+<p>The system distinguishes between internal and external touch screens and displays.
+An orientation aware internal touch screen is rotated based on the orientation
+of the internal display.  An orientation aware external touch screen is rotated
+based on the orientation of the external display.</p>
+<p>Orientation awareness is used to support rotation of touch screens on devices
+like the Nexus One.  For example, when the device is rotated clockwise 90 degrees
+from its natural orientation, the absolute positions of touches are remapped such
+that a touch in the top-left corner of the touch screen's absolute coordinate system
+is reported as a touch in the top-left corner of the display's rotated coordinate system.
+This is done so that touches are reported with the same coordinate system that
+applications use to draw their visual elements.</p>
+<p>Prior to Honeycomb, all touch devices were assumed to be orientation aware.</p>
+<h4 id="touchgesturemode"><code>touch.gestureMode</code></h4>
+<p><em>Definition:</em> <code>touch.gestureMode</code> = <code>pointer</code> | <code>spots</code> | <code>default</code></p>
+<p>Specifies the presentation mode for pointer gestures.  This configuration property
+is only relevant when the touch device is of type <em>pointer</em>.</p>
+<ul>
+<li>
+<p>If the value is <code>pointer</code>, the touch pad gestures are presented by way of a cursor
+    similar to a mouse pointer.</p>
+</li>
+<li>
+<p>If the value is <code>spots</code>, the touch pad gestures are presented by an anchor
+    that represents the centroid of the gesture and a set of circular spots
+    that represent the position of individual fingers.</p>
+</li>
+</ul>
+<p>The default value is <code>pointer</code> when the <code>INPUT_PROP_SEMI_MT</code> input property
+is set, or <code>spots</code> otherwise.</p>
+<h3 id="x-and-y-fields"><code>X</code> and <code>Y</code> Fields</h3>
+<p>The X and Y fields provide positional information for the center of the contact area.</p>
+<h4 id="calculation">Calculation</h4>
+<p>The calculation is straightforward: positional information from the touch driver is
+linearly interpolated to the output coordinate system.</p>
+<pre><code>xScale = output.width / raw.width
+yScale = output.height / raw.height
+
+If not orientation aware or screen rotation is 0 degrees:
+output.x = (raw.x - raw.x.min) * xScale
+output.y = (raw.y - raw.y.min) * yScale
+Else If rotation is 90 degrees:
+    output.x = (raw.y - raw.y.min) * yScale
+    output.y = (raw.x.max - raw.x) * xScale
+Else If rotation is 180 degrees:
+    output.x = (raw.x.max - raw.x) * xScale
+    output.y = (raw.y.max - raw.y) * yScale
+Else If rotation is 270 degrees:
+    output.x = (raw.y.max - raw.y) * yScale
+    output.y = (raw.x - raw.x.min) * xScale
+End If
+</code></pre>
+<h3 id="touchmajor-touchminor-toolmajor-toolminor-size-fields"><code>TouchMajor</code>, <code>TouchMinor</code>, <code>ToolMajor</code>, <code>ToolMinor</code>, <code>Size</code> Fields</h3>
+<p>The <code>TouchMajor</code> and <code>TouchMinor</code> fields describe the approximate dimensions
+of the contact area in output units (pixels).</p>
+<p>The <code>ToolMajor</code> and <code>ToolMinor</code> fields describe the approximate dimensions
+of the <a href="#tools-and-tool-types">tool</a> itself in output units (pixels).</p>
+<p>The <code>Size</code> field describes the normalized size of the touch relative to
+the largest possible touch that the touch device can sense.  The smallest
+possible normalized size is 0.0 (no contact, or it is unmeasurable), and the largest
+possible normalized size is 1.0 (sensor area is saturated).</p>
+<p>When both the approximate length and breadth can be measured, then the <code>TouchMajor</code> field
+specifies the longer dimension and the <code>TouchMinor</code> field specifies the shorter dimension
+of the contact area.  When only the approximate diameter of the contact area can be measured,
+then the <code>TouchMajor</code> and <code>TouchMinor</code> fields will be equal.</p>
+<p>Likewise, the <code>ToolMajor</code> field specifies the longer dimension and the <code>ToolMinor</code>
+field specifies the shorter dimension of the tool's cross-sectional area.</p>
+<p>If the touch size is unavailable but the tool size is available, then the tool size
+will be set equal to the touch size.  Conversely, if the tool size is unavailable
+but the touch size is available, then the touch size will be set equal to the tool size.</p>
+<p>Touch devices measure or report the touch size and tool size in various ways.
+The current implementation supports three different kinds of measurements:
+diameter, area, and geometric bounding box in surface units.</p>
+<h4 id="touchsizecalibration"><code>touch.size.calibration</code></h4>
+<p><em>Definition:</em> <code>touch.size.calibration</code> = <code>none</code> | <code>geometric</code> | <code>diameter</code>
+| <code>area</code> | <code>default</code></p>
+<p>Specifies the kind of measurement used by the touch driver to report the
+touch size and tool size.</p>
+<ul>
+<li>
+<p>If the value is <code>none</code>, the size is set to zero.</p>
+</li>
+<li>
+<p>If the value is <code>geometric</code>, the size is assumed to be specified in the same
+    surface units as the position, so it is scaled in the same manner.</p>
+</li>
+<li>
+<p>If the value is <code>diameter</code>, the size is assumed to be proportional to
+    the diameter (width) of the touch or tool.</p>
+</li>
+<li>
+<p>If the value is <code>area</code>, the size is assumed to be proportional to the
+    area of the touch or tool.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system uses the <code>geometric</code> calibration if the
+    <code>raw.touchMajor</code> or <code>raw.toolMajor</code> axis is available, otherwise it uses
+    the <code>none</code> calibration.</p>
+</li>
+</ul>
+<h4 id="touchsizescale"><code>touch.size.scale</code></h4>
+<p><em>Definition:</em> <code>touch.size.scale</code> = &lt;a non-negative floating point number&gt;</p>
+<p>Specifies a constant scale factor used in the calibration.</p>
+<p>The default value is <code>1.0</code>.</p>
+<h4 id="touchsizebias"><code>touch.size.bias</code></h4>
+<p><em>Definition:</em> <code>touch.size.bias</code> = &lt;a non-negative floating point number&gt;</p>
+<p>Specifies a constant bias value used in the calibration.</p>
+<p>The default value is <code>0.0</code>.</p>
+<h4 id="touchsizeissummed"><code>touch.size.isSummed</code></h4>
+<p><em>Definition:</em> <code>touch.size.isSummed</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the size is reported as the sum of the sizes of all
+active contacts, or is reported individually for each contact.</p>
+<ul>
+<li>
+<p>If the value is <code>1</code>, the reported size will be divided by the number
+    of contacts prior to use.</p>
+</li>
+<li>
+<p>If the value is <code>0</code>, the reported size will be used as is.</p>
+</li>
+</ul>
+<p>The default value is <code>0</code>.</p>
+<p>Some touch devices, particularly "Semi-MT" devices cannot distinguish the
+individual dimensions of multiple contacts so they report a size measurement
+that represents their total area or width.  This property should only be set to
+<code>1</code> for such devices.  If in doubt, set this value to <code>0</code>.</p>
+<h4 id="calculation_1">Calculation</h4>
+<p>The calculation of the <code>TouchMajor</code>, <code>TouchMinor</code>, <code>ToolMajor</code>, <code>ToolMinor</code>
+and <code>Size</code> fields depends on the specified calibration parameters.</p>
+<pre><code>If raw.touchMajor and raw.toolMajor are available:
+    touchMajor = raw.touchMajor
+    touchMinor = raw.touchMinor
+    toolMajor = raw.toolMajor
+    toolMinor = raw.toolMinor
+Else If raw.touchMajor is available:
+    toolMajor = touchMajor = raw.touchMajor
+    toolMinor = touchMinor = raw.touchMinor
+Else If raw.toolMajor is available:
+    touchMajor = toolMajor = raw.toolMajor
+    touchMinor = toolMinor = raw.toolMinor
+Else
+    touchMajor = toolMajor = 0
+    touchMinor = toolMinor = 0
+    size = 0
+End If
+
+size = avg(touchMajor, touchMinor)
+
+If touch.size.isSummed == 1:
+    touchMajor = touchMajor / numberOfActiveContacts
+    touchMinor = touchMinor / numberOfActiveContacts
+    toolMajor = toolMajor / numberOfActiveContacts
+    toolMinor = toolMinor / numberOfActiveContacts
+    size = size / numberOfActiveContacts
+End If
+
+If touch.size.calibration == "none":
+    touchMajor = toolMajor = 0
+    touchMinor = toolMinor = 0
+    size = 0
+Else If touch.size.calibration == "geometric":
+    outputScale = average(output.width / raw.width, output.height / raw.height)
+    touchMajor = touchMajor * outputScale
+    touchMinor = touchMinor * outputScale
+    toolMajor = toolMajor * outputScale
+    toolMinor = toolMinor * outputScale
+Else If touch.size.calibration == "area":
+    touchMajor = sqrt(touchMajor)
+    touchMinor = touchMajor
+    toolMajor = sqrt(toolMajor)
+    toolMinor = toolMajor
+Else If touch.size.calibration == "diameter":
+    touchMinor = touchMajor
+    toolMinor = toolMajor
+End If
+
+If touchMajor != 0:
+    output.touchMajor = touchMajor * touch.size.scale + touch.size.bias
+Else
+    output.touchMajor = 0
+End If
+
+If touchMinor != 0:
+    output.touchMinor = touchMinor * touch.size.scale + touch.size.bias
+Else
+    output.touchMinor = 0
+End If
+
+If toolMajor != 0:
+    output.toolMajor = toolMajor * touch.size.scale + touch.size.bias
+Else
+    output.toolMajor = 0
+End If
+
+If toolMinor != 0:
+    output.toolMinor = toolMinor * touch.size.scale + touch.size.bias
+Else
+    output.toolMinor = 0
+End If
+
+output.size = size
+</code></pre>
+<h3 id="pressure-field"><code>Pressure</code> Field</h3>
+<p>The <code>Pressure</code> field describes the approximate physical pressure applied to the
+touch device as a normalized value between 0.0 (no touch) and 1.0 (full force).</p>
+<p>A zero pressure indicates that the tool is hovering.</p>
+<h4 id="touchpressurecalibration"><code>touch.pressure.calibration</code></h4>
+<p><em>Definition:</em> <code>touch.pressure.calibration</code> = <code>none</code> | <code>physical</code> | <code>amplitude</code> | <code>default</code></p>
+<p>Specifies the kind of measurement used by the touch driver to report the pressure.</p>
+<ul>
+<li>
+<p>If the value is <code>none</code>, the pressure is unknown so it is set to 1.0 when
+    touching and 0.0 when hovering.</p>
+</li>
+<li>
+<p>If the value is <code>physical</code>, the pressure axis is assumed to measure the actual
+    physical intensity of pressure applied to the touch pad.</p>
+</li>
+<li>
+<p>If the value is <code>amplitude</code>, the pressure axis is assumed to measure the signal
+    amplitude, which is related to the size of the contact and the pressure applied.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system uses the <code>physical</code> calibration if the
+    pressure axis available, otherwise uses <code>none</code>.</p>
+</li>
+</ul>
+<h4 id="touchpressurescale"><code>touch.pressure.scale</code></h4>
+<p><em>Definition:</em> <code>touch.pressure.scale</code> = &lt;a non-negative floating point number&gt;</p>
+<p>Specifies a constant scale factor used in the calibration.</p>
+<p>The default value is <code>1.0 / raw.pressure.max</code>.</p>
+<h4 id="calculation_2">Calculation</h4>
+<p>The calculation of the <code>Pressure</code> field depends on the specified calibration parameters.</p>
+<pre><code>If touch.pressure.calibration == "physical" or "amplitude":
+    output.pressure = raw.pressure * touch.pressure.scale
+Else
+    If hovering:
+        output.pressure = 0
+    Else
+        output.pressure = 1
+    End If
+End If
+</code></pre>
+<h3 id="orientation-and-tilt-fields"><code>Orientation</code> and <code>Tilt</code> Fields</h3>
+<p>The <code>Orientation</code> field describes the orientation of the touch and tool as an
+angular measurement.  An orientation of <code>0</code> indicates that the major axis is
+oriented vertically, <code>-PI/2</code> indicates that the major axis is oriented to the left,
+<code>PI/2</code> indicates that the major axis is oriented to the right.  When a stylus
+tool is present, the orientation range may be described in a full circle range
+from <code>-PI</code> or <code>PI</code>.</p>
+<p>The <code>Tilt</code> field describes the inclination of the tool as an angular measurement.
+A tilt of <code>0</code> indicates that the tool is perpendicular to the surface.
+A tilt of <code>PI/2</code> indicates that the tool is flat on the surface.</p>
+<h4 id="touchorientationcalibration"><code>touch.orientation.calibration</code></h4>
+<p><em>Definition:</em> <code>touch.orientation.calibration</code> = <code>none</code> | <code>interpolated</code> | <code>vector</code> | <code>default</code></p>
+<p>Specifies the kind of measurement used by the touch driver to report the orientation.</p>
+<ul>
+<li>
+<p>If the value is <code>none</code>, the orientation is unknown so it is set to 0.</p>
+</li>
+<li>
+<p>If the value is <code>interpolated</code>, the orientation is linearly interpolated such that a
+    raw value of <code>raw.orientation.min</code> maps to <code>-PI/2</code> and a raw value of
+    <code>raw.orientation.max</code> maps to <code>PI/2</code>.  The center value of
+    <code>(raw.orientation.min + raw.orientation.max) / 2</code> maps to <code>0</code>.</p>
+</li>
+<li>
+<p>If the value is <code>vector</code>, the orientation is interpreted as a packed vector consisiting
+    of two signed 4-bit fields.  This representation is used on Atmel Object Based Protocol
+    parts.  When decoded, the vector yields an orientation angle and confidence
+    magnitude.  The confidence magnitude is used to scale the size information,
+    unless it is geometric.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system uses the <code>interpolated</code> calibration if the
+    orientation axis available, otherwise uses <code>none</code>.</p>
+</li>
+</ul>
+<h4 id="calculation_3">Calculation</h4>
+<p>The calculation of the <code>Orientation</code> and <code>Tilt</code> fields depends on the specified
+calibration parameters and available input.</p>
+<pre><code>If touch.tiltX and touch.tiltY are available:
+    tiltXCenter = average(raw.tiltX.min, raw.tiltX.max)
+    tiltYCenter = average(raw.tiltY.min, raw.tiltY.max)
+    tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180
+    tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180
+    output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle))
+    output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle))
+Else If touch.orientation.calibration == "interpolated":
+    center = average(raw.orientation.min, raw.orientation.max)
+    output.orientation = PI / (raw.orientation.max - raw.orientation.min)
+    output.tilt = 0
+Else If touch.orientation.calibration == "vector":
+    c1 = (raw.orientation &amp; 0xF0) &gt;&gt; 4
+    c2 = raw.orientation &amp; 0x0F
+
+    If c1 != 0 or c2 != 0:
+        If c1 &gt;= 8 Then c1 = c1 - 16
+        If c2 &gt;= 8 Then c2 = c2 - 16
+        angle = atan2(c1, c2) / 2
+        confidence = sqrt(c1*c1 + c2*c2)
+
+        output.orientation = angle
+
+        If touch.size.calibration == "diameter" or "area":
+            scale = 1.0 + confidence / 16
+            output.touchMajor *= scale
+            output.touchMinor /= scale
+            output.toolMajor *= scale
+            output.toolMinor /= scale
+        End If
+    Else
+        output.orientation = 0
+    End If
+    output.tilt = 0
+Else
+    output.orientation = 0
+    output.tilt = 0
+End If
+
+If orientation aware:
+    If screen rotation is 90 degrees:
+        output.orientation = output.orientation - PI / 2
+    Else If screen rotation is 270 degrees:
+        output.orientation = output.orientation + PI / 2
+    End If
+End If
+</code></pre>
+<h3 id="distance-field"><code>Distance</code> Field</h3>
+<p>The <code>Distance</code> field describes the distance between the tool and the touch device
+surface.  A value of 0.0 indicates direct contact and larger values indicate
+increasing distance from the surface.</p>
+<h4 id="touchdistancecalibration"><code>touch.distance.calibration</code></h4>
+<p><em>Definition:</em> <code>touch.distance.calibration</code> = <code>none</code> | <code>scaled</code> | <code>default</code></p>
+<p>Specifies the kind of measurement used by the touch driver to report the distance.</p>
+<ul>
+<li>
+<p>If the value is <code>none</code>, the distance is unknown so it is set to 0.</p>
+</li>
+<li>
+<p>If the value is <code>scaled</code>, the reported distance is multiplied by a
+    constant scale factor.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system uses the <code>scaled</code> calibration if the
+    distance axis available, otherwise uses <code>none</code>.</p>
+</li>
+</ul>
+<h4 id="touchdistancescale"><code>touch.distance.scale</code></h4>
+<p><em>Definition:</em> <code>touch.distance.scale</code> = &lt;a non-negative floating point number&gt;</p>
+<p>Specifies a constant scale factor used in the calibration.</p>
+<p>The default value is <code>1.0</code>.</p>
+<h4 id="calculation_4">Calculation</h4>
+<p>The calculation of the <code>Distance</code> field depends on the specified calibration parameters.</p>
+<pre><code>If touch.distance.calibration == "scaled":
+    output.distance = raw.distance * touch.distance.scale
+Else
+    output.distance = 0
+End If
+</code></pre>
+<h3 id="example">Example</h3>
+<pre><code># Input device configuration file for a touch screen that supports pressure,
+# size and orientation.  The pressure and size scale factors were obtained
+# by measuring the characteristics of the device itself and deriving
+# useful approximations based on the resolution of the touch sensor and the
+# display.
+#
+# Note that these parameters are specific to a particular device model.
+# Different parameters will need to be used for other devices.
+
+# Basic Parameters
+touch.deviceType = touchScreen
+touch.orientationAware = 1
+
+# Size
+# Based on empirical measurements, we estimate the size of the contact
+# using size = sqrt(area) * 28 + 0.
+touch.size.calibration = area
+touch.size.scale = 28
+touch.size.bias = 0
+touch.size.isSummed = 0
+
+# Pressure
+# Driver reports signal strength as pressure.
+#
+# A normal index finger touch typically registers about 80 signal strength
+# units although we don't expect these values to be accurate.
+touch.pressure.calibration = amplitude
+touch.pressure.scale = 0.0125
+
+# Orientation
+touch.orientation.calibration = vector
+</code></pre>
+<h3 id="compatibility-notes">Compatibility Notes</h3>
+<p>The configuration properties for touch devices changed significantly in
+Android Ice Cream Sandwich 4.0.  <strong>All input device configuration files for touch
+devices must be updated to use the new configuration properties.</strong></p>
+<p>Older touch device <a href="#touch-device-driver-requirements">drivers</a> may also need to be
+updated.</p>
+<h2 id="virtual-key-map-files">Virtual Key Map Files</h2>
+<p>Touch devices are often used to implement virtual keys.</p>
+<p>There are several ways of doing this, depending on the capabilities of the
+touch controller.  Some touch controllers can be directly configured to implement
+soft keys by setting firmware registers.  Other times it is desirable to perform
+the mapping from touch coordinates to key codes in software.</p>
+<p>When virtual keys are implemented in software, the kernel must export a virtual key map
+file called <code>virtualkeys.&lt;devicename&gt;</code> as a board property.  For example,
+if the touch screen device drivers reports its name as "touchyfeely" then
+the virtual key map file must have the path <code>/sys/board_properties/virtualkeys.touchyfeely</code>.</p>
+<p>A virtual key map file describes the coordinates and Linux key codes of virtual keys
+on the touch screen.</p>
+<p>In addition to the virtual key map file, there must be a corresponding key layout
+file and key character map file to map the Linux key codes to Android key codes and
+to specify the type of the keyboard device (usually <code>SPECIAL_FUNCTION</code>).</p>
+<h3 id="syntax">Syntax</h3>
+<p>A virtual key map file is a plain text file consisting of a sequence of virtual key
+layout descriptions either separated by newlines or by colons.</p>
+<p>Comment lines begin with '#' and continue to the end of the line.</p>
+<p>Each virtual key is described by 6 colon-delimited components:</p>
+<ul>
+<li><code>0x01</code>: A version code.  Must always be <code>0x01</code>.</li>
+<li>&lt;Linux key code&gt;: The Linux key code of the virtual key.</li>
+<li>&lt;centerX&gt;: The X pixel coordinate of the center of the virtual key.</li>
+<li>&lt;centerY&gt;: The Y pixel coordinate of the center of the virtual key.</li>
+<li>&lt;width&gt;: The width of the virtual key in pixels.</li>
+<li>&lt;height&gt;: The height of the virtual key in pixels.</li>
+</ul>
+<p>All coordinates and sizes are specified in terms of the display coordinate system.</p>
+<p>Here is a virtual key map file all written on one line.</p>
+<pre><code># All on one line
+0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55
+</code></pre>
+<p>The same virtual key map file can also be written on multiple lines.</p>
+<pre><code># One key per line
+0x01:158:55:835:90:55
+0x01:139:172:835:125:55
+0x01:102:298:835:115:55
+0x01:217:412:835:95:55
+</code></pre>
+<p>In the above example, the touch screen has a resolution of 480x800.  Accordingly, all of
+the virtual keys have a &lt;centerY&gt; coordinate of 835, which is a little bit below
+the visible area of the touch screen.</p>
+<p>The first key has a Linux scan code of <code>158</code> (<code>KEY_BACK</code>), centerX of <code>55</code>,
+centerY of <code>835</code>, width of <code>90</code> and height of <code>55</code>.</p>
+<h3 id="example_1">Example</h3>
+<p>Virtual key map file: <code>/sys/board_properties/virtualkeys.touchyfeely</code>.</p>
+<pre><code>0x01:158:55:835:90:55
+0x01:139:172:835:125:55
+0x01:102:298:835:115:55
+0x01:217:412:835:95:55
+</code></pre>
+<p>Key layout file: <code>/system/usr/keylayout/touchyfeely.kl</code>.</p>
+<pre><code>key 158 BACK
+key 139 MENU
+key 102 HOME
+key 217 SEARCH
+</code></pre>
+<p>Key character map file: <code>/system/usr/keychars/touchyfeely.kcm</code>.</p>
+<pre><code>type SPECIAL_FUNCTION
+</code></pre>
+<h2 id="indirect-multi-touch-pointer-gestures">Indirect Multi-touch Pointer Gestures</h2>
+<p>In pointer mode, the system interprets the following gestures:</p>
+<ol>
+<li>
+<p>Single finger tap: click.</p>
+</li>
+<li>
+<p>Single finger motion: move the pointer.</p>
+</li>
+<li>
+<p>Single finger motion plus button presses: drag the pointer.</p>
+</li>
+<li>
+<p>Two finger motion both fingers moving in the same direction: drag the area under the pointer
+    in that direction.  The pointer itself does not move.</p>
+</li>
+<li>
+<p>Two finger motion both fingers moving towards each other or apart in
+    different directions: pan/scale/rotate the area surrounding the pointer.
+    The pointer itself does not move.</p>
+</li>
+<li>
+<p>Multiple finger motion: freeform gesture.</p>
+</li>
+</ol>
+<h2 id="further-reading">Further Reading</h2>
+<ol>
+<li><a href="http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt">Linux multi-touch protocol</a></li>
+<li><a href="http://lii-enac.fr/en/architecture/linux-input/multitouch-devices.html">ENAC list of available multitouch devices on Linux</a></li>
+</ol>
diff --git a/src/devices/tech/input/validate-keymaps.jd b/src/devices/tech/input/validate-keymaps.jd
new file mode 100644
index 0000000..7730f11
--- /dev/null
+++ b/src/devices/tech/input/validate-keymaps.jd
@@ -0,0 +1,85 @@
+page.title=Validate Keymaps Tool
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+<p>The Android framework has a small tool called <code>validatekeymaps</code> to validate the
+syntax of input device configuration files, key layout files, key character
+maps files and virtual key definition files.</p>
+<h2 id="compilation">Compilation</h2>
+<p>To compile <code>validatekeymaps</code>, set up the development environment, download
+the Android source tree, compile it, then run:</p>
+<pre><code>$ mmm frameworks/base/tools/validatekeymaps
+</code></pre>
+<p>This command should compile a host tool called validatekeymaps into the
+<code>out/host/&amp;lt;os&amp;gt;/bin</code> directory.</p>
+<h2 id="usage">Usage</h2>
+<p>If you ran <code>envsetup.sh</code> to set up your development environment, then the
+<code>validatekeymaps</code> tool should already be on your path.  You can verify
+this by running <code>validatekeymaps</code>.</p>
+<pre><code>$ validatekeymaps
+
+Keymap Validation Tool
+
+Usage:
+ validatekeymaps [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]
+   Validates the specified key layouts, key character maps, 
+   input device configurations, or virtual key definitions.
+</code></pre>
+<p>Then all you need to do is run <code>validatekeymaps</code> an give it the path of
+one or more files to validate.</p>
+<pre><code>$ validatekeymaps frameworks/base/data/keyboards/Generic.kl
+
+Validating file 'frameworks/base/data/keyboards/Generic.kl'...
+No errors.
+
+Success.
+</code></pre>
+<p>And if there is an error...</p>
+<pre><code>$ validatekeymaps Bad.kl
+
+Validating file 'Bad.kl'...
+E/KeyLayoutMap(87688): Bad.kl:24: Expected keyword, got 'ke'.
+Error -22 parsing key layout file.
+
+Failed!
+</code></pre>
+<h2 id="automation">Automation</h2>
+<p>It is a <em>very</em> good idea to run <code>validatekeymaps</code> on all configuration files
+before installing them on a device.</p>
+<p>The process can easily be automated as part of the build system by using a
+script or a makefile.</p>
+<p>The following sample makefile is based on the contents of
+<code>frameworks/base/data/keyboards/Android.mk</code>.</p>
+<pre><code># This makefile performs build time validation of framework keymap files.
+
+LOCAL_PATH := $(call my-dir)
+
+# Validate all key maps.
+include $(CLEAR_VARS)
+
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+files := MyKeyboard.kl MyKeyboard.kcm MyTouchScreen.idc
+
+LOCAL_MODULE := validate_framework_keymaps
+LOCAL_MODULE_TAGS := optional
+LOCAL_REQUIRED_MODULES := validatekeymaps
+
+validate_framework_keymaps: $(files)
+    $(hide) $(validatekeymaps) $(files)
+
+include $(BUILD_PHONY_PACKAGE)
+</code></pre>