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 "?" 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