1// Copyright (c) 2012 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/chromeos/events/system_key_event_listener.h" 6 7#define XK_MISCELLANY 1 8#include <X11/keysymdef.h> 9#include <X11/XF86keysym.h> 10#include <X11/XKBlib.h> 11#undef Status 12 13#include "chromeos/ime/ime_keyboard.h" 14#include "chromeos/ime/input_method_manager.h" 15#include "ui/base/x/x11_util.h" 16#include "ui/events/platform/platform_event_source.h" 17 18namespace chromeos { 19 20namespace { 21static SystemKeyEventListener* g_system_key_event_listener = NULL; 22} // namespace 23 24// static 25void SystemKeyEventListener::Initialize() { 26 CHECK(!g_system_key_event_listener); 27 g_system_key_event_listener = new SystemKeyEventListener(); 28} 29 30// static 31void SystemKeyEventListener::Shutdown() { 32 // We may call Shutdown without calling Initialize, e.g. if we exit early. 33 if (g_system_key_event_listener) { 34 delete g_system_key_event_listener; 35 g_system_key_event_listener = NULL; 36 } 37} 38 39// static 40SystemKeyEventListener* SystemKeyEventListener::GetInstance() { 41 return g_system_key_event_listener; 42} 43 44SystemKeyEventListener::SystemKeyEventListener() 45 : stopped_(false), 46 xkb_event_base_(0) { 47 XDisplay* display = gfx::GetXDisplay(); 48 int xkb_major_version = XkbMajorVersion; 49 int xkb_minor_version = XkbMinorVersion; 50 if (!XkbQueryExtension(display, 51 NULL, // opcode_return 52 &xkb_event_base_, 53 NULL, // error_return 54 &xkb_major_version, 55 &xkb_minor_version)) { 56 LOG(WARNING) << "Could not query Xkb extension"; 57 } 58 59 if (!XkbSelectEvents(display, XkbUseCoreKbd, 60 XkbStateNotifyMask, 61 XkbStateNotifyMask)) { 62 LOG(WARNING) << "Could not install Xkb Indicator observer"; 63 } 64 65 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); 66} 67 68SystemKeyEventListener::~SystemKeyEventListener() { 69 Stop(); 70} 71 72void SystemKeyEventListener::Stop() { 73 if (stopped_) 74 return; 75 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this); 76 stopped_ = true; 77} 78 79void SystemKeyEventListener::WillProcessEvent(const base::NativeEvent& event) { 80 ProcessedXEvent(event); 81} 82 83void SystemKeyEventListener::DidProcessEvent(const base::NativeEvent& event) { 84} 85 86void SystemKeyEventListener::ProcessedXEvent(XEvent* xevent) { 87 input_method::InputMethodManager* input_method_manager = 88 input_method::InputMethodManager::Get(); 89 90 if (xevent->type == xkb_event_base_) { 91 // TODO(yusukes): Move this part to aura::WindowTreeHost. 92 XkbEvent* xkey_event = reinterpret_cast<XkbEvent*>(xevent); 93 if (xkey_event->any.xkb_type == XkbStateNotify) { 94 if (xkey_event->state.mods) { 95 // TODO(yusukes,adlr): Let the user know that num lock is unsupported. 96 // Force turning off Num Lock (crosbug.com/29169) 97 input_method_manager->GetImeKeyboard()->DisableNumLock(); 98 } 99 } 100 } 101} 102 103} // namespace chromeos 104