• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Keymaps and Keyboard Input
2pdk.version=1.0
3doc.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
92key 2     1
93key 3     2
94key 4     3
95key 5     4
96key 6     5
97key 7     6
98key 8     7
99key 9     8
100key 10    9
101key 11    0
102key 158   BACK              WAKE_DROPPED
103key 230   SOFT_RIGHT        WAKE
104key 60    SOFT_RIGHT        WAKE
105key 107   ENDCALL           WAKE_DROPPED
106key 62    ENDCALL           WAKE_DROPPED
107key 229   MENU         WAKE_DROPPED
108key 59    MENU         WAKE_DROPPED
109key 228   POUND
110key 227   STAR
111key 231   CALL              WAKE_DROPPED
112key 61    CALL              WAKE_DROPPED
113key 232   DPAD_CENTER       WAKE_DROPPED
114key 108   DPAD_DOWN         WAKE_DROPPED
115key 103   DPAD_UP           WAKE_DROPPED
116key 102   HOME              WAKE
117key 105   DPAD_LEFT         WAKE_DROPPED
118key 106   DPAD_RIGHT        WAKE_DROPPED
119key 115   VOLUME_UP
120key 114   VOLUME_DOWN
121key 116   POWER             WAKE
122key 212   SLASH
123
124key 16    Q
125key 17    W
126key 18    E
127key 19    R
128key 20    T
129key 21    Y
130key 22    U
131key 23    I
132key 24    O
133key 25    P
134
135key 30    A
136key 31    S
137key 32    D
138key 33    F
139key 34    G
140key 35    H
141key 36    J
142key 37    K
143key 38    L
144key 14    DEL
145
146key 44    Z
147key 45    X
148key 46    C
149key 47    V
150key 48    B
151key 49    N
152key 50    M
153key 51    COMMA
154key 52    PERIOD
155key 28    NEWLINE
156
157key 56    ALT_LEFT
158key 42    SHIFT_LEFT
159key 215   AT
160key 57    SPACE
161key 53    SLASH
162key 127   SYM
163key 100   ALT_LEFT
164
165key 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
235A           'a'     'A'     '%'     0x00    '%'     'A'
236B           'b'     'B'     '='     0x00    '='     'B'
237C           'c'     'C'     '8'     0x00E7  '8'     'C'
238D           'd'     'D'     '5'     0x00    '5'     'D'
239E           'e'     'E'     '2'     0x0301  '2'     'E'
240F           'f'     'F'     '6'     0x00A5  '6'     'F'
241G           'g'     'G'     '-'     '_'     '-'     'G'
242H           'h'     'H'     '['     '{'     '['     'H'
243I           'i'     'I'     '$'     0x0302  '$'     'I'
244J           'j'     'J'     ']'     '}'     ']'     'J'
245K           'k'     'K'     '"'     '~'     '"'     'K'
246L           'l'     'L'     '''     '`'     '''     'L'
247M           'm'     'M'     '>'     0x00    '>'     'M'
248N           'n'     'N'     '<'     0x0303  '<'     'N'
249O           'o'     'O'     '('     0x00    '('     'O'
250P           'p'     'P'     ')'     0x00    ')'     'P'
251Q           'q'     'Q'     '*'     0x0300  '*'     'Q'
252R           'r'     'R'     '3'     0x20AC  '3'     'R'
253S           's'     'S'     '4'     0x00DF  '4'     'S'
254T           't'     'T'     '+'     0x00A3  '+'     'T'
255U           'u'     'U'     '&'     0x0308  '&'     'U'
256V           'v'     'V'     '9'     '^'     '9'     'V'
257W           'w'     'W'     '1'     0x00    '1'     'W'
258X           'x'     'X'     '7'     0xEF00  '7'     'X'
259Y           'y'     'Y'     '!'     0x00A1  '!'     'Y'
260Z           'z'     'Z'     '#'     0x00    '#'     'Z'
261
262COMMA       ','     ';'     ';'     '|'     ','     ','
263PERIOD      '.'     ':'     ':'     0x2026  '.'     '.'
264AT          '@'     '0'     '0'     0x2022  '0'     '@'
265SLASH       '/'     '?'     '?'     '\'     '/'     '/'
266
267SPACE       0x20    0x20    0x9     0x9     0x20    0x20
268NEWLINE     0xa     0xa     0xa     0xa     0xa     0xa
269
270# on pc keyboards
271TAB         0x9     0x9     0x9     0x9     0x9     0x9
2720           '0'     ')'     ')'     ')'     '0'     '0'
2731           '1'     '!'     '!'     '!'     '1'     '1'
2742           '2'     '@'     '@'     '@'     '2'     '2'
2753           '3'     '#'     '#'     '#'     '3'     '3'
2764           '4'     '$'     '$'     '$'     '4'     '4'
2775           '5'     '%'     '%'     '%'     '5'     '5'
2786           '6'     '^'     '^'     '^'     '6'     '6'
2797           '7'     '&'     '&'     '&'     '7'     '7'
2808           '8'     '*'     '*'     '*'     '8'     '8'
2819           '9'     '('     '('     '('     '9'     '9'
282
283GRAVE         '`'     '~'     '`'     '~'     '`'     '`'
284MINUS         '-'     '_'     '-'     '_'     '-'     '-'
285EQUALS        '='     '+'     '='     '+'     '='     '='
286LEFT_BRACKET  '['     '{'     '['     '{'     '['     '['
287RIGHT_BRACKET ']'     '}'     ']'     '}'     ']'     ']'
288BACKSLASH     '\'     '|'     '\'     '|'     '\'     '\'
289SEMICOLON     ';'     ':'     ';'     ':'     ';'     ';'
290APOSTROPHE    '''     '"'     '''     '"'     '''     '''
291STAR          '*'     '*'     '*'     '*'     '*'     '*'
292POUND         '#'     '#'     '#'     '#'     '#'     '#'
293PLUS          '+'     '+'     '+'     '+'     '+'     '+'
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
395struct event_dev {
396    struct input_dev *input;
397    int irq;
398};
399
400static 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
413static 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
451fail:
452    kfree(edev);
453    input_free_device(input_dev);
454
455    return -EINVAL;
456}
457
458static struct platform_driver pguide_events_driver = {
459    .probe = pguide_events_probe,
460    .driver = {
461        .name = "pguide_events",
462    },
463};
464
465static int __devinit pguide_events_init(void)
466{
467    return platform_driver_register(&pguide_events_driver);
468}
469
470
471static void __exit pguide_events_exit(void)
472{
473}
474
475module_init(pguide_events_init);
476module_exit(pguide_events_exit);
477
478MODULE_DESCRIPTION("Pguide Event Device");
479MODULE_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">
487android.keylayout.partnerxx_keypad = /system/usr/keylayout/partnerxx_keypad.kl
488android.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">
492I/EventHub( 1548): New device: path=/dev/input/event0 name=partnerxx_keypad id=0x10000 (of 0x1) index=1 fd=30
493I/EventHub( 1548): new keyboard input device added, name = partnerxx_keypad
494D/WindowManager( 1548): Starting input thread.
495D/WindowManager( 1548): Startup complete!
496I/EventHub( 1548): New keyboard: name=partnerxx_keypad
497  keymap=partnerxx_keypad.kl
498  keymapPath=/system/usr/keychars/partnerxx_keypad.kcm.bin
499I/ServiceManager( 1535): ServiceManager: addService(window, 0x13610)
500I/EventHub( 1548): Reporting device opened: id=0x10000, name=/dev/input/event0
501I/KeyInputQueue( 1548): Device added: id=0x10000, name=partnerxx_keypad, classes=1
502I/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