1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/events/keycodes/dom4/keycode_converter.h"
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace ui {
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace {
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN)
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, win, code}
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#elif defined(OS_LINUX)
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, xkb, code}
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#elif defined(OS_MACOSX)
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, mac, code}
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, 0, code}
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/events/keycodes/dom4/keycode_converter_data.h"
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const size_t kKeycodeMapEntries = arraysize(usb_keycode_map);
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)size_t KeycodeConverter::NumKeycodeMapEntriesForTest() {
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return kKeycodeMapEntries;
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const KeycodeMapEntry* KeycodeConverter::GetKeycodeMapForTest() {
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return &usb_keycode_map[0];
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)uint16_t KeycodeConverter::InvalidNativeKeycode() {
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return usb_keycode_map[0].native_keycode;
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char* KeycodeConverter::InvalidKeyboardEventCode() {
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return "Unidentified";
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char* KeycodeConverter::NativeKeycodeToCode(uint16_t native_keycode) {
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (usb_keycode_map[i].native_keycode == native_keycode) {
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (usb_keycode_map[i].code != NULL)
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return usb_keycode_map[i].code;
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return InvalidKeyboardEventCode();
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)uint16_t KeycodeConverter::CodeToNativeKeycode(const char* code) {
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!code ||
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      strcmp(code, InvalidKeyboardEventCode()) == 0) {
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return InvalidNativeKeycode();
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (usb_keycode_map[i].code &&
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        strcmp(usb_keycode_map[i].code, code) == 0) {
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return usb_keycode_map[i].native_keycode;
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return InvalidNativeKeycode();
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// USB keycodes
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Note that USB keycodes are not part of any web standard.
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Please don't use USB keycodes in new code.
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)uint16_t KeycodeConverter::InvalidUsbKeycode() {
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return usb_keycode_map[0].usb_keycode;
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)uint16_t KeycodeConverter::UsbKeycodeToNativeKeycode(uint32_t usb_keycode) {
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Deal with some special-cases that don't fit the 1:1 mapping.
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (usb_keycode == 0x070032) // non-US hash.
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    usb_keycode = 0x070031; // US backslash.
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_MACOSX)
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (usb_keycode == 0x070046) // PrintScreen.
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    usb_keycode = 0x070068; // F13.
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (usb_keycode_map[i].usb_keycode == usb_keycode)
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return usb_keycode_map[i].native_keycode;
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return InvalidNativeKeycode();
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)uint32_t KeycodeConverter::NativeKeycodeToUsbKeycode(uint16_t native_keycode) {
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (usb_keycode_map[i].native_keycode == native_keycode)
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return usb_keycode_map[i].usb_keycode;
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return InvalidUsbKeycode();
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char* KeycodeConverter::UsbKeycodeToCode(uint32_t usb_keycode) {
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (usb_keycode_map[i].usb_keycode == usb_keycode)
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return usb_keycode_map[i].code;
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return InvalidKeyboardEventCode();
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)uint32_t KeycodeConverter::CodeToUsbKeycode(const char* code) {
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!code ||
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      strcmp(code, InvalidKeyboardEventCode()) == 0) {
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return InvalidUsbKeycode();
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < kKeycodeMapEntries; ++i) {
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (usb_keycode_map[i].code &&
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        strcmp(usb_keycode_map[i].code, code) == 0) {
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return usb_keycode_map[i].usb_keycode;
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return InvalidUsbKeycode();
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace ui
135