| Index: chrome/browser/ui/views/tabs/native_view_photobooth_win.cc | 
| =================================================================== | 
| --- chrome/browser/ui/views/tabs/native_view_photobooth_win.cc	(revision 244941) | 
| +++ chrome/browser/ui/views/tabs/native_view_photobooth_win.cc	(working copy) | 
| @@ -1,165 +0,0 @@ | 
| -// Copyright (c) 2012 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/views/tabs/native_view_photobooth_win.h" | 
| - | 
| -#include "third_party/skia/include/core/SkBitmap.h" | 
| -#include "ui/gfx/canvas.h" | 
| -#include "ui/gfx/point.h" | 
| -#include "ui/gfx/rect.h" | 
| -#include "ui/views/widget/widget.h" | 
| - | 
| -namespace { | 
| - | 
| -static BOOL CALLBACK MonitorEnumProc(HMONITOR monitor, HDC monitor_dc, | 
| -                                     RECT* monitor_rect, LPARAM data) { | 
| -  gfx::Point* point = reinterpret_cast<gfx::Point*>(data); | 
| -  if (monitor_rect->right > point->x() && monitor_rect->bottom > point->y()) { | 
| -    point->set_x(monitor_rect->right); | 
| -    point->set_y(monitor_rect->bottom); | 
| -  } | 
| -  return TRUE; | 
| -} | 
| - | 
| -gfx::Point GetCaptureWindowPosition() { | 
| -  // Since the capture window must be visible to be painted, it must be opened | 
| -  // off screen to avoid flashing. But if it is opened completely off-screen | 
| -  // (e.g. at 0xFFFFx0xFFFF) then on Windows Vista it will not paint even if it | 
| -  // _is_ visible. So we need to find the right/bottommost monitor, and | 
| -  // position it so that 1x1 pixel is on-screen on that monitor which is enough | 
| -  // to convince Vista to paint it. Don't ask why this is so - this appears to | 
| -  // be a regression over XP. | 
| -  gfx::Point point(0, 0); | 
| -  EnumDisplayMonitors(NULL, NULL, &MonitorEnumProc, | 
| -                      reinterpret_cast<LPARAM>(&point)); | 
| -  return gfx::Point(point.x() - 1, point.y() - 1); | 
| -} | 
| - | 
| -}  // namespace | 
| - | 
| -/////////////////////////////////////////////////////////////////////////////// | 
| -// NativeViewPhotoboothWin, public: | 
| - | 
| -// static | 
| -NativeViewPhotobooth* NativeViewPhotobooth::Create( | 
| -    gfx::NativeView initial_view) { | 
| -  return new NativeViewPhotoboothWin(initial_view); | 
| -} | 
| - | 
| -NativeViewPhotoboothWin::NativeViewPhotoboothWin(HWND initial_hwnd) | 
| -    : capture_window_(NULL), | 
| -      current_hwnd_(initial_hwnd) { | 
| -  DCHECK(IsWindow(current_hwnd_)); | 
| -  CreateCaptureWindow(initial_hwnd); | 
| -} | 
| - | 
| -NativeViewPhotoboothWin::~NativeViewPhotoboothWin() { | 
| -  // Detach the attached HWND. The creator of the photo-booth is responsible | 
| -  // for destroying it. | 
| -  Replace(NULL); | 
| -  capture_window_->Close(); | 
| -} | 
| - | 
| -void NativeViewPhotoboothWin::Replace(HWND new_hwnd) { | 
| -  if (IsWindow(current_hwnd_) && | 
| -      GetParent(current_hwnd_) == capture_window_->GetNativeView()) { | 
| -    // We need to hide the window too, so it doesn't show up in the TaskBar or | 
| -    // be parented to the desktop. | 
| -    ShowWindow(current_hwnd_, SW_HIDE); | 
| -    SetParent(current_hwnd_, NULL); | 
| -  } | 
| -  current_hwnd_ = new_hwnd; | 
| - | 
| -  if (IsWindow(new_hwnd)) { | 
| -    // Insert the WebContents into the capture window. | 
| -    SetParent(current_hwnd_, capture_window_->GetNativeView()); | 
| - | 
| -    // Show the window (it may not be visible). This is the only safe way of | 
| -    // doing this. ShowWindow does not work. | 
| -    SetWindowPos(current_hwnd_, NULL, 0, 0, 0, 0, | 
| -                 SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 
| -                     SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER | | 
| -                     SWP_SHOWWINDOW | SWP_NOSIZE); | 
| -  } | 
| -} | 
| - | 
| -void NativeViewPhotoboothWin::PaintScreenshotIntoCanvas( | 
| -    gfx::Canvas* canvas, | 
| -    const gfx::Rect& target_bounds) { | 
| -  // Our contained window may have been re-parented. Make sure it belongs to | 
| -  // us until someone calls Replace(NULL). | 
| -  if (IsWindow(current_hwnd_) && | 
| -      GetParent(current_hwnd_) != capture_window_->GetNativeView()) { | 
| -    Replace(current_hwnd_); | 
| -  } | 
| - | 
| -  // We compel the contained HWND to paint now, synchronously. We do this to | 
| -  // populate the device context with valid and current data. | 
| -  RedrawWindow(current_hwnd_, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); | 
| - | 
| -  // Transfer the contents of the layered capture window to the screen-shot | 
| -  // canvas' DIB. | 
| -  HDC target_dc = canvas->BeginPlatformPaint(); | 
| -  HDC source_dc = GetDC(current_hwnd_); | 
| -  RECT window_rect = {0}; | 
| -  GetWindowRect(current_hwnd_, &window_rect); | 
| -  BitBlt(target_dc, target_bounds.x(), target_bounds.y(), | 
| -         target_bounds.width(), target_bounds.height(), source_dc, 0, 0, | 
| -         SRCCOPY); | 
| -  // Windows screws up the alpha channel on all text it draws, and so we need | 
| -  // to call makeOpaque _after_ the blit to correct for this. | 
| -  skia::MakeOpaque(canvas->sk_canvas(), target_bounds.x(), | 
| -                   target_bounds.y(), target_bounds.width(), | 
| -                   target_bounds.height()); | 
| -  ReleaseDC(current_hwnd_, source_dc); | 
| -  canvas->EndPlatformPaint(); | 
| -} | 
| - | 
| -/////////////////////////////////////////////////////////////////////////////// | 
| -// NativeViewPhotoboothWin, private: | 
| - | 
| -void NativeViewPhotoboothWin::CreateCaptureWindow(HWND initial_hwnd) { | 
| -  // Snapshotting a HWND is tricky - if the HWND is clipped (e.g. positioned | 
| -  // partially off-screen) then just blitting from the HWND' DC to the capture | 
| -  // bitmap would be incorrect, since the capture bitmap would show only the | 
| -  // visible area of the HWND. | 
| -  // | 
| -  // The approach turns out to be to create a second layered window in | 
| -  // hyperspace the to act as a "photo booth." The window is created with the | 
| -  // size of the unclipped HWND, and we attach the HWND as a child, refresh the | 
| -  // HWND' by calling |Paint| on it, and then blitting from the HWND's DC to | 
| -  // the capture bitmap. This results in the entire unclipped HWND display | 
| -  // bitmap being captured. | 
| -  // | 
| -  // The capture window must be layered so that Windows generates a backing | 
| -  // store for it, so that blitting from a child window's DC produces data. If | 
| -  // the window is not layered, because it is off-screen Windows does not | 
| -  // retain its contents and blitting results in blank data. The capture window | 
| -  // is a "basic" (1 level of alpha) layered window because that is the mode | 
| -  // that supports having child windows (variable alpha layered windows do not | 
| -  // support child HWNDs). | 
| -  // | 
| -  // This function sets up the off-screen capture window, and attaches the | 
| -  // associated HWND to it. Note that the details are important here, see below | 
| -  // for further comments. | 
| -  // | 
| -  RECT contents_rect; | 
| -  GetClientRect(initial_hwnd, &contents_rect); | 
| -  gfx::Point window_position = GetCaptureWindowPosition(); | 
| -  gfx::Rect capture_bounds(window_position.x(), window_position.y(), | 
| -                           contents_rect.right - contents_rect.left, | 
| -                           contents_rect.bottom - contents_rect.top); | 
| -  capture_window_ = new views::Widget; | 
| -  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 
| -  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 
| -  params.bounds = capture_bounds; | 
| -  capture_window_->Init(params); | 
| -  // If the capture window isn't visible, blitting from the WebContents's | 
| -  // HWND's DC to the capture bitmap produces blankness. | 
| -  capture_window_->Show(); | 
| -  SetLayeredWindowAttributes( | 
| -      capture_window_->GetNativeView(), RGB(0xFF, 0xFF, 0xFF), 0xFF, LWA_ALPHA); | 
| - | 
| -  Replace(initial_hwnd); | 
| -} | 
|  |