| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "webkit/tools/test_shell/webwidget_host.h" | 5 #include "webkit/tools/test_shell/webwidget_host.h" |
| 6 | 6 |
| 7 #include "base/gfx/platform_canvas.h" |
| 7 #include "base/gfx/platform_canvas_win.h" | 8 #include "base/gfx/platform_canvas_win.h" |
| 8 #include "base/gfx/rect.h" | 9 #include "base/gfx/rect.h" |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/win_util.h" | 11 #include "base/win_util.h" |
| 11 #include "webkit/glue/webinputevent.h" | 12 #include "webkit/glue/webinputevent.h" |
| 12 #include "webkit/glue/webwidget.h" | 13 #include "webkit/glue/webwidget.h" |
| 13 | 14 |
| 14 static const wchar_t kWindowClassName[] = L"WebWidgetHost"; | 15 static const wchar_t kWindowClassName[] = L"WebWidgetHost"; |
| 15 | 16 |
| 16 /*static*/ | 17 /*static*/ |
| 17 WebWidgetHost* WebWidgetHost::Create(HWND parent_window, WebWidgetDelegate* dele
gate) { | 18 WebWidgetHost* WebWidgetHost::Create(gfx::WindowHandle parent_window, |
| 19 WebWidgetDelegate* delegate) { |
| 18 WebWidgetHost* host = new WebWidgetHost(); | 20 WebWidgetHost* host = new WebWidgetHost(); |
| 19 | 21 |
| 20 static bool registered_class = false; | 22 static bool registered_class = false; |
| 21 if (!registered_class) { | 23 if (!registered_class) { |
| 22 WNDCLASSEX wcex = {0}; | 24 WNDCLASSEX wcex = {0}; |
| 23 wcex.cbSize = sizeof(wcex); | 25 wcex.cbSize = sizeof(wcex); |
| 24 wcex.style = CS_DBLCLKS; | 26 wcex.style = CS_DBLCLKS; |
| 25 wcex.lpfnWndProc = WebWidgetHost::WndProc; | 27 wcex.lpfnWndProc = WebWidgetHost::WndProc; |
| 26 wcex.hInstance = GetModuleHandle(NULL); | 28 wcex.hInstance = GetModuleHandle(NULL); |
| 27 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); | 29 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); |
| 28 wcex.lpszClassName = kWindowClassName; | 30 wcex.lpszClassName = kWindowClassName; |
| 29 RegisterClassEx(&wcex); | 31 RegisterClassEx(&wcex); |
| 30 registered_class = true; | 32 registered_class = true; |
| 31 } | 33 } |
| 32 | 34 |
| 33 host->hwnd_ = CreateWindowEx(WS_EX_TOOLWINDOW, | 35 host->view_ = CreateWindowEx(WS_EX_TOOLWINDOW, |
| 34 kWindowClassName, kWindowClassName, WS_POPUP, | 36 kWindowClassName, kWindowClassName, WS_POPUP, |
| 35 0, 0, 0, 0, | 37 0, 0, 0, 0, |
| 36 parent_window, NULL, GetModuleHandle(NULL), NULL)
; | 38 parent_window, NULL, GetModuleHandle(NULL), NULL)
; |
| 37 | 39 |
| 38 win_util::SetWindowUserData(host->hwnd_, host); | 40 win_util::SetWindowUserData(host->view_, host); |
| 39 | 41 |
| 40 host->webwidget_ = WebWidget::Create(delegate); | 42 host->webwidget_ = WebWidget::Create(delegate); |
| 41 | 43 |
| 42 return host; | 44 return host; |
| 43 } | 45 } |
| 44 | 46 |
| 45 /*static*/ | 47 /*static*/ |
| 46 WebWidgetHost* WebWidgetHost::FromWindow(HWND hwnd) { | 48 WebWidgetHost* WebWidgetHost::FromWindow(gfx::WindowHandle hwnd) { |
| 47 return reinterpret_cast<WebWidgetHost*>(win_util::GetWindowUserData(hwnd)); | 49 return reinterpret_cast<WebWidgetHost*>(win_util::GetWindowUserData(hwnd)); |
| 48 } | 50 } |
| 49 | 51 |
| 50 /*static*/ | 52 /*static*/ |
| 51 LRESULT CALLBACK WebWidgetHost::WndProc(HWND hwnd, UINT message, WPARAM wparam, | 53 LRESULT CALLBACK WebWidgetHost::WndProc(HWND hwnd, UINT message, WPARAM wparam, |
| 52 LPARAM lparam) { | 54 LPARAM lparam) { |
| 53 WebWidgetHost* host = FromWindow(hwnd); | 55 WebWidgetHost* host = FromWindow(hwnd); |
| 54 if (host && !host->WndProc(message, wparam, lparam)) { | 56 if (host && !host->WndProc(message, wparam, lparam)) { |
| 55 switch (message) { | 57 switch (message) { |
| 56 case WM_DESTROY: | 58 case WM_DESTROY: |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 | 124 |
| 123 // If this invalidate overlaps with a pending scroll, then we have to | 125 // If this invalidate overlaps with a pending scroll, then we have to |
| 124 // downgrade to invalidating the scroll rect. | 126 // downgrade to invalidating the scroll rect. |
| 125 if (damaged_rect.Intersects(scroll_rect_)) { | 127 if (damaged_rect.Intersects(scroll_rect_)) { |
| 126 paint_rect_ = paint_rect_.Union(scroll_rect_); | 128 paint_rect_ = paint_rect_.Union(scroll_rect_); |
| 127 ResetScrollRect(); | 129 ResetScrollRect(); |
| 128 } | 130 } |
| 129 paint_rect_ = paint_rect_.Union(damaged_rect); | 131 paint_rect_ = paint_rect_.Union(damaged_rect); |
| 130 | 132 |
| 131 RECT r = damaged_rect.ToRECT(); | 133 RECT r = damaged_rect.ToRECT(); |
| 132 InvalidateRect(hwnd_, &r, FALSE); | 134 InvalidateRect(view_, &r, FALSE); |
| 133 } | 135 } |
| 134 | 136 |
| 135 void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { | 137 void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { |
| 136 DCHECK(dx || dy); | 138 DCHECK(dx || dy); |
| 137 | 139 |
| 138 // If we already have a pending scroll operation or if this scroll operation | 140 // If we already have a pending scroll operation or if this scroll operation |
| 139 // intersects the existing paint region, then just failover to invalidating. | 141 // intersects the existing paint region, then just failover to invalidating. |
| 140 if (!scroll_rect_.IsEmpty() || paint_rect_.Intersects(clip_rect)) { | 142 if (!scroll_rect_.IsEmpty() || paint_rect_.Intersects(clip_rect)) { |
| 141 paint_rect_ = paint_rect_.Union(scroll_rect_); | 143 paint_rect_ = paint_rect_.Union(scroll_rect_); |
| 142 ResetScrollRect(); | 144 ResetScrollRect(); |
| 143 paint_rect_ = paint_rect_.Union(clip_rect); | 145 paint_rect_ = paint_rect_.Union(clip_rect); |
| 144 } | 146 } |
| 145 | 147 |
| 146 // We will perform scrolling lazily, when requested to actually paint. | 148 // We will perform scrolling lazily, when requested to actually paint. |
| 147 scroll_rect_ = clip_rect; | 149 scroll_rect_ = clip_rect; |
| 148 scroll_dx_ = dx; | 150 scroll_dx_ = dx; |
| 149 scroll_dy_ = dy; | 151 scroll_dy_ = dy; |
| 150 | 152 |
| 151 RECT r = clip_rect.ToRECT(); | 153 RECT r = clip_rect.ToRECT(); |
| 152 InvalidateRect(hwnd_, &r, FALSE); | 154 InvalidateRect(view_, &r, FALSE); |
| 153 } | 155 } |
| 154 | 156 |
| 155 void WebWidgetHost::SetCursor(HCURSOR cursor) { | 157 void WebWidgetHost::SetCursor(HCURSOR cursor) { |
| 156 SetClassLong(hwnd_, GCL_HCURSOR, | 158 SetClassLong(view_, GCL_HCURSOR, |
| 157 static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor))); | 159 static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor))); |
| 158 ::SetCursor(cursor); | 160 ::SetCursor(cursor); |
| 159 } | 161 } |
| 160 | 162 |
| 161 void WebWidgetHost::DiscardBackingStore() { | 163 void WebWidgetHost::DiscardBackingStore() { |
| 162 canvas_.reset(); | 164 canvas_.reset(); |
| 163 } | 165 } |
| 164 | 166 |
| 165 WebWidgetHost::WebWidgetHost() | 167 WebWidgetHost::WebWidgetHost() |
| 166 : hwnd_(NULL), | 168 : view_(NULL), |
| 167 webwidget_(NULL), | 169 webwidget_(NULL), |
| 168 track_mouse_leave_(false), | 170 track_mouse_leave_(false), |
| 169 scroll_dx_(0), | 171 scroll_dx_(0), |
| 170 scroll_dy_(0) { | 172 scroll_dy_(0) { |
| 171 set_painting(false); | 173 set_painting(false); |
| 172 } | 174 } |
| 173 | 175 |
| 174 WebWidgetHost::~WebWidgetHost() { | 176 WebWidgetHost::~WebWidgetHost() { |
| 175 win_util::SetWindowUserData(hwnd_, 0); | 177 win_util::SetWindowUserData(view_, 0); |
| 176 | 178 |
| 177 TrackMouseLeave(false); | 179 TrackMouseLeave(false); |
| 178 | 180 |
| 179 webwidget_->Close(); | 181 webwidget_->Close(); |
| 180 webwidget_->Release(); | 182 webwidget_->Release(); |
| 181 } | 183 } |
| 182 | 184 |
| 183 bool WebWidgetHost::WndProc(UINT message, WPARAM wparam, LPARAM lparam) { | 185 bool WebWidgetHost::WndProc(UINT message, WPARAM wparam, LPARAM lparam) { |
| 184 switch (message) { | 186 switch (message) { |
| 185 case WM_ACTIVATE: | 187 case WM_ACTIVATE: |
| 186 if (wparam == WA_INACTIVE) { | 188 if (wparam == WA_INACTIVE) { |
| 187 PostMessage(hwnd_, WM_CLOSE, 0, 0); | 189 PostMessage(view_, WM_CLOSE, 0, 0); |
| 188 return true; | 190 return true; |
| 189 } | 191 } |
| 190 break; | 192 break; |
| 191 } | 193 } |
| 192 | 194 |
| 193 return false; | 195 return false; |
| 194 } | 196 } |
| 195 | 197 |
| 196 void WebWidgetHost::Paint() { | 198 void WebWidgetHost::Paint() { |
| 197 RECT r; | 199 RECT r; |
| 198 GetClientRect(hwnd_, &r); | 200 GetClientRect(view_, &r); |
| 199 gfx::Rect client_rect(r); | 201 gfx::Rect client_rect(r); |
| 200 | 202 |
| 201 // Allocate a canvas if necessary | 203 // Allocate a canvas if necessary |
| 202 if (!canvas_.get()) { | 204 if (!canvas_.get()) { |
| 203 ResetScrollRect(); | 205 ResetScrollRect(); |
| 204 paint_rect_ = client_rect; | 206 paint_rect_ = client_rect; |
| 205 canvas_.reset(new gfx::PlatformCanvasWin( | 207 canvas_.reset(new gfx::PlatformCanvas( |
| 206 paint_rect_.width(), paint_rect_.height(), true)); | 208 paint_rect_.width(), paint_rect_.height(), true)); |
| 207 } | 209 } |
| 208 | 210 |
| 209 // This may result in more invalidation | 211 // This may result in more invalidation |
| 210 webwidget_->Layout(); | 212 webwidget_->Layout(); |
| 211 | 213 |
| 212 // Scroll the canvas if necessary | 214 // Scroll the canvas if necessary |
| 213 scroll_rect_ = client_rect.Intersect(scroll_rect_); | 215 scroll_rect_ = client_rect.Intersect(scroll_rect_); |
| 214 if (!scroll_rect_.IsEmpty()) { | 216 if (!scroll_rect_.IsEmpty()) { |
| 215 HDC hdc = canvas_->getTopPlatformDevice().getBitmapDC(); | 217 HDC hdc = canvas_->getTopPlatformDevice().getBitmapDC(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 231 paint_rect_ = gfx::Rect(); | 233 paint_rect_ = gfx::Rect(); |
| 232 | 234 |
| 233 DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations"; | 235 DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations"; |
| 234 PaintRect(rect); | 236 PaintRect(rect); |
| 235 } | 237 } |
| 236 } | 238 } |
| 237 DCHECK(paint_rect_.IsEmpty()); | 239 DCHECK(paint_rect_.IsEmpty()); |
| 238 | 240 |
| 239 // Paint to the screen | 241 // Paint to the screen |
| 240 PAINTSTRUCT ps; | 242 PAINTSTRUCT ps; |
| 241 BeginPaint(hwnd_, &ps); | 243 BeginPaint(view_, &ps); |
| 242 canvas_->getTopPlatformDevice().drawToHDC(ps.hdc, | 244 canvas_->getTopPlatformDevice().drawToHDC(ps.hdc, |
| 243 ps.rcPaint.left, | 245 ps.rcPaint.left, |
| 244 ps.rcPaint.top, | 246 ps.rcPaint.top, |
| 245 &ps.rcPaint); | 247 &ps.rcPaint); |
| 246 EndPaint(hwnd_, &ps); | 248 EndPaint(view_, &ps); |
| 247 | 249 |
| 248 // Draw children | 250 // Draw children |
| 249 UpdateWindow(hwnd_); | 251 UpdateWindow(view_); |
| 250 } | 252 } |
| 251 | 253 |
| 252 void WebWidgetHost::Resize(LPARAM lparam) { | 254 void WebWidgetHost::Resize(LPARAM lparam) { |
| 253 // Force an entire re-paint. TODO(darin): Maybe reuse this memory buffer. | 255 // Force an entire re-paint. TODO(darin): Maybe reuse this memory buffer. |
| 254 DiscardBackingStore(); | 256 DiscardBackingStore(); |
| 255 | 257 |
| 256 webwidget_->Resize(gfx::Size(LOWORD(lparam), HIWORD(lparam))); | 258 webwidget_->Resize(gfx::Size(LOWORD(lparam), HIWORD(lparam))); |
| 257 } | 259 } |
| 258 | 260 |
| 259 void WebWidgetHost::MouseEvent(UINT message, WPARAM wparam, LPARAM lparam) { | 261 void WebWidgetHost::MouseEvent(UINT message, WPARAM wparam, LPARAM lparam) { |
| 260 WebMouseEvent event(hwnd_, message, wparam, lparam); | 262 WebMouseEvent event(view_, message, wparam, lparam); |
| 261 switch (event.type) { | 263 switch (event.type) { |
| 262 case WebInputEvent::MOUSE_MOVE: | 264 case WebInputEvent::MOUSE_MOVE: |
| 263 TrackMouseLeave(true); | 265 TrackMouseLeave(true); |
| 264 break; | 266 break; |
| 265 case WebInputEvent::MOUSE_LEAVE: | 267 case WebInputEvent::MOUSE_LEAVE: |
| 266 TrackMouseLeave(false); | 268 TrackMouseLeave(false); |
| 267 break; | 269 break; |
| 268 case WebInputEvent::MOUSE_DOWN: | 270 case WebInputEvent::MOUSE_DOWN: |
| 269 SetCapture(hwnd_); | 271 SetCapture(view_); |
| 270 break; | 272 break; |
| 271 case WebInputEvent::MOUSE_UP: | 273 case WebInputEvent::MOUSE_UP: |
| 272 if (GetCapture() == hwnd_) | 274 if (GetCapture() == view_) |
| 273 ReleaseCapture(); | 275 ReleaseCapture(); |
| 274 break; | 276 break; |
| 275 } | 277 } |
| 276 webwidget_->HandleInputEvent(&event); | 278 webwidget_->HandleInputEvent(&event); |
| 277 } | 279 } |
| 278 | 280 |
| 279 void WebWidgetHost::WheelEvent(WPARAM wparam, LPARAM lparam) { | 281 void WebWidgetHost::WheelEvent(WPARAM wparam, LPARAM lparam) { |
| 280 WebMouseWheelEvent event(hwnd_, WM_MOUSEWHEEL, wparam, lparam); | 282 WebMouseWheelEvent event(view_, WM_MOUSEWHEEL, wparam, lparam); |
| 281 webwidget_->HandleInputEvent(&event); | 283 webwidget_->HandleInputEvent(&event); |
| 282 } | 284 } |
| 283 | 285 |
| 284 void WebWidgetHost::KeyEvent(UINT message, WPARAM wparam, LPARAM lparam) { | 286 void WebWidgetHost::KeyEvent(UINT message, WPARAM wparam, LPARAM lparam) { |
| 285 WebKeyboardEvent event(hwnd_, message, wparam, lparam); | 287 WebKeyboardEvent event(view_, message, wparam, lparam); |
| 286 webwidget_->HandleInputEvent(&event); | 288 webwidget_->HandleInputEvent(&event); |
| 287 } | 289 } |
| 288 | 290 |
| 289 void WebWidgetHost::CaptureLostEvent() { | 291 void WebWidgetHost::CaptureLostEvent() { |
| 290 webwidget_->MouseCaptureLost(); | 292 webwidget_->MouseCaptureLost(); |
| 291 } | 293 } |
| 292 | 294 |
| 293 void WebWidgetHost::SetFocus(bool enable) { | 295 void WebWidgetHost::SetFocus(bool enable) { |
| 294 webwidget_->SetFocus(enable); | 296 webwidget_->SetFocus(enable); |
| 295 } | 297 } |
| 296 | 298 |
| 297 void WebWidgetHost::TrackMouseLeave(bool track) { | 299 void WebWidgetHost::TrackMouseLeave(bool track) { |
| 298 if (track == track_mouse_leave_) | 300 if (track == track_mouse_leave_) |
| 299 return; | 301 return; |
| 300 track_mouse_leave_ = track; | 302 track_mouse_leave_ = track; |
| 301 | 303 |
| 302 DCHECK(hwnd_); | 304 DCHECK(view_); |
| 303 | 305 |
| 304 TRACKMOUSEEVENT tme; | 306 TRACKMOUSEEVENT tme; |
| 305 tme.cbSize = sizeof(TRACKMOUSEEVENT); | 307 tme.cbSize = sizeof(TRACKMOUSEEVENT); |
| 306 tme.dwFlags = TME_LEAVE; | 308 tme.dwFlags = TME_LEAVE; |
| 307 if (!track_mouse_leave_) | 309 if (!track_mouse_leave_) |
| 308 tme.dwFlags |= TME_CANCEL; | 310 tme.dwFlags |= TME_CANCEL; |
| 309 tme.hwndTrack = hwnd_; | 311 tme.hwndTrack = view_; |
| 310 | 312 |
| 311 TrackMouseEvent(&tme); | 313 TrackMouseEvent(&tme); |
| 312 } | 314 } |
| 313 | 315 |
| 314 void WebWidgetHost::ResetScrollRect() { | 316 void WebWidgetHost::ResetScrollRect() { |
| 315 scroll_rect_ = gfx::Rect(); | 317 scroll_rect_ = gfx::Rect(); |
| 316 scroll_dx_ = 0; | 318 scroll_dx_ = 0; |
| 317 scroll_dy_ = 0; | 319 scroll_dy_ = 0; |
| 318 } | 320 } |
| 319 | 321 |
| 320 void WebWidgetHost::PaintRect(const gfx::Rect& rect) { | 322 void WebWidgetHost::PaintRect(const gfx::Rect& rect) { |
| 321 #ifndef NDEBUG | 323 #ifndef NDEBUG |
| 322 DCHECK(!painting_); | 324 DCHECK(!painting_); |
| 323 #endif | 325 #endif |
| 324 DCHECK(canvas_.get()); | 326 DCHECK(canvas_.get()); |
| 325 | 327 |
| 326 set_painting(true); | 328 set_painting(true); |
| 327 webwidget_->Paint(canvas_.get(), rect); | 329 webwidget_->Paint(canvas_.get(), rect); |
| 328 set_painting(false); | 330 set_painting(false); |
| 329 } | 331 } |
| 330 | |
| OLD | NEW |