• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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|.
MapModifierFlags(brlapi_keyCode_t code,KeyEvent * event)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.
MapKeySym(brlapi_keyCode_t code,KeyEvent * event)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 
MapCommand(brlapi_keyCode_t code,KeyEvent * event)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 
BrlapiKeyCodeToEvent(brlapi_keyCode_t code)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