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 10 namespace extensions { 11 namespace api { 12 namespace braille_display_private { 13 14 namespace { 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. 18 const 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. 22 const 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. 27 const brlapi_keyCode_t kMinFunctionKey = BRLAPI_KEY_SYM_FUNCTION; 28 const brlapi_keyCode_t kMaxFunctionKey = BRLAPI_KEY_SYM_FUNCTION + 23; 29 30 // Maps the keyboard modifier flags to their corresponding flags in a 31 // |KeyEvent|. 32 void 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. 45 void 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 115 void 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 153 scoped_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