| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/aura/root_window_host_linux.h" | 5 #include "ui/aura/root_window_host_linux.h" |
| 6 | 6 |
| 7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
| 8 #include <X11/Xcursor/Xcursor.h> | 8 #include <X11/Xcursor/Xcursor.h> |
| 9 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
| 10 #include <X11/cursorfont.h> | 10 #include <X11/cursorfont.h> |
| 11 #include <X11/extensions/XInput2.h> | 11 #include <X11/extensions/XInput2.h> |
| 12 #include <X11/extensions/Xfixes.h> | 12 #include <X11/extensions/Xfixes.h> |
| 13 #include <X11/extensions/Xrandr.h> | 13 #include <X11/extensions/Xrandr.h> |
| 14 #include <algorithm> | 14 #include <algorithm> |
| 15 | 15 |
| 16 #include "base/message_pump_x.h" | 16 #include "base/message_pump_aurax11.h" |
| 17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 18 #include "base/stringprintf.h" | 18 #include "base/stringprintf.h" |
| 19 #include "grit/ui_resources_standard.h" | 19 #include "grit/ui_resources_standard.h" |
| 20 #include "third_party/skia/include/core/SkBitmap.h" | 20 #include "third_party/skia/include/core/SkBitmap.h" |
| 21 #include "ui/aura/client/user_gesture_client.h" | 21 #include "ui/aura/client/user_gesture_client.h" |
| 22 #include "ui/aura/dispatcher_linux.h" | 22 #include "ui/aura/dispatcher_linux.h" |
| 23 #include "ui/aura/env.h" | 23 #include "ui/aura/env.h" |
| 24 #include "ui/aura/event.h" | 24 #include "ui/aura/event.h" |
| 25 #include "ui/aura/root_window.h" | 25 #include "ui/aura/root_window.h" |
| 26 #include "ui/aura/x11_atom_cache.h" | |
| 27 #include "ui/base/cursor/cursor.h" | 26 #include "ui/base/cursor/cursor.h" |
| 28 #include "ui/base/keycodes/keyboard_codes.h" | 27 #include "ui/base/keycodes/keyboard_codes.h" |
| 29 #include "ui/base/resource/resource_bundle.h" | 28 #include "ui/base/resource/resource_bundle.h" |
| 30 #include "ui/base/touch/touch_factory.h" | 29 #include "ui/base/touch/touch_factory.h" |
| 31 #include "ui/base/view_prop.h" | 30 #include "ui/base/view_prop.h" |
| 32 #include "ui/base/x/x11_util.h" | 31 #include "ui/base/x/x11_util.h" |
| 33 #include "ui/compositor/layer.h" | 32 #include "ui/compositor/layer.h" |
| 34 #include "ui/gfx/codec/png_codec.h" | 33 #include "ui/gfx/codec/png_codec.h" |
| 35 #include "ui/gfx/image/image.h" | 34 #include "ui/gfx/image/image.h" |
| 36 #include "ui/gfx/image/image_skia.h" | 35 #include "ui/gfx/image/image_skia.h" |
| 37 | 36 |
| 37 using base::MessagePumpAuraX11; |
| 38 using std::max; | 38 using std::max; |
| 39 using std::min; | 39 using std::min; |
| 40 | 40 |
| 41 namespace aura { | 41 namespace aura { |
| 42 | 42 |
| 43 namespace { | 43 namespace { |
| 44 | 44 |
| 45 // Standard Linux mouse buttons for going back and forward. | 45 // Standard Linux mouse buttons for going back and forward. |
| 46 const int kBackMouseButton = 8; | 46 const int kBackMouseButton = 8; |
| 47 const int kForwardMouseButton = 9; | 47 const int kForwardMouseButton = 9; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 // A map to hold all image cursors. It maps the cursor ID to the X Cursor. | 378 // A map to hold all image cursors. It maps the cursor ID to the X Cursor. |
| 379 std::map<int, Cursor> cursors_; | 379 std::map<int, Cursor> cursors_; |
| 380 | 380 |
| 381 float scale_factor_; | 381 float scale_factor_; |
| 382 | 382 |
| 383 DISALLOW_COPY_AND_ASSIGN(ImageCursors); | 383 DISALLOW_COPY_AND_ASSIGN(ImageCursors); |
| 384 }; | 384 }; |
| 385 | 385 |
| 386 RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) | 386 RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) |
| 387 : root_window_(NULL), | 387 : root_window_(NULL), |
| 388 xdisplay_(base::MessagePumpX::GetDefaultXDisplay()), | 388 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), |
| 389 xwindow_(0), | 389 xwindow_(0), |
| 390 x_root_window_(DefaultRootWindow(xdisplay_)), | 390 x_root_window_(DefaultRootWindow(xdisplay_)), |
| 391 current_cursor_(ui::kCursorNull), | 391 current_cursor_(ui::kCursorNull), |
| 392 cursor_shown_(true), | 392 cursor_shown_(true), |
| 393 bounds_(bounds), | 393 bounds_(bounds), |
| 394 focus_when_shown_(false), | 394 focus_when_shown_(false), |
| 395 pointer_barriers_(NULL), | 395 pointer_barriers_(NULL), |
| 396 image_cursors_(new ImageCursors) { | 396 image_cursors_(new ImageCursors) { |
| 397 XSetWindowAttributes swa; | 397 XSetWindowAttributes swa; |
| 398 memset(&swa, 0, sizeof(swa)); | 398 memset(&swa, 0, sizeof(swa)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank, | 432 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank, |
| 433 &black, &black, 0, 0); | 433 &black, &black, 0, 0); |
| 434 XFreePixmap(xdisplay_, blank); | 434 XFreePixmap(xdisplay_, blank); |
| 435 | 435 |
| 436 if (RootWindow::hide_host_cursor()) | 436 if (RootWindow::hide_host_cursor()) |
| 437 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_); | 437 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_); |
| 438 | 438 |
| 439 // TODO(erg): We currently only request window deletion events. We also | 439 // TODO(erg): We currently only request window deletion events. We also |
| 440 // should listen for activation events and anything else that GTK+ listens | 440 // should listen for activation events and anything else that GTK+ listens |
| 441 // for, and do something useful. | 441 // for, and do something useful. |
| 442 X11AtomCache* cache = aura::Env::GetInstance()->atom_cache(); | |
| 443 ::Atom protocols[2]; | 442 ::Atom protocols[2]; |
| 444 protocols[0] = cache->GetAtom(ATOM_WM_DELETE_WINDOW); | 443 protocols[0] = MessagePumpAuraX11::GetAtom(base::atom::WM_DELETE_WINDOW); |
| 445 protocols[1] = cache->GetAtom(ATOM__NET_WM_PING); | 444 protocols[1] = MessagePumpAuraX11::GetAtom(base::atom::_NET_WM_PING); |
| 446 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); | 445 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); |
| 447 | 446 |
| 448 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with | 447 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with |
| 449 // the desktop environment. | 448 // the desktop environment. |
| 450 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL); | 449 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL); |
| 451 | 450 |
| 452 // Likewise, the X server needs to know this window's pid so it knows which | 451 // Likewise, the X server needs to know this window's pid so it knows which |
| 453 // program to kill if the window hangs. | 452 // program to kill if the window hangs. |
| 454 pid_t pid = getpid(); | 453 pid_t pid = getpid(); |
| 455 XChangeProperty(xdisplay_, | 454 XChangeProperty(xdisplay_, |
| 456 xwindow_, | 455 xwindow_, |
| 457 cache->GetAtom(ATOM__NET_WM_PID), | 456 MessagePumpAuraX11::GetAtom(base::atom::_NET_WM_PID), |
| 458 XA_CARDINAL, | 457 XA_CARDINAL, |
| 459 32, | 458 32, |
| 460 PropModeReplace, | 459 PropModeReplace, |
| 461 reinterpret_cast<unsigned char*>(&pid), 1); | 460 reinterpret_cast<unsigned char*>(&pid), 1); |
| 462 | 461 |
| 463 // crbug.com/120229 - set the window title so gtalk can find the primary root | 462 // crbug.com/120229 - set the window title so gtalk can find the primary root |
| 464 // window to broadcast. | 463 // window to broadcast. |
| 465 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. | 464 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. |
| 466 static int root_window_number = 0; | 465 static int root_window_number = 0; |
| 467 std::string name = StringPrintf("aura_root_%d", root_window_number++); | 466 std::string name = StringPrintf("aura_root_%d", root_window_number++); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 } | 618 } |
| 620 case MapNotify: { | 619 case MapNotify: { |
| 621 // If there's no window manager running, we need to assign the X input | 620 // If there's no window manager running, we need to assign the X input |
| 622 // focus to our host window. | 621 // focus to our host window. |
| 623 if (!IsWindowManagerPresent() && focus_when_shown_) | 622 if (!IsWindowManagerPresent() && focus_when_shown_) |
| 624 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); | 623 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); |
| 625 break; | 624 break; |
| 626 } | 625 } |
| 627 case ClientMessage: { | 626 case ClientMessage: { |
| 628 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); | 627 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); |
| 629 X11AtomCache* cache = aura::Env::GetInstance()->atom_cache(); | 628 if (message_type == MessagePumpAuraX11::GetAtom( |
| 630 if (message_type == cache->GetAtom(ATOM_WM_DELETE_WINDOW)) { | 629 base::atom::WM_DELETE_WINDOW)) { |
| 631 // We have received a close message from the window manager. | 630 // We have received a close message from the window manager. |
| 632 root_window_->OnRootWindowHostClosed(); | 631 root_window_->OnRootWindowHostClosed(); |
| 633 } else if (message_type == cache->GetAtom(ATOM__NET_WM_PING)) { | 632 } else if (message_type == MessagePumpAuraX11::GetAtom( |
| 633 base::atom::_NET_WM_PING)) { |
| 634 XEvent reply_event = *xev; | 634 XEvent reply_event = *xev; |
| 635 reply_event.xclient.window = x_root_window_; | 635 reply_event.xclient.window = x_root_window_; |
| 636 | 636 |
| 637 XSendEvent(xdisplay_, | 637 XSendEvent(xdisplay_, |
| 638 reply_event.xclient.window, | 638 reply_event.xclient.window, |
| 639 False, | 639 False, |
| 640 SubstructureRedirectMask | SubstructureNotifyMask, | 640 SubstructureRedirectMask | SubstructureNotifyMask, |
| 641 &reply_event); | 641 &reply_event); |
| 642 } | 642 } |
| 643 break; | 643 break; |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 void RootWindowHostLinux::OnDeviceScaleFactorChanged( | 923 void RootWindowHostLinux::OnDeviceScaleFactorChanged( |
| 924 float device_scale_factor) { | 924 float device_scale_factor) { |
| 925 image_cursors_->Reload(device_scale_factor); | 925 image_cursors_->Reload(device_scale_factor); |
| 926 } | 926 } |
| 927 | 927 |
| 928 bool RootWindowHostLinux::IsWindowManagerPresent() { | 928 bool RootWindowHostLinux::IsWindowManagerPresent() { |
| 929 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership | 929 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
| 930 // of WM_Sn selections (where n is a screen number). | 930 // of WM_Sn selections (where n is a screen number). |
| 931 return XGetSelectionOwner( | 931 return XGetSelectionOwner( |
| 932 xdisplay_, | 932 xdisplay_, |
| 933 aura::Env::GetInstance()->atom_cache()->GetAtom(ATOM_WM_S0)) != None; | 933 MessagePumpAuraX11::GetAtom(base::atom::WM_S0)) != None; |
| 934 } | 934 } |
| 935 | 935 |
| 936 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { | 936 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
| 937 ::Cursor xcursor = | 937 ::Cursor xcursor = |
| 938 image_cursors_->IsImageCursor(cursor) ? | 938 image_cursors_->IsImageCursor(cursor) ? |
| 939 image_cursors_->ImageCursorFromNative(cursor) : | 939 image_cursors_->ImageCursorFromNative(cursor) : |
| 940 (cursor == ui::kCursorNone ? invisible_cursor_ : | 940 (cursor == ui::kCursorNone ? invisible_cursor_ : |
| 941 (cursor == ui::kCursorCustom ? cursor.platform() : | 941 (cursor == ui::kCursorCustom ? cursor.platform() : |
| 942 ui::GetXCursor(CursorShapeFromNative(cursor)))); | 942 ui::GetXCursor(CursorShapeFromNative(cursor)))); |
| 943 XDefineCursor(xdisplay_, xwindow_, xcursor); | 943 XDefineCursor(xdisplay_, xwindow_, xcursor); |
| 944 } | 944 } |
| 945 | 945 |
| 946 // static | 946 // static |
| 947 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { | 947 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { |
| 948 return new RootWindowHostLinux(bounds); | 948 return new RootWindowHostLinux(bounds); |
| 949 } | 949 } |
| 950 | 950 |
| 951 // static | 951 // static |
| 952 RootWindowHost* RootWindowHost::GetForAcceleratedWidget( | 952 RootWindowHost* RootWindowHost::GetForAcceleratedWidget( |
| 953 gfx::AcceleratedWidget accelerated_widget) { | 953 gfx::AcceleratedWidget accelerated_widget) { |
| 954 return reinterpret_cast<RootWindowHost*>( | 954 return reinterpret_cast<RootWindowHost*>( |
| 955 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); | 955 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); |
| 956 } | 956 } |
| 957 | 957 |
| 958 // static | 958 // static |
| 959 gfx::Size RootWindowHost::GetNativeScreenSize() { | 959 gfx::Size RootWindowHost::GetNativeScreenSize() { |
| 960 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); | 960 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); |
| 961 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 961 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
| 962 } | 962 } |
| 963 | 963 |
| 964 } // namespace aura | 964 } // namespace aura |
| OLD | NEW |