| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright 2016 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/ozone/platform/wayland/wayland_keyboard.h" | 
 |    6  | 
 |    7 #include <sys/mman.h> | 
 |    8 #include <wayland-client.h> | 
 |    9  | 
 |   10 #include "base/files/scoped_file.h" | 
 |   11 #include "ui/base/ui_features.h" | 
 |   12 #include "ui/events/event.h" | 
 |   13 #include "ui/events/keycodes/dom/dom_code.h" | 
 |   14 #include "ui/events/keycodes/dom/keycode_converter.h" | 
 |   15 #include "ui/events/ozone/layout/keyboard_layout_engine.h" | 
 |   16 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" | 
 |   17 #include "ui/ozone/platform/wayland/wayland_window.h" | 
 |   18  | 
 |   19 #if BUILDFLAG(USE_XKBCOMMON) | 
 |   20 #include "ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h" | 
 |   21 #endif | 
 |   22  | 
 |   23 namespace ui { | 
 |   24  | 
 |   25 namespace { | 
 |   26  | 
 |   27 const int kXkbKeycodeOffset = 8; | 
 |   28  | 
 |   29 }  // namespace | 
 |   30  | 
 |   31 WaylandKeyboard::WaylandKeyboard(wl_keyboard* keyboard, | 
 |   32                                  const EventDispatchCallback& callback) | 
 |   33     : obj_(keyboard), callback_(callback) { | 
 |   34   static const wl_keyboard_listener listener = { | 
 |   35       &WaylandKeyboard::Keymap,    &WaylandKeyboard::Enter, | 
 |   36       &WaylandKeyboard::Leave,     &WaylandKeyboard::Key, | 
 |   37       &WaylandKeyboard::Modifiers, &WaylandKeyboard::RepeatInfo, | 
 |   38   }; | 
 |   39  | 
 |   40   wl_keyboard_add_listener(obj_.get(), &listener, this); | 
 |   41  | 
 |   42   // TODO(tonikitoo): Default auto-repeat to ON here? | 
 |   43 } | 
 |   44  | 
 |   45 WaylandKeyboard::~WaylandKeyboard() {} | 
 |   46  | 
 |   47 void WaylandKeyboard::Keymap(void* data, | 
 |   48                              wl_keyboard* obj, | 
 |   49                              uint32_t format, | 
 |   50                              int32_t raw_fd, | 
 |   51                              uint32_t size) { | 
 |   52   base::ScopedFD fd(raw_fd); | 
 |   53   if (!data || format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) | 
 |   54     return; | 
 |   55  | 
 |   56   char* keymap_str = reinterpret_cast<char*>( | 
 |   57       mmap(nullptr, size, PROT_READ, MAP_SHARED, fd.get(), 0)); | 
 |   58   if (keymap_str == MAP_FAILED) | 
 |   59     return; | 
 |   60  | 
 |   61   bool success = | 
 |   62       KeyboardLayoutEngineManager::GetKeyboardLayoutEngine() | 
 |   63           ->SetCurrentLayoutFromBuffer(keymap_str, strnlen(keymap_str, size)); | 
 |   64   DCHECK(success) << "Failed to set the XKB keyboard mapping."; | 
 |   65   munmap(keymap_str, size); | 
 |   66 } | 
 |   67  | 
 |   68 void WaylandKeyboard::Enter(void* data, | 
 |   69                             wl_keyboard* obj, | 
 |   70                             uint32_t serial, | 
 |   71                             wl_surface* surface, | 
 |   72                             wl_array* keys) { | 
 |   73   WaylandWindow::FromSurface(surface)->set_keyboard_focus(true); | 
 |   74 } | 
 |   75  | 
 |   76 void WaylandKeyboard::Leave(void* data, | 
 |   77                             wl_keyboard* obj, | 
 |   78                             uint32_t serial, | 
 |   79                             wl_surface* surface) { | 
 |   80   WaylandWindow::FromSurface(surface)->set_keyboard_focus(false); | 
 |   81 } | 
 |   82  | 
 |   83 void WaylandKeyboard::Key(void* data, | 
 |   84                           wl_keyboard* obj, | 
 |   85                           uint32_t serial, | 
 |   86                           uint32_t time, | 
 |   87                           uint32_t key, | 
 |   88                           uint32_t state) { | 
 |   89   WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data); | 
 |   90  | 
 |   91   DomCode dom_code = | 
 |   92       KeycodeConverter::NativeKeycodeToDomCode(key + kXkbKeycodeOffset); | 
 |   93   if (dom_code == ui::DomCode::NONE) | 
 |   94     return; | 
 |   95  | 
 |   96   uint8_t flags = keyboard->modifiers_; | 
 |   97   DomKey dom_key; | 
 |   98   KeyboardCode key_code; | 
 |   99   if (!KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup( | 
 |  100           dom_code, flags, &dom_key, &key_code)) | 
 |  101     return; | 
 |  102  | 
 |  103   // TODO(tonikitoo): handle repeat here. | 
 |  104   bool down = state == WL_KEYBOARD_KEY_STATE_PRESSED; | 
 |  105   ui::KeyEvent event( | 
 |  106       down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code, dom_code, | 
 |  107       keyboard->modifiers_, dom_key, | 
 |  108       base::TimeTicks() + base::TimeDelta::FromMilliseconds(time)); | 
 |  109   event.set_source_device_id(keyboard->obj_.id()); | 
 |  110   keyboard->callback_.Run(&event); | 
 |  111 } | 
 |  112  | 
 |  113 void WaylandKeyboard::Modifiers(void* data, | 
 |  114                                 wl_keyboard* obj, | 
 |  115                                 uint32_t serial, | 
 |  116                                 uint32_t mods_depressed, | 
 |  117                                 uint32_t mods_latched, | 
 |  118                                 uint32_t mods_locked, | 
 |  119                                 uint32_t group) { | 
 |  120 #if BUILDFLAG(USE_XKBCOMMON) | 
 |  121   WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data); | 
 |  122   auto* engine = static_cast<WaylandXkbKeyboardLayoutEngine*>( | 
 |  123       KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()); | 
 |  124  | 
 |  125   keyboard->modifiers_ = | 
 |  126       engine->UpdateModifiers(mods_depressed, mods_latched, mods_locked, group); | 
 |  127  | 
 |  128 #endif | 
 |  129 } | 
 |  130  | 
 |  131 void WaylandKeyboard::RepeatInfo(void* data, | 
 |  132                                  wl_keyboard* obj, | 
 |  133                                  int32_t rate, | 
 |  134                                  int32_t delay) { | 
 |  135   // TODO(tonikitoo): Implement proper repeat handling. | 
 |  136   NOTIMPLEMENTED(); | 
 |  137 } | 
 |  138  | 
 |  139 }  // namespace ui | 
| OLD | NEW |