summaryrefslogtreecommitdiffstats
path: root/ui/aura/dispatcher_linux.cc
blob: 8fbf7f401118900493042d936259c4be7bf55505 (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
// 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/aura/root_window_host_linux.h"
#include "ui/base/events.h"

namespace aura {

DispatcherLinux::DispatcherLinux() {
  base::MessagePumpX::SetDefaultDispatcher(this);
}

DispatcherLinux::~DispatcherLinux() {
  base::MessagePumpX::SetDefaultDispatcher(NULL);
}

void DispatcherLinux::RootWindowHostCreated(::Window window,
                                            ::Window root,
                                            RootWindowHostLinux* host) {
  hosts_.insert(std::make_pair(window, host));
  // Only the 1st root window listens to the root window.
  if (hosts_.find(root) == hosts_.end())
    hosts_.insert(std::make_pair(root, host));
}

void DispatcherLinux::RootWindowHostDestroying(::Window window, ::Window root) {
  if (hosts_[window] == hosts_[root])
    hosts_.erase(root);
  hosts_.erase(window);
}

base::MessagePumpDispatcher::DispatchStatus DispatcherLinux::Dispatch(
    XEvent* 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 EVENT_PROCESSED;
  }
  RootWindowHostLinux* host = GetRootWindowHostForXEvent(xev);
  return host ? host->Dispatch(xev) : EVENT_IGNORED;
}

RootWindowHostLinux* DispatcherLinux::GetRootWindowHostForXEvent(
    XEvent* xev) const {
  ::Window window = xev->xany.window;
  if (xev->type == GenericEvent) {
    XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
    window = xievent->event;
  }
  HostsMap::const_iterator it = hosts_.find(window);
  return it != hosts_.end() ? it->second : NULL;
}

Dispatcher* CreateDispatcher() {
  return new DispatcherLinux;
}

}  // namespace aura