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