Home | History | Annotate | Download | only in events
      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 
     18 namespace chromeos {
     19 
     20 namespace {
     21 static SystemKeyEventListener* g_system_key_event_listener = NULL;
     22 }  // namespace
     23 
     24 // static
     25 void SystemKeyEventListener::Initialize() {
     26   CHECK(!g_system_key_event_listener);
     27   g_system_key_event_listener = new SystemKeyEventListener();
     28 }
     29 
     30 // static
     31 void 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
     40 SystemKeyEventListener* SystemKeyEventListener::GetInstance() {
     41   return g_system_key_event_listener;
     42 }
     43 
     44 SystemKeyEventListener::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 
     68 SystemKeyEventListener::~SystemKeyEventListener() {
     69   Stop();
     70 }
     71 
     72 void SystemKeyEventListener::Stop() {
     73   if (stopped_)
     74     return;
     75   ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
     76   stopped_ = true;
     77 }
     78 
     79 void SystemKeyEventListener::WillProcessEvent(const base::NativeEvent& event) {
     80   ProcessedXEvent(event);
     81 }
     82 
     83 void SystemKeyEventListener::DidProcessEvent(const base::NativeEvent& event) {
     84 }
     85 
     86 void 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