Home | History | Annotate | Download | only in porting
      1 page.title=Keymaps and Keyboard Input
      2 pdk.version=1.0
      3 doc.type=porting
      4 @jd:body
      5 
      6 
      7 <div id="qv-wrapper">
      8 <div id="qv">
      9 <h2>In this document</h2>
     10 <a name="toc"/>
     11 <ul>
     12 <li><a href="#androidKeymapFunctionality">Functionality</a></li>
     13 <li><a href="#androidKeymapKeyLayoutMapTitle">Key Layout Map</a></li>
     14 <li><a href="#androidKeymapKeyCharMap">Key Character Map</a></li>
     15 <li><a href="#androidKeymapDriverTemplate">Implementing Your Own Driver (Driver Template)</a></li>
     16 <li><a href="#androidKeymapKeyCharMapSampleImplementation">Sample Implementation</a></li>
     17 </ul>
     18 </div>
     19 </div>
     20 
     21 <p>This document describes how keyboard input gets translated into Android actions and how you can customize key layout and key character maps to match the needs of your own device. </p>
     22 <p>Android uses the standard Linux input event device (<code>/dev/event0</code>) and driver as described in the <code>linux/input.h</code> kernel header file. For more information regarding standard Linux input drivers, please see <a href="http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.24.y.git;a=blob;f=Documentation/input/input.txt">Linux Input drivers</a> at <a href="http://kernel.org">http://kernel.org</a>.</p>
     23 
     24 
     25 
     26 
     27 <a name="androidKeymapFunctionality"></a><h3>Functionality</h3>
     28 
     29 <p>Android's input event device is structured around an interrupt or polling routine that captures the device-specific scancode and converts it to a standard form acceptable to Linux (as defined in <code>input.h</code>) before passing it to the kernel with <code>input_event()</code>.</p>
     30 <p>The keymap driver's other primary function is to establish a probe function that sets up the interrupt or polling function, handles hardware initialization, and attaches the driver to the input subsystem with <code>input_register_device()</code>.</p>
     31 <p>The table below describes the steps required to translate from keyboard input to application action: </p>
     32 <table border=1>
     33     <tbody><tr>
     34       <th scope="col">Step</th>
     35         <th scope="col">Action</th>
     36         <th scope="col">Explanation</th>
     37     </tr>
     38 	<tr>
     39 	  <td>1.</td>
     40 	  <td>Window manager reads key event from Linux keyboard driver. </td>
     41 	  <td>Events are typically positional. For example, the top-left position on a keypad returns 16 regardless of whether that key is printed with a Q (as on a QWERTY keypad) or an A (as on an AZERTY keypads). This first conversion by the Linux Keyboard Driver yields a scancode (for example, 16).</td>
     42 	</tr>
     43 	<tr>
     44 	  <td>2. </td>
     45 	  <td>Window manager maps scancode to keycode.</td>
     46 	  <td>When the window manager reads a key event out of the driver, it maps the scancode to a keycode using a key layout map file. Typically, the keycode is the primary symbol screen-printed on a key. For example, <code>KEYCODE_DPAD_CENTER</code> is the center button on the five-way navigation control. Even though ALT + G generates a &quot;?&quot; character, <code>KEYCODE_G</code> is the keycode.</td>
     47 	  </tr>
     48 	<tr>
     49 	  <td>3. </td>
     50 	  <td>Window manager  sends both the scancode and the keycode to the application.</td>
     51 	  <td>Both the scancode and keycode are handled by the view with focus. 
     52   How the application interprets both depend on the application.</td>
     53 	  </tr>
     54 </tbody>
     55 </table>
     56 
     57 
     58 <a name="androidKeymapKeyLayoutMapTitle"></a><h3>Key Layout Map</h3>
     59 
     60 
     61 
     62 <a name="androidKeymapKeyLayoutMapSelection"></a><h4>Selection of a Key Layout Map</h4>
     63 
     64 <p>Key layout maps are installed in <code>/system/usr/keylayout</code> and <code>/data/usr/keylayout</code>.</p>
     65 <p>For each keyboard device xxx, set the <code>android.keylayout.xxx</code> system property (see <a href="build_new_device.html">Building New Device</a> for help setting system properties). If you don't specify a keylayout file, Android will default to <code>/system/usr/keylayout/qwerty.kl</code>.</p>
     66 
     67 
     68 <a name="androidKeymapKeyLayoutMapFileFormat"></a><h4>File Format</h4>
     69 
     70 <p>Key layout maps are stored on the device as UTF-8 text files and have the following characteristics:</p>
     71 <p><ul>
     72 <li>Comments: The pound symbol (#) denotes a comment and everything after the pound symbol on a line is ignored.</li>
     73 <li>Whitespace: All empty lines are ignored.</li>
     74 <li>Key definitions: Key definitions follow the syntax <code>key SCANCODE KEYCODE [FLAGS...]</code>, where <code>SCANCODE</code> is a number, <code>KEYCODE</code> is defined in your specific keylayout file (<code>android.keylayout.xxx</code>), and potential <code>FLAGS</code> are defined as follows:
     75 <ul><li>SHIFT: While pressed, the shift key modifier is set</li>
     76 <li>ALT: While pressed, the alt key modifier is set</li>
     77 <li>CAPS: While pressed, the caps lock key modifier is set</li>
     78 <li>WAKE: When this key is pressed while the device is asleep, the device will wake up and the key event gets sent to the app.</li>
     79 <li>WAKE_DROPPED: When this key is pressed while the device is asleep, the device will wake up and the key event does not get sent to the app.</li>
     80 </ul>
     81 </li>
     82 </ul>
     83 </p>
     84 
     85 
     86 <a name="androidKeymapKeyLayoutMapExample"></a><h4>Example of a Key Layout Map File</h4>
     87 
     88 <p>The following code comes from  <code>android/src/device/product/generic/tuttle2.kl</code> and is an example of a complete key layout file:</p>
     89 <pre class="prettify">
     90 # Copyright 2007 Google Inc.
     91 
     92 key 2     1
     93 key 3     2
     94 key 4     3
     95 key 5     4
     96 key 6     5
     97 key 7     6
     98 key 8     7
     99 key 9     8
    100 key 10    9
    101 key 11    0
    102 key 158   BACK              WAKE_DROPPED
    103 key 230   SOFT_RIGHT        WAKE
    104 key 60    SOFT_RIGHT        WAKE
    105 key 107   ENDCALL           WAKE_DROPPED
    106 key 62    ENDCALL           WAKE_DROPPED
    107 key 229   MENU         WAKE_DROPPED
    108 key 59    MENU         WAKE_DROPPED
    109 key 228   POUND
    110 key 227   STAR
    111 key 231   CALL              WAKE_DROPPED
    112 key 61    CALL              WAKE_DROPPED
    113 key 232   DPAD_CENTER       WAKE_DROPPED
    114 key 108   DPAD_DOWN         WAKE_DROPPED
    115 key 103   DPAD_UP           WAKE_DROPPED
    116 key 102   HOME              WAKE
    117 key 105   DPAD_LEFT         WAKE_DROPPED
    118 key 106   DPAD_RIGHT        WAKE_DROPPED
    119 key 115   VOLUME_UP
    120 key 114   VOLUME_DOWN
    121 key 116   POWER             WAKE
    122 key 212   SLASH
    123 
    124 key 16    Q
    125 key 17    W
    126 key 18    E
    127 key 19    R
    128 key 20    T
    129 key 21    Y
    130 key 22    U
    131 key 23    I
    132 key 24    O
    133 key 25    P
    134 
    135 key 30    A
    136 key 31    S
    137 key 32    D
    138 key 33    F
    139 key 34    G
    140 key 35    H
    141 key 36    J
    142 key 37    K
    143 key 38    L
    144 key 14    DEL
    145         
    146 key 44    Z
    147 key 45    X
    148 key 46    C
    149 key 47    V
    150 key 48    B
    151 key 49    N
    152 key 50    M
    153 key 51    COMMA
    154 key 52    PERIOD
    155 key 28    NEWLINE
    156         
    157 key 56    ALT_LEFT
    158 key 42    SHIFT_LEFT
    159 key 215   AT
    160 key 57    SPACE
    161 key 53    SLASH
    162 key 127   SYM
    163 key 100   ALT_LEFT
    164 
    165 key 399   GRAVE
    166 </pre>
    167 
    168 
    169 <a name="androidKeymapKeyCharMap"></a><h3>Key Character Map</h3>
    170 
    171 
    172 
    173 <a name="androidKeymapKeyCharMapSelection"></a><h4>Selection of a Key Character Map</h4>
    174 
    175 <p>Key character maps are installed in <code>/system/usr/keychars</code> and <code>/data/usr/keychars</code>.</p>
    176 <p>For each keyboard device xxx, set the <code>android.keychar.xxx</code> system property to the full path of the desired keychar file. If you don't specify a keychar file, Android will default to <code>/system/usr/keychar/qwerty.kl</code>.
    177 
    178 
    179 <a name="androidKeymapKeyCharMapFileFormat"></a><h4>File Format</h4>
    180 
    181 <p>Key character maps are stored on the device as binary resources in order to reduce loading time. Key character maps have the following characteristics:</p>
    182 <p><ul>
    183 
    184 <li>Comments: The pound symbol (#) denotes a comment and everything after the pound symbol on a line is ignored.</li>
    185 <li>Whitespace: All empty lines are ignored.</li>
    186 <li>Column definitions: Column definitions follow the syntax <code>columns MODIFIERS [...]</code>, where <code>MODIFIERS</code> are defined as follows:
    187 <table border=1 cellpadding=2 cellspacing=0>
    188     <tbody><tr>
    189         <th scope="col">Character in MODIFIERS</th>
    190         <th scope="col">Corresponding bit in the modifiers</th>
    191     </tr>
    192     <tr>
    193         <td>O</td>
    194         <td>no modifiers</td>
    195     </tr>
    196     <tr>
    197         <td>S</td>
    198         <td>MODIFIER_SHIFT</td>
    199     </tr>
    200     <tr>
    201         <td>C</td>
    202         <td>MODIFIER_CONTROL</td>
    203     </tr>
    204     <tr>
    205         <td>L</td>
    206         <td>MODIFIER_CAPS_LOCK</td>
    207     </tr>
    208     <tr>
    209         <td>A</td>
    210         <td>MODIFIER_ALT</td>
    211     </tr>
    212 </table>
    213 </li>
    214 <li>Key definitions: Key definitions have the syntax <code>key SCANCODE CHARACTER [...]</code> where <code>SCANCODE</code> is a number and <code>CHARACTER</code> values are either UTF-8 characters in quotation marks (for example, "a") or a numeric value that <code>strtol</code> can parse.</li>
    215 </ul></p>
    216 
    217 
    218 <a name="androidKeymapKeyCharMapExample"></a><h4>Example of a Key Character Map File</h4>
    219 
    220 <p>The following code comes from <code>android/src/device/product/generic/tuttle2.kcm</code> and represents a complete key character file:</p>
    221 <p>The type line indicates what kind of keyboard your device implements. Possible types include:</p>
    222 <p><ul>
    223 <li><b>NUMERIC</b>: A numeric (12-key) keyboard.</li>
    224 <li><b>Q14</b>: A keyboard that includes all letters but multiple letters per key.</li>
    225 <li><b>QWERTY</b>: A keyboard with all letters and possibly numbers. This option applies to all full keyboard configurations, such as AZERTY.</li>
    226 </ul>
    227 </p>
    228 <pre class="prettify">
    229 # Copyright 2007 Google Inc.
    230 
    231 [type=QWERTY]
    232 
    233 # keycode   base    caps    fn      caps_fn number  display_label
    234 
    235 A           'a'     'A'     '%'     0x00    '%'     'A'
    236 B           'b'     'B'     '='     0x00    '='     'B'
    237 C           'c'     'C'     '8'     0x00E7  '8'     'C'
    238 D           'd'     'D'     '5'     0x00    '5'     'D'
    239 E           'e'     'E'     '2'     0x0301  '2'     'E'
    240 F           'f'     'F'     '6'     0x00A5  '6'     'F'
    241 G           'g'     'G'     '-'     '_'     '-'     'G'
    242 H           'h'     'H'     '['     '{'     '['     'H'
    243 I           'i'     'I'     '$'     0x0302  '$'     'I'
    244 J           'j'     'J'     ']'     '}'     ']'     'J'
    245 K           'k'     'K'     '"'     '~'     '"'     'K'
    246 L           'l'     'L'     '''     '`'     '''     'L'
    247 M           'm'     'M'     '>'     0x00    '>'     'M'
    248 N           'n'     'N'     '<'     0x0303  '<'     'N'
    249 O           'o'     'O'     '('     0x00    '('     'O'
    250 P           'p'     'P'     ')'     0x00    ')'     'P'
    251 Q           'q'     'Q'     '*'     0x0300  '*'     'Q'
    252 R           'r'     'R'     '3'     0x20AC  '3'     'R'
    253 S           's'     'S'     '4'     0x00DF  '4'     'S'
    254 T           't'     'T'     '+'     0x00A3  '+'     'T'
    255 U           'u'     'U'     '&'     0x0308  '&'     'U'
    256 V           'v'     'V'     '9'     '^'     '9'     'V'
    257 W           'w'     'W'     '1'     0x00    '1'     'W'
    258 X           'x'     'X'     '7'     0xEF00  '7'     'X'
    259 Y           'y'     'Y'     '!'     0x00A1  '!'     'Y'
    260 Z           'z'     'Z'     '#'     0x00    '#'     'Z'
    261 
    262 COMMA       ','     ';'     ';'     '|'     ','     ','
    263 PERIOD      '.'     ':'     ':'     0x2026  '.'     '.'
    264 AT          '@'     '0'     '0'     0x2022  '0'     '@'
    265 SLASH       '/'     '?'     '?'     '\'     '/'     '/'
    266 
    267 SPACE       0x20    0x20    0x9     0x9     0x20    0x20
    268 NEWLINE     0xa     0xa     0xa     0xa     0xa     0xa
    269 
    270 # on pc keyboards
    271 TAB         0x9     0x9     0x9     0x9     0x9     0x9
    272 0           '0'     ')'     ')'     ')'     '0'     '0'
    273 1           '1'     '!'     '!'     '!'     '1'     '1'
    274 2           '2'     '@'     '@'     '@'     '2'     '2'
    275 3           '3'     '#'     '#'     '#'     '3'     '3'
    276 4           '4'     '$'     '$'     '$'     '4'     '4'
    277 5           '5'     '%'     '%'     '%'     '5'     '5'
    278 6           '6'     '^'     '^'     '^'     '6'     '6'
    279 7           '7'     '&'     '&'     '&'     '7'     '7'
    280 8           '8'     '*'     '*'     '*'     '8'     '8'
    281 9           '9'     '('     '('     '('     '9'     '9'
    282 
    283 GRAVE         '`'     '~'     '`'     '~'     '`'     '`'
    284 MINUS         '-'     '_'     '-'     '_'     '-'     '-'
    285 EQUALS        '='     '+'     '='     '+'     '='     '='
    286 LEFT_BRACKET  '['     '{'     '['     '{'     '['     '['
    287 RIGHT_BRACKET ']'     '}'     ']'     '}'     ']'     ']'
    288 BACKSLASH     '\'     '|'     '\'     '|'     '\'     '\'
    289 SEMICOLON     ';'     ':'     ';'     ':'     ';'     ';'
    290 APOSTROPHE    '''     '"'     '''     '"'     '''     '''
    291 STAR          '*'     '*'     '*'     '*'     '*'     '*'
    292 POUND         '#'     '#'     '#'     '#'     '#'     '#'
    293 PLUS          '+'     '+'     '+'     '+'     '+'     '+'
    294 </pre>
    295 
    296 
    297 <a name="androidKeymapKeyCharMapResourceBinaryFileFormat"></a><h4>Resource Binary File Format</h4>
    298 
    299 <p>The file snippet above gets converted to the following by the <code>makekcharmap</code> tool as part of the build process. You can <code>mmap</code> this file in and share the approximately 4k of memory that it uses between processes to minimize load time.</p>
    300 <table>
    301     <tbody><tr>
    302         <th scope="col">Offset</th>
    303 
    304         <th scope="col">Size (bytes)</th>
    305         <th scope="col">Description</th>
    306     </tr>
    307     <tr>
    308         <td>0x00-0x0b</td>
    309         <td></td>
    310         <td>The ascii value "keycharmap1" including the null character</td>
    311 
    312     </tr>
    313     <tr>
    314         <td>0x0c-0x0f</td>
    315         <td></td>
    316         <td>padding</td>
    317     </tr>
    318     <tr>
    319         <td>0x10-0x13</td>
    320 
    321         <td></td>
    322         <td>The number of entries in the modifiers table (COLS)</td>
    323     </tr>
    324     <tr>
    325         <td>0x14-0x17</td>
    326         <td></td>
    327         <td>The number of entries in the characters table (ROWS)</td>
    328 
    329     </tr>
    330     <tr>
    331         <td>0x18-0x1f</td>
    332         <td></td>
    333         <td>padding</td>
    334     </tr>
    335     <tr>
    336         <td></td>
    337 
    338         <td>4*COLS</td>
    339         <td>Modifiers table.  The modifier mask values that each of the 
    340             columns in the characters table correspond to.</td>
    341     </tr>
    342     <tr>
    343         <td></td>
    344         <td></td>
    345         <td>padding to the next 16 byte boundary</td>
    346 
    347     </tr>
    348     <tr>
    349         <td></td>
    350         <td>4*COLS*ROWS</td>
    351         <td>Characters table.  The modifier mask values that each of the
    352             columns correspond to.</td>
    353     </tr>
    354 </tbody></table>
    355 
    356 
    357 <a name="androidKeymapDriverTemplate"></a><h3>Implementing Your Own Driver (Driver Template)</h3>
    358 
    359 <p>The following file, <code>pguide_events.c</code>, illustrates how to implement an Android keymap driver.</p>
    360 <pre class="prettyprint">
    361 /*
    362  * pguide_events.c
    363  *
    364  * ANDROID PORTING GUIDE: INPUT EVENTS DRIVER TEMPLATE
    365  *
    366  * This template is designed to an example of the functionality
    367  * necessary for Android to recieve input events.  The PGUIDE_EVENT
    368  * macros are meant as pointers indicating where to implement the
    369  * hardware specific code necessary for the new device.  The existence
    370  * of the macros is not meant to trivialize the work required, just as
    371  * an indication of where the work needs to be done.
    372  * 
    373  * Copyright 2007, Google Inc.
    374  * Based on goldfish-events.c
    375  *
    376  */
    377 
    378 #include <linux/module.h>
    379 #include <linux/init.h>
    380 #include <linux/interrupt.h>
    381 #include <linux/types.h>
    382 #include <linux/input.h>
    383 #include <linux/kernel.h>
    384 #include <linux/platform_device.h>
    385 
    386 
    387 #include <asm/irq.h>
    388 #include <asm/io.h>
    389 
    390 
    391 
    392 #define PGUIDE_EVENTS_INTERRUPT do{} while(0)
    393 #define PGUIDE_EVENTS_PROBE do{} while(0)
    394 
    395 struct event_dev {
    396     struct input_dev *input;
    397     int irq;
    398 };
    399 
    400 static irqreturn_t pguide_events_interrupt(int irq, void *dev_id)
    401 {
    402     struct event_dev *edev = dev_id;
    403     unsigned type=0, code=0, value=0;
    404 
    405     /* Set up type, code, and value per input.h
    406      */
    407     PGUIDE_EVENTS_INTERRUPT;
    408 
    409     input_event(edev->input, type, code, value);
    410     return IRQ_HANDLED;
    411 }
    412 
    413 static int pguide_events_probe(struct platform_device *pdev)
    414 {
    415     struct input_dev *input_dev;
    416     struct event_dev *edev;
    417     
    418     printk("*** pguide events probe ***\n");
    419 
    420     edev = kzalloc(sizeof(struct event_dev), GFP_KERNEL);
    421     input_dev = input_allocate_device();
    422 
    423     /* Setup edev->irq and do any hardware init */
    424     PGUIDE_EVENTS_PROBE;
    425 
    426     if(request_irq(edev->irq, pguide_events_interrupt, 0,
    427                    "pguide_events", edev) < 0) {
    428         goto fail;
    429     }
    430     
    431         /* indicate that we generate key events */
    432     set_bit(EV_KEY, input_dev->evbit);
    433     set_bit(EV_REL, input_dev->evbit);
    434     set_bit(EV_ABS, input_dev->evbit);
    435 
    436     /* indicate that we generate *any* key event */
    437 
    438     bitmap_fill(input_dev->keybit, KEY_MAX);
    439     bitmap_fill(input_dev->relbit, REL_MAX);
    440     bitmap_fill(input_dev->absbit, ABS_MAX);
    441     
    442     platform_set_drvdata(pdev, edev);
    443 
    444     input_dev->name = "pguide_events";
    445     input_dev->private = edev;
    446     input_dev->cdev.dev = &pdev->dev;
    447     
    448     input_register_device(input_dev);
    449     return 0;
    450 
    451 fail:
    452     kfree(edev);
    453     input_free_device(input_dev);
    454     
    455     return -EINVAL;
    456 }
    457 
    458 static struct platform_driver pguide_events_driver = {
    459     .probe = pguide_events_probe,
    460     .driver = {
    461         .name = "pguide_events",
    462     },
    463 };
    464 
    465 static int __devinit pguide_events_init(void)
    466 {
    467     return platform_driver_register(&pguide_events_driver);
    468 }
    469 
    470 
    471 static void __exit pguide_events_exit(void)
    472 {
    473 }
    474 
    475 module_init(pguide_events_init);
    476 module_exit(pguide_events_exit);
    477 
    478 MODULE_DESCRIPTION("Pguide Event Device");
    479 MODULE_LICENSE("GPL");
    480 </pre>
    481 
    482 
    483 <a name="androidKeymapKeyCharMapSampleImplementation"></a><h3>Sample Implementation</h3>
    484 
    485 <p>Assume the following for the setup of a new keypad device:</p>
    486 <pre class="prettify">
    487 android.keylayout.partnerxx_keypad = /system/usr/keylayout/partnerxx_keypad.kl
    488 android.keychar.partnerxx_keypad = /system/usr/keychars/partnerxx.kcm
    489 </pre>
    490 <p>The following example log file indicates that you have correctly registered the new keypad:</p>
    491 <pre class="prettify">
    492 I/EventHub( 1548): New device: path=/dev/input/event0 name=partnerxx_keypad id=0x10000 (of 0x1) index=1 fd=30
    493 I/EventHub( 1548): new keyboard input device added, name = partnerxx_keypad
    494 D/WindowManager( 1548): Starting input thread.
    495 D/WindowManager( 1548): Startup complete!
    496 I/EventHub( 1548): New keyboard: name=partnerxx_keypad 
    497   keymap=partnerxx_keypad.kl 
    498   keymapPath=/system/usr/keychars/partnerxx_keypad.kcm.bin
    499 I/ServiceManager( 1535): ServiceManager: addService(window, 0x13610)
    500 I/EventHub( 1548): Reporting device opened: id=0x10000, name=/dev/input/event0
    501 I/KeyInputQueue( 1548): Device added: id=0x10000, name=partnerxx_keypad, classes=1
    502 I/KeyInputQueue( 1548):   Keymap: partnerxx_keypad.kl
    503 </pre>
    504 <p>The snippet above contains artificial line breaks to maintain a print-friendly document.</p>
    505