blob: 7ce4f5e7044018960ac9ed31873eeab40afe6101 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/events/system_key_event_listener.h"
#define XK_MISCELLANY 1
#include <X11/keysymdef.h>
#include <X11/XF86keysym.h>
#include <X11/XKBlib.h>
#undef Status
#include "chromeos/ime/ime_keyboard.h"
#include "chromeos/ime/input_method_manager.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/platform/platform_event_source.h"
namespace chromeos {
namespace {
static SystemKeyEventListener* g_system_key_event_listener = NULL;
} // namespace
// static
void SystemKeyEventListener::Initialize() {
CHECK(!g_system_key_event_listener);
g_system_key_event_listener = new SystemKeyEventListener();
}
// static
void SystemKeyEventListener::Shutdown() {
// We may call Shutdown without calling Initialize, e.g. if we exit early.
if (g_system_key_event_listener) {
delete g_system_key_event_listener;
g_system_key_event_listener = NULL;
}
}
// static
SystemKeyEventListener* SystemKeyEventListener::GetInstance() {
return g_system_key_event_listener;
}
SystemKeyEventListener::SystemKeyEventListener()
: stopped_(false),
xkb_event_base_(0) {
XDisplay* display = gfx::GetXDisplay();
int xkb_major_version = XkbMajorVersion;
int xkb_minor_version = XkbMinorVersion;
if (!XkbQueryExtension(display,
NULL, // opcode_return
&xkb_event_base_,
NULL, // error_return
&xkb_major_version,
&xkb_minor_version)) {
LOG(WARNING) << "Could not query Xkb extension";
}
if (!XkbSelectEvents(display, XkbUseCoreKbd,
XkbStateNotifyMask,
XkbStateNotifyMask)) {
LOG(WARNING) << "Could not install Xkb Indicator observer";
}
ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
}
SystemKeyEventListener::~SystemKeyEventListener() {
Stop();
}
void SystemKeyEventListener::Stop() {
if (stopped_)
return;
ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
stopped_ = true;
}
void SystemKeyEventListener::WillProcessEvent(const base::NativeEvent& event) {
ProcessedXEvent(event);
}
void SystemKeyEventListener::DidProcessEvent(const base::NativeEvent& event) {
}
void SystemKeyEventListener::ProcessedXEvent(XEvent* xevent) {
input_method::InputMethodManager* input_method_manager =
input_method::InputMethodManager::Get();
if (xevent->type == xkb_event_base_) {
// TODO(yusukes): Move this part to aura::WindowTreeHost.
XkbEvent* xkey_event = reinterpret_cast<XkbEvent*>(xevent);
if (xkey_event->any.xkb_type == XkbStateNotify) {
if (xkey_event->state.mods) {
// TODO(yusukes,adlr): Let the user know that num lock is unsupported.
// Force turning off Num Lock (crosbug.com/29169)
input_method_manager->GetImeKeyboard()->DisableNumLock();
}
}
}
}
} // namespace chromeos