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 |