summaryrefslogtreecommitdiff
path: root/chromium/ui/platform_window/x11/x11_window.cc
blob: f54b41667430e3915d97646f945c6d2a761b90ff (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright 2014 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/platform_window/x11/x11_window.h"

#include <X11/extensions/XInput2.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/platform_window/platform_window_delegate.h"

namespace ui {

X11Window::X11Window(PlatformWindowDelegate* delegate)
    : X11WindowBase(delegate) {
  DCHECK(PlatformEventSource::GetInstance());
  PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
}

X11Window::~X11Window() {
  PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
}

void X11Window::SetCursor(PlatformCursor cursor) {
  XDefineCursor(xdisplay(), xwindow(), cursor);
}

void X11Window::ProcessXInput2Event(XEvent* xev) {
  if (!TouchFactory::GetInstance()->ShouldProcessXI2Event(xev))
    return;
  EventType event_type = EventTypeFromNative(xev);
  switch (event_type) {
    case ET_KEY_PRESSED:
    case ET_KEY_RELEASED: {
      KeyEvent key_event(xev);
      delegate()->DispatchEvent(&key_event);
      break;
    }
    case ET_MOUSE_PRESSED:
    case ET_MOUSE_MOVED:
    case ET_MOUSE_DRAGGED:
    case ET_MOUSE_RELEASED: {
      MouseEvent mouse_event(xev);
      delegate()->DispatchEvent(&mouse_event);
      break;
    }
    case ET_MOUSEWHEEL: {
      MouseWheelEvent wheel_event(xev);
      delegate()->DispatchEvent(&wheel_event);
      break;
    }
    case ET_SCROLL_FLING_START:
    case ET_SCROLL_FLING_CANCEL:
    case ET_SCROLL: {
      ScrollEvent scroll_event(xev);
      delegate()->DispatchEvent(&scroll_event);
      break;
    }
    case ET_TOUCH_MOVED:
    case ET_TOUCH_PRESSED:
    case ET_TOUCH_CANCELLED:
    case ET_TOUCH_RELEASED: {
      TouchEvent touch_event(xev);
      delegate()->DispatchEvent(&touch_event);
      break;
    }
    default:
      break;
  }
}

bool X11Window::CanDispatchEvent(const PlatformEvent& xev) {
  return IsEventForXWindow(*xev);
}

uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
  XEvent* xev = event;
  switch (xev->type) {
    case EnterNotify: {
      // EnterNotify creates ET_MOUSE_MOVED. Mark as synthesized as this is
      // not real mouse move event.
      MouseEvent mouse_event(xev);
      CHECK_EQ(ET_MOUSE_MOVED, mouse_event.type());
      mouse_event.set_flags(mouse_event.flags() | EF_IS_SYNTHESIZED);
      delegate()->DispatchEvent(&mouse_event);
      break;
    }
    case LeaveNotify: {
      MouseEvent mouse_event(xev);
      delegate()->DispatchEvent(&mouse_event);
      break;
    }

    case KeyPress:
    case KeyRelease: {
      KeyEvent key_event(xev);
      delegate()->DispatchEvent(&key_event);
      break;
    }

    case ButtonPress:
    case ButtonRelease: {
      switch (EventTypeFromNative(xev)) {
        case ET_MOUSEWHEEL: {
          MouseWheelEvent mouseev(xev);
          delegate()->DispatchEvent(&mouseev);
          break;
        }
        case ET_MOUSE_PRESSED:
        case ET_MOUSE_RELEASED: {
          MouseEvent mouseev(xev);
          delegate()->DispatchEvent(&mouseev);
          break;
        }
        case ET_UNKNOWN:
          // No event is created for X11-release events for mouse-wheel
          // buttons.
          break;
        default:
          NOTREACHED();
      }
      break;
    }

    case Expose:
    case FocusOut:
    case ConfigureNotify:
    case ClientMessage: {
      ProcessXWindowEvent(xev);
      break;
    }

    case GenericEvent: {
      ProcessXInput2Event(xev);
      break;
    }
  }
  return POST_DISPATCH_STOP_PROPAGATION;
}

}  // namespace ui