summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/window_snapshot
diff options
context:
space:
mode:
authormsw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-03 06:01:16 +0000
committermsw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-03 06:01:16 +0000
commit75b6805083c906bb17192a738b311bd21791e9f8 (patch)
treebce38efec20d50a7ef55a694f58036ae365d5e0a /chrome/browser/ui/window_snapshot
parent2aa8b71eb688aa13a4f745027bcd4bb726bf6663 (diff)
downloadchromium_src-75b6805083c906bb17192a738b311bd21791e9f8.zip
chromium_src-75b6805083c906bb17192a738b311bd21791e9f8.tar.gz
chromium_src-75b6805083c906bb17192a738b311bd21791e9f8.tar.bz2
Cross-platform CL to remove app/win/win_util.h&cc and related work.
See Issue 70141 for the full move details; see my inline review comments. Changes significantly different from or beyond those prescribed by the bug: *Consolidated a lot of GrabWindowSnapshot code. *Moved EnsureRectIsVisibleInRect to views::internal namespace for test access. *Moved app/win/win_util_unittest.cc to views/window/window_win_unittest.h *Named ui/base/message_box_win.h instead of ui/base/message_box.h *Made WindowWin::GetWindowTitleFont static; needed in static contexts. *Denoted WindowWin::FrameTypeChanged as a Window override, moved code. *Moved TestGrabWindowSnapshot into new file: chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm BUG=70141 TEST=none Review URL: http://codereview.chromium.org/6386009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73589 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui/window_snapshot')
-rwxr-xr-xchrome/browser/ui/window_snapshot/window_snapshot.h26
-rwxr-xr-xchrome/browser/ui/window_snapshot/window_snapshot_mac.mm44
-rwxr-xr-xchrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm49
-rwxr-xr-xchrome/browser/ui/window_snapshot/window_snapshot_win.cc72
-rwxr-xr-xchrome/browser/ui/window_snapshot/window_snapshot_x.cc66
5 files changed, 257 insertions, 0 deletions
diff --git a/chrome/browser/ui/window_snapshot/window_snapshot.h b/chrome/browser/ui/window_snapshot/window_snapshot.h
new file mode 100755
index 0000000..3372009
--- /dev/null
+++ b/chrome/browser/ui/window_snapshot/window_snapshot.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2011 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.
+
+#ifndef CHROME_BROWSER_UI_WINDOW_SNAPSHOT_WINDOW_SNAPSHOT_H_
+#define CHROME_BROWSER_UI_WINDOW_SNAPSHOT_WINDOW_SNAPSHOT_H_
+#pragma once
+
+#include <vector>
+
+#include "gfx/native_widget_types.h"
+
+namespace gfx {
+ class Rect;
+}
+
+namespace browser {
+
+// Grabs a snapshot of the designated window and stores a PNG representation
+// into a byte vector. Returns the image bounds.
+gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window,
+ std::vector<unsigned char>* png_representation);
+
+} // namespace browser
+
+#endif // CHROME_BROWSER_UI_WINDOW_SNAPSHOT_WINDOW_SNAPSHOT_H_
diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_mac.mm b/chrome/browser/ui/window_snapshot/window_snapshot_mac.mm
new file mode 100755
index 0000000..deb7220
--- /dev/null
+++ b/chrome/browser/ui/window_snapshot/window_snapshot_mac.mm
@@ -0,0 +1,44 @@
+// Copyright (c) 2011 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 "chrome/browser/ui/window_snapshot/window_snapshot.h"
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/logging.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/scoped_nsobject.h"
+#include "gfx/rect.h"
+
+namespace browser {
+
+gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window,
+ std::vector<unsigned char>* png_representation) {
+ png_representation->clear();
+
+ // Make sure to grab the "window frame" view so we get current tab +
+ // tabstrip.
+ NSView* view = [[window contentView] superview];
+ base::mac::ScopedCFTypeRef<CGImageRef> windowSnapshot(CGWindowListCreateImage(
+ CGRectNull, kCGWindowListOptionIncludingWindow,
+ [[view window] windowNumber], kCGWindowImageBoundsIgnoreFraming));
+ if (CGImageGetWidth(windowSnapshot) <= 0)
+ return gfx::Rect();
+
+ scoped_nsobject<NSBitmapImageRep> rep(
+ [[NSBitmapImageRep alloc] initWithCGImage:windowSnapshot]);
+ NSData* data = [rep representationUsingType:NSPNGFileType properties:nil];
+ const unsigned char* buf = static_cast<const unsigned char*>([data bytes]);
+ NSUInteger length = [data length];
+ if (buf == NULL || length == 0)
+ return gfx::Rect();
+
+ png_representation->assign(buf, buf + length);
+ DCHECK(png_representation->size() > 0);
+
+ return gfx::Rect(static_cast<int>([rep pixelsWide]),
+ static_cast<int>([rep pixelsHigh]));
+}
+
+} // namespace browser
diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm b/chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm
new file mode 100755
index 0000000..a7a377b
--- /dev/null
+++ b/chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm
@@ -0,0 +1,49 @@
+// Copyright (c) 2011 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 "chrome/browser/ui/window_snapshot/window_snapshot.h"
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/scoped_nsobject.h"
+#include "base/scoped_ptr.h"
+#include "base/test/mock_chrome_application_mac.h"
+#include "gfx/rect.h"
+#include "testing/platform_test.h"
+
+namespace browser {
+namespace {
+
+typedef PlatformTest GrabWindowSnapshotTest;
+
+TEST_F(GrabWindowSnapshotTest, TestGrabWindowSnapshot) {
+ // Launch a test window so we can take a snapshot.
+ NSRect frame = NSMakeRect(0, 0, 400, 400);
+ scoped_nsobject<NSWindow> window(
+ [[NSWindow alloc] initWithContentRect:frame
+ styleMask:NSBorderlessWindowMask
+ backing:NSBackingStoreBuffered
+ defer:NO]);
+ [window setBackgroundColor:[NSColor whiteColor]];
+ [window makeKeyAndOrderFront:NSApp];
+
+ scoped_ptr<std::vector<unsigned char> > png_representation(
+ new std::vector<unsigned char>);
+ browser::GrabWindowSnapshot(window, png_representation.get());
+
+ // Copy png back into NSData object so we can make sure we grabbed a png.
+ scoped_nsobject<NSData> image_data(
+ [[NSData alloc] initWithBytes:&(*png_representation)[0]
+ length:png_representation->size()]);
+ NSBitmapImageRep* rep = [NSBitmapImageRep imageRepWithData:image_data.get()];
+ EXPECT_TRUE([rep isKindOfClass:[NSBitmapImageRep class]]);
+ EXPECT_TRUE(CGImageGetWidth([rep CGImage]) == 400);
+ NSColor* color = [rep colorAtX:200 y:200];
+ CGFloat red = 0, green = 0, blue = 0, alpha = 0;
+ [color getRed:&red green:&green blue:&blue alpha:&alpha];
+ EXPECT_GE(red + green + blue, 3.0);
+}
+
+} // namespace
+} // namespace browser
diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_win.cc b/chrome/browser/ui/window_snapshot/window_snapshot_win.cc
new file mode 100755
index 0000000..66e0071
--- /dev/null
+++ b/chrome/browser/ui/window_snapshot/window_snapshot_win.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2011 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 "chrome/browser/ui/window_snapshot/window_snapshot.h"
+
+#include "base/win/scoped_gdi_object.h"
+#include "base/win/scoped_hdc.h"
+#include "gfx/codec/png_codec.h"
+#include "gfx/gdi_util.h"
+#include "gfx/rect.h"
+
+namespace browser {
+
+gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window_handle,
+ std::vector<unsigned char>* png_representation) {
+ // Create a memory DC that's compatible with the window.
+ HDC window_hdc = GetWindowDC(window_handle);
+ base::win::ScopedHDC mem_hdc(CreateCompatibleDC(window_hdc));
+
+ // Create a DIB that's the same size as the window.
+ RECT content_rect = {0, 0, 0, 0};
+ ::GetWindowRect(window_handle, &content_rect);
+ content_rect.right++; // Match what PrintWindow wants.
+ int width = content_rect.right - content_rect.left;
+ int height = content_rect.bottom - content_rect.top;
+ BITMAPINFOHEADER hdr;
+ gfx::CreateBitmapHeader(width, height, &hdr);
+ unsigned char *bit_ptr = NULL;
+ base::win::ScopedBitmap bitmap(
+ CreateDIBSection(mem_hdc,
+ reinterpret_cast<BITMAPINFO*>(&hdr),
+ DIB_RGB_COLORS,
+ reinterpret_cast<void **>(&bit_ptr),
+ NULL, 0));
+
+ SelectObject(mem_hdc, bitmap);
+ // Clear the bitmap to white (so that rounded corners on windows
+ // show up on a white background, and strangely-shaped windows
+ // look reasonable). Not capturing an alpha mask saves a
+ // bit of space.
+ PatBlt(mem_hdc, 0, 0, width, height, WHITENESS);
+ // Grab a copy of the window
+ // First, see if PrintWindow is defined (it's not in Windows 2000).
+ typedef BOOL (WINAPI *PrintWindowPointer)(HWND, HDC, UINT);
+ PrintWindowPointer print_window =
+ reinterpret_cast<PrintWindowPointer>(
+ GetProcAddress(GetModuleHandle(L"User32.dll"), "PrintWindow"));
+
+ // If PrintWindow is defined, use it. It will work on partially
+ // obscured windows, and works better for out of process sub-windows.
+ // Otherwise grab the bits we can get with BitBlt; it's better
+ // than nothing and will work fine in the average case (window is
+ // completely on screen).
+ if (print_window)
+ (*print_window)(window_handle, mem_hdc, 0);
+ else
+ BitBlt(mem_hdc, 0, 0, width, height, window_hdc, 0, 0, SRCCOPY);
+
+ // We now have a copy of the window contents in a DIB, so
+ // encode it into a useful format for posting to the bug report
+ // server.
+ gfx::PNGCodec::Encode(bit_ptr, gfx::PNGCodec::FORMAT_BGRA,
+ width, height, width * 4, true,
+ png_representation);
+
+ ReleaseDC(window_handle, window_hdc);
+
+ return gfx::Rect(width, height);
+}
+
+} // namespace browser
diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_x.cc b/chrome/browser/ui/window_snapshot/window_snapshot_x.cc
new file mode 100755
index 0000000..48f8169
--- /dev/null
+++ b/chrome/browser/ui/window_snapshot/window_snapshot_x.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2011 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 "chrome/browser/ui/window_snapshot/window_snapshot.h"
+
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include "base/logging.h"
+#include "gfx/rect.h"
+#include "ui/base/x/x11_util.h"
+
+namespace browser {
+
+static cairo_status_t SnapshotCallback(
+ void *closure, const unsigned char *data, unsigned int length) {
+ std::vector<unsigned char>* png_representation =
+ static_cast<std::vector<unsigned char>*>(closure);
+
+ size_t old_size = png_representation->size();
+ png_representation->resize(old_size + length);
+ memcpy(&(*png_representation)[old_size], data, length);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+gfx::Rect GrabWindowSnapshot(gfx::NativeWindow gtk_window,
+ std::vector<unsigned char>* png_representation) {
+ GdkWindow* gdk_window = GTK_WIDGET(gtk_window)->window;
+ Display* display = GDK_WINDOW_XDISPLAY(gdk_window);
+ XID win = GDK_WINDOW_XID(gdk_window);
+ XWindowAttributes attr;
+ if (XGetWindowAttributes(display, win, &attr) == 0) {
+ LOG(ERROR) << "Couldn't get window attributes";
+ return gfx::Rect();
+ }
+ XImage* image = XGetImage(
+ display, win, 0, 0, attr.width, attr.height, AllPlanes, ZPixmap);
+ if (!image) {
+ LOG(ERROR) << "Couldn't get image";
+ return gfx::Rect();
+ }
+ if (image->depth != 24) {
+ LOG(ERROR)<< "Unsupported image depth " << image->depth;
+ return gfx::Rect();
+ }
+ cairo_surface_t* surface =
+ cairo_image_surface_create_for_data(
+ reinterpret_cast<unsigned char*>(image->data),
+ CAIRO_FORMAT_RGB24,
+ image->width,
+ image->height,
+ image->bytes_per_line);
+
+ if (!surface) {
+ LOG(ERROR) << "Unable to create Cairo surface from XImage data";
+ return gfx::Rect();
+ }
+ cairo_surface_write_to_png_stream(
+ surface, SnapshotCallback, png_representation);
+ cairo_surface_destroy(surface);
+
+ return gfx::Rect(image->width, image->height);
+}
+
+} // namespace browser