OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkTypes.h" | 8 #include "SkTypes.h" |
9 | 9 |
10 #if defined(SK_BUILD_FOR_WIN) | 10 #if defined(SK_BUILD_FOR_WIN) |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "gl/GrGLInterface.h" | 25 #include "gl/GrGLInterface.h" |
26 #include "GLES2/gl2.h" | 26 #include "GLES2/gl2.h" |
27 | 27 |
28 #define ANGLE_GL_CALL(IFACE, X) \ | 28 #define ANGLE_GL_CALL(IFACE, X) \ |
29 do { \ | 29 do { \ |
30 (IFACE)->fFunctions.f##X; \ | 30 (IFACE)->fFunctions.f##X; \ |
31 } while (false) | 31 } while (false) |
32 | 32 |
33 #endif | 33 #endif |
34 | 34 |
35 static SkOSWindow* gCurrOSWin; | |
36 static HWND gEventTarget; | |
37 | |
38 #define WM_EVENT_CALLBACK (WM_USER+0) | 35 #define WM_EVENT_CALLBACK (WM_USER+0) |
39 | 36 |
40 void post_skwinevent() | 37 void post_skwinevent(HWND hwnd) |
41 { | 38 { |
42 PostMessage(gEventTarget, WM_EVENT_CALLBACK, 0, 0); | 39 PostMessage(hwnd, WM_EVENT_CALLBACK, 0, 0); |
43 } | 40 } |
44 | 41 |
45 SkOSWindow::SkOSWindow(void* hWnd) { | 42 SkTHashMap<void*, SkOSWindow*> SkOSWindow::gHwndToOSWindowMap; |
46 fHWND = hWnd; | 43 |
| 44 SkOSWindow::SkOSWindow(const void* winInit) { |
| 45 fWinInit = *(const WindowInit*)winInit; |
| 46 |
| 47 fHWND = CreateWindow(fWinInit.fClass, NULL, WS_OVERLAPPEDWINDOW, |
| 48 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, fWinIni
t.fInstance, NULL); |
| 49 gHwndToOSWindowMap.set(fHWND, this); |
47 #if SK_SUPPORT_GPU | 50 #if SK_SUPPORT_GPU |
48 #if SK_ANGLE | 51 #if SK_ANGLE |
49 fDisplay = EGL_NO_DISPLAY; | 52 fDisplay = EGL_NO_DISPLAY; |
50 fContext = EGL_NO_CONTEXT; | 53 fContext = EGL_NO_CONTEXT; |
51 fSurface = EGL_NO_SURFACE; | 54 fSurface = EGL_NO_SURFACE; |
52 #endif | 55 #endif |
53 fHGLRC = NULL; | 56 fHGLRC = NULL; |
54 #endif | 57 #endif |
55 fAttached = kNone_BackEndType; | 58 fAttached = kNone_BackEndType; |
56 gEventTarget = (HWND)hWnd; | 59 fFullscreen = false; |
57 } | 60 } |
58 | 61 |
59 SkOSWindow::~SkOSWindow() { | 62 SkOSWindow::~SkOSWindow() { |
| 63 this->setFullscreen(false); |
60 #if SK_SUPPORT_GPU | 64 #if SK_SUPPORT_GPU |
61 if (fHGLRC) { | 65 if (fHGLRC) { |
62 wglDeleteContext((HGLRC)fHGLRC); | 66 wglDeleteContext((HGLRC)fHGLRC); |
63 } | 67 } |
64 #if SK_ANGLE | 68 #if SK_ANGLE |
65 if (EGL_NO_CONTEXT != fContext) { | 69 if (EGL_NO_CONTEXT != fContext) { |
66 eglDestroyContext(fDisplay, fContext); | 70 eglDestroyContext(fDisplay, fContext); |
67 fContext = EGL_NO_CONTEXT; | 71 fContext = EGL_NO_CONTEXT; |
68 } | 72 } |
69 | 73 |
70 if (EGL_NO_SURFACE != fSurface) { | 74 if (EGL_NO_SURFACE != fSurface) { |
71 eglDestroySurface(fDisplay, fSurface); | 75 eglDestroySurface(fDisplay, fSurface); |
72 fSurface = EGL_NO_SURFACE; | 76 fSurface = EGL_NO_SURFACE; |
73 } | 77 } |
74 | 78 |
75 if (EGL_NO_DISPLAY != fDisplay) { | 79 if (EGL_NO_DISPLAY != fDisplay) { |
76 eglTerminate(fDisplay); | 80 eglTerminate(fDisplay); |
77 fDisplay = EGL_NO_DISPLAY; | 81 fDisplay = EGL_NO_DISPLAY; |
78 } | 82 } |
79 #endif // SK_ANGLE | 83 #endif // SK_ANGLE |
80 #endif // SK_SUPPORT_GPU | 84 #endif // SK_SUPPORT_GPU |
| 85 gHwndToOSWindowMap.remove(fHWND); |
| 86 DestroyWindow((HWND)fHWND); |
81 } | 87 } |
82 | 88 |
83 static SkKey winToskKey(WPARAM vk) { | 89 static SkKey winToskKey(WPARAM vk) { |
84 static const struct { | 90 static const struct { |
85 WPARAM fVK; | 91 WPARAM fVK; |
86 SkKey fKey; | 92 SkKey fKey; |
87 } gPair[] = { | 93 } gPair[] = { |
88 { VK_BACK, kBack_SkKey }, | 94 { VK_BACK, kBack_SkKey }, |
89 { VK_CLEAR, kBack_SkKey }, | 95 { VK_CLEAR, kBack_SkKey }, |
90 { VK_RETURN, kOK_SkKey }, | 96 { VK_RETURN, kOK_SkKey }, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 Click::kMoved_State, NULL, getModifiers(message)); | 158 Click::kMoved_State, NULL, getModifiers(message)); |
153 return true; | 159 return true; |
154 | 160 |
155 case WM_LBUTTONUP: | 161 case WM_LBUTTONUP: |
156 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), | 162 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), |
157 Click::kUp_State, NULL, getModifiers(message)); | 163 Click::kUp_State, NULL, getModifiers(message)); |
158 return true; | 164 return true; |
159 | 165 |
160 case WM_EVENT_CALLBACK: | 166 case WM_EVENT_CALLBACK: |
161 if (SkEvent::ProcessEvent()) { | 167 if (SkEvent::ProcessEvent()) { |
162 post_skwinevent(); | 168 post_skwinevent(hWnd); |
163 } | 169 } |
164 return true; | 170 return true; |
165 } | 171 } |
166 return false; | 172 return false; |
167 } | 173 } |
168 | 174 |
169 void SkOSWindow::doPaint(void* ctx) { | 175 void SkOSWindow::doPaint(void* ctx) { |
170 this->update(NULL); | 176 this->update(NULL); |
171 | 177 |
172 if (kNone_BackEndType == fAttached) | 178 if (kNone_BackEndType == fAttached) |
(...skipping 28 matching lines...) Expand all Loading... |
201 0, 0, | 207 0, 0, |
202 0, bitmap.height(), | 208 0, bitmap.height(), |
203 bitmap.getPixels(), | 209 bitmap.getPixels(), |
204 &bmi, | 210 &bmi, |
205 DIB_RGB_COLORS); | 211 DIB_RGB_COLORS); |
206 (void)ret; // we're ignoring potential failures for now. | 212 (void)ret; // we're ignoring potential failures for now. |
207 bitmap.unlockPixels(); | 213 bitmap.unlockPixels(); |
208 } | 214 } |
209 } | 215 } |
210 | 216 |
211 #if 0 | |
212 void SkOSWindow::updateSize() | 217 void SkOSWindow::updateSize() |
213 { | 218 { |
214 RECT r; | 219 RECT r; |
215 GetWindowRect((HWND)this->getHWND(), &r); | 220 GetWindowRect((HWND)fHWND, &r); |
216 this->resize(r.right - r.left, r.bottom - r.top); | 221 this->resize(r.right - r.left, r.bottom - r.top); |
217 } | 222 } |
218 #endif | |
219 | 223 |
220 void SkOSWindow::onHandleInval(const SkIRect& r) { | 224 void SkOSWindow::onHandleInval(const SkIRect& r) { |
221 RECT rect; | 225 RECT rect; |
222 rect.left = r.fLeft; | 226 rect.left = r.fLeft; |
223 rect.top = r.fTop; | 227 rect.top = r.fTop; |
224 rect.right = r.fRight; | 228 rect.right = r.fRight; |
225 rect.bottom = r.fBottom; | 229 rect.bottom = r.fBottom; |
226 InvalidateRect((HWND)fHWND, &rect, FALSE); | 230 InvalidateRect((HWND)fHWND, &rect, FALSE); |
227 } | 231 } |
228 | 232 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++) | 287 for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++) |
284 if (gKeys[i].fRaw == raw) | 288 if (gKeys[i].fRaw == raw) |
285 return gKeys[i].fKey; | 289 return gKeys[i].fKey; |
286 return kNONE_SkKey; | 290 return kNONE_SkKey; |
287 } | 291 } |
288 | 292 |
289 ////////////////////////////////////////////////////////////////////////////////
/////// | 293 ////////////////////////////////////////////////////////////////////////////////
/////// |
290 | 294 |
291 void SkEvent::SignalNonEmptyQueue() | 295 void SkEvent::SignalNonEmptyQueue() |
292 { | 296 { |
293 post_skwinevent(); | 297 SkOSWindow::ForAllWindows([](void* hWND, SkOSWindow**) { |
294 //SkDebugf("signal nonempty\n"); | 298 post_skwinevent((HWND)hWND); |
| 299 }); |
295 } | 300 } |
296 | 301 |
297 static UINT_PTR gTimer; | 302 static UINT_PTR gTimer; |
298 | 303 |
299 VOID CALLBACK sk_timer_proc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime
) | 304 VOID CALLBACK sk_timer_proc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime
) |
300 { | 305 { |
301 SkEvent::ServiceQueueTimer(); | 306 SkEvent::ServiceQueueTimer(); |
302 //SkDebugf("timer task fired\n"); | 307 //SkDebugf("timer task fired\n"); |
303 } | 308 } |
304 | 309 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 return false; | 365 return false; |
361 } | 366 } |
362 | 367 |
363 void SkOSWindow::detachGL() { | 368 void SkOSWindow::detachGL() { |
364 wglMakeCurrent(GetDC((HWND)fHWND), 0); | 369 wglMakeCurrent(GetDC((HWND)fHWND), 0); |
365 wglDeleteContext((HGLRC)fHGLRC); | 370 wglDeleteContext((HGLRC)fHGLRC); |
366 fHGLRC = NULL; | 371 fHGLRC = NULL; |
367 } | 372 } |
368 | 373 |
369 void SkOSWindow::presentGL() { | 374 void SkOSWindow::presentGL() { |
370 glFlush(); | |
371 HDC dc = GetDC((HWND)fHWND); | 375 HDC dc = GetDC((HWND)fHWND); |
372 SwapBuffers(dc); | 376 SwapBuffers(dc); |
373 ReleaseDC((HWND)fHWND, dc); | 377 ReleaseDC((HWND)fHWND, dc); |
374 } | 378 } |
375 | 379 |
376 #if SK_ANGLE | 380 #if SK_ANGLE |
377 | 381 |
378 bool create_ANGLE(EGLNativeWindowType hWnd, | 382 bool create_ANGLE(EGLNativeWindowType hWnd, |
379 int msaaSampleCount, | 383 int msaaSampleCount, |
380 EGLDisplay* eglDisplay, | 384 EGLDisplay* eglDisplay, |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 presentANGLE(); | 606 presentANGLE(); |
603 break; | 607 break; |
604 #endif // SK_ANGLE | 608 #endif // SK_ANGLE |
605 #endif // SK_SUPPORT_GPU | 609 #endif // SK_SUPPORT_GPU |
606 default: | 610 default: |
607 SkASSERT(false); | 611 SkASSERT(false); |
608 break; | 612 break; |
609 } | 613 } |
610 } | 614 } |
611 | 615 |
| 616 void SkOSWindow::setFullscreen(bool fullscreen) { |
| 617 if (fullscreen == fFullscreen) { |
| 618 return; |
| 619 } |
| 620 if (fHGLRC) { |
| 621 this->detachGL(); |
| 622 } |
| 623 // This is hacked together from various sources on the web. It can certainly
be improved and be |
| 624 // made more robust. |
| 625 if (fullscreen) { |
| 626 // Save current window/resolution information. |
| 627 fSavedWindowState.fZoomed = SkToBool(IsZoomed((HWND)fHWND)); |
| 628 if (fSavedWindowState.fZoomed) { |
| 629 SendMessage((HWND)fHWND, WM_SYSCOMMAND, SC_RESTORE, 0); |
| 630 } |
| 631 fSavedWindowState.fStyle = GetWindowLong((HWND)fHWND, GWL_STYLE); |
| 632 fSavedWindowState.fExStyle = GetWindowLong((HWND)fHWND, GWL_EXSTYLE); |
| 633 GetWindowRect((HWND)fHWND, &fSavedWindowState.fRect); |
| 634 DEVMODE dmScreenSettings; // Device Mode |
| 635 memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sur
e Memory's Cleared |
| 636 dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The D
evmode Structure |
| 637 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dmScreenSettings); |
| 638 fSavedWindowState.fScreenWidth = dmScreenSettings.dmPelsWidth; |
| 639 fSavedWindowState.fScreenHeight = dmScreenSettings.dmPelsHeight; |
| 640 fSavedWindowState.fScreenBits = dmScreenSettings.dmBitsPerPel; |
| 641 fSavedWindowState.fHWND = fHWND; |
| 642 } |
| 643 |
| 644 if (fullscreen) { |
| 645 // Try different sizes to find an allowed setting? Use ChangeDisplaySett
ingsEx? |
| 646 static const int kWidth = 1280; |
| 647 static const int kHeight = 1024; |
| 648 DEVMODE dmScreenSettings; |
| 649 memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); |
| 650 dmScreenSettings.dmSize=sizeof(dmScreenSettings); |
| 651 dmScreenSettings.dmPelsWidth = kWidth; |
| 652 dmScreenSettings.dmPelsHeight = kHeight; |
| 653 dmScreenSettings.dmBitsPerPel = 32; |
| 654 dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; |
| 655 if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHA
NGE_SUCCESSFUL) { |
| 656 return; |
| 657 } |
| 658 RECT WindowRect; |
| 659 WindowRect.left = 0; |
| 660 WindowRect.right = kWidth; |
| 661 WindowRect.top = 0; |
| 662 WindowRect.bottom = kHeight; |
| 663 ShowCursor(FALSE); |
| 664 AdjustWindowRectEx(&WindowRect, WS_POPUP, FALSE, WS_EX_APPWINDOW); |
| 665 HWND fsHWND = CreateWindowEx( |
| 666 WS_EX_APPWINDOW, |
| 667 fWinInit.fClass, |
| 668 NULL, |
| 669 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, |
| 670 0, 0, WindowRect.right-WindowRect.left, WindowRect.bottom-WindowRect
.top, |
| 671 NULL, |
| 672 NULL, |
| 673 fWinInit.fInstance, |
| 674 NULL |
| 675 ); |
| 676 if (!fsHWND) { |
| 677 return; |
| 678 } |
| 679 // Hide the old window and set the entry in the global mapping for this
SkOSWindow to the |
| 680 // new HWND. |
| 681 ShowWindow((HWND)fHWND, SW_HIDE); |
| 682 gHwndToOSWindowMap.remove(fHWND); |
| 683 fHWND = fsHWND; |
| 684 gHwndToOSWindowMap.set(fHWND, this); |
| 685 this->updateSize(); |
| 686 } else { |
| 687 DEVMODE dmScreenSettings; |
| 688 memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); |
| 689 dmScreenSettings.dmSize=sizeof(dmScreenSettings); |
| 690 dmScreenSettings.dmPelsWidth = fSavedWindowState.fScreenWidth; |
| 691 dmScreenSettings.dmPelsHeight = fSavedWindowState.fScreenHeight; |
| 692 dmScreenSettings.dmBitsPerPel = fSavedWindowState.fScreenBits; |
| 693 dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; |
| 694 if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHA
NGE_SUCCESSFUL) { |
| 695 return; |
| 696 } |
| 697 gHwndToOSWindowMap.remove(fHWND); |
| 698 DestroyWindow((HWND)fHWND); |
| 699 fHWND = fSavedWindowState.fHWND; |
| 700 gHwndToOSWindowMap.set(fHWND, this); |
| 701 ShowWindow((HWND)fHWND, SW_SHOW); |
| 702 SetWindowLong((HWND)fHWND, GWL_STYLE, fSavedWindowState.fStyle); |
| 703 SetWindowLong((HWND)fHWND, GWL_EXSTYLE, fSavedWindowState.fExStyle); |
| 704 |
| 705 int width = fSavedWindowState.fRect.right - fSavedWindowState.fRect.left
; |
| 706 int height = fSavedWindowState.fRect.right - fSavedWindowState.fRect.lef
t; |
| 707 SetWindowPos((HWND)fHWND, NULL, fSavedWindowState.fRect.left, fSavedWind
owState.fRect.top, |
| 708 width, height, |
| 709 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); |
| 710 if (fSavedWindowState.fZoomed) { |
| 711 SendMessage((HWND)fHWND, WM_SYSCOMMAND, SC_MAXIMIZE, 0); |
| 712 } |
| 713 this->updateSize(); |
| 714 } |
| 715 fFullscreen = fullscreen; |
| 716 } |
| 717 |
| 718 void SkOSWindow::setVsync(bool enable) { |
| 719 SkWGLExtensions wgl; |
| 720 wgl.swapInterval(enable ? 1 : 0); |
| 721 } |
| 722 |
| 723 void SkOSWindow::closeWindow() { |
| 724 this->setFullscreen(false); |
| 725 DestroyWindow((HWND)fHWND); |
| 726 } |
612 #endif | 727 #endif |
OLD | NEW |