blob: e6e70d0d4f091bb26f13cb8ea7cd1aa892f211b6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
// 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 "ui/aura/dispatcher_linux.h"
#include <X11/extensions/XInput2.h>
#include "ui/base/events.h"
namespace {
// Pro-processes an XEvent before it is handled. The pre-processings include:
// - Map Alt+Button1 to Button3
void PreprocessXEvent(XEvent* xevent) {
if (!xevent || xevent->type != GenericEvent)
return;
XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
if ((xievent->evtype == XI_ButtonPress ||
xievent->evtype == XI_ButtonRelease) &&
(xievent->mods.effective & Mod1Mask) &&
xievent->detail == 1) {
xievent->mods.effective &= ~Mod1Mask;
xievent->detail = 3;
if (xievent->evtype == XI_ButtonRelease) {
// On the release clear the left button from the existing state and the
// mods, and set the right button.
XISetMask(xievent->buttons.mask, 3);
XIClearMask(xievent->buttons.mask, 1);
xievent->mods.effective &= ~Button1Mask;
}
}
}
} // namespace
namespace aura {
DispatcherLinux::DispatcherLinux() {
base::MessagePumpX::SetDefaultDispatcher(this);
}
DispatcherLinux::~DispatcherLinux() {
base::MessagePumpX::SetDefaultDispatcher(NULL);
}
void DispatcherLinux::WindowDispatcherCreated(
::Window window,
MessageLoop::Dispatcher* dispatcher) {
dispatchers_.insert(std::make_pair(window, dispatcher));
}
void DispatcherLinux::WindowDispatcherDestroying(::Window window) {
dispatchers_.erase(window);
}
bool DispatcherLinux::Dispatch(const base::NativeEvent& xev) {
PreprocessXEvent(xev);
// XI_HierarchyChanged events are special. There is no window associated with
// these events. So process them directly from here.
if (xev->type == GenericEvent &&
xev->xgeneric.evtype == XI_HierarchyChanged) {
ui::UpdateDeviceList();
return true;
}
// MappingNotify events (meaning that the keyboard or pointer buttons have
// been remapped) aren't associated with a window; send them to all
// dispatchers.
if (xev->type == MappingNotify) {
for (DispatchersMap::const_iterator it = dispatchers_.begin();
it != dispatchers_.end(); ++it) {
it->second->Dispatch(xev);
}
return true;
}
MessageLoop::Dispatcher* dispatcher = GetDispatcherForXEvent(xev);
return dispatcher ? dispatcher->Dispatch(xev) : true;
}
MessageLoop::Dispatcher* DispatcherLinux::GetDispatcherForXEvent(
XEvent* xev) const {
::Window window = xev->xany.window;
if (xev->type == GenericEvent) {
XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
window = xievent->event;
}
DispatchersMap::const_iterator it = dispatchers_.find(window);
return it != dispatchers_.end() ? it->second : NULL;
}
MessageLoop::Dispatcher* CreateDispatcher() {
return new DispatcherLinux;
}
} // namespace aura
|