1// Copyright 2013 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 "ui/events/keycodes/dom4/keycode_converter.h"
6
7namespace ui {
8
9namespace {
10
11#if defined(OS_WIN)
12#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, win, code}
13#elif defined(OS_LINUX)
14#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, xkb, code}
15#elif defined(OS_MACOSX)
16#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, mac, code}
17#else
18#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, 0, code}
19#endif
20#include "ui/events/keycodes/dom4/keycode_converter_data.h"
21
22const size_t kKeycodeMapEntries = arraysize(usb_keycode_map);
23
24}  // namespace
25
26// static
27size_t KeycodeConverter::NumKeycodeMapEntriesForTest() {
28  return kKeycodeMapEntries;
29}
30
31// static
32const KeycodeMapEntry* KeycodeConverter::GetKeycodeMapForTest() {
33  return &usb_keycode_map[0];
34}
35
36// static
37uint16_t KeycodeConverter::InvalidNativeKeycode() {
38  return usb_keycode_map[0].native_keycode;
39}
40
41// static
42const char* KeycodeConverter::InvalidKeyboardEventCode() {
43  return "Unidentified";
44}
45
46// static
47const char* KeycodeConverter::NativeKeycodeToCode(uint16_t native_keycode) {
48  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
49    if (usb_keycode_map[i].native_keycode == native_keycode) {
50      if (usb_keycode_map[i].code != NULL)
51        return usb_keycode_map[i].code;
52      break;
53    }
54  }
55  return InvalidKeyboardEventCode();
56}
57
58// static
59uint16_t KeycodeConverter::CodeToNativeKeycode(const char* code) {
60  if (!code ||
61      strcmp(code, InvalidKeyboardEventCode()) == 0) {
62    return InvalidNativeKeycode();
63  }
64
65  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
66    if (usb_keycode_map[i].code &&
67        strcmp(usb_keycode_map[i].code, code) == 0) {
68      return usb_keycode_map[i].native_keycode;
69    }
70  }
71  return InvalidNativeKeycode();
72}
73
74// USB keycodes
75// Note that USB keycodes are not part of any web standard.
76// Please don't use USB keycodes in new code.
77
78// static
79uint16_t KeycodeConverter::InvalidUsbKeycode() {
80  return usb_keycode_map[0].usb_keycode;
81}
82
83// static
84uint16_t KeycodeConverter::UsbKeycodeToNativeKeycode(uint32_t usb_keycode) {
85  // Deal with some special-cases that don't fit the 1:1 mapping.
86  if (usb_keycode == 0x070032) // non-US hash.
87    usb_keycode = 0x070031; // US backslash.
88#if defined(OS_MACOSX)
89  if (usb_keycode == 0x070046) // PrintScreen.
90    usb_keycode = 0x070068; // F13.
91#endif
92
93  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
94    if (usb_keycode_map[i].usb_keycode == usb_keycode)
95      return usb_keycode_map[i].native_keycode;
96  }
97  return InvalidNativeKeycode();
98}
99
100// static
101uint32_t KeycodeConverter::NativeKeycodeToUsbKeycode(uint16_t native_keycode) {
102  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
103    if (usb_keycode_map[i].native_keycode == native_keycode)
104      return usb_keycode_map[i].usb_keycode;
105  }
106  return InvalidUsbKeycode();
107}
108
109// static
110const char* KeycodeConverter::UsbKeycodeToCode(uint32_t usb_keycode) {
111  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
112    if (usb_keycode_map[i].usb_keycode == usb_keycode)
113      return usb_keycode_map[i].code;
114  }
115  return InvalidKeyboardEventCode();
116}
117
118// static
119uint32_t KeycodeConverter::CodeToUsbKeycode(const char* code) {
120  if (!code ||
121      strcmp(code, InvalidKeyboardEventCode()) == 0) {
122    return InvalidUsbKeycode();
123  }
124
125  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
126    if (usb_keycode_map[i].code &&
127        strcmp(usb_keycode_map[i].code, code) == 0) {
128      return usb_keycode_map[i].usb_keycode;
129    }
130  }
131  return InvalidUsbKeycode();
132}
133
134}  // namespace ui
135