Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Unified Diff: ui/aura/root_window_host_linux.cc

Issue 11273059: ash: Clean up system background layer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update window id Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/aura/root_window_host_linux.h ('k') | ui/aura/root_window_host_mac.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/aura/root_window_host_linux.cc
diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc
index e6b61c1fed9c5a08372fec0391f57898200bb820..63dc4cf1808ecbca80918335752d6672680b219d 100644
--- a/ui/aura/root_window_host_linux.cc
+++ b/ui/aura/root_window_host_linux.cc
@@ -4,6 +4,7 @@
#include "ui/aura/root_window_host_linux.h"
+#include <strings.h>
#include <X11/cursorfont.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/XInput2.h>
@@ -11,6 +12,7 @@
#include <X11/Xatom.h>
#include <X11/Xcursor/Xcursor.h>
#include <X11/Xlib.h>
+
#include <algorithm>
#include "base/command_line.h"
@@ -18,6 +20,8 @@
#include "base/message_pump_aurax11.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/client/screen_position_client.h"
@@ -432,123 +436,6 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
return true;
}
-bool RootWindowHostLinux::DispatchEventForRootWindow(
- const base::NativeEvent& event) {
- switch (event->type) {
- case ConfigureNotify:
- DCHECK_EQ(x_root_window_, event->xconfigure.event);
- x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y,
- event->xconfigure.width, event->xconfigure.height);
- break;
-
- case GenericEvent:
- DispatchXI2Event(event);
- break;
- }
-
- return true;
-}
-
-void RootWindowHostLinux::DispatchXI2Event(const base::NativeEvent& event) {
- ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
- XEvent* xev = event;
- if (!factory->ShouldProcessXI2Event(xev))
- return;
-
- ui::EventType type = ui::EventTypeFromNative(xev);
- XEvent last_event;
- int num_coalesced = 0;
-
- switch (type) {
- case ui::ET_TOUCH_MOVED:
- num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
- if (num_coalesced > 0)
- xev = &last_event;
- // fallthrough
- case ui::ET_TOUCH_PRESSED:
- case ui::ET_TOUCH_RELEASED: {
- ui::TouchEvent touchev(xev);
-#if defined(OS_CHROMEOS)
- // X maps the touch-surface to the size of the X root-window. In
- // multi-monitor setup, the X root-window size is a combination of
- // both the monitor sizes. So it is necessary to remap the location of
- // the event from the X root-window to the X host-window for the aura
- // root-window.
- if (base::chromeos::IsRunningOnChromeOS()) {
- touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size());
- if (!bounds_.Contains(touchev.location())) {
- // This might still be in the bezel region.
- gfx::Rect expanded(bounds_);
- expanded.Inset(-kXRootWindowPaddingLeft,
- -kXRootWindowPaddingTop,
- -kXRootWindowPaddingRight,
- -kXRootWindowPaddingBottom);
- if (!expanded.Contains(touchev.location()))
- break;
- }
- }
-#endif // defined(OS_CHROMEOS)
- delegate_->OnHostTouchEvent(&touchev);
- break;
- }
- case ui::ET_MOUSE_MOVED:
- case ui::ET_MOUSE_DRAGGED:
- case ui::ET_MOUSE_PRESSED:
- case ui::ET_MOUSE_RELEASED:
- case ui::ET_MOUSE_ENTERED:
- case ui::ET_MOUSE_EXITED: {
- if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) {
- // If this is a motion event, we want to coalesce all pending motion
- // events that are at the top of the queue.
- num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
- if (num_coalesced > 0)
- xev = &last_event;
- } else if (type == ui::ET_MOUSE_PRESSED) {
- XIDeviceEvent* xievent =
- static_cast<XIDeviceEvent*>(xev->xcookie.data);
- int button = xievent->detail;
- if (button == kBackMouseButton || button == kForwardMouseButton) {
- client::UserActionClient* gesture_client =
- client::GetUserActionClient(delegate_->AsRootWindow());
- if (gesture_client) {
- bool reverse_direction =
- ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled();
- gesture_client->OnUserAction(
- (button == kBackMouseButton && !reverse_direction) ||
- (button == kForwardMouseButton && reverse_direction) ?
- client::UserActionClient::BACK :
- client::UserActionClient::FORWARD);
- }
- break;
- }
- }
- ui::MouseEvent mouseev(xev);
- TranslateAndDispatchMouseEvent(&mouseev);
- break;
- }
- case ui::ET_MOUSEWHEEL: {
- ui::MouseWheelEvent mouseev(xev);
- TranslateAndDispatchMouseEvent(&mouseev);
- break;
- }
- case ui::ET_SCROLL_FLING_START:
- case ui::ET_SCROLL_FLING_CANCEL:
- case ui::ET_SCROLL: {
- ui::ScrollEvent scrollev(xev);
- delegate_->OnHostScrollEvent(&scrollev);
- break;
- }
- case ui::ET_UNKNOWN:
- break;
- default:
- NOTREACHED();
- }
-
- // If we coalesced an event we need to free its cookie.
- if (num_coalesced > 0)
- XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
-}
-
void RootWindowHostLinux::SetDelegate(RootWindowHostDelegate* delegate) {
delegate_ = delegate;
}
@@ -741,19 +628,53 @@ void RootWindowHostLinux::SetFocusWhenShown(bool focus_when_shown) {
}
}
+bool RootWindowHostLinux::CopyAreaToSkCanvas(const gfx::Rect& source_bounds,
+ const gfx::Point& dest_offset,
+ SkCanvas* canvas) {
+ scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(source_bounds));
+ if (!scoped_image.get())
+ return false;
+
+ XImage* image = scoped_image->get();
+ DCHECK(image);
+
+ if (image->bits_per_pixel == 32) {
+ // Set the alpha channel before copying to the canvas. Otherwise, areas of
+ // the framebuffer that were cleared by ply-image rather than being obscured
+ // by an image during boot may end up transparent.
+ // TODO(derat|marcheu): Remove this if/when ply-image has been updated to
+ // set the framebuffer's alpha channel regardless of whether the device
+ // claims to support alpha or not.
+ for (int i = 0; i < image->width * image->height * 4; i += 4)
+ image->data[i + 3] = 0xff;
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ image->width, image->height,
+ image->bytes_per_line);
+ bitmap.setPixels(image->data);
+ SkCanvas::Config8888 config =
+ (image->byte_order == LSBFirst) ?
+ SkCanvas::kBGRA_Unpremul_Config8888 :
+ SkCanvas::kRGBA_Unpremul_Config8888;
+ canvas->writePixels(bitmap, dest_offset.x(), dest_offset.y(), config);
+ } else if (image->bits_per_pixel == 24) {
+ NOTIMPLEMENTED() << "Unsupported bits-per-pixel " << image->bits_per_pixel;
+ return false;
+ }
+
+ return true;
+}
+
bool RootWindowHostLinux::GrabSnapshot(
const gfx::Rect& snapshot_bounds,
std::vector<unsigned char>* png_representation) {
- ui::XScopedImage image(XGetImage(
- xdisplay_, xwindow_,
- snapshot_bounds.x(), snapshot_bounds.y(),
- snapshot_bounds.width(), snapshot_bounds.height(),
- AllPlanes, ZPixmap));
-
- if (!image.get()) {
- LOG(ERROR) << "XGetImage failed";
+ scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(snapshot_bounds));
+ if (!scoped_image.get())
return false;
- }
+
+ XImage* image = scoped_image->get();
+ DCHECK(image);
gfx::PNGCodec::ColorFormat color_format;
@@ -827,6 +748,123 @@ void RootWindowHostLinux::PrepareForShutdown() {
base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
}
+bool RootWindowHostLinux::DispatchEventForRootWindow(
Daniel Erat 2012/10/26 00:41:15 sorry, moved this code without any changes to it t
+ const base::NativeEvent& event) {
+ switch (event->type) {
+ case ConfigureNotify:
+ DCHECK_EQ(x_root_window_, event->xconfigure.event);
+ x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y,
+ event->xconfigure.width, event->xconfigure.height);
+ break;
+
+ case GenericEvent:
+ DispatchXI2Event(event);
+ break;
+ }
+
+ return true;
+}
+
+void RootWindowHostLinux::DispatchXI2Event(const base::NativeEvent& event) {
+ ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
+ XEvent* xev = event;
+ if (!factory->ShouldProcessXI2Event(xev))
+ return;
+
+ ui::EventType type = ui::EventTypeFromNative(xev);
+ XEvent last_event;
+ int num_coalesced = 0;
+
+ switch (type) {
+ case ui::ET_TOUCH_MOVED:
+ num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
+ if (num_coalesced > 0)
+ xev = &last_event;
+ // fallthrough
+ case ui::ET_TOUCH_PRESSED:
+ case ui::ET_TOUCH_RELEASED: {
+ ui::TouchEvent touchev(xev);
+#if defined(OS_CHROMEOS)
+ // X maps the touch-surface to the size of the X root-window. In
+ // multi-monitor setup, the X root-window size is a combination of
+ // both the monitor sizes. So it is necessary to remap the location of
+ // the event from the X root-window to the X host-window for the aura
+ // root-window.
+ if (base::chromeos::IsRunningOnChromeOS()) {
+ touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size());
+ if (!bounds_.Contains(touchev.location())) {
+ // This might still be in the bezel region.
+ gfx::Rect expanded(bounds_);
+ expanded.Inset(-kXRootWindowPaddingLeft,
+ -kXRootWindowPaddingTop,
+ -kXRootWindowPaddingRight,
+ -kXRootWindowPaddingBottom);
+ if (!expanded.Contains(touchev.location()))
+ break;
+ }
+ }
+#endif // defined(OS_CHROMEOS)
+ delegate_->OnHostTouchEvent(&touchev);
+ break;
+ }
+ case ui::ET_MOUSE_MOVED:
+ case ui::ET_MOUSE_DRAGGED:
+ case ui::ET_MOUSE_PRESSED:
+ case ui::ET_MOUSE_RELEASED:
+ case ui::ET_MOUSE_ENTERED:
+ case ui::ET_MOUSE_EXITED: {
+ if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) {
+ // If this is a motion event, we want to coalesce all pending motion
+ // events that are at the top of the queue.
+ num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
+ if (num_coalesced > 0)
+ xev = &last_event;
+ } else if (type == ui::ET_MOUSE_PRESSED) {
+ XIDeviceEvent* xievent =
+ static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ int button = xievent->detail;
+ if (button == kBackMouseButton || button == kForwardMouseButton) {
+ client::UserActionClient* gesture_client =
+ client::GetUserActionClient(delegate_->AsRootWindow());
+ if (gesture_client) {
+ bool reverse_direction =
+ ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled();
+ gesture_client->OnUserAction(
+ (button == kBackMouseButton && !reverse_direction) ||
+ (button == kForwardMouseButton && reverse_direction) ?
+ client::UserActionClient::BACK :
+ client::UserActionClient::FORWARD);
+ }
+ break;
+ }
+ }
+ ui::MouseEvent mouseev(xev);
+ TranslateAndDispatchMouseEvent(&mouseev);
+ break;
+ }
+ case ui::ET_MOUSEWHEEL: {
+ ui::MouseWheelEvent mouseev(xev);
+ TranslateAndDispatchMouseEvent(&mouseev);
+ break;
+ }
+ case ui::ET_SCROLL_FLING_START:
+ case ui::ET_SCROLL_FLING_CANCEL:
+ case ui::ET_SCROLL: {
+ ui::ScrollEvent scrollev(xev);
+ delegate_->OnHostScrollEvent(&scrollev);
+ break;
+ }
+ case ui::ET_UNKNOWN:
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ // If we coalesced an event we need to free its cookie.
+ if (num_coalesced > 0)
+ XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
+}
+
bool RootWindowHostLinux::IsWindowManagerPresent() {
// Per ICCCM 2.8, "Manager Selections", window managers should take ownership
// of WM_Sn selections (where n is a screen number).
@@ -856,6 +894,20 @@ void RootWindowHostLinux::TranslateAndDispatchMouseEvent(
delegate_->OnHostMouseEvent(event);
}
+scoped_ptr<ui::XScopedImage> RootWindowHostLinux::GetXImage(
+ const gfx::Rect& snapshot_bounds) {
+ scoped_ptr<ui::XScopedImage> image(new ui::XScopedImage(
+ XGetImage(xdisplay_, xwindow_,
+ snapshot_bounds.x(), snapshot_bounds.y(),
+ snapshot_bounds.width(), snapshot_bounds.height(),
+ AllPlanes, ZPixmap)));
+ if (!image->get()) {
+ LOG(ERROR) << "XGetImage failed";
+ image.reset();
+ }
+ return image.Pass();
+}
+
// static
RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) {
return new RootWindowHostLinux(bounds);
« no previous file with comments | « ui/aura/root_window_host_linux.h ('k') | ui/aura/root_window_host_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698