1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci* Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci*
4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci* found in the LICENSE file.
6cb93a386Sopenharmony_ci*/
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkVulkan.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "tools/sk_app/win/Window_win.h"
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ci#include <tchar.h>
13cb93a386Sopenharmony_ci#include <windows.h>
14cb93a386Sopenharmony_ci#include <windowsx.h>
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci#include "src/utils/SkUTF.h"
17cb93a386Sopenharmony_ci#include "tools/sk_app/WindowContext.h"
18cb93a386Sopenharmony_ci#include "tools/sk_app/win/WindowContextFactory_win.h"
19cb93a386Sopenharmony_ci#include "tools/skui/ModifierKey.h"
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ci#ifdef SK_VULKAN
22cb93a386Sopenharmony_ci#include "tools/sk_app/VulkanWindowContext.h"
23cb93a386Sopenharmony_ci#endif
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_cinamespace sk_app {
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_cistatic int gWindowX = CW_USEDEFAULT;
28cb93a386Sopenharmony_cistatic int gWindowY = 0;
29cb93a386Sopenharmony_cistatic int gWindowWidth = CW_USEDEFAULT;
30cb93a386Sopenharmony_cistatic int gWindowHeight = 0;
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ciWindow* Window::CreateNativeWindow(void* platformData) {
33cb93a386Sopenharmony_ci    HINSTANCE hInstance = (HINSTANCE)platformData;
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci    Window_win* window = new Window_win();
36cb93a386Sopenharmony_ci    if (!window->init(hInstance)) {
37cb93a386Sopenharmony_ci        delete window;
38cb93a386Sopenharmony_ci        return nullptr;
39cb93a386Sopenharmony_ci    }
40cb93a386Sopenharmony_ci
41cb93a386Sopenharmony_ci    return window;
42cb93a386Sopenharmony_ci}
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_civoid Window_win::closeWindow() {
45cb93a386Sopenharmony_ci    RECT r;
46cb93a386Sopenharmony_ci    if (GetWindowRect(fHWnd, &r)) {
47cb93a386Sopenharmony_ci        gWindowX = r.left;
48cb93a386Sopenharmony_ci        gWindowY = r.top;
49cb93a386Sopenharmony_ci        gWindowWidth = r.right - r.left;
50cb93a386Sopenharmony_ci        gWindowHeight = r.bottom - r.top;
51cb93a386Sopenharmony_ci    }
52cb93a386Sopenharmony_ci    DestroyWindow(fHWnd);
53cb93a386Sopenharmony_ci}
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_ciWindow_win::~Window_win() {
56cb93a386Sopenharmony_ci    this->closeWindow();
57cb93a386Sopenharmony_ci}
58cb93a386Sopenharmony_ci
59cb93a386Sopenharmony_ciLRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_ci
62cb93a386Sopenharmony_cibool Window_win::init(HINSTANCE hInstance) {
63cb93a386Sopenharmony_ci    fHInstance = hInstance ? hInstance : GetModuleHandle(nullptr);
64cb93a386Sopenharmony_ci
65cb93a386Sopenharmony_ci    // The main window class name
66cb93a386Sopenharmony_ci    static const TCHAR gSZWindowClass[] = _T("SkiaApp");
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci    static WNDCLASSEX wcex;
69cb93a386Sopenharmony_ci    static bool wcexInit = false;
70cb93a386Sopenharmony_ci    if (!wcexInit) {
71cb93a386Sopenharmony_ci        wcex.cbSize = sizeof(WNDCLASSEX);
72cb93a386Sopenharmony_ci
73cb93a386Sopenharmony_ci        wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
74cb93a386Sopenharmony_ci        wcex.lpfnWndProc = WndProc;
75cb93a386Sopenharmony_ci        wcex.cbClsExtra = 0;
76cb93a386Sopenharmony_ci        wcex.cbWndExtra = 0;
77cb93a386Sopenharmony_ci        wcex.hInstance = fHInstance;
78cb93a386Sopenharmony_ci        wcex.hIcon = LoadIcon(fHInstance, (LPCTSTR)IDI_WINLOGO);
79cb93a386Sopenharmony_ci        wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
80cb93a386Sopenharmony_ci        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
81cb93a386Sopenharmony_ci        wcex.lpszMenuName = nullptr;
82cb93a386Sopenharmony_ci        wcex.lpszClassName = gSZWindowClass;
83cb93a386Sopenharmony_ci        wcex.hIconSm = LoadIcon(fHInstance, (LPCTSTR)IDI_WINLOGO);
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci        if (!RegisterClassEx(&wcex)) {
86cb93a386Sopenharmony_ci            return false;
87cb93a386Sopenharmony_ci        }
88cb93a386Sopenharmony_ci        wcexInit = true;
89cb93a386Sopenharmony_ci    }
90cb93a386Sopenharmony_ci
91cb93a386Sopenharmony_ci   /*
92cb93a386Sopenharmony_ci    if (fullscreen)
93cb93a386Sopenharmony_ci    {
94cb93a386Sopenharmony_ci        DEVMODE dmScreenSettings;
95cb93a386Sopenharmony_ci        // If full screen set the screen to maximum size of the users desktop and 32bit.
96cb93a386Sopenharmony_ci        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
97cb93a386Sopenharmony_ci        dmScreenSettings.dmSize = sizeof(dmScreenSettings);
98cb93a386Sopenharmony_ci        dmScreenSettings.dmPelsWidth = (unsigned long)width;
99cb93a386Sopenharmony_ci        dmScreenSettings.dmPelsHeight = (unsigned long)height;
100cb93a386Sopenharmony_ci        dmScreenSettings.dmBitsPerPel = 32;
101cb93a386Sopenharmony_ci        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
102cb93a386Sopenharmony_ci
103cb93a386Sopenharmony_ci        // Change the display settings to full screen.
104cb93a386Sopenharmony_ci        ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
105cb93a386Sopenharmony_ci
106cb93a386Sopenharmony_ci        // Set the position of the window to the top left corner.
107cb93a386Sopenharmony_ci        posX = posY = 0;
108cb93a386Sopenharmony_ci    }
109cb93a386Sopenharmony_ci    */
110cb93a386Sopenharmony_ci //   gIsFullscreen = fullscreen;
111cb93a386Sopenharmony_ci
112cb93a386Sopenharmony_ci    fHWnd = CreateWindow(gSZWindowClass, nullptr, WS_OVERLAPPEDWINDOW,
113cb93a386Sopenharmony_ci                         gWindowX, gWindowY, gWindowWidth, gWindowHeight,
114cb93a386Sopenharmony_ci                         nullptr, nullptr, fHInstance, nullptr);
115cb93a386Sopenharmony_ci    if (!fHWnd)
116cb93a386Sopenharmony_ci    {
117cb93a386Sopenharmony_ci        return false;
118cb93a386Sopenharmony_ci    }
119cb93a386Sopenharmony_ci
120cb93a386Sopenharmony_ci    SetWindowLongPtr(fHWnd, GWLP_USERDATA, (LONG_PTR)this);
121cb93a386Sopenharmony_ci    RegisterTouchWindow(fHWnd, 0);
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ci    return true;
124cb93a386Sopenharmony_ci}
125cb93a386Sopenharmony_ci
126cb93a386Sopenharmony_cistatic skui::Key get_key(WPARAM vk) {
127cb93a386Sopenharmony_ci    static const struct {
128cb93a386Sopenharmony_ci        WPARAM      fVK;
129cb93a386Sopenharmony_ci        skui::Key fKey;
130cb93a386Sopenharmony_ci    } gPair[] = {
131cb93a386Sopenharmony_ci        { VK_BACK,    skui::Key::kBack     },
132cb93a386Sopenharmony_ci        { VK_CLEAR,   skui::Key::kBack     },
133cb93a386Sopenharmony_ci        { VK_RETURN,  skui::Key::kOK       },
134cb93a386Sopenharmony_ci        { VK_UP,      skui::Key::kUp       },
135cb93a386Sopenharmony_ci        { VK_DOWN,    skui::Key::kDown     },
136cb93a386Sopenharmony_ci        { VK_LEFT,    skui::Key::kLeft     },
137cb93a386Sopenharmony_ci        { VK_RIGHT,   skui::Key::kRight    },
138cb93a386Sopenharmony_ci        { VK_TAB,     skui::Key::kTab      },
139cb93a386Sopenharmony_ci        { VK_PRIOR,   skui::Key::kPageUp   },
140cb93a386Sopenharmony_ci        { VK_NEXT,    skui::Key::kPageDown },
141cb93a386Sopenharmony_ci        { VK_HOME,    skui::Key::kHome     },
142cb93a386Sopenharmony_ci        { VK_END,     skui::Key::kEnd      },
143cb93a386Sopenharmony_ci        { VK_DELETE,  skui::Key::kDelete   },
144cb93a386Sopenharmony_ci        { VK_ESCAPE,  skui::Key::kEscape   },
145cb93a386Sopenharmony_ci        { VK_SHIFT,   skui::Key::kShift    },
146cb93a386Sopenharmony_ci        { VK_CONTROL, skui::Key::kCtrl     },
147cb93a386Sopenharmony_ci        { VK_MENU,    skui::Key::kOption   },
148cb93a386Sopenharmony_ci        { 'A',        skui::Key::kA        },
149cb93a386Sopenharmony_ci        { 'C',        skui::Key::kC        },
150cb93a386Sopenharmony_ci        { 'V',        skui::Key::kV        },
151cb93a386Sopenharmony_ci        { 'X',        skui::Key::kX        },
152cb93a386Sopenharmony_ci        { 'Y',        skui::Key::kY        },
153cb93a386Sopenharmony_ci        { 'Z',        skui::Key::kZ        },
154cb93a386Sopenharmony_ci    };
155cb93a386Sopenharmony_ci    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
156cb93a386Sopenharmony_ci        if (gPair[i].fVK == vk) {
157cb93a386Sopenharmony_ci            return gPair[i].fKey;
158cb93a386Sopenharmony_ci        }
159cb93a386Sopenharmony_ci    }
160cb93a386Sopenharmony_ci    return skui::Key::kNONE;
161cb93a386Sopenharmony_ci}
162cb93a386Sopenharmony_ci
163cb93a386Sopenharmony_cistatic skui::ModifierKey get_modifiers(UINT message, WPARAM wParam, LPARAM lParam) {
164cb93a386Sopenharmony_ci    skui::ModifierKey modifiers = skui::ModifierKey::kNone;
165cb93a386Sopenharmony_ci
166cb93a386Sopenharmony_ci    switch (message) {
167cb93a386Sopenharmony_ci        case WM_UNICHAR:
168cb93a386Sopenharmony_ci        case WM_CHAR:
169cb93a386Sopenharmony_ci            if (0 == (lParam & (1 << 30))) {
170cb93a386Sopenharmony_ci                modifiers |= skui::ModifierKey::kFirstPress;
171cb93a386Sopenharmony_ci            }
172cb93a386Sopenharmony_ci            if (lParam & (1 << 29)) {
173cb93a386Sopenharmony_ci                modifiers |= skui::ModifierKey::kOption;
174cb93a386Sopenharmony_ci            }
175cb93a386Sopenharmony_ci            break;
176cb93a386Sopenharmony_ci
177cb93a386Sopenharmony_ci        case WM_KEYDOWN:
178cb93a386Sopenharmony_ci        case WM_SYSKEYDOWN:
179cb93a386Sopenharmony_ci            if (0 == (lParam & (1 << 30))) {
180cb93a386Sopenharmony_ci                modifiers |= skui::ModifierKey::kFirstPress;
181cb93a386Sopenharmony_ci            }
182cb93a386Sopenharmony_ci            if (lParam & (1 << 29)) {
183cb93a386Sopenharmony_ci                modifiers |= skui::ModifierKey::kOption;
184cb93a386Sopenharmony_ci            }
185cb93a386Sopenharmony_ci            break;
186cb93a386Sopenharmony_ci
187cb93a386Sopenharmony_ci        case WM_KEYUP:
188cb93a386Sopenharmony_ci        case WM_SYSKEYUP:
189cb93a386Sopenharmony_ci            if (lParam & (1 << 29)) {
190cb93a386Sopenharmony_ci                modifiers |= skui::ModifierKey::kOption;
191cb93a386Sopenharmony_ci            }
192cb93a386Sopenharmony_ci            break;
193cb93a386Sopenharmony_ci
194cb93a386Sopenharmony_ci        case WM_LBUTTONDOWN:
195cb93a386Sopenharmony_ci        case WM_LBUTTONUP:
196cb93a386Sopenharmony_ci        case WM_MOUSEMOVE:
197cb93a386Sopenharmony_ci        case WM_MOUSEWHEEL:
198cb93a386Sopenharmony_ci            if (wParam & MK_CONTROL) {
199cb93a386Sopenharmony_ci                modifiers |= skui::ModifierKey::kControl;
200cb93a386Sopenharmony_ci            }
201cb93a386Sopenharmony_ci            if (wParam & MK_SHIFT) {
202cb93a386Sopenharmony_ci                modifiers |= skui::ModifierKey::kShift;
203cb93a386Sopenharmony_ci            }
204cb93a386Sopenharmony_ci            break;
205cb93a386Sopenharmony_ci    }
206cb93a386Sopenharmony_ci
207cb93a386Sopenharmony_ci    return modifiers;
208cb93a386Sopenharmony_ci}
209cb93a386Sopenharmony_ci
210cb93a386Sopenharmony_ciLRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
211cb93a386Sopenharmony_ci{
212cb93a386Sopenharmony_ci    PAINTSTRUCT ps;
213cb93a386Sopenharmony_ci
214cb93a386Sopenharmony_ci    Window_win* window = (Window_win*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
215cb93a386Sopenharmony_ci
216cb93a386Sopenharmony_ci    bool eventHandled = false;
217cb93a386Sopenharmony_ci
218cb93a386Sopenharmony_ci    switch (message) {
219cb93a386Sopenharmony_ci        case WM_PAINT:
220cb93a386Sopenharmony_ci            BeginPaint(hWnd, &ps);
221cb93a386Sopenharmony_ci            window->onPaint();
222cb93a386Sopenharmony_ci            EndPaint(hWnd, &ps);
223cb93a386Sopenharmony_ci            eventHandled = true;
224cb93a386Sopenharmony_ci            break;
225cb93a386Sopenharmony_ci
226cb93a386Sopenharmony_ci        case WM_CLOSE:
227cb93a386Sopenharmony_ci            PostQuitMessage(0);
228cb93a386Sopenharmony_ci            eventHandled = true;
229cb93a386Sopenharmony_ci            break;
230cb93a386Sopenharmony_ci
231cb93a386Sopenharmony_ci        case WM_ACTIVATE:
232cb93a386Sopenharmony_ci            // disable/enable rendering here, depending on wParam != WA_INACTIVE
233cb93a386Sopenharmony_ci            break;
234cb93a386Sopenharmony_ci
235cb93a386Sopenharmony_ci        case WM_SIZE:
236cb93a386Sopenharmony_ci            window->onResize(LOWORD(lParam), HIWORD(lParam));
237cb93a386Sopenharmony_ci            eventHandled = true;
238cb93a386Sopenharmony_ci            break;
239cb93a386Sopenharmony_ci
240cb93a386Sopenharmony_ci        case WM_UNICHAR:
241cb93a386Sopenharmony_ci            eventHandled = window->onChar((SkUnichar)wParam,
242cb93a386Sopenharmony_ci                                          get_modifiers(message, wParam, lParam));
243cb93a386Sopenharmony_ci            break;
244cb93a386Sopenharmony_ci
245cb93a386Sopenharmony_ci        case WM_CHAR: {
246cb93a386Sopenharmony_ci            const uint16_t* cPtr = reinterpret_cast<uint16_t*>(&wParam);
247cb93a386Sopenharmony_ci            SkUnichar c = SkUTF::NextUTF16(&cPtr, cPtr + 2);
248cb93a386Sopenharmony_ci            eventHandled = window->onChar(c, get_modifiers(message, wParam, lParam));
249cb93a386Sopenharmony_ci        } break;
250cb93a386Sopenharmony_ci
251cb93a386Sopenharmony_ci        case WM_KEYDOWN:
252cb93a386Sopenharmony_ci        case WM_SYSKEYDOWN:
253cb93a386Sopenharmony_ci            eventHandled = window->onKey(get_key(wParam), skui::InputState::kDown,
254cb93a386Sopenharmony_ci                                         get_modifiers(message, wParam, lParam));
255cb93a386Sopenharmony_ci            break;
256cb93a386Sopenharmony_ci
257cb93a386Sopenharmony_ci        case WM_KEYUP:
258cb93a386Sopenharmony_ci        case WM_SYSKEYUP:
259cb93a386Sopenharmony_ci            eventHandled = window->onKey(get_key(wParam), skui::InputState::kUp,
260cb93a386Sopenharmony_ci                                         get_modifiers(message, wParam, lParam));
261cb93a386Sopenharmony_ci            break;
262cb93a386Sopenharmony_ci
263cb93a386Sopenharmony_ci        case WM_LBUTTONDOWN:
264cb93a386Sopenharmony_ci        case WM_LBUTTONUP: {
265cb93a386Sopenharmony_ci            int xPos = GET_X_LPARAM(lParam);
266cb93a386Sopenharmony_ci            int yPos = GET_Y_LPARAM(lParam);
267cb93a386Sopenharmony_ci
268cb93a386Sopenharmony_ci            //if (!gIsFullscreen)
269cb93a386Sopenharmony_ci            //{
270cb93a386Sopenharmony_ci            //    RECT rc = { 0, 0, 640, 480 };
271cb93a386Sopenharmony_ci            //    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
272cb93a386Sopenharmony_ci            //    xPos -= rc.left;
273cb93a386Sopenharmony_ci            //    yPos -= rc.top;
274cb93a386Sopenharmony_ci            //}
275cb93a386Sopenharmony_ci
276cb93a386Sopenharmony_ci            skui::InputState istate = ((wParam & MK_LBUTTON) != 0) ? skui::InputState::kDown
277cb93a386Sopenharmony_ci                                                                     : skui::InputState::kUp;
278cb93a386Sopenharmony_ci
279cb93a386Sopenharmony_ci            eventHandled = window->onMouse(xPos, yPos, istate,
280cb93a386Sopenharmony_ci                                            get_modifiers(message, wParam, lParam));
281cb93a386Sopenharmony_ci        } break;
282cb93a386Sopenharmony_ci
283cb93a386Sopenharmony_ci        case WM_MOUSEMOVE: {
284cb93a386Sopenharmony_ci            int xPos = GET_X_LPARAM(lParam);
285cb93a386Sopenharmony_ci            int yPos = GET_Y_LPARAM(lParam);
286cb93a386Sopenharmony_ci
287cb93a386Sopenharmony_ci            //if (!gIsFullscreen)
288cb93a386Sopenharmony_ci            //{
289cb93a386Sopenharmony_ci            //    RECT rc = { 0, 0, 640, 480 };
290cb93a386Sopenharmony_ci            //    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
291cb93a386Sopenharmony_ci            //    xPos -= rc.left;
292cb93a386Sopenharmony_ci            //    yPos -= rc.top;
293cb93a386Sopenharmony_ci            //}
294cb93a386Sopenharmony_ci
295cb93a386Sopenharmony_ci            eventHandled = window->onMouse(xPos, yPos, skui::InputState::kMove,
296cb93a386Sopenharmony_ci                                           get_modifiers(message, wParam, lParam));
297cb93a386Sopenharmony_ci        } break;
298cb93a386Sopenharmony_ci
299cb93a386Sopenharmony_ci        case WM_MOUSEWHEEL:
300cb93a386Sopenharmony_ci            eventHandled = window->onMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f,
301cb93a386Sopenharmony_ci                                                get_modifiers(message, wParam, lParam));
302cb93a386Sopenharmony_ci            break;
303cb93a386Sopenharmony_ci
304cb93a386Sopenharmony_ci        case WM_TOUCH: {
305cb93a386Sopenharmony_ci            uint16_t numInputs = LOWORD(wParam);
306cb93a386Sopenharmony_ci            std::unique_ptr<TOUCHINPUT[]> inputs(new TOUCHINPUT[numInputs]);
307cb93a386Sopenharmony_ci            if (GetTouchInputInfo((HTOUCHINPUT)lParam, numInputs, inputs.get(),
308cb93a386Sopenharmony_ci                                  sizeof(TOUCHINPUT))) {
309cb93a386Sopenharmony_ci                POINT topLeft = {0, 0};
310cb93a386Sopenharmony_ci                ClientToScreen(hWnd, &topLeft);
311cb93a386Sopenharmony_ci                for (uint16_t i = 0; i < numInputs; ++i) {
312cb93a386Sopenharmony_ci                    TOUCHINPUT ti = inputs[i];
313cb93a386Sopenharmony_ci                    skui::InputState state;
314cb93a386Sopenharmony_ci                    if (ti.dwFlags & TOUCHEVENTF_DOWN) {
315cb93a386Sopenharmony_ci                        state = skui::InputState::kDown;
316cb93a386Sopenharmony_ci                    } else if (ti.dwFlags & TOUCHEVENTF_MOVE) {
317cb93a386Sopenharmony_ci                        state = skui::InputState::kMove;
318cb93a386Sopenharmony_ci                    } else if (ti.dwFlags & TOUCHEVENTF_UP) {
319cb93a386Sopenharmony_ci                        state = skui::InputState::kUp;
320cb93a386Sopenharmony_ci                    } else {
321cb93a386Sopenharmony_ci                        continue;
322cb93a386Sopenharmony_ci                    }
323cb93a386Sopenharmony_ci                    // TOUCHINPUT coordinates are in 100ths of pixels
324cb93a386Sopenharmony_ci                    // Adjust for that, and make them window relative
325cb93a386Sopenharmony_ci                    LONG tx = (ti.x / 100) - topLeft.x;
326cb93a386Sopenharmony_ci                    LONG ty = (ti.y / 100) - topLeft.y;
327cb93a386Sopenharmony_ci                    eventHandled = window->onTouch(ti.dwID, state, tx, ty) || eventHandled;
328cb93a386Sopenharmony_ci                }
329cb93a386Sopenharmony_ci            }
330cb93a386Sopenharmony_ci        } break;
331cb93a386Sopenharmony_ci
332cb93a386Sopenharmony_ci        default:
333cb93a386Sopenharmony_ci            return DefWindowProc(hWnd, message, wParam, lParam);
334cb93a386Sopenharmony_ci    }
335cb93a386Sopenharmony_ci
336cb93a386Sopenharmony_ci    return eventHandled ? 0 : 1;
337cb93a386Sopenharmony_ci}
338cb93a386Sopenharmony_ci
339cb93a386Sopenharmony_civoid Window_win::setTitle(const char* title) {
340cb93a386Sopenharmony_ci    SetWindowTextA(fHWnd, title);
341cb93a386Sopenharmony_ci}
342cb93a386Sopenharmony_ci
343cb93a386Sopenharmony_civoid Window_win::show() {
344cb93a386Sopenharmony_ci    ShowWindow(fHWnd, SW_SHOW);
345cb93a386Sopenharmony_ci}
346cb93a386Sopenharmony_ci
347cb93a386Sopenharmony_ci
348cb93a386Sopenharmony_cibool Window_win::attach(BackendType attachType) {
349cb93a386Sopenharmony_ci    fBackend = attachType;
350cb93a386Sopenharmony_ci    fInitializedBackend = true;
351cb93a386Sopenharmony_ci
352cb93a386Sopenharmony_ci    switch (attachType) {
353cb93a386Sopenharmony_ci#ifdef SK_GL
354cb93a386Sopenharmony_ci        case kNativeGL_BackendType:
355cb93a386Sopenharmony_ci            fWindowContext = window_context_factory::MakeGLForWin(fHWnd, fRequestedDisplayParams);
356cb93a386Sopenharmony_ci            break;
357cb93a386Sopenharmony_ci#endif
358cb93a386Sopenharmony_ci#if SK_ANGLE
359cb93a386Sopenharmony_ci        case kANGLE_BackendType:
360cb93a386Sopenharmony_ci            fWindowContext =
361cb93a386Sopenharmony_ci                    window_context_factory::MakeANGLEForWin(fHWnd, fRequestedDisplayParams);
362cb93a386Sopenharmony_ci            break;
363cb93a386Sopenharmony_ci#endif
364cb93a386Sopenharmony_ci#ifdef SK_DAWN
365cb93a386Sopenharmony_ci        case kDawn_BackendType:
366cb93a386Sopenharmony_ci            fWindowContext =
367cb93a386Sopenharmony_ci                    window_context_factory::MakeDawnD3D12ForWin(fHWnd, fRequestedDisplayParams);
368cb93a386Sopenharmony_ci            break;
369cb93a386Sopenharmony_ci#endif
370cb93a386Sopenharmony_ci        case kRaster_BackendType:
371cb93a386Sopenharmony_ci            fWindowContext =
372cb93a386Sopenharmony_ci                    window_context_factory::MakeRasterForWin(fHWnd, fRequestedDisplayParams);
373cb93a386Sopenharmony_ci            break;
374cb93a386Sopenharmony_ci#ifdef SK_VULKAN
375cb93a386Sopenharmony_ci        case kVulkan_BackendType:
376cb93a386Sopenharmony_ci            fWindowContext =
377cb93a386Sopenharmony_ci                    window_context_factory::MakeVulkanForWin(fHWnd, fRequestedDisplayParams);
378cb93a386Sopenharmony_ci            break;
379cb93a386Sopenharmony_ci#endif
380cb93a386Sopenharmony_ci#ifdef SK_DIRECT3D
381cb93a386Sopenharmony_ci        case kDirect3D_BackendType:
382cb93a386Sopenharmony_ci            fWindowContext =
383cb93a386Sopenharmony_ci                window_context_factory::MakeD3D12ForWin(fHWnd, fRequestedDisplayParams);
384cb93a386Sopenharmony_ci            break;
385cb93a386Sopenharmony_ci#endif
386cb93a386Sopenharmony_ci    }
387cb93a386Sopenharmony_ci    this->onBackendCreated();
388cb93a386Sopenharmony_ci
389cb93a386Sopenharmony_ci    return (SkToBool(fWindowContext));
390cb93a386Sopenharmony_ci}
391cb93a386Sopenharmony_ci
392cb93a386Sopenharmony_civoid Window_win::onInval() {
393cb93a386Sopenharmony_ci    InvalidateRect(fHWnd, nullptr, false);
394cb93a386Sopenharmony_ci}
395cb93a386Sopenharmony_ci
396cb93a386Sopenharmony_civoid Window_win::setRequestedDisplayParams(const DisplayParams& params, bool allowReattach) {
397cb93a386Sopenharmony_ci    // GL on Windows doesn't let us change MSAA after the window is created
398cb93a386Sopenharmony_ci    if (params.fMSAASampleCount != this->getRequestedDisplayParams().fMSAASampleCount
399cb93a386Sopenharmony_ci            && allowReattach) {
400cb93a386Sopenharmony_ci        // Need to change these early, so attach() creates the window context correctly
401cb93a386Sopenharmony_ci        fRequestedDisplayParams = params;
402cb93a386Sopenharmony_ci
403cb93a386Sopenharmony_ci        fWindowContext = nullptr;
404cb93a386Sopenharmony_ci        this->closeWindow();
405cb93a386Sopenharmony_ci        this->init(fHInstance);
406cb93a386Sopenharmony_ci        if (fInitializedBackend) {
407cb93a386Sopenharmony_ci            this->attach(fBackend);
408cb93a386Sopenharmony_ci        }
409cb93a386Sopenharmony_ci    }
410cb93a386Sopenharmony_ci
411cb93a386Sopenharmony_ci    INHERITED::setRequestedDisplayParams(params, allowReattach);
412cb93a386Sopenharmony_ci}
413cb93a386Sopenharmony_ci
414cb93a386Sopenharmony_ci}   // namespace sk_app
415