blob: 75cd89f4b5c69af68d83c4b3d18fde17481078a8 [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/xinput_hierarchy_changed_event_listener.h"
#include <X11/extensions/XInput2.h>
#include <X11/Xlib.h>
#include "ui/base/ime/chromeos/ime_keyboard.h"
#include "ui/base/ime/chromeos/input_method_manager.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/platform/platform_event_source.h"
namespace chromeos {
namespace {
// Checks the |event| and asynchronously sets the XKB layout when necessary.
void HandleHierarchyChangedEvent(XIHierarchyEvent* event) {
if (!(event->flags & (XISlaveAdded | XISlaveRemoved)))
return;
bool update_keyboard_status = false;
for (int i = 0; i < event->num_info; ++i) {
XIHierarchyInfo* info = &event->info[i];
if ((info->flags & XISlaveAdded) && (info->use == XIFloatingSlave)) {
update_keyboard_status = true;
break;
}
}
if (update_keyboard_status) {
chromeos::input_method::InputMethodManager* input_method_manager =
chromeos::input_method::InputMethodManager::Get();
chromeos::input_method::ImeKeyboard* keyboard =
input_method_manager->GetImeKeyboard();
keyboard->ReapplyCurrentModifierLockStatus();
keyboard->ReapplyCurrentKeyboardLayout();
}
}
} // namespace
// static
XInputHierarchyChangedEventListener*
XInputHierarchyChangedEventListener::GetInstance() {
return base::Singleton<XInputHierarchyChangedEventListener>::get();
}
XInputHierarchyChangedEventListener::XInputHierarchyChangedEventListener()
: stopped_(false) {
ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
}
XInputHierarchyChangedEventListener::~XInputHierarchyChangedEventListener() {
Stop();
}
void XInputHierarchyChangedEventListener::Stop() {
if (stopped_)
return;
ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
stopped_ = true;
}
void XInputHierarchyChangedEventListener::WillProcessEvent(
const ui::PlatformEvent& event) {
ProcessedXEvent(event);
}
void XInputHierarchyChangedEventListener::DidProcessEvent(
const ui::PlatformEvent& event) {
}
void XInputHierarchyChangedEventListener::ProcessedXEvent(XEvent* xevent) {
if (xevent->xcookie.type != GenericEvent)
return;
XGenericEventCookie* cookie = &(xevent->xcookie);
if (cookie->evtype == XI_HierarchyChanged) {
XIHierarchyEvent* event = static_cast<XIHierarchyEvent*>(cookie->data);
HandleHierarchyChangedEvent(event);
}
}
} // namespace chromeos