chromeos: Lock proxy settings UI for policy managed network.
[chromium-blink-merge.git] / chrome / browser / chromeos / xinput_hierarchy_changed_event_listener.cc
blobfcab3423f14cfd15a76c4e5154234a1b5ab70129
1 // Copyright (c) 2011 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/xinput_hierarchy_changed_event_listener.h"
7 #include <X11/Xlib.h>
8 #include <X11/extensions/XInput2.h>
10 #include "chrome/browser/chromeos/input_method/input_method_manager.h"
11 #include "chrome/browser/chromeos/input_method/xkeyboard.h"
12 #include "ui/base/x/x11_util.h"
14 namespace {
16 // Gets the major opcode for XInput2. Returns -1 on error.
17 int GetXInputOpCode() {
18 static const char kExtensionName[] = "XInputExtension";
19 int xi_opcode = -1;
20 int event;
21 int error;
23 if (!XQueryExtension(
24 ui::GetXDisplay(), kExtensionName, &xi_opcode, &event, &error)) {
25 VLOG(1) << "X Input extension not available: error=" << error;
26 return -1;
28 return xi_opcode;
31 // Starts listening to the XI_HierarchyChanged events.
32 void SelectXInputEvents() {
33 XIEventMask evmask;
34 unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {};
35 XISetMask(mask, XI_HierarchyChanged);
37 evmask.deviceid = XIAllDevices;
38 evmask.mask_len = sizeof(mask);
39 evmask.mask = mask;
41 Display* display = ui::GetXDisplay();
42 XISelectEvents(display, DefaultRootWindow(display), &evmask, 1);
45 // Checks the |event| and asynchronously sets the XKB layout when necessary.
46 void HandleHierarchyChangedEvent(XIHierarchyEvent* event) {
47 if (!(event->flags & XISlaveAdded))
48 return;
50 for (int i = 0; i < event->num_info; ++i) {
51 XIHierarchyInfo* info = &event->info[i];
52 if ((info->flags & XISlaveAdded) && (info->use == XIFloatingSlave)) {
53 chromeos::input_method::InputMethodManager* input_method_manager =
54 chromeos::input_method::InputMethodManager::GetInstance();
55 chromeos::input_method::XKeyboard* xkeyboard =
56 input_method_manager->GetXKeyboard();
57 xkeyboard->ReapplyCurrentModifierLockStatus();
58 xkeyboard->ReapplyCurrentKeyboardLayout();
59 break;
64 } // namespace
66 namespace chromeos {
68 // static
69 XInputHierarchyChangedEventListener*
70 XInputHierarchyChangedEventListener::GetInstance() {
71 return Singleton<XInputHierarchyChangedEventListener>::get();
74 XInputHierarchyChangedEventListener::XInputHierarchyChangedEventListener()
75 : stopped_(false),
76 xiopcode_(GetXInputOpCode()) {
77 SelectXInputEvents();
78 Init();
81 XInputHierarchyChangedEventListener::~XInputHierarchyChangedEventListener() {
82 Stop();
85 void XInputHierarchyChangedEventListener::Stop() {
86 if (stopped_)
87 return;
89 StopImpl();
90 stopped_ = true;
91 xiopcode_ = -1;
94 void XInputHierarchyChangedEventListener::AddObserver(
95 DeviceHierarchyObserver* observer) {
96 observer_list_.AddObserver(observer);
99 void XInputHierarchyChangedEventListener::RemoveObserver(
100 DeviceHierarchyObserver* observer) {
101 observer_list_.RemoveObserver(observer);
104 bool XInputHierarchyChangedEventListener::ProcessedXEvent(XEvent* xevent) {
105 if ((xevent->xcookie.type != GenericEvent) ||
106 (xevent->xcookie.extension != xiopcode_)) {
107 return false;
110 XGenericEventCookie* cookie = &(xevent->xcookie);
111 const bool hierarchy_changed = (cookie->evtype == XI_HierarchyChanged);
113 if (hierarchy_changed) {
114 XIHierarchyEvent* event = static_cast<XIHierarchyEvent*>(cookie->data);
115 HandleHierarchyChangedEvent(event);
116 if (event->flags & XIDeviceEnabled || event->flags & XIDeviceDisabled)
117 NotifyDeviceHierarchyChanged();
120 return hierarchy_changed;
123 void XInputHierarchyChangedEventListener::NotifyDeviceHierarchyChanged() {
124 FOR_EACH_OBSERVER(DeviceHierarchyObserver,
125 observer_list_,
126 DeviceHierarchyChanged());
129 } // namespace chromeos