15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/root_window_host_x11.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <strings.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/cursorfont.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/extensions/Xfixes.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/extensions/XInput2.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/extensions/Xrandr.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xatom.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xcursor/Xcursor.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xlib.h>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <limits>
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/basictypes.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/debug/trace_event.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop.h"
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/message_loop/message_pump_x11.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
265e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
275e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
285e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/cursor_client.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/screen_position_client.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/user_action_client.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/env.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/cursor/cursor.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_switches.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/view_prop.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/x/x11_util.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/dip_util.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_utils.h"
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/events/x/device_data_manager.h"
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/events/x/device_list_cache_x.h"
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/events/x/touch_factory_x11.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::max;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace aura {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Standard Linux mouse buttons for going back and forward.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBackMouseButton = 8;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kForwardMouseButton = 9;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kAtomsToCache[] = {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "WM_DELETE_WINDOW",
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "_NET_WM_PING",
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "_NET_WM_PID",
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "WM_S0",
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  "Tap Paused",  // Defined in the gestures library.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NULL
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)::Window FindEventTarget(const base::NativeEvent& xev) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::Window target = xev->xany.window;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (xev->type == GenericEvent)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return target;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(USE_XI2_MT)
79558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool IsSideBezelsEnabled() {
80558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  static bool side_bezels_enabled =
81558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          switches::kTouchSideBezels) != "0";
83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return side_bezels_enabled;
84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
86558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SelectXInput2EventsForRootWindow(XDisplay* display, ::Window root_window) {
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CHECK(ui::IsXInput2Available());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {};
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(mask, 0, sizeof(mask));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XISetMask(mask, XI_HierarchyChanged);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XISetMask(mask, XI_KeyPress);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XISetMask(mask, XI_KeyRelease);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  XIEventMask evmask;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  evmask.deviceid = XIAllDevices;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  evmask.mask_len = sizeof(mask);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  evmask.mask = mask;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  XISelectEvents(display, root_window, &evmask, 1);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_CHROMEOS)
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (base::SysInfo::IsRunningOnChromeOS()) {
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // It is necessary to listen for touch events on the root window for proper
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // touch event calibration on Chrome OS, but this is not currently necessary
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // on the desktop. This seems to fail in some cases (e.g. when logging
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // in incognito). So select for non-touch events first, and then select for
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // touch-events (but keep the other events in the mask, i.e. do not memset
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // |mask| back to 0).
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // TODO(sad): Figure out why this happens. http://crbug.com/153976
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    XISetMask(mask, XI_TouchBegin);
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    XISetMask(mask, XI_TouchUpdate);
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    XISetMask(mask, XI_TouchEnd);
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    XISelectEvents(display, root_window, &evmask, 1);
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool default_override_redirect = false;
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Accomplishes 2 tasks concerning touch event calibration:
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. Being a message-pump observer,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    routes all the touch events to the X root window,
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    where they can be calibrated later.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. Has the Calibrate method that does the actual bezel calibration,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    when invoked from X root window's event dispatcher.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TouchEventCalibrate : public base::MessagePumpObserver {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TouchEventCalibrate()
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : left_(0),
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      right_(0),
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      top_(0),
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bottom_(0) {
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoopForUI::current()->AddObserver(this);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_XI2_MT)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<std::string> parts;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        switches::kTouchCalibration), ",", &parts) >= 4) {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!base::StringToInt(parts[0], &left_))
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DLOG(ERROR) << "Incorrect left border calibration value passed.";
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!base::StringToInt(parts[1], &right_))
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DLOG(ERROR) << "Incorrect right border calibration value passed.";
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!base::StringToInt(parts[2], &top_))
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DLOG(ERROR) << "Incorrect top border calibration value passed.";
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!base::StringToInt(parts[3], &bottom_))
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DLOG(ERROR) << "Incorrect bottom border calibration value passed.";
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(USE_XI2_MT)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TouchEventCalibrate() {
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoopForUI::current()->RemoveObserver(this);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(USE_XI2_MT)
160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool IsEventOnSideBezels(
161558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      const base::NativeEvent& xev,
162558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      const gfx::Rect& bounds) {
163558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (!left_ && !right_)
164558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return false;
165558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    gfx::Point location = ui::EventLocationFromNative(xev);
167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    int x = location.x();
168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return x < left_ || x > bounds.width() - right_;
169558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif  // defined(USE_XI2_MT)
171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Modify the location of the |event|,
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // expanding it from |bounds| to (|bounds| + bezels).
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Required when touchscreen is bigger than screen (i.e. has bezels),
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // because we receive events in touchscreen coordinates,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // which need to be expanded when converting to screen coordinates,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so that location on bezels will be outside of screen area.
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_XI2_MT)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int x = event->x();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int y = event->y();
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!left_ && !right_ && !top_ && !bottom_)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const int resolution_x = bounds.width();
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const int resolution_y = bounds.height();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The "grace area" (10% in this case) is to make it easier for the user to
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // navigate to the corner.
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const double kGraceAreaFraction = 0.1;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (left_ || right_) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Offset the x position to the real
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      x -= left_;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Check if we are in the grace area of the left side.
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Note: We might not want to do this when the gesture is locked?
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (x < 0 && x > -left_ * kGraceAreaFraction)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        x = 0;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Check if we are in the grace area of the right side.
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Note: We might not want to do this when the gesture is locked?
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (x > resolution_x - left_ &&
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          x < resolution_x - left_ + right_ * kGraceAreaFraction)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        x = resolution_x - left_;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Scale the screen area back to the full resolution of the screen.
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      x = (x * resolution_x) / (resolution_x - (right_ + left_));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (top_ || bottom_) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // When there is a top bezel we add our border,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      y -= top_;
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Check if we are in the grace area of the top side.
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Note: We might not want to do this when the gesture is locked?
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (y < 0 && y > -top_ * kGraceAreaFraction)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        y = 0;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Check if we are in the grace area of the bottom side.
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Note: We might not want to do this when the gesture is locked?
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (y > resolution_y - top_ &&
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          y < resolution_y - top_ + bottom_ * kGraceAreaFraction)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        y = resolution_y - top_;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Scale the screen area back to the full resolution of the screen.
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      y = (y * resolution_y) / (resolution_y - (bottom_ + top_));
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Set the modified coordinate back to the event.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (event->root_location() == event->location()) {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Usually those will be equal,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // if not, I am not sure what the correct value should be.
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->set_root_location(gfx::Point(x, y));
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->set_location(gfx::Point(x, y));
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(USE_XI2_MT)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from base::MessagePumpObserver:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::EventStatus WillProcessEvent(
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::NativeEvent& event) OVERRIDE {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_XI2_MT)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type == GenericEvent &&
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (event->xgeneric.evtype == XI_TouchBegin ||
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         event->xgeneric.evtype == XI_TouchUpdate ||
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         event->xgeneric.evtype == XI_TouchEnd)) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xievent->event = xievent->root;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xievent->event_x = xievent->root_x;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xievent->event_y = xievent->root_y;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(USE_XI2_MT)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::EVENT_CONTINUE;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The difference in screen's native resolution pixels between
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the border of the touchscreen and the border of the screen,
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // aka bezel sizes.
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int left_;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int right_;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int top_;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int bottom_;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TouchEventCalibrate);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// RootWindowHostX11::MouseMoveFilter filters out the move events that
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// jump back and forth between two points. This happens when sub pixel mouse
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// move is enabled and mouse move events could be jumping between two neighbor
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// pixels, e.g. move(0,0), move(1,0), move(0,0), move(1,0) and on and on.
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The filtering is done by keeping track of the last two event locations and
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// provides a Filter method to find out whether a mouse event is in a different
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// location and should be processed.
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RootWindowHostX11::MouseMoveFilter {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MouseMoveFilter() : insert_index_(0) {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < kMaxEvents; ++i) {
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const int int_max = std::numeric_limits<int>::max();
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      recent_locations_[i] = gfx::Point(int_max, int_max);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~MouseMoveFilter() {}
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if |event| is known and should be ignored.
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool Filter(const base::NativeEvent& event) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Point& location = ui::EventLocationFromNative(event);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < kMaxEvents; ++i) {
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (location == recent_locations_[i])
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return true;
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    recent_locations_[insert_index_] = location;
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    insert_index_ = (insert_index_ + 1) % kMaxEvents;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const size_t kMaxEvents = 2;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point recent_locations_[kMaxEvents];
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t insert_index_;
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MouseMoveFilter);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// RootWindowHostX11
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RootWindowHostX11::RootWindowHostX11(const gfx::Rect& bounds)
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : xdisplay_(gfx::GetXDisplay()),
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xwindow_(0),
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x_root_window_(DefaultRootWindow(xdisplay_)),
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_cursor_(ui::kCursorNull),
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_mapped_(false),
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds_(bounds),
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_internal_display_(false),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      touch_calibrate_(new internal::TouchEventCalibrate),
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mouse_move_filter_(new MouseMoveFilter),
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      atom_cache_(xdisplay_, kAtomsToCache),
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      bezel_tracking_ids_(0) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XSetWindowAttributes swa;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&swa, 0, sizeof(swa));
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  swa.background_pixmap = None;
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  swa.override_redirect = default_override_redirect;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  xwindow_ = XCreateWindow(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xdisplay_, x_root_window_,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds.x(), bounds.y(), bounds.width(), bounds.height(),
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,               // border width
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CopyFromParent,  // depth
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InputOutput,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CopyFromParent,  // visual
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CWBackPixmap | CWOverrideRedirect,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &swa);
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::MessagePumpX11::Current()->AddDispatcherForWindow(this, xwindow_);
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::MessagePumpX11::Current()->AddDispatcherForRootWindow(this);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    KeyPressMask | KeyReleaseMask |
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    EnterWindowMask | LeaveWindowMask |
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ExposureMask | VisibilityChangeMask |
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    StructureNotifyMask | PropertyChangeMask |
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PointerMotionMask;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XSelectInput(xdisplay_, xwindow_, event_mask);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XFlush(xdisplay_);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (ui::IsXInput2Available()) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SelectXInput2EventsForRootWindow(xdisplay_, x_root_window_);
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(erg): We currently only request window deletion events. We also
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should listen for activation events and anything else that GTK+ listens
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for, and do something useful.
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::Atom protocols[2];
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the desktop environment.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Likewise, the X server needs to know this window's pid so it knows which
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // program to kill if the window hangs.
3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // XChangeProperty() expects "pid" to be long.
3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  COMPILE_ASSERT(sizeof(long) >= sizeof(pid_t), pid_t_bigger_than_long);
3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  long pid = getpid();
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XChangeProperty(xdisplay_,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  xwindow_,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  atom_cache_.GetAtom("_NET_WM_PID"),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  XA_CARDINAL,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  32,
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  PropModeReplace,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  reinterpret_cast<unsigned char*>(&pid), 1);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XRRSelectInput(xdisplay_, x_root_window_,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Env::GetInstance()->AddObserver(this);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RootWindowHostX11::~RootWindowHostX11() {
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Env::GetInstance()->RemoveObserver(this);
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow(this);
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::MessagePumpX11::Current()->RemoveDispatcherForWindow(xwindow_);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnConfineCursor();
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XDestroyWindow(xdisplay_, xwindow_);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::Dispatch(const base::NativeEvent& event) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XEvent* xev = event;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FindEventTarget(event) == x_root_window_)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DispatchEventForRootWindow(event);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (xev->type) {
4013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case EnterNotify: {
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      aura::Window* root_window = GetRootWindow()->window();
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      client::CursorClient* cursor_client =
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          client::GetCursorClient(root_window);
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (cursor_client) {
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        const gfx::Display display = gfx::Screen::GetScreenFor(root_window)->
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            GetDisplayNearestWindow(root_window);
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        cursor_client->SetDisplay(display);
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
4103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      ui::MouseEvent mouse_event(xev);
4113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      // EnterNotify creates ET_MOUSE_MOVE. Mark as synthesized as this is not
4123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      // real mouse move event.
4133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      mouse_event.set_flags(mouse_event.flags() | ui::EF_IS_SYNTHESIZED);
4143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      TranslateAndDispatchMouseEvent(&mouse_event);
4153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      break;
4163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case LeaveNotify: {
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ui::MouseEvent mouse_event(xev);
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      TranslateAndDispatchMouseEvent(&mouse_event);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case Expose: {
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y,
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            xev->xexpose.width, xev->xexpose.height);
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      delegate_->AsRootWindow()->ScheduleRedrawRect(damage_rect);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case KeyPress: {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::KeyEvent keydown_event(xev, false);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnHostKeyEvent(&keydown_event);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case KeyRelease: {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::KeyEvent keyup_event(xev, false);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnHostKeyEvent(&keyup_event);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ButtonPress: {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (static_cast<int>(xev->xbutton.button) == kBackMouseButton ||
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<int>(xev->xbutton.button) == kForwardMouseButton) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        client::UserActionClient* gesture_client =
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            client::GetUserActionClient(delegate_->AsRootWindow()->window());
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (gesture_client) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          gesture_client->OnUserAction(
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              static_cast<int>(xev->xbutton.button) == kBackMouseButton ?
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              client::UserActionClient::BACK :
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              client::UserActionClient::FORWARD);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }  // fallthrough
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ButtonRelease: {
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switch (ui::EventTypeFromNative(xev)) {
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case ui::ET_MOUSEWHEEL: {
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          ui::MouseWheelEvent mouseev(xev);
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          TranslateAndDispatchMouseEvent(&mouseev);
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case ui::ET_MOUSE_PRESSED:
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case ui::ET_MOUSE_RELEASED: {
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          ui::MouseEvent mouseev(xev);
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          TranslateAndDispatchMouseEvent(&mouseev);
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case ui::ET_UNKNOWN:
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          // No event is created for X11-release events for mouse-wheel buttons.
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        default:
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          NOTREACHED();
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case FocusOut:
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (xev->xfocus.mode != NotifyGrab)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnHostLostWindowCapture();
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ConfigureNotify: {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_EQ(xwindow_, xev->xconfigure.event);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_EQ(xwindow_, xev->xconfigure.window);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // It's possible that the X window may be resized by some other means
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // than from within aura (e.g. the X window manager can change the
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // size). Make sure the root window size is maintained properly.
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          xev->xconfigure.width, xev->xconfigure.height);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool size_changed = bounds_.size() != bounds.size();
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool origin_changed = bounds_.origin() != bounds.origin();
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds_ = bounds;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateIsInternalDisplay();
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Always update barrier and mouse location because |bounds_| might
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // have already been updated in |SetBounds|.
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (pointer_barriers_) {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UnConfineCursor();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ConfineCursorToRootWindow();
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (size_changed)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnHostResized(bounds.size());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (origin_changed)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnHostMoved(bounds_.origin());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GenericEvent:
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DispatchXI2Event(event);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ClientMessage: {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // We have received a close message from the window manager.
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->AsRootWindow()->OnRootWindowHostCloseRequested();
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XEvent reply_event = *xev;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reply_event.xclient.window = x_root_window_;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XSendEvent(xdisplay_,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   reply_event.xclient.window,
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   False,
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SubstructureRedirectMask | SubstructureNotifyMask,
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   &reply_event);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MappingNotify: {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (xev->xmapping.request) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case MappingModifier:
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case MappingKeyboard:
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          XRefreshKeyboardMapping(&xev->xmapping);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          delegate_->AsRootWindow()->OnKeyboardMappingChanged();
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case MappingPointer:
52968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          ui::DeviceDataManager::GetInstance()->UpdateButtonMap();
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NOTIMPLEMENTED() << " Unknown request: " << xev->xmapping.request;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MotionNotify: {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Discard all but the most recent motion event that targets the same
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // window with unchanged state.
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      XEvent last_event;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      while (XPending(xev->xany.display)) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XEvent next_event;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XPeekEvent(xev->xany.display, &next_event);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (next_event.type == MotionNotify &&
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            next_event.xmotion.window == xev->xmotion.window &&
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            next_event.xmotion.subwindow == xev->xmotion.subwindow &&
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            next_event.xmotion.state == xev->xmotion.state) {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          XNextEvent(xev->xany.display, &last_event);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          xev = &last_event;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::MouseEvent mouseev(xev);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TranslateAndDispatchMouseEvent(&mouseev);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RootWindow* RootWindowHostX11::GetRootWindow() {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return delegate_->AsRootWindow();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::AcceleratedWidget RootWindowHostX11::GetAcceleratedWidget() {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return xwindow_;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::Show() {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window_mapped_) {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Before we map the window, set size hints. Otherwise, some window managers
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // will ignore toplevel XMoveWindow commands.
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSizeHints size_hints;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_hints.flags = PPosition | PWinGravity;
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_hints.x = bounds_.x();
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_hints.y = bounds_.y();
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set StaticGravity so that the window position is not affected by the
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // frame width when running with window manager.
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_hints.win_gravity = StaticGravity;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XMapWindow(xdisplay_, xwindow_);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We now block until our window is mapped. Some X11 APIs will crash and
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // asynchronous.
58958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::MessagePumpX11::Current()->BlockUntilWindowMapped(xwindow_);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_mapped_ = true;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::Hide() {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (window_mapped_) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XWithdrawWindow(xdisplay_, xwindow_, 0);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_mapped_ = false;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::ToggleFullScreen() {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Rect RootWindowHostX11::GetBounds() const {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bounds_;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetBounds(const gfx::Rect& bounds) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Even if the host window's size doesn't change, aura's root window
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // size, which is in DIP, changes when the scale changes.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float current_scale = delegate_->GetDeviceScaleFactor();
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float new_scale = gfx::Screen::GetScreenFor(
614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      delegate_->AsRootWindow()->window())->GetDisplayNearestWindow(
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          delegate_->AsRootWindow()->window()).device_scale_factor();
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool origin_changed = bounds_.origin() != bounds.origin();
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool size_changed = bounds_.size() != bounds.size();
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XWindowChanges changes = {0};
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned value_mask = 0;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size_changed) {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    changes.width = bounds.width();
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    changes.height = bounds.height();
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value_mask = CWHeight | CWWidth;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (origin_changed) {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    changes.x = bounds.x();
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    changes.y = bounds.y();
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value_mask |= CWX | CWY;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value_mask)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume that the resize will go through as requested, which should be the
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // case if we're running without a window manager.  If there's a window
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // manager, it can modify or ignore the request, but (per ICCCM) we'll get a
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (possibly synthetic) ConfigureNotify about the actual size and correct
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |bounds_| later.
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_ = bounds;
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateIsInternalDisplay();
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (origin_changed)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnHostMoved(bounds.origin());
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size_changed || current_scale != new_scale) {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnHostResized(bounds.size());
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_->AsRootWindow()->window()->SchedulePaintInRect(
648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_->AsRootWindow()->window()->bounds());
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Insets RootWindowHostX11::GetInsets() const {
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return insets_;
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetInsets(const gfx::Insets& insets) {
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  insets_ = insets;
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (pointer_barriers_) {
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UnConfineCursor();
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ConfineCursorToRootWindow();
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Point RootWindowHostX11::GetLocationOnNativeScreen() const {
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bounds_.origin();
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetCapture() {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(oshima): Grab x input.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::ReleaseCapture() {
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(oshima): Release x input.
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetCursor(gfx::NativeCursor cursor) {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cursor == current_cursor_)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_cursor_ = cursor;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetCursorInternal(cursor);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::QueryMouseLocation(gfx::Point* location_return) {
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client::CursorClient* cursor_client =
685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      client::GetCursorClient(GetRootWindow()->window());
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (cursor_client && !cursor_client->IsMouseEventsEnabled()) {
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *location_return = gfx::Point(0, 0);
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::Window root_return, child_return;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int root_x_return, root_y_return, win_x_return, win_y_return;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int mask_return;
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XQueryPointer(xdisplay_,
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xwindow_,
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                &root_return,
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                &child_return,
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                &root_x_return, &root_y_return,
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                &win_x_return, &win_y_return,
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                &mask_return);
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *location_return = gfx::Point(max(0, min(bounds_.width(), win_x_return)),
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                max(0, min(bounds_.height(), win_y_return)));
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (win_x_return >= 0 && win_x_return < bounds_.width() &&
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          win_y_return >= 0 && win_y_return < bounds_.height());
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::ConfineCursorToRootWindow() {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if XFIXES_MAJOR >= 5
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!pointer_barriers_.get());
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (pointer_barriers_)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pointer_barriers_.reset(new XID[4]);
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds(bounds_);
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds.Inset(insets_);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Horizontal, top barriers.
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pointer_barriers_[0] = XFixesCreatePointerBarrier(
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xdisplay_, x_root_window_,
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bounds.x(), bounds.y(), bounds.right(), bounds.y(),
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BarrierPositiveY,
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0, XIAllDevices);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Horizontal, bottom barriers.
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pointer_barriers_[1] = XFixesCreatePointerBarrier(
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xdisplay_, x_root_window_,
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bounds.x(), bounds.bottom(), bounds.right(),  bounds.bottom(),
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BarrierNegativeY,
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0, XIAllDevices);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vertical, left  barriers.
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pointer_barriers_[2] = XFixesCreatePointerBarrier(
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xdisplay_, x_root_window_,
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bounds.x(), bounds.y(), bounds.x(), bounds.bottom(),
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BarrierPositiveX,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0, XIAllDevices);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vertical, right barriers.
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pointer_barriers_[3] = XFixesCreatePointerBarrier(
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xdisplay_, x_root_window_,
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bounds.right(), bounds.y(), bounds.right(), bounds.bottom(),
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BarrierNegativeX,
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0, XIAllDevices);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::UnConfineCursor() {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if XFIXES_MAJOR >= 5
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (pointer_barriers_) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[0]);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[1]);
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[2]);
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[3]);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pointer_barriers_.reset();
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::OnCursorVisibilityChanged(bool show) {
756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetCrOSTapPaused(!show);
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::MoveCursorTo(const gfx::Point& location) {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0,
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               bounds_.x() + location.x(),
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               bounds_.y() + location.y());
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::PostNativeEvent(
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::NativeEvent& native_event) {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(xwindow_);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(xdisplay_);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XEvent xevent = *native_event;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  xevent.xany.display = xdisplay_;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  xevent.xany.window = xwindow_;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (xevent.type) {
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case EnterNotify:
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case LeaveNotify:
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MotionNotify:
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case KeyPress:
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case KeyRelease:
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ButtonPress:
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ButtonRelease: {
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The fields used below are in the same place for all of events
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // above. Using xmotion from XEvent's unions to avoid repeating
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the code.
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xevent.xmotion.root = x_root_window_;
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xevent.xmotion.time = CurrentTime;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point point(xevent.xmotion.x, xevent.xmotion.y);
788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      delegate_->AsRootWindow()->host()->ConvertPointToNativeScreen(&point);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xevent.xmotion.x_root = point.x();
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xevent.xmotion.y_root = point.y();
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XSendEvent(xdisplay_, xwindow_, False, 0, &xevent);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::OnDeviceScaleFactorChanged(
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float device_scale_factor) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::PrepareForShutdown() {
80358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::MessagePumpX11::Current()->RemoveDispatcherForWindow(xwindow_);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::OnWindowInitialized(Window* window) {
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::OnRootWindowInitialized(RootWindow* root_window) {
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // UpdateIsInternalDisplay relies on:
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1. delegate_ pointing to RootWindow - available after SetDelegate.
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2. RootWindow's kDisplayIdKey property set - available by the time
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //    RootWindow::Init is called.
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //    (set in DisplayManager::CreateRootWindowForDisplay)
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ready when NotifyRootWindowInitialized is called from RootWindow::Init.
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!delegate_ || root_window != GetRootWindow())
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateIsInternalDisplay();
819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We have to enable Tap-to-click by default because the cursor is set to
821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // visible in Shell::InitRootWindowController.
822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetCrOSTapPaused(false);
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
825a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ui::EventProcessor* RootWindowHostX11::GetEventProcessor() {
826a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return delegate_->GetEventProcessor();
827a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
828a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::DispatchEventForRootWindow(
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::NativeEvent& event) {
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event->type) {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GenericEvent:
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DispatchXI2Event(event);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::DispatchXI2Event(const base::NativeEvent& event) {
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XEvent* xev = event;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!factory->ShouldProcessXI2Event(xev))
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT1("input", "RootWindowHostX11::DispatchXI2Event",
847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               "event_latency_us",
848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               (ui::EventTimeForNow() - ui::EventTimeFromNative(event)).
849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 InMicroseconds());
850868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::EventType type = ui::EventTypeFromNative(xev);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XEvent last_event;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_coalesced = 0;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_MOVED:
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_PRESSED:
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::ET_TOUCH_CANCELLED:
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_RELEASED: {
860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_CHROMEOS)
861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Bail out early before generating a ui::TouchEvent if this event
862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // is not within the range of this RootWindow. Converting an xevent
863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // to ui::TouchEvent might change the state of the global touch tracking
864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // state, e.g. touch release event can remove the touch id from the
865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // record, and doing this multiple time when there are multiple
866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // RootWindow will cause problem. So only generate the ui::TouchEvent
867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // when we are sure it belongs to this RootWindow.
868f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (base::SysInfo::IsRunningOnChromeOS() &&
869f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          !bounds_.Contains(ui::EventLocationFromNative(xev)))
870f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        break;
871f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // defined(OS_CHROMEOS)
87258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ui::TouchEvent touchev(xev);
873558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(USE_XI2_MT)
87458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Ignore touch events with touch press happening on the side bezel.
87558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (!IsSideBezelsEnabled()) {
87658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        uint32 tracking_id = (1 << touchev.touch_id());
87758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (type == ui::ET_TOUCH_PRESSED &&
87858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            touch_calibrate_->IsEventOnSideBezels(xev, bounds_))
87958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          bezel_tracking_ids_ |= tracking_id;
88058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (bezel_tracking_ids_ & tracking_id) {
88158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          if (type == ui::ET_TOUCH_CANCELLED || type == ui::ET_TOUCH_RELEASED)
88258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            bezel_tracking_ids_ =
88358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                (bezel_tracking_ids_ | tracking_id) ^ tracking_id;
88458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          return;
88558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        }
886558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      }
887558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif  // defined(USE_XI2_MT)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
8894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (base::SysInfo::IsRunningOnChromeOS()) {
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // X maps the touch-surface to the size of the X root-window.
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // In multi-monitor setup, Coordinate Transformation Matrix
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // repositions the touch-surface onto part of X root-window
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // containing aura root-window corresponding to the touchscreen.
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // However, if aura root-window has non-zero origin,
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // we need to relocate the event into aura root-window coordinates.
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        touchev.Relocate(bounds_.origin());
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_XI2_MT)
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (is_internal_display_)
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          touch_calibrate_->Calibrate(&touchev, bounds_);
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(USE_XI2_MT)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_CHROMEOS)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnHostTouchEvent(&touchev);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_MOUSE_MOVED:
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_MOUSE_DRAGGED:
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_MOUSE_PRESSED:
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_MOUSE_RELEASED:
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_MOUSE_ENTERED:
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_MOUSE_EXITED: {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) {
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // If this is a motion event, we want to coalesce all pending motion
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // events that are at the top of the queue.
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (num_coalesced > 0)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          xev = &last_event;
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (mouse_move_filter_ && mouse_move_filter_->Filter(xev))
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (type == ui::ET_MOUSE_PRESSED ||
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 type == ui::ET_MOUSE_RELEASED) {
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XIDeviceEvent* xievent =
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<XIDeviceEvent*>(xev->xcookie.data);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int button = xievent->detail;
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (button == kBackMouseButton || button == kForwardMouseButton) {
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (type == ui::ET_MOUSE_RELEASED)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          client::UserActionClient* gesture_client =
930f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              client::GetUserActionClient(delegate_->AsRootWindow()->window());
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (gesture_client) {
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bool reverse_direction =
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled();
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            gesture_client->OnUserAction(
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                (button == kBackMouseButton && !reverse_direction) ||
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                (button == kForwardMouseButton && reverse_direction) ?
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                client::UserActionClient::BACK :
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                client::UserActionClient::FORWARD);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::MouseEvent mouseev(xev);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TranslateAndDispatchMouseEvent(&mouseev);
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_MOUSEWHEEL: {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::MouseWheelEvent mouseev(xev);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TranslateAndDispatchMouseEvent(&mouseev);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_SCROLL_FLING_START:
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_SCROLL_FLING_CANCEL:
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_SCROLL: {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ScrollEvent scrollev(xev);
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnHostScrollEvent(&scrollev);
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case ui::ET_UMA_DATA:
960eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_UNKNOWN:
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we coalesced an event we need to free its cookie.
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_coalesced > 0)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::IsWindowManagerPresent() {
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of WM_Sn selections (where n is a screen number).
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return XGetSelectionOwner(
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetCursorInternal(gfx::NativeCursor cursor) {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XDefineCursor(xdisplay_, xwindow_, cursor.platform());
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::TranslateAndDispatchMouseEvent(
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent* event) {
985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Window* root_window = GetRootWindow()->window();
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client::ScreenPositionClient* screen_position_client =
987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      client::GetScreenPositionClient(root_window);
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect local(bounds_.size());
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (screen_position_client && !local.Contains(event->location())) {
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Point location(event->location());
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // In order to get the correct point in screen coordinates
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // during passive grab, we first need to find on which host window
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the mouse is on, and find out the screen coordinates on that
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // host window, then convert it back to this host window's coordinate.
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    screen_position_client->ConvertHostPointToScreen(root_window, &location);
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    screen_position_client->ConvertPointFromScreen(root_window, &location);
998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    root_window->GetDispatcher()->ConvertPointToHost(&location);
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->set_location(location);
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->set_root_location(location);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->OnHostMouseEvent(event);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::UpdateIsInternalDisplay() {
1006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Window* root_window = GetRootWindow()->window();
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window);
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Display display = screen->GetDisplayNearestWindow(root_window);
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_internal_display_ = display.IsInternal();
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid RootWindowHostX11::SetCrOSTapPaused(bool state) {
1013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_CHROMEOS)
1014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!ui::IsXInput2Available())
1015f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
1016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Temporarily pause tap-to-click when the cursor is hidden.
1017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Atom prop = atom_cache_.GetAtom("Tap Paused");
1018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned char value = state;
1019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  XIDeviceList dev_list =
1020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(xdisplay_);
1021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Only slave pointer devices could possibly have tap-paused property.
1023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (int i = 0; i < dev_list.count; i++) {
1024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (dev_list[i].use == XISlavePointer) {
1025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Atom old_type;
1026eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int old_format;
1027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      unsigned long old_nvalues, bytes;
1028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      unsigned char* data;
1029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int result = XIGetProperty(xdisplay_, dev_list[i].deviceid, prop, 0, 0,
1030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 False, AnyPropertyType, &old_type, &old_format,
1031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 &old_nvalues, &bytes, &data);
1032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (result != Success)
1033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        continue;
1034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      XFree(data);
1035eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      XIChangeProperty(xdisplay_, dev_list[i].deviceid, prop, XA_INTEGER, 8,
1036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       PropModeReplace, &value, 1);
1037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
1038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
1040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) {
1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new RootWindowHostX11(bounds);
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size RootWindowHost::GetNativeScreenSize() {
104968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ::XDisplay* xdisplay = gfx::GetXDisplay();
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace test {
105490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
105590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
105690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  default_override_redirect = override_redirect;
105790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
105890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
105990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace test
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace aura
1061