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.
5 #include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener.h"
7 #include <X11/extensions/XInput2.h>
10 #include "chromeos/ime/ime_keyboard.h"
11 #include "chromeos/ime/input_method_manager.h"
12 #include "ui/base/x/x11_util.h"
13 #include "ui/events/platform/platform_event_source.h"
18 // Checks the |event| and asynchronously sets the XKB layout when necessary.
19 void HandleHierarchyChangedEvent(
20 XIHierarchyEvent* event,
21 ObserverList<DeviceHierarchyObserver>* observer_list) {
22 if (!(event->flags & (XISlaveAdded | XISlaveRemoved)))
25 bool update_keyboard_status = false;
26 for (int i = 0; i < event->num_info; ++i) {
27 XIHierarchyInfo* info = &event->info[i];
28 if ((info->flags & XISlaveAdded) && (info->use == XIFloatingSlave)) {
29 FOR_EACH_OBSERVER(DeviceHierarchyObserver,
31 DeviceAdded(info->deviceid));
32 update_keyboard_status = true;
33 } else if (info->flags & XISlaveRemoved) {
34 // Can't check info->use here; it appears to always be 0.
35 FOR_EACH_OBSERVER(DeviceHierarchyObserver,
37 DeviceRemoved(info->deviceid));
41 if (update_keyboard_status) {
42 chromeos::input_method::InputMethodManager* input_method_manager =
43 chromeos::input_method::InputMethodManager::Get();
44 chromeos::input_method::ImeKeyboard* keyboard =
45 input_method_manager->GetImeKeyboard();
46 keyboard->ReapplyCurrentModifierLockStatus();
47 keyboard->ReapplyCurrentKeyboardLayout();
54 XInputHierarchyChangedEventListener*
55 XInputHierarchyChangedEventListener::GetInstance() {
56 return Singleton<XInputHierarchyChangedEventListener>::get();
59 XInputHierarchyChangedEventListener::XInputHierarchyChangedEventListener()
61 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
64 XInputHierarchyChangedEventListener::~XInputHierarchyChangedEventListener() {
68 void XInputHierarchyChangedEventListener::Stop() {
72 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
76 void XInputHierarchyChangedEventListener::AddObserver(
77 DeviceHierarchyObserver* observer) {
78 observer_list_.AddObserver(observer);
81 void XInputHierarchyChangedEventListener::RemoveObserver(
82 DeviceHierarchyObserver* observer) {
83 observer_list_.RemoveObserver(observer);
86 void XInputHierarchyChangedEventListener::WillProcessEvent(
87 const ui::PlatformEvent& event) {
88 ProcessedXEvent(event);
91 void XInputHierarchyChangedEventListener::DidProcessEvent(
92 const ui::PlatformEvent& event) {
95 void XInputHierarchyChangedEventListener::ProcessedXEvent(XEvent* xevent) {
96 if (xevent->xcookie.type != GenericEvent)
99 XGenericEventCookie* cookie = &(xevent->xcookie);
101 if (cookie->evtype == XI_HierarchyChanged) {
102 XIHierarchyEvent* event = static_cast<XIHierarchyEvent*>(cookie->data);
103 HandleHierarchyChangedEvent(event, &observer_list_);
104 if (event->flags & XIDeviceEnabled || event->flags & XIDeviceDisabled)
105 NotifyDeviceHierarchyChanged();
109 void XInputHierarchyChangedEventListener::NotifyDeviceHierarchyChanged() {
110 FOR_EACH_OBSERVER(DeviceHierarchyObserver,
112 DeviceHierarchyChanged());
115 } // namespace chromeos