Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / ui / aura / window_tree_host_x11.cc
blob0fb463e2d528476f470e52420b6b5833300ce5c7
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 "ui/aura/window_tree_host_x11.h"
7 #include <strings.h>
8 #include <X11/cursorfont.h>
9 #include <X11/extensions/XInput2.h>
10 #include <X11/extensions/Xrandr.h>
11 #include <X11/Xatom.h>
12 #include <X11/Xcursor/Xcursor.h>
13 #include <X11/Xlib.h>
15 #include <algorithm>
16 #include <limits>
17 #include <string>
19 #include "base/basictypes.h"
20 #include "base/command_line.h"
21 #include "base/stl_util.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/string_util.h"
24 #include "base/strings/stringprintf.h"
25 #include "base/sys_info.h"
26 #include "base/trace_event/trace_event.h"
27 #include "ui/aura/client/cursor_client.h"
28 #include "ui/aura/env.h"
29 #include "ui/aura/window.h"
30 #include "ui/aura/window_event_dispatcher.h"
31 #include "ui/base/cursor/cursor.h"
32 #include "ui/base/ui_base_switches.h"
33 #include "ui/base/view_prop.h"
34 #include "ui/base/x/x11_util.h"
35 #include "ui/compositor/compositor.h"
36 #include "ui/compositor/dip_util.h"
37 #include "ui/compositor/layer.h"
38 #include "ui/events/devices/x11/device_data_manager_x11.h"
39 #include "ui/events/devices/x11/device_list_cache_x11.h"
40 #include "ui/events/devices/x11/touch_factory_x11.h"
41 #include "ui/events/event.h"
42 #include "ui/events/event_switches.h"
43 #include "ui/events/event_utils.h"
44 #include "ui/events/keycodes/keyboard_codes.h"
45 #include "ui/events/platform/platform_event_observer.h"
46 #include "ui/events/platform/x11/x11_event_source.h"
47 #include "ui/gfx/screen.h"
49 using std::max;
50 using std::min;
52 namespace aura {
54 namespace {
56 const char* kAtomsToCache[] = {
57 "WM_DELETE_WINDOW",
58 "_NET_WM_PING",
59 "_NET_WM_PID",
60 NULL
63 ::Window FindEventTarget(const base::NativeEvent& xev) {
64 ::Window target = xev->xany.window;
65 if (xev->type == GenericEvent)
66 target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event;
67 return target;
70 void SelectXInput2EventsForRootWindow(XDisplay* display, ::Window root_window) {
71 CHECK(ui::IsXInput2Available());
72 unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {};
73 memset(mask, 0, sizeof(mask));
75 XISetMask(mask, XI_HierarchyChanged);
77 XIEventMask evmask;
78 evmask.deviceid = XIAllDevices;
79 evmask.mask_len = sizeof(mask);
80 evmask.mask = mask;
81 XISelectEvents(display, root_window, &evmask, 1);
83 #if defined(OS_CHROMEOS)
84 if (base::SysInfo::IsRunningOnChromeOS()) {
85 // It is necessary to listen for touch events on the root window for proper
86 // touch event calibration on Chrome OS, but this is not currently necessary
87 // on the desktop. This seems to fail in some cases (e.g. when logging
88 // in incognito). So select for non-touch events first, and then select for
89 // touch-events (but keep the other events in the mask, i.e. do not memset
90 // |mask| back to 0).
91 // TODO(sad): Figure out why this happens. http://crbug.com/153976
92 XISetMask(mask, XI_TouchBegin);
93 XISetMask(mask, XI_TouchUpdate);
94 XISetMask(mask, XI_TouchEnd);
95 XISelectEvents(display, root_window, &evmask, 1);
97 #endif
100 bool default_override_redirect = false;
102 } // namespace
104 namespace internal {
106 // TODO(miletus) : Move this into DeviceDataManager.
107 // Accomplishes 2 tasks concerning touch event calibration:
108 // 1. Being a message-pump observer,
109 // routes all the touch events to the X root window,
110 // where they can be calibrated later.
111 // 2. Has the Calibrate method that does the actual bezel calibration,
112 // when invoked from X root window's event dispatcher.
113 class TouchEventCalibrate : public ui::PlatformEventObserver {
114 public:
115 TouchEventCalibrate() : left_(0), right_(0), top_(0), bottom_(0) {
116 if (ui::PlatformEventSource::GetInstance())
117 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
118 std::vector<std::string> parts;
119 if (Tokenize(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
120 switches::kTouchCalibration),
121 ",", &parts) >= 4) {
122 if (!base::StringToInt(parts[0], &left_))
123 DLOG(ERROR) << "Incorrect left border calibration value passed.";
124 if (!base::StringToInt(parts[1], &right_))
125 DLOG(ERROR) << "Incorrect right border calibration value passed.";
126 if (!base::StringToInt(parts[2], &top_))
127 DLOG(ERROR) << "Incorrect top border calibration value passed.";
128 if (!base::StringToInt(parts[3], &bottom_))
129 DLOG(ERROR) << "Incorrect bottom border calibration value passed.";
133 ~TouchEventCalibrate() override {
134 if (ui::PlatformEventSource::GetInstance())
135 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
138 // Modify the location of the |event|,
139 // expanding it from |bounds| to (|bounds| + bezels).
140 // Required when touchscreen is bigger than screen (i.e. has bezels),
141 // because we receive events in touchscreen coordinates,
142 // which need to be expanded when converting to screen coordinates,
143 // so that location on bezels will be outside of screen area.
144 void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) {
145 int x = event->x();
146 int y = event->y();
148 if (!left_ && !right_ && !top_ && !bottom_)
149 return;
151 const int resolution_x = bounds.width();
152 const int resolution_y = bounds.height();
153 if (left_ || right_) {
154 // Offset the x position to the real
155 x -= left_;
156 // Scale the screen area back to the full resolution of the screen.
157 x = (x * resolution_x) / (resolution_x - (right_ + left_));
159 if (top_ || bottom_) {
160 // When there is a top bezel we add our border,
161 y -= top_;
162 // Scale the screen area back to the full resolution of the screen.
163 y = (y * resolution_y) / (resolution_y - (bottom_ + top_));
166 // Set the modified coordinate back to the event.
167 if (event->root_location() == event->location()) {
168 // Usually those will be equal,
169 // if not, I am not sure what the correct value should be.
170 event->set_root_location(gfx::Point(x, y));
172 event->set_location(gfx::Point(x, y));
175 private:
176 // ui::PlatformEventObserver:
177 void WillProcessEvent(const ui::PlatformEvent& event) override {
178 if (event->type == GenericEvent &&
179 (event->xgeneric.evtype == XI_TouchBegin ||
180 event->xgeneric.evtype == XI_TouchUpdate ||
181 event->xgeneric.evtype == XI_TouchEnd)) {
182 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data);
183 xievent->event = xievent->root;
184 xievent->event_x = xievent->root_x;
185 xievent->event_y = xievent->root_y;
189 void DidProcessEvent(const ui::PlatformEvent& event) override {}
191 // The difference in screen's native resolution pixels between
192 // the border of the touchscreen and the border of the screen,
193 // aka bezel sizes.
194 int left_;
195 int right_;
196 int top_;
197 int bottom_;
199 DISALLOW_COPY_AND_ASSIGN(TouchEventCalibrate);
202 } // namespace internal
204 ////////////////////////////////////////////////////////////////////////////////
205 // WindowTreeHostX11
207 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds)
208 : xdisplay_(gfx::GetXDisplay()),
209 xwindow_(0),
210 x_root_window_(DefaultRootWindow(xdisplay_)),
211 current_cursor_(ui::kCursorNull),
212 window_mapped_(false),
213 bounds_(bounds),
214 touch_calibrate_(new internal::TouchEventCalibrate),
215 atom_cache_(xdisplay_, kAtomsToCache) {
216 XSetWindowAttributes swa;
217 memset(&swa, 0, sizeof(swa));
218 swa.background_pixmap = None;
219 swa.override_redirect = default_override_redirect;
220 xwindow_ = XCreateWindow(
221 xdisplay_, x_root_window_,
222 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
223 0, // border width
224 CopyFromParent, // depth
225 InputOutput,
226 CopyFromParent, // visual
227 CWBackPixmap | CWOverrideRedirect,
228 &swa);
229 if (ui::PlatformEventSource::GetInstance())
230 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
232 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
233 KeyPressMask | KeyReleaseMask |
234 EnterWindowMask | LeaveWindowMask |
235 ExposureMask | VisibilityChangeMask |
236 StructureNotifyMask | PropertyChangeMask |
237 PointerMotionMask;
238 XSelectInput(xdisplay_, xwindow_, event_mask);
239 XFlush(xdisplay_);
241 if (ui::IsXInput2Available()) {
242 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
243 SelectXInput2EventsForRootWindow(xdisplay_, x_root_window_);
246 // TODO(erg): We currently only request window deletion events. We also
247 // should listen for activation events and anything else that GTK+ listens
248 // for, and do something useful.
249 ::Atom protocols[2];
250 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
251 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
252 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
254 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
255 // the desktop environment.
256 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
258 // Likewise, the X server needs to know this window's pid so it knows which
259 // program to kill if the window hangs.
260 // XChangeProperty() expects "pid" to be long.
261 static_assert(sizeof(long) >= sizeof(pid_t),
262 "pid_t should not be larger than long");
263 long pid = getpid();
264 XChangeProperty(xdisplay_,
265 xwindow_,
266 atom_cache_.GetAtom("_NET_WM_PID"),
267 XA_CARDINAL,
269 PropModeReplace,
270 reinterpret_cast<unsigned char*>(&pid), 1);
272 // Allow subclasses to create and cache additional atoms.
273 atom_cache_.allow_uncached_atoms();
275 XRRSelectInput(xdisplay_, x_root_window_,
276 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
277 CreateCompositor(GetAcceleratedWidget());
280 WindowTreeHostX11::~WindowTreeHostX11() {
281 if (ui::PlatformEventSource::GetInstance())
282 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
284 DestroyCompositor();
285 DestroyDispatcher();
286 XDestroyWindow(xdisplay_, xwindow_);
289 bool WindowTreeHostX11::CanDispatchEvent(const ui::PlatformEvent& event) {
290 ::Window target = FindEventTarget(event);
291 return target == xwindow_ || target == x_root_window_;
294 uint32_t WindowTreeHostX11::DispatchEvent(const ui::PlatformEvent& event) {
295 XEvent* xev = event;
296 if (FindEventTarget(xev) == x_root_window_) {
297 if (xev->type == GenericEvent)
298 DispatchXI2Event(xev);
299 return ui::POST_DISPATCH_NONE;
302 if (xev->type == MotionNotify) {
303 // Discard all but the most recent motion event that targets the same
304 // window with unchanged state.
305 XEvent last_event;
306 while (XPending(xev->xany.display)) {
307 XEvent next_event;
308 XPeekEvent(xev->xany.display, &next_event);
309 if (next_event.type == MotionNotify &&
310 next_event.xmotion.window == xev->xmotion.window &&
311 next_event.xmotion.subwindow == xev->xmotion.subwindow &&
312 next_event.xmotion.state == xev->xmotion.state) {
313 XNextEvent(xev->xany.display, &last_event);
314 xev = &last_event;
315 } else {
316 break;
321 if ((xev->type == EnterNotify || xev->type == LeaveNotify) &&
322 xev->xcrossing.detail == NotifyInferior) {
323 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|.
324 // NativeViewGLSurfaceGLX adds a child to |xwindow_|.
325 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is
326 // necessary. crbug.com/385716
327 return ui::POST_DISPATCH_STOP_PROPAGATION;
330 if (xev->type == EnterNotify ||
331 xev->type == LeaveNotify ||
332 xev->type == KeyPress ||
333 xev->type == KeyRelease ||
334 xev->type == ButtonPress ||
335 xev->type == ButtonRelease ||
336 xev->type == MotionNotify) {
337 switch (ui::EventTypeFromNative(xev)) {
338 case ui::ET_KEY_PRESSED:
339 case ui::ET_KEY_RELEASED: {
340 ui::KeyEvent keydown_event(xev);
341 SendEventToProcessor(&keydown_event);
342 break;
344 case ui::ET_MOUSE_MOVED:
345 case ui::ET_MOUSE_DRAGGED:
346 case ui::ET_MOUSE_ENTERED:
347 case ui::ET_MOUSE_EXITED:
348 case ui::ET_MOUSE_PRESSED:
349 case ui::ET_MOUSE_RELEASED: {
350 ui::MouseEvent mouse_event(xev);
351 if (xev->type == EnterNotify) {
352 aura::Window* root_window = window();
353 client::CursorClient* cursor_client =
354 client::GetCursorClient(root_window);
355 if (cursor_client) {
356 const gfx::Display display = gfx::Screen::GetScreenFor(
357 root_window)->GetDisplayNearestWindow(root_window);
358 cursor_client->SetDisplay(display);
360 // EnterNotify creates ET_MOUSE_MOVE. Mark as synthesized as this is
361 // not a real mouse move event.
362 mouse_event.set_flags(mouse_event.flags() | ui::EF_IS_SYNTHESIZED);
365 TranslateAndDispatchLocatedEvent(&mouse_event);
366 break;
368 case ui::ET_MOUSEWHEEL: {
369 ui::MouseWheelEvent mouseev(xev);
370 TranslateAndDispatchLocatedEvent(&mouseev);
371 break;
373 case ui::ET_UNKNOWN:
374 // No event is created for X11-release events for mouse-wheel buttons.
375 break;
376 default:
377 NOTREACHED();
379 return ui::POST_DISPATCH_STOP_PROPAGATION;
382 switch (xev->type) {
383 case Expose: {
384 gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y,
385 xev->xexpose.width, xev->xexpose.height);
386 compositor()->ScheduleRedrawRect(damage_rect);
387 break;
389 case FocusOut:
390 if (xev->xfocus.mode != NotifyGrab)
391 OnHostLostWindowCapture();
392 break;
393 case ConfigureNotify: {
394 DCHECK_EQ(xwindow_, xev->xconfigure.event);
395 DCHECK_EQ(xwindow_, xev->xconfigure.window);
396 // It's possible that the X window may be resized by some other means
397 // than from within aura (e.g. the X window manager can change the
398 // size). Make sure the root window size is maintained properly.
399 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
400 xev->xconfigure.width, xev->xconfigure.height);
401 bool size_changed = bounds_.size() != bounds.size();
402 bool origin_changed = bounds_.origin() != bounds.origin();
403 bounds_ = bounds;
404 OnConfigureNotify();
405 if (size_changed)
406 OnHostResized(bounds.size());
407 if (origin_changed)
408 OnHostMoved(bounds_.origin());
409 break;
411 case GenericEvent:
412 DispatchXI2Event(xev);
413 break;
414 case ClientMessage: {
415 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
416 if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
417 // We have received a close message from the window manager.
418 OnHostCloseRequested();
419 } else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) {
420 XEvent reply_event = *xev;
421 reply_event.xclient.window = x_root_window_;
423 XSendEvent(xdisplay_,
424 reply_event.xclient.window,
425 False,
426 SubstructureRedirectMask | SubstructureNotifyMask,
427 &reply_event);
428 XFlush(xdisplay_);
430 break;
432 case MappingNotify: {
433 switch (xev->xmapping.request) {
434 case MappingModifier:
435 case MappingKeyboard:
436 XRefreshKeyboardMapping(&xev->xmapping);
437 break;
438 case MappingPointer:
439 ui::DeviceDataManagerX11::GetInstance()->UpdateButtonMap();
440 break;
441 default:
442 NOTIMPLEMENTED() << " Unknown request: " << xev->xmapping.request;
443 break;
445 break;
448 return ui::POST_DISPATCH_STOP_PROPAGATION;
451 ui::EventSource* WindowTreeHostX11::GetEventSource() {
452 return this;
455 gfx::AcceleratedWidget WindowTreeHostX11::GetAcceleratedWidget() {
456 return xwindow_;
459 void WindowTreeHostX11::Show() {
460 if (!window_mapped_) {
461 // Before we map the window, set size hints. Otherwise, some window managers
462 // will ignore toplevel XMoveWindow commands.
463 XSizeHints size_hints;
464 size_hints.flags = PPosition | PWinGravity;
465 size_hints.x = bounds_.x();
466 size_hints.y = bounds_.y();
467 // Set StaticGravity so that the window position is not affected by the
468 // frame width when running with window manager.
469 size_hints.win_gravity = StaticGravity;
470 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
472 XMapWindow(xdisplay_, xwindow_);
474 // We now block until our window is mapped. Some X11 APIs will crash and
475 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
476 // asynchronous.
477 if (ui::X11EventSource::GetInstance())
478 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_);
479 window_mapped_ = true;
483 void WindowTreeHostX11::Hide() {
484 if (window_mapped_) {
485 XWithdrawWindow(xdisplay_, xwindow_, 0);
486 window_mapped_ = false;
490 gfx::Rect WindowTreeHostX11::GetBounds() const {
491 return bounds_;
494 void WindowTreeHostX11::SetBounds(const gfx::Rect& bounds) {
495 // Even if the host window's size doesn't change, aura's root window
496 // size, which is in DIP, changes when the scale changes.
497 float current_scale = compositor()->device_scale_factor();
498 float new_scale = gfx::Screen::GetScreenFor(window())->
499 GetDisplayNearestWindow(window()).device_scale_factor();
500 bool origin_changed = bounds_.origin() != bounds.origin();
501 bool size_changed = bounds_.size() != bounds.size();
502 XWindowChanges changes = {0};
503 unsigned value_mask = 0;
505 if (size_changed) {
506 changes.width = bounds.width();
507 changes.height = bounds.height();
508 value_mask = CWHeight | CWWidth;
511 if (origin_changed) {
512 changes.x = bounds.x();
513 changes.y = bounds.y();
514 value_mask |= CWX | CWY;
516 if (value_mask)
517 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
519 // Assume that the resize will go through as requested, which should be the
520 // case if we're running without a window manager. If there's a window
521 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a
522 // (possibly synthetic) ConfigureNotify about the actual size and correct
523 // |bounds_| later.
524 bounds_ = bounds;
525 if (origin_changed)
526 OnHostMoved(bounds.origin());
527 if (size_changed || current_scale != new_scale) {
528 OnHostResized(bounds.size());
529 } else {
530 window()->SchedulePaintInRect(window()->bounds());
534 gfx::Point WindowTreeHostX11::GetLocationOnNativeScreen() const {
535 return bounds_.origin();
538 void WindowTreeHostX11::SetCapture() {
539 // Do not grab X11 input. Grabbing X11 input is asynchronous and this method
540 // is expected to be synchronous. Grabbing X11 input is unnecessary on
541 // ChromeOS because ChromeOS manages all of the X windows. When running
542 // ChromeOS on the desktop for the sake of debugging:
543 // - Implicit pointer grab as a result of pressing a mouse button
544 // - Releasing capture as a result of losing activation (FocusOut)
545 // is sufficient.
548 void WindowTreeHostX11::ReleaseCapture() {
551 void WindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) {
552 if (cursor == current_cursor_)
553 return;
554 current_cursor_ = cursor;
555 SetCursorInternal(cursor);
558 void WindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) {
559 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0,
560 bounds_.x() + location.x(),
561 bounds_.y() + location.y());
564 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) {
567 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() {
568 return dispatcher();
571 void WindowTreeHostX11::DispatchXI2Event(const base::NativeEvent& event) {
572 ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
573 XEvent* xev = event;
574 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
575 if (!factory->ShouldProcessXI2Event(xev))
576 return;
578 TRACE_EVENT1("input", "WindowTreeHostX11::DispatchXI2Event",
579 "event_latency_us",
580 (ui::EventTimeForNow() - ui::EventTimeFromNative(event)).
581 InMicroseconds());
583 int num_coalesced = 0;
584 XEvent last_event;
585 if (xev->xgeneric.evtype == XI_Motion) {
586 // If this is a motion event, we want to coalesce all pending motion
587 // events that are at the top of the queue. Note, we don't coalesce
588 // touch update events here.
589 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
590 if (num_coalesced > 0)
591 xev = &last_event;
593 ui::EventType type = ui::EventTypeFromNative(xev);
595 switch (type) {
596 case ui::ET_TOUCH_MOVED:
597 case ui::ET_TOUCH_PRESSED:
598 case ui::ET_TOUCH_CANCELLED:
599 case ui::ET_TOUCH_RELEASED: {
600 ui::TouchEvent touchev(xev);
601 if (ui::DeviceDataManagerX11::GetInstance()->TouchEventNeedsCalibrate(
602 xiev->deviceid)) {
603 touch_calibrate_->Calibrate(&touchev, bounds_);
605 TranslateAndDispatchLocatedEvent(&touchev);
606 break;
608 case ui::ET_MOUSE_MOVED:
609 case ui::ET_MOUSE_DRAGGED:
610 case ui::ET_MOUSE_PRESSED:
611 case ui::ET_MOUSE_RELEASED:
612 case ui::ET_MOUSE_ENTERED:
613 case ui::ET_MOUSE_EXITED: {
614 ui::MouseEvent mouseev(xev);
615 TranslateAndDispatchLocatedEvent(&mouseev);
616 break;
618 case ui::ET_MOUSEWHEEL: {
619 ui::MouseWheelEvent mouseev(xev);
620 TranslateAndDispatchLocatedEvent(&mouseev);
621 break;
623 case ui::ET_SCROLL_FLING_START:
624 case ui::ET_SCROLL_FLING_CANCEL:
625 case ui::ET_SCROLL: {
626 ui::ScrollEvent scrollev(xev);
627 SendEventToProcessor(&scrollev);
628 break;
630 case ui::ET_KEY_PRESSED:
631 case ui::ET_KEY_RELEASED: {
632 ui::KeyEvent key_event(xev);
633 SendEventToProcessor(&key_event);
634 break;
636 case ui::ET_UMA_DATA:
637 break;
638 case ui::ET_UNKNOWN:
639 break;
640 default:
641 NOTREACHED();
644 // If we coalesced an event we need to free its cookie.
645 if (num_coalesced > 0)
646 XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
649 void WindowTreeHostX11::SetCursorInternal(gfx::NativeCursor cursor) {
650 XDefineCursor(xdisplay_, xwindow_, cursor.platform());
653 void WindowTreeHostX11::OnConfigureNotify() {}
655 void WindowTreeHostX11::TranslateAndDispatchLocatedEvent(
656 ui::LocatedEvent* event) {
657 SendEventToProcessor(event);
660 // static
661 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) {
662 return new WindowTreeHostX11(bounds);
665 // static
666 gfx::Size WindowTreeHost::GetNativeScreenSize() {
667 ::XDisplay* xdisplay = gfx::GetXDisplay();
668 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
671 namespace test {
673 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
674 default_override_redirect = override_redirect;
677 } // namespace test
678 } // namespace aura