1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/extensions/api/braille_display_private/brlapi_keycode_map.h" 6 7#include "base/strings/stringprintf.h" 8#include "base/strings/utf_string_conversion_utils.h" 9 10namespace extensions { 11namespace api { 12namespace braille_display_private { 13 14namespace { 15// Bitmask for all braille dots in a key command argument, which coincides 16// with the representation in the braille_dots member of the KeyEvent 17// class. 18const int kAllDots = BRLAPI_DOT1 | BRLAPI_DOT2 | BRLAPI_DOT3 | BRLAPI_DOT4 | 19 BRLAPI_DOT5 | BRLAPI_DOT6 | BRLAPI_DOT7 | BRLAPI_DOT8; 20 21// Maximum Latin 1 character keyboard symbol. 22const brlapi_keyCode_t kMaxLatin1KeySym = 0xff; 23 24// Range of function keys that we support. 25// See ui/events/keycodes/dom4/keycode_converter_data.h for the list of all 26// key codes. 27const brlapi_keyCode_t kMinFunctionKey = BRLAPI_KEY_SYM_FUNCTION; 28const brlapi_keyCode_t kMaxFunctionKey = BRLAPI_KEY_SYM_FUNCTION + 23; 29 30// Maps the keyboard modifier flags to their corresponding flags in a 31// |KeyEvent|. 32void MapModifierFlags(brlapi_keyCode_t code, KeyEvent* event) { 33 if (code & BRLAPI_KEY_FLG_CONTROL) 34 event->ctrl_key.reset(new bool(true)); 35 if (code & BRLAPI_KEY_FLG_META) 36 event->alt_key.reset(new bool(true)); 37 if (code & BRLAPI_KEY_FLG_SHIFT) 38 event->shift_key.reset(new bool(true)); 39} 40 41// Maps a brlapi keysym, which is similar to an X keysym into the 42// provided event. 43// See ui/events/keycodes/dom4/keycode_converter_data.cc for the full 44// list of key codes. 45void MapKeySym(brlapi_keyCode_t code, KeyEvent* event) { 46 brlapi_keyCode_t key_sym = code & BRLAPI_KEY_CODE_MASK; 47 if (key_sym < kMaxLatin1KeySym || 48 (key_sym & BRLAPI_KEY_SYM_UNICODE) != 0) { 49 uint32 code_point = key_sym & ~BRLAPI_KEY_SYM_UNICODE; 50 if (!base::IsValidCharacter(code_point)) 51 return; 52 event->standard_key_char.reset(new std::string); 53 base::WriteUnicodeCharacter(code_point, event->standard_key_char.get()); 54 } else if (key_sym >= kMinFunctionKey && key_sym <= kMaxFunctionKey) { 55 // Function keys are 0-based here, so we need to add one to get e.g. 56 // 'F1' for the first key. 57 int function_key_number = key_sym - kMinFunctionKey + 1; 58 event->standard_key_code.reset( 59 new std::string(base::StringPrintf("F%d", function_key_number))); 60 } else { 61 // Explicitly map the keys that brlapi provides. 62 const char* code_string; 63 switch (key_sym) { 64 case BRLAPI_KEY_SYM_BACKSPACE: 65 code_string = "Backspace"; 66 break; 67 case BRLAPI_KEY_SYM_TAB: 68 code_string = "Tab"; 69 break; 70 case BRLAPI_KEY_SYM_LINEFEED: 71 code_string = "Enter"; 72 break; 73 case BRLAPI_KEY_SYM_ESCAPE: 74 code_string = "Escape"; 75 break; 76 case BRLAPI_KEY_SYM_HOME: 77 code_string = "Home"; 78 break; 79 case BRLAPI_KEY_SYM_LEFT: 80 code_string = "ArrowLeft"; 81 break; 82 case BRLAPI_KEY_SYM_UP: 83 code_string = "ArrowUp"; 84 break; 85 case BRLAPI_KEY_SYM_RIGHT: 86 code_string = "ArrowRight"; 87 break; 88 case BRLAPI_KEY_SYM_DOWN: 89 code_string = "ArrowDown"; 90 break; 91 case BRLAPI_KEY_SYM_PAGE_UP: 92 code_string = "PageUp"; 93 break; 94 case BRLAPI_KEY_SYM_PAGE_DOWN: 95 code_string = "PageDown"; 96 break; 97 case BRLAPI_KEY_SYM_END: 98 code_string = "End"; 99 break; 100 case BRLAPI_KEY_SYM_INSERT: 101 code_string = "Insert"; 102 break; 103 case BRLAPI_KEY_SYM_DELETE: 104 code_string = "Delete"; 105 break; 106 default: 107 return; 108 } 109 event->standard_key_code.reset(new std::string(code_string)); 110 } 111 MapModifierFlags(code, event); 112 event->command = KEY_COMMAND_STANDARD_KEY; 113} 114 115void MapCommand(brlapi_keyCode_t code, KeyEvent* event) { 116 brlapi_keyCode_t argument = code & BRLAPI_KEY_CMD_ARG_MASK; 117 switch (code & BRLAPI_KEY_CODE_MASK) { 118 case BRLAPI_KEY_CMD_LNUP: 119 event->command = KEY_COMMAND_LINE_UP; 120 break; 121 case BRLAPI_KEY_CMD_LNDN: 122 event->command = KEY_COMMAND_LINE_DOWN; 123 break; 124 case BRLAPI_KEY_CMD_FWINLT: 125 event->command = KEY_COMMAND_PAN_LEFT; 126 break; 127 case BRLAPI_KEY_CMD_FWINRT: 128 event->command = KEY_COMMAND_PAN_RIGHT; 129 break; 130 case BRLAPI_KEY_CMD_TOP: 131 event->command = KEY_COMMAND_TOP; 132 break; 133 case BRLAPI_KEY_CMD_BOT: 134 event->command = KEY_COMMAND_BOTTOM; 135 break; 136 default: 137 switch (code & BRLAPI_KEY_CMD_BLK_MASK) { 138 case BRLAPI_KEY_CMD_ROUTE: 139 event->command = KEY_COMMAND_ROUTING; 140 event->display_position.reset(new int(argument)); 141 break; 142 case BRLAPI_KEY_CMD_PASSDOTS: 143 event->command = KEY_COMMAND_DOTS; 144 event->braille_dots.reset(new int(argument & kAllDots)); 145 MapModifierFlags(code, event); 146 break; 147 } 148 } 149} 150 151} // namespace 152 153scoped_ptr<KeyEvent> BrlapiKeyCodeToEvent(brlapi_keyCode_t code) { 154 scoped_ptr<KeyEvent> result(new KeyEvent); 155 result->command = KEY_COMMAND_NONE; 156 switch (code & BRLAPI_KEY_TYPE_MASK) { 157 case BRLAPI_KEY_TYPE_SYM: 158 MapKeySym(code, result.get()); 159 break; 160 case BRLAPI_KEY_TYPE_CMD: 161 MapCommand(code, result.get()); 162 break; 163 } 164 if (result->command == KEY_COMMAND_NONE) 165 result.reset(); 166 return result.Pass(); 167} 168 169} // namespace braille_display_private 170} // namespace api 171} // namespace extensions 172