root_window_host_x11.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
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) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/debug/trace_event.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_pump_aurax11.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 255e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 265e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 275e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkPostConfig.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/capture_client.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/cursor_client.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/screen_position_client.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/user_action_client.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/env.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/cursor/cursor.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event_utils.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/keycodes/keyboard_codes.h" 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/touch/touch_factory_x11.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_switches.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/view_prop.h" 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/x/device_list_cache_x.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/x/valuators.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/x/x11_util.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/dip_util.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/chromeos/chromeos_version.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::max; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace aura { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Standard Linux mouse buttons for going back and forward. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBackMouseButton = 8; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kForwardMouseButton = 9; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kAtomsToCache[] = { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WM_DELETE_WINDOW", 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "_NET_WM_PING", 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "_NET_WM_PID", 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WM_S0", 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Tap Paused", // Defined in the gestures library. 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)::Window FindEventTarget(const base::NativeEvent& xev) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Window target = xev->xany.window; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xev->type == GenericEvent) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SelectEventsForRootWindow() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Display* display = ui::GetXDisplay(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Window root_window = ui::GetX11RootWindow(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive resize events for the root-window so |x_root_bounds_| can be 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // updated. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes attr; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XGetWindowAttributes(display, root_window, &attr); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(attr.your_event_mask & StructureNotifyMask)) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSelectInput(display, root_window, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StructureNotifyMask | attr.your_event_mask); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::MessagePumpForUI::HasXInput2()) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(mask, 0, sizeof(mask)); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XISetMask(mask, XI_HierarchyChanged); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XISetMask(mask, XI_KeyPress); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XISetMask(mask, XI_KeyRelease); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XIEventMask evmask; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evmask.deviceid = XIAllDevices; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evmask.mask_len = sizeof(mask); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evmask.mask = mask; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XISelectEvents(display, root_window, &evmask, 1); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Selecting for touch events seems to fail on some cases (e.g. when logging 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in incognito). So select for non-touch events first, and then select for 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // touch-events (but keep the other events in the mask, i.e. do not memset 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |mask| back to 0). 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(sad): Figure out why this happens. http://crbug.com/153976 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_XI2_MT) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XISetMask(mask, XI_TouchBegin); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XISetMask(mask, XI_TouchUpdate); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XISetMask(mask, XI_TouchEnd); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XISelectEvents(display, root_window, &evmask, 1); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// generated for certain keys; see 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. Per 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// discussion on http://crbug.com/108480, char events should furthermore not be 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// generated for Tab, Escape, and Backspace. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) || 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) || 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (keycode >= ui::VKEY_NUMPAD0 && keycode <= ui::VKEY_NUMPAD9)) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (keycode) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_RETURN: 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_SPACE: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In addition to the keys listed at MSDN, we include other 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // graphic-character and numpad keys. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_MULTIPLY: 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_ADD: 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_SUBTRACT: 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_DECIMAL: 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_DIVIDE: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_1: 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_2: 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_3: 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_4: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_5: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_6: 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_7: 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_102: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_PLUS: 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_COMMA: 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_MINUS: 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_PERIOD: 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool default_override_redirect = false; 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Accomplishes 2 tasks concerning touch event calibration: 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. Being a message-pump observer, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// routes all the touch events to the X root window, 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// where they can be calibrated later. 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. Has the Calibrate method that does the actual bezel calibration, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// when invoked from X root window's event dispatcher. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TouchEventCalibrate : public base::MessagePumpObserver { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TouchEventCalibrate() 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : left_(0), 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) right_(0), 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) top_(0), 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom_(0) { 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForUI::current()->AddObserver(this); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_XI2_MT) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> parts; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kTouchCalibration), ",", &parts) >= 4) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::StringToInt(parts[0], &left_)) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Incorrect left border calibration value passed."; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::StringToInt(parts[1], &right_)) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Incorrect right border calibration value passed."; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::StringToInt(parts[2], &top_)) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Incorrect top border calibration value passed."; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::StringToInt(parts[3], &bottom_)) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Incorrect bottom border calibration value passed."; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(USE_XI2_MT) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TouchEventCalibrate() { 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForUI::current()->RemoveObserver(this); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Modify the location of the |event|, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expanding it from |bounds| to (|bounds| + bezels). 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Required when touchscreen is bigger than screen (i.e. has bezels), 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // because we receive events in touchscreen coordinates, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which need to be expanded when converting to screen coordinates, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // so that location on bezels will be outside of screen area. 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_XI2_MT) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x = event->x(); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int y = event->y(); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!left_ && !right_ && !top_ && !bottom_) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int resolution_x = bounds.width(); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int resolution_y = bounds.height(); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The "grace area" (10% in this case) is to make it easier for the user to 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // navigate to the corner. 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const double kGraceAreaFraction = 0.1; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (left_ || right_) { 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Offset the x position to the real 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x -= left_; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if we are in the grace area of the left side. 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note: We might not want to do this when the gesture is locked? 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (x < 0 && x > -left_ * kGraceAreaFraction) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x = 0; 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if we are in the grace area of the right side. 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note: We might not want to do this when the gesture is locked? 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (x > resolution_x - left_ && 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x < resolution_x - left_ + right_ * kGraceAreaFraction) 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x = resolution_x - left_; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Scale the screen area back to the full resolution of the screen. 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x = (x * resolution_x) / (resolution_x - (right_ + left_)); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (top_ || bottom_) { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When there is a top bezel we add our border, 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y -= top_; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if we are in the grace area of the top side. 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note: We might not want to do this when the gesture is locked? 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (y < 0 && y > -top_ * kGraceAreaFraction) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y = 0; 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if we are in the grace area of the bottom side. 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note: We might not want to do this when the gesture is locked? 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (y > resolution_y - top_ && 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y < resolution_y - top_ + bottom_ * kGraceAreaFraction) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y = resolution_y - top_; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Scale the screen area back to the full resolution of the screen. 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y = (y * resolution_y) / (resolution_y - (bottom_ + top_)); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set the modified coordinate back to the event. 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event->root_location() == event->location()) { 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Usually those will be equal, 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if not, I am not sure what the correct value should be. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->set_root_location(gfx::Point(x, y)); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->set_location(gfx::Point(x, y)); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(USE_XI2_MT) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overridden from base::MessagePumpObserver: 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual base::EventStatus WillProcessEvent( 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::NativeEvent& event) OVERRIDE { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_XI2_MT) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event->type == GenericEvent && 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (event->xgeneric.evtype == XI_TouchBegin || 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->xgeneric.evtype == XI_TouchUpdate || 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->xgeneric.evtype == XI_TouchEnd)) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xievent->event = xievent->root; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xievent->event_x = xievent->root_x; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xievent->event_y = xievent->root_y; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(USE_XI2_MT) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::EVENT_CONTINUE; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The difference in screen's native resolution pixels between 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the border of the touchscreen and the border of the screen, 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // aka bezel sizes. 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int left_; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int right_; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top_; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom_; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TouchEventCalibrate); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// RootWindowHostX11::MouseMoveFilter filters out the move events that 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// jump back and forth between two points. This happens when sub pixel mouse 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// move is enabled and mouse move events could be jumping between two neighbor 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// pixels, e.g. move(0,0), move(1,0), move(0,0), move(1,0) and on and on. 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The filtering is done by keeping track of the last two event locations and 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// provides a Filter method to find out whether a mouse event is in a different 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// location and should be processed. 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RootWindowHostX11::MouseMoveFilter { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MouseMoveFilter() : insert_index_(0) { 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < kMaxEvents; ++i) { 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int int_max = std::numeric_limits<int>::max(); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recent_locations_[i] = gfx::Point(int_max, int_max); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~MouseMoveFilter() {} 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true if |event| is known and should be ignored. 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool Filter(const base::NativeEvent& event) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Point& location = ui::EventLocationFromNative(event); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < kMaxEvents; ++i) { 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (location == recent_locations_[i]) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recent_locations_[insert_index_] = location; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) insert_index_ = (insert_index_ + 1) % kMaxEvents; 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const size_t kMaxEvents = 2; 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point recent_locations_[kMaxEvents]; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t insert_index_; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MouseMoveFilter); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// RootWindowHostX11 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RootWindowHostX11::RootWindowHostX11(const gfx::Rect& bounds) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(NULL), 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xwindow_(0), 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_root_window_(DefaultRootWindow(xdisplay_)), 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_cursor_(ui::kCursorNull), 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_mapped_(false), 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_(bounds), 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_internal_display_(false), 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focus_when_shown_(false), 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) touch_calibrate_(new internal::TouchEventCalibrate), 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_move_filter_(new MouseMoveFilter), 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom_cache_(xdisplay_, kAtomsToCache) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSetWindowAttributes swa; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&swa, 0, sizeof(swa)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swa.background_pixmap = None; 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) swa.override_redirect = default_override_redirect; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xwindow_ = XCreateWindow( 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xdisplay_, x_root_window_, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds.x(), bounds.y(), bounds.width(), bounds.height(), 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // border width 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyFromParent, // depth 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputOutput, 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyFromParent, // visual 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CWBackPixmap | CWOverrideRedirect, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &swa); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(this); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KeyPressMask | KeyReleaseMask | 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnterWindowMask | LeaveWindowMask | 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExposureMask | VisibilityChangeMask | 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StructureNotifyMask | PropertyChangeMask | 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerMotionMask; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSelectInput(xdisplay_, xwindow_, event_mask); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFlush(xdisplay_); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::MessagePumpForUI::HasXInput2()) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectEventsForRootWindow(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the initial size of the X root window. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes attrs; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XGetWindowAttributes(xdisplay_, x_root_window_, &attrs); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_root_bounds_.SetRect(attrs.x, attrs.y, attrs.width, attrs.height); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erg): We currently only request window deletion events. We also 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should listen for activation events and anything else that GTK+ listens 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for, and do something useful. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Atom protocols[2]; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW"); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocols[1] = atom_cache_.GetAtom("_NET_WM_PING"); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the desktop environment. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Likewise, the X server needs to know this window's pid so it knows which 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // program to kill if the window hangs. 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pid_t pid = getpid(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XChangeProperty(xdisplay_, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xwindow_, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom_cache_.GetAtom("_NET_WM_PID"), 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XA_CARDINAL, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32, 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PropModeReplace, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<unsigned char*>(&pid), 1); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // crbug.com/120229 - set the window title so gtalk can find the primary root 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window to broadcast. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int root_window_number = 0; 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string name = base::StringPrintf("aura_root_%d", root_window_number++); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XStoreName(xdisplay_, xwindow_, name.c_str()); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XRRSelectInput(xdisplay_, x_root_window_, 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RRScreenChangeNotifyMask | RROutputChangeNotifyMask); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->AddObserver(this); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RootWindowHostX11::~RootWindowHostX11() { 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->RemoveObserver(this); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnConfineCursor(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XDestroyWindow(xdisplay_, xwindow_); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::Dispatch(const base::NativeEvent& event) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XEvent* xev = event; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindEventTarget(event) == x_root_window_) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DispatchEventForRootWindow(event); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (xev->type) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EnterNotify: { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MouseEvent mouseenter_event(xev); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TranslateAndDispatchMouseEvent(&mouseenter_event); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Expose: { 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y, 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) xev->xexpose.width, xev->xexpose.height); 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate_->AsRootWindow()->ScheduleRedrawRect(damage_rect); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case KeyPress: { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::KeyEvent keydown_event(xev, false); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostKeyEvent(&keydown_event); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case KeyRelease: { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::KeyEvent keyup_event(xev, false); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostKeyEvent(&keyup_event); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ButtonPress: { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (static_cast<int>(xev->xbutton.button) == kBackMouseButton || 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(xev->xbutton.button) == kForwardMouseButton) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::UserActionClient* gesture_client = 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::GetUserActionClient(delegate_->AsRootWindow()); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gesture_client) { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gesture_client->OnUserAction( 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(xev->xbutton.button) == kBackMouseButton ? 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::UserActionClient::BACK : 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::UserActionClient::FORWARD); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } // fallthrough 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ButtonRelease: { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MouseEvent mouseev(xev); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TranslateAndDispatchMouseEvent(&mouseev); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FocusOut: 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xev->xfocus.mode != NotifyGrab) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostLostWindowCapture(); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ConfigureNotify: { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(xwindow_, xev->xconfigure.event); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(xwindow_, xev->xconfigure.window); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible that the X window may be resized by some other means 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // than from within aura (e.g. the X window manager can change the 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size). Make sure the root window size is maintained properly. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xev->xconfigure.width, xev->xconfigure.height); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool size_changed = bounds_.size() != bounds.size(); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool origin_changed = bounds_.origin() != bounds.origin(); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_ = bounds; 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateIsInternalDisplay(); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always update barrier and mouse location because |bounds_| might 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have already been updated in |SetBounds|. 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pointer_barriers_) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnConfineCursor(); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfineCursorToRootWindow(); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size_changed) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostResized(bounds.size()); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (origin_changed) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostMoved(bounds_.origin()); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GenericEvent: 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchXI2Event(event); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MapNotify: { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there's no window manager running, we need to assign the X input 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // focus to our host window. 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsWindowManagerPresent() && focus_when_shown_) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ClientMessage: { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have received a close message from the window manager. 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->AsRootWindow()->OnRootWindowHostCloseRequested(); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XEvent reply_event = *xev; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_event.xclient.window = x_root_window_; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSendEvent(xdisplay_, 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_event.xclient.window, 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) False, 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SubstructureRedirectMask | SubstructureNotifyMask, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &reply_event); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MappingNotify: { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (xev->xmapping.request) { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MappingModifier: 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MappingKeyboard: 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XRefreshKeyboardMapping(&xev->xmapping); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->AsRootWindow()->OnKeyboardMappingChanged(); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MappingPointer: 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::UpdateButtonMap(); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED() << " Unknown request: " << xev->xmapping.request; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MotionNotify: { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Discard all but the most recent motion event that targets the same 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window with unchanged state. 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XEvent last_event; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (XPending(xev->xany.display)) { 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XEvent next_event; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XPeekEvent(xev->xany.display, &next_event); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_event.type == MotionNotify && 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_event.xmotion.window == xev->xmotion.window && 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_event.xmotion.subwindow == xev->xmotion.subwindow && 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_event.xmotion.state == xev->xmotion.state) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XNextEvent(xev->xany.display, &last_event); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xev = &last_event; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MouseEvent mouseev(xev); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TranslateAndDispatchMouseEvent(&mouseev); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetDelegate(RootWindowHostDelegate* delegate) { 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_ = delegate; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RootWindow* RootWindowHostX11::GetRootWindow() { 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delegate_->AsRootWindow(); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::AcceleratedWidget RootWindowHostX11::GetAcceleratedWidget() { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return xwindow_; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::Show() { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window_mapped_) { 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Before we map the window, set size hints. Otherwise, some window managers 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will ignore toplevel XMoveWindow commands. 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSizeHints size_hints; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_hints.flags = PPosition | PWinGravity; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_hints.x = bounds_.x(); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_hints.y = bounds_.y(); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set StaticGravity so that the window position is not affected by the 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame width when running with window manager. 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_hints.win_gravity = StaticGravity; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XMapWindow(xdisplay_, xwindow_); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We now block until our window is mapped. Some X11 APIs will crash and 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // burn if passed |xwindow_| before the window is mapped, and XMapWindow is 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // asynchronous. 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessagePumpAuraX11::Current()->BlockUntilWindowMapped(xwindow_); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_mapped_ = true; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::Hide() { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_mapped_) { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWithdrawWindow(xdisplay_, xwindow_, 0); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_mapped_ = false; 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::ToggleFullScreen() { 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Rect RootWindowHostX11::GetBounds() const { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bounds_; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetBounds(const gfx::Rect& bounds) { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Even if the host window's size doesn't change, aura's root window 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size, which is in DIP, changes when the scale changes. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float current_scale = delegate_->GetDeviceScaleFactor(); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float new_scale = gfx::Screen::GetScreenFor(delegate_->AsRootWindow())-> 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDisplayNearestWindow(delegate_->AsRootWindow()).device_scale_factor(); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool origin_changed = bounds_.origin() != bounds.origin(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool size_changed = bounds_.size() != bounds.size(); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowChanges changes = {0}; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned value_mask = 0; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size_changed) { 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changes.width = bounds.width(); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changes.height = bounds.height(); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_mask = CWHeight | CWWidth; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (origin_changed) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changes.x = bounds.x(); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changes.y = bounds.y(); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_mask |= CWX | CWY; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value_mask) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assume that the resize will go through as requested, which should be the 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // case if we're running without a window manager. If there's a window 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manager, it can modify or ignore the request, but (per ICCCM) we'll get a 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (possibly synthetic) ConfigureNotify about the actual size and correct 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |bounds_| later. 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_ = bounds; 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateIsInternalDisplay(); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (origin_changed) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostMoved(bounds.origin()); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size_changed || current_scale != new_scale) { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostResized(bounds.size()); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->AsRootWindow()->SchedulePaintInRect( 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->AsRootWindow()->bounds()); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Insets RootWindowHostX11::GetInsets() const { 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return insets_; 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetInsets(const gfx::Insets& insets) { 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) insets_ = insets; 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pointer_barriers_) { 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UnConfineCursor(); 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfineCursorToRootWindow(); 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Point RootWindowHostX11::GetLocationOnNativeScreen() const { 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bounds_.origin(); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetCapture() { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(oshima): Grab x input. 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::ReleaseCapture() { 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(oshima): Release x input. 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetCursor(gfx::NativeCursor cursor) { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cursor == current_cursor_) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_cursor_ = cursor; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetCursorInternal(cursor); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::QueryMouseLocation(gfx::Point* location_return) { 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client::CursorClient* cursor_client = 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client::GetCursorClient(GetRootWindow()); 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cursor_client && !cursor_client->IsMouseEventsEnabled()) { 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *location_return = gfx::Point(0, 0); 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Window root_return, child_return; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int root_x_return, root_y_return, win_x_return, win_y_return; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int mask_return; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XQueryPointer(xdisplay_, 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xwindow_, 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &root_return, 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &child_return, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &root_x_return, &root_y_return, 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &win_x_return, &win_y_return, 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mask_return); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *location_return = gfx::Point(max(0, min(bounds_.width(), win_x_return)), 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max(0, min(bounds_.height(), win_y_return))); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (win_x_return >= 0 && win_x_return < bounds_.width() && 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) win_y_return >= 0 && win_y_return < bounds_.height()); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::ConfineCursorToRootWindow() { 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if XFIXES_MAJOR >= 5 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pointer_barriers_.get()); 733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pointer_barriers_) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pointer_barriers_.reset(new XID[4]); 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect bounds(bounds_); 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.Inset(insets_); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Horizontal, top barriers. 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pointer_barriers_[0] = XFixesCreatePointerBarrier( 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xdisplay_, x_root_window_, 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.x(), bounds.y(), bounds.right(), bounds.y(), 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BarrierPositiveY, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, XIAllDevices); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Horizontal, bottom barriers. 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pointer_barriers_[1] = XFixesCreatePointerBarrier( 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xdisplay_, x_root_window_, 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.x(), bounds.bottom(), bounds.right(), bounds.bottom(), 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BarrierNegativeY, 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, XIAllDevices); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vertical, left barriers. 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pointer_barriers_[2] = XFixesCreatePointerBarrier( 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xdisplay_, x_root_window_, 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.x(), bounds.y(), bounds.x(), bounds.bottom(), 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BarrierPositiveX, 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, XIAllDevices); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vertical, right barriers. 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pointer_barriers_[3] = XFixesCreatePointerBarrier( 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xdisplay_, x_root_window_, 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.right(), bounds.y(), bounds.right(), bounds.bottom(), 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BarrierNegativeX, 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, XIAllDevices); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::UnConfineCursor() { 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if XFIXES_MAJOR >= 5 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pointer_barriers_) { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[0]); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[1]); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[2]); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[3]); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pointer_barriers_.reset(); 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::OnCursorVisibilityChanged(bool show) { 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Temporarily pause tap-to-click when the cursor is hidden. 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Atom prop = atom_cache_.GetAtom("Tap Paused"); 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char value = !show; 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XIDeviceList dev_list = 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(xdisplay_); 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only slave pointer devices could possibly have tap-paused property. 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < dev_list.count; i++) { 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dev_list[i].use == XISlavePointer) { 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Atom old_type; 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int old_format; 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long old_nvalues, bytes; 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char* data; 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int result = XIGetProperty(xdisplay_, dev_list[i].deviceid, prop, 0, 0, 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) False, AnyPropertyType, &old_type, &old_format, 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &old_nvalues, &bytes, &data); 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != Success) 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XFree(data); 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XIChangeProperty(xdisplay_, dev_list[i].deviceid, prop, XA_INTEGER, 8, 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PropModeReplace, &value, 1); 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::MoveCursorTo(const gfx::Point& location) { 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0, 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_.x() + location.x(), 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_.y() + location.y()); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetFocusWhenShown(bool focus_when_shown) { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* k_NET_WM_USER_TIME = "_NET_WM_USER_TIME"; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focus_when_shown_ = focus_when_shown; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsWindowManagerPresent() && !focus_when_shown_) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SetIntProperty(xwindow_, 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k_NET_WM_USER_TIME, 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k_NET_WM_USER_TIME, 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::CopyAreaToSkCanvas(const gfx::Rect& source_bounds, 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& dest_offset, 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkCanvas* canvas) { 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(source_bounds)); 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!scoped_image) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XImage* image = scoped_image->get(); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(image); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image->bits_per_pixel == 32) { 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((0xff << SK_R32_SHIFT) != image->red_mask || 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (0xff << SK_G32_SHIFT) != image->green_mask || 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (0xff << SK_B32_SHIFT) != image->blue_mask) { 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "XImage and Skia byte orders differ"; 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the alpha channel before copying to the canvas. Otherwise, areas of 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the framebuffer that were cleared by ply-image rather than being obscured 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by an image during boot may end up transparent. 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(derat|marcheu): Remove this if/when ply-image has been updated to 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // set the framebuffer's alpha channel regardless of whether the device 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // claims to support alpha or not. 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < image->width * image->height * 4; i += 4) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image->data[i + 3] = 0xff; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.setConfig(SkBitmap::kARGB_8888_Config, 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image->width, image->height, 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image->bytes_per_line); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.setPixels(image->data); 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->drawBitmap(bitmap, SkIntToScalar(0), SkIntToScalar(0), NULL); 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED() << "Unsupported bits-per-pixel " << image->bits_per_pixel; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::PostNativeEvent( 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::NativeEvent& native_event) { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(xwindow_); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(xdisplay_); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XEvent xevent = *native_event; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xevent.xany.display = xdisplay_; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xevent.xany.window = xwindow_; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (xevent.type) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EnterNotify: 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LeaveNotify: 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MotionNotify: 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case KeyPress: 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case KeyRelease: 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ButtonPress: 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ButtonRelease: { 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The fields used below are in the same place for all of events 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // above. Using xmotion from XEvent's unions to avoid repeating 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the code. 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xevent.xmotion.root = x_root_window_; 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xevent.xmotion.time = CurrentTime; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point point(xevent.xmotion.x, xevent.xmotion.y); 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->AsRootWindow()->ConvertPointToNativeScreen(&point); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xevent.xmotion.x_root = point.x(); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xevent.xmotion.y_root = point.y(); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::OnDeviceScaleFactorChanged( 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float device_scale_factor) { 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::PrepareForShutdown() { 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::OnWindowInitialized(Window* window) { 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::OnRootWindowInitialized(RootWindow* root_window) { 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // UpdateIsInternalDisplay relies on: 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1. delegate_ pointing to RootWindow - available after SetDelegate. 9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2. RootWindow's kDisplayIdKey property set - available by the time 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // RootWindow::Init is called. 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (set in DisplayManager::CreateRootWindowForDisplay) 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ready when NotifyRootWindowInitialized is called from RootWindow::Init. 9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!delegate_ || root_window != GetRootWindow()) 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateIsInternalDisplay(); 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::DispatchEventForRootWindow( 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::NativeEvent& event) { 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (event->type) { 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ConfigureNotify: 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(x_root_window_, event->xconfigure.event); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y, 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->xconfigure.width, event->xconfigure.height); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GenericEvent: 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchXI2Event(event); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::DispatchXI2Event(const base::NativeEvent& event) { 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XEvent* xev = event; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!factory->ShouldProcessXI2Event(xev)) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TRACE_EVENT1("input", "RootWindowHostX11::DispatchXI2Event", 944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "event_latency_us", 945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (ui::EventTimeForNow() - ui::EventTimeFromNative(event)). 946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) InMicroseconds()); 947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::EventType type = ui::EventTypeFromNative(xev); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XEvent last_event; 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_coalesced = 0; 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_TOUCH_MOVED: 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_TOUCH_PRESSED: 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_TOUCH_CANCELLED: 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_TOUCH_RELEASED: { 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::TouchEvent touchev(xev); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::chromeos::IsRunningOnChromeOS()) { 9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!bounds_.Contains(touchev.location())) 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // X maps the touch-surface to the size of the X root-window. 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In multi-monitor setup, Coordinate Transformation Matrix 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // repositions the touch-surface onto part of X root-window 9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // containing aura root-window corresponding to the touchscreen. 9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // However, if aura root-window has non-zero origin, 9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // we need to relocate the event into aura root-window coordinates. 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touchev.Relocate(bounds_.origin()); 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_XI2_MT) 9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_internal_display_) 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touch_calibrate_->Calibrate(&touchev, bounds_); 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(USE_XI2_MT) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_CHROMEOS) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostTouchEvent(&touchev); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_MOUSE_MOVED: 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_MOUSE_DRAGGED: 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_MOUSE_PRESSED: 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_MOUSE_RELEASED: 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_MOUSE_ENTERED: 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_MOUSE_EXITED: { 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is a motion event, we want to coalesce all pending motion 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // events that are at the top of the queue. 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_coalesced > 0) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xev = &last_event; 9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mouse_move_filter_ && mouse_move_filter_->Filter(xev)) 9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (type == ui::ET_MOUSE_PRESSED || 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type == ui::ET_MOUSE_RELEASED) { 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XIDeviceEvent* xievent = 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<XIDeviceEvent*>(xev->xcookie.data); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int button = xievent->detail; 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button == kBackMouseButton || button == kForwardMouseButton) { 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == ui::ET_MOUSE_RELEASED) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::UserActionClient* gesture_client = 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::GetUserActionClient(delegate_->AsRootWindow()); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gesture_client) { 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool reverse_direction = 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gesture_client->OnUserAction( 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (button == kBackMouseButton && !reverse_direction) || 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (button == kForwardMouseButton && reverse_direction) ? 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::UserActionClient::BACK : 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::UserActionClient::FORWARD); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MouseEvent mouseev(xev); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TranslateAndDispatchMouseEvent(&mouseev); 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_MOUSEWHEEL: { 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MouseWheelEvent mouseev(xev); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TranslateAndDispatchMouseEvent(&mouseev); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_SCROLL_FLING_START: 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_SCROLL_FLING_CANCEL: 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_SCROLL: { 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScrollEvent scrollev(xev); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostScrollEvent(&scrollev); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_UNKNOWN: 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we coalesced an event we need to free its cookie. 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_coalesced > 0) 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFreeEventData(xev->xgeneric.display, &last_event.xcookie); 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RootWindowHostX11::IsWindowManagerPresent() { 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Per ICCCM 2.8, "Manager Selections", window managers should take ownership 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of WM_Sn selections (where n is a screen number). 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return XGetSelectionOwner( 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::SetCursorInternal(gfx::NativeCursor cursor) { 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XDefineCursor(xdisplay_, xwindow_, cursor.platform()); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::TranslateAndDispatchMouseEvent( 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MouseEvent* event) { 10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RootWindow* root_window = GetRootWindow(); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client::ScreenPositionClient* screen_position_client = 10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetScreenPositionClient(root_window); 10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect local(bounds_.size()); 10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (screen_position_client && !local.Contains(event->location())) { 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point location(event->location()); 10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In order to get the correct point in screen coordinates 10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // during passive grab, we first need to find on which host window 10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the mouse is on, and find out the screen coordinates on that 10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // host window, then convert it back to this host window's coordinate. 10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) screen_position_client->ConvertHostPointToScreen(root_window, &location); 10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) screen_position_client->ConvertPointFromScreen(root_window, &location); 10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_window->ConvertPointToHost(&location); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->set_location(location); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->set_root_location(location); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnHostMouseEvent(event); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ui::XScopedImage> RootWindowHostX11::GetXImage( 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& snapshot_bounds) { 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::XScopedImage> image(new ui::XScopedImage( 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XGetImage(xdisplay_, xwindow_, 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snapshot_bounds.x(), snapshot_bounds.y(), 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snapshot_bounds.width(), snapshot_bounds.height(), 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllPlanes, ZPixmap))); 1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!image) { 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "XGetImage failed"; 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.reset(); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image.Pass(); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RootWindowHostX11::UpdateIsInternalDisplay() { 10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RootWindow* root_window = GetRootWindow(); 10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window); 10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Display display = screen->GetDisplayNearestWindow(root_window); 10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_internal_display_ = display.IsInternal(); 10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { 1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new RootWindowHostX11(bounds); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size RootWindowHost::GetNativeScreenSize() { 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace test { 110890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 110990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void SetUseOverrideRedirectWindowByDefault(bool override_redirect) { 111090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default_override_redirect = override_redirect; 111190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 111290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 111390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace test 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace aura 1115