Home | History | Annotate | Download | only in braille_display_private
      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