Index: ui/aura/root_window_host_wayland.cc |
diff --git a/ui/aura/root_window_host_wayland.cc b/ui/aura/root_window_host_wayland.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c27f2cd603ab5d51f890d0b244a222af4dd037ad |
--- /dev/null |
+++ b/ui/aura/root_window_host_wayland.cc |
@@ -0,0 +1,287 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/aura/root_window_host_wayland.h" |
+ |
+#include <strings.h> |
+ |
+#include <algorithm> |
+#include <limits> |
+#include <string> |
+ |
+#include "base/wayland/wayland_event.h" |
+#include "ui/wayland/wayland_screen.h" |
+#include "base/command_line.h" |
+#include "base/message_loop.h" |
+#include "base/message_pump_wayland.h" |
+#include "base/stl_util.h" |
+#include "base/string_number_conversions.h" |
+#include "base/string_util.h" |
+#include "base/stringprintf.h" |
+#include "ui/aura/client/capture_client.h" |
+#include "ui/aura/client/cursor_client.h" |
+#include "ui/aura/client/screen_position_client.h" |
+#include "ui/aura/client/user_action_client.h" |
+#include "ui/aura/env.h" |
+#include "ui/aura/root_window.h" |
+#include "ui/base/cursor/cursor.h" |
+#include "ui/base/events/event.h" |
+#include "ui/base/events/event_utils.h" |
+#include "ui/base/keycodes/keyboard_codes.h" |
+#include "ui/base/touch/touch_factory_x11.h" |
+#include "ui/base/ui_base_switches.h" |
+#include "ui/base/view_prop.h" |
+#include "ui/compositor/dip_util.h" |
+#include "ui/compositor/layer.h" |
+#include "ui/gfx/codec/png_codec.h" |
+#include "ui/gfx/screen.h" |
+ |
+#if defined(OS_CHROMEOS) |
+#include "base/chromeos/chromeos_version.h" |
+#endif |
+ |
+using std::max; |
+using std::min; |
+ |
+namespace aura { |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// RootWindowHostWayland |
+ |
+RootWindowHostWayland::RootWindowHostWayland(const gfx::Rect& bounds) |
+ : delegate_(NULL), |
+ display_(ui::WaylandDisplay::GetDisplay()), |
+ current_cursor_(ui::kCursorNull), |
+ bounds_(bounds), |
+ focus_when_shown_(false) { |
+ |
+ window_ = new ui::WaylandWindow(NULL, display_); |
+ window_->SetParentWindow(NULL); |
+ window_->SetBounds(bounds_); |
+ |
+ base::MessagePumpWayland::Current()->AddDispatcherForWindow(this, window_); |
+ base::MessagePumpWayland::Current()->AddDispatcherForRootWindow(this); |
+ |
+ Env::GetInstance()->AddObserver(this); |
+} |
+ |
+RootWindowHostWayland::~RootWindowHostWayland() { |
+ Env::GetInstance()->RemoveObserver(this); |
+ base::MessagePumpWayland::Current()->RemoveDispatcherForRootWindow(this); |
+ base::MessagePumpWayland::Current()->RemoveDispatcherForWindow(window_); |
+ |
+ delete window_; |
+} |
+ |
+bool RootWindowHostWayland::Dispatch(const base::NativeEvent& event) { |
+ return true; |
+} |
+ |
+void RootWindowHostWayland::SetDelegate(RootWindowHostDelegate* delegate) { |
+ delegate_ = delegate; |
+} |
+ |
+RootWindow* RootWindowHostWayland::GetRootWindow() { |
+ return delegate_->AsRootWindow(); |
+} |
+ |
+gfx::AcceleratedWidget RootWindowHostWayland::GetAcceleratedWidget() { |
+ return window_; |
+} |
+ |
+void RootWindowHostWayland::Show() { |
+ window_->ScheduleRedraw(); |
+} |
+ |
+void RootWindowHostWayland::Hide() { |
+} |
+ |
+void RootWindowHostWayland::ToggleFullScreen() { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+gfx::Rect RootWindowHostWayland::GetBounds() const { |
+ return bounds_; |
+} |
+ |
+void RootWindowHostWayland::SetBounds(const gfx::Rect& bounds) { |
+ // Even if the host window's size doesn't change, aura's root window |
+ // size, which is in DIP, changes when the scale changes. |
+ float current_scale = delegate_->GetDeviceScaleFactor(); |
+ float new_scale = gfx::Screen::GetScreenFor(delegate_->AsRootWindow())-> |
+ GetDisplayNearestWindow(delegate_->AsRootWindow()).device_scale_factor(); |
+ bool origin_changed = bounds_.origin() != bounds.origin(); |
+ bool size_changed = bounds_.size() != bounds.size(); |
+ |
+ // Assume that the resize will go through as requested, which should be the |
+ // case if we're running without a window manager. If there's a window |
+ // manager, it can modify or ignore the request, but (per ICCCM) we'll get a |
+ // (possibly synthetic) ConfigureNotify about the actual size and correct |
+ // |bounds_| later. |
+ bounds_ = bounds; |
+ UpdateIsInternalDisplay(); |
+ if (origin_changed) |
+ delegate_->OnHostMoved(bounds.origin()); |
+ if (size_changed || current_scale != new_scale) { |
+ delegate_->OnHostResized(bounds.size()); |
+ } else { |
+ delegate_->AsRootWindow()->SchedulePaintInRect( |
+ delegate_->AsRootWindow()->bounds()); |
+ } |
+ |
+ window_->SetBounds(bounds_); |
+} |
+ |
+gfx::Insets RootWindowHostWayland::GetInsets() const { |
+ return insets_; |
+} |
+ |
+void RootWindowHostWayland::SetInsets(const gfx::Insets& insets) { |
+ insets_ = insets; |
+} |
+ |
+gfx::Point RootWindowHostWayland::GetLocationOnNativeScreen() const { |
+ return bounds_.origin(); |
+} |
+ |
+void RootWindowHostWayland::SetCapture() { |
+ // TODO(oshima): Grab x input. |
+} |
+ |
+void RootWindowHostWayland::ReleaseCapture() { |
+ // TODO(oshima): Release x input. |
+} |
+ |
+void RootWindowHostWayland::SetCursor(gfx::NativeCursor cursor) { |
+ if (cursor == current_cursor_) |
+ return; |
+ current_cursor_ = cursor; |
+ SetCursorInternal(cursor); |
+} |
+ |
+bool RootWindowHostWayland::QueryMouseLocation(gfx::Point* location_return) { |
+ return false; |
+} |
+ |
+bool RootWindowHostWayland::ConfineCursorToRootWindow() { |
+ return true; |
+} |
+ |
+void RootWindowHostWayland::UnConfineCursor() { |
+} |
+ |
+void RootWindowHostWayland::OnCursorVisibilityChanged(bool show) { |
+} |
+ |
+void RootWindowHostWayland::MoveCursorTo(const gfx::Point& location) { |
+} |
+ |
+void RootWindowHostWayland::SetFocusWhenShown(bool focus_when_shown) { |
+} |
+ |
+bool RootWindowHostWayland::CopyAreaToSkCanvas(const gfx::Rect& source_bounds, |
+ const gfx::Point& dest_offset, |
+ SkCanvas* canvas) { |
+ NOTIMPLEMENTED(); |
+ return false; |
+} |
+ |
+bool RootWindowHostWayland::GrabSnapshot( |
+ const gfx::Rect& snapshot_bounds, |
+ std::vector<unsigned char>* png_representation) { |
+ return false; |
+} |
+ |
+void RootWindowHostWayland::PostNativeEvent( |
+ const base::NativeEvent& native_event) { |
+ DCHECK(window_); |
+ DCHECK(display_); |
+ |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RootWindowHostWayland::OnDeviceScaleFactorChanged( |
+ float device_scale_factor) { |
+} |
+ |
+void RootWindowHostWayland::PrepareForShutdown() { |
+ base::MessagePumpWayland::Current()->RemoveDispatcherForWindow(window_); |
+} |
+ |
+void RootWindowHostWayland::OnWindowInitialized(Window* window) { |
+} |
+ |
+void RootWindowHostWayland::OnRootWindowInitialized(RootWindow* root_window) { |
+ // UpdateIsInternalDisplay relies on: |
+ // 1. delegate_ pointing to RootWindow - available after SetDelegate. |
+ // 2. RootWindow's kDisplayIdKey property set - available by the time |
+ // RootWindow::Init is called. |
+ // (set in DisplayManager::CreateRootWindowForDisplay) |
+ // Ready when NotifyRootWindowInitialized is called from RootWindow::Init. |
+ if (!delegate_ || root_window != GetRootWindow()) |
+ return; |
+ UpdateIsInternalDisplay(); |
+} |
+ |
+bool RootWindowHostWayland::DispatchEventForRootWindow( |
+ const base::NativeEvent& event) { |
+ NOTIMPLEMENTED(); |
+ |
+ return true; |
+} |
+ |
+bool RootWindowHostWayland::IsWindowManagerPresent() { |
+ return true; |
+} |
+ |
+void RootWindowHostWayland::SetCursorInternal(gfx::NativeCursor cursor) { |
+} |
+ |
+void RootWindowHostWayland::TranslateAndDispatchMouseEvent( |
+ ui::MouseEvent* event) { |
+ RootWindow* root_window = GetRootWindow(); |
+ client::ScreenPositionClient* screen_position_client = |
+ GetScreenPositionClient(root_window); |
+ gfx::Rect local(bounds_.size()); |
+ |
+ if (screen_position_client && !local.Contains(event->location())) { |
+ gfx::Point location(event->location()); |
+ // In order to get the correct point in screen coordinates |
+ // during passive grab, we first need to find on which host window |
+ // the mouse is on, and find out the screen coordinates on that |
+ // host window, then convert it back to this host window's coordinate. |
+ screen_position_client->ConvertHostPointToScreen(root_window, &location); |
+ screen_position_client->ConvertPointFromScreen(root_window, &location); |
+ root_window->ConvertPointToHost(&location); |
+ event->set_location(location); |
+ event->set_root_location(location); |
+ } |
+ delegate_->OnHostMouseEvent(event); |
+} |
+ |
+void RootWindowHostWayland::UpdateIsInternalDisplay() { |
+ RootWindow* root_window = GetRootWindow(); |
+ gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window); |
+ gfx::Display display = screen->GetDisplayNearestWindow(root_window); |
+ is_internal_display_ = display.IsInternal(); |
+} |
+ |
+// static |
+RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { |
+ return new RootWindowHostWayland(bounds); |
+} |
+ |
+// static |
+gfx::Size RootWindowHost::GetNativeScreenSize() { |
+ ui::WaylandDisplay *d = base::MessagePumpWayland::GetDefaultWaylandDisplay(); |
+ std::list<ui::WaylandScreen*> list = d->GetScreenList(); |
+ |
+ if(list.size() < 1) |
+ return gfx::Size(); |
+ |
+ ui::WaylandScreen *screen = list.front(); |
+ return screen->GetAllocation().size(); |
+} |
+ |
+} // namespace aura |