xref: /aosp_15_r20/external/angle/util/windows/win32/Win32Window.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // Win32Window.cpp: Implementation of OSWindow for Win32 (Windows)
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "util/windows/win32/Win32Window.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include <crtdbg.h>
12*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
15*8975f5c5SAndroid Build Coastguard Worker 
VirtualKeyCodeToKey(WPARAM key,LPARAM flags)16*8975f5c5SAndroid Build Coastguard Worker Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags)
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker     switch (key)
19*8975f5c5SAndroid Build Coastguard Worker     {
20*8975f5c5SAndroid Build Coastguard Worker         // Check the scancode to distinguish between left and right shift
21*8975f5c5SAndroid Build Coastguard Worker         case VK_SHIFT:
22*8975f5c5SAndroid Build Coastguard Worker         {
23*8975f5c5SAndroid Build Coastguard Worker             static unsigned int lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
24*8975f5c5SAndroid Build Coastguard Worker             unsigned int scancode      = static_cast<unsigned int>((flags & (0xFF << 16)) >> 16);
25*8975f5c5SAndroid Build Coastguard Worker             return scancode == lShift ? KEY_LSHIFT : KEY_RSHIFT;
26*8975f5c5SAndroid Build Coastguard Worker         }
27*8975f5c5SAndroid Build Coastguard Worker 
28*8975f5c5SAndroid Build Coastguard Worker         // Check the "extended" flag to distinguish between left and right alt
29*8975f5c5SAndroid Build Coastguard Worker         case VK_MENU:
30*8975f5c5SAndroid Build Coastguard Worker             return (HIWORD(flags) & KF_EXTENDED) ? KEY_RALT : KEY_LALT;
31*8975f5c5SAndroid Build Coastguard Worker 
32*8975f5c5SAndroid Build Coastguard Worker         // Check the "extended" flag to distinguish between left and right control
33*8975f5c5SAndroid Build Coastguard Worker         case VK_CONTROL:
34*8975f5c5SAndroid Build Coastguard Worker             return (HIWORD(flags) & KF_EXTENDED) ? KEY_RCONTROL : KEY_LCONTROL;
35*8975f5c5SAndroid Build Coastguard Worker 
36*8975f5c5SAndroid Build Coastguard Worker         // Other keys are reported properly
37*8975f5c5SAndroid Build Coastguard Worker         case VK_LWIN:
38*8975f5c5SAndroid Build Coastguard Worker             return KEY_LSYSTEM;
39*8975f5c5SAndroid Build Coastguard Worker         case VK_RWIN:
40*8975f5c5SAndroid Build Coastguard Worker             return KEY_RSYSTEM;
41*8975f5c5SAndroid Build Coastguard Worker         case VK_APPS:
42*8975f5c5SAndroid Build Coastguard Worker             return KEY_MENU;
43*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_1:
44*8975f5c5SAndroid Build Coastguard Worker             return KEY_SEMICOLON;
45*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_2:
46*8975f5c5SAndroid Build Coastguard Worker             return KEY_SLASH;
47*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_PLUS:
48*8975f5c5SAndroid Build Coastguard Worker             return KEY_EQUAL;
49*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_MINUS:
50*8975f5c5SAndroid Build Coastguard Worker             return KEY_DASH;
51*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_4:
52*8975f5c5SAndroid Build Coastguard Worker             return KEY_LBRACKET;
53*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_6:
54*8975f5c5SAndroid Build Coastguard Worker             return KEY_RBRACKET;
55*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_COMMA:
56*8975f5c5SAndroid Build Coastguard Worker             return KEY_COMMA;
57*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_PERIOD:
58*8975f5c5SAndroid Build Coastguard Worker             return KEY_PERIOD;
59*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_7:
60*8975f5c5SAndroid Build Coastguard Worker             return KEY_QUOTE;
61*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_5:
62*8975f5c5SAndroid Build Coastguard Worker             return KEY_BACKSLASH;
63*8975f5c5SAndroid Build Coastguard Worker         case VK_OEM_3:
64*8975f5c5SAndroid Build Coastguard Worker             return KEY_TILDE;
65*8975f5c5SAndroid Build Coastguard Worker         case VK_ESCAPE:
66*8975f5c5SAndroid Build Coastguard Worker             return KEY_ESCAPE;
67*8975f5c5SAndroid Build Coastguard Worker         case VK_SPACE:
68*8975f5c5SAndroid Build Coastguard Worker             return KEY_SPACE;
69*8975f5c5SAndroid Build Coastguard Worker         case VK_RETURN:
70*8975f5c5SAndroid Build Coastguard Worker             return KEY_RETURN;
71*8975f5c5SAndroid Build Coastguard Worker         case VK_BACK:
72*8975f5c5SAndroid Build Coastguard Worker             return KEY_BACK;
73*8975f5c5SAndroid Build Coastguard Worker         case VK_TAB:
74*8975f5c5SAndroid Build Coastguard Worker             return KEY_TAB;
75*8975f5c5SAndroid Build Coastguard Worker         case VK_PRIOR:
76*8975f5c5SAndroid Build Coastguard Worker             return KEY_PAGEUP;
77*8975f5c5SAndroid Build Coastguard Worker         case VK_NEXT:
78*8975f5c5SAndroid Build Coastguard Worker             return KEY_PAGEDOWN;
79*8975f5c5SAndroid Build Coastguard Worker         case VK_END:
80*8975f5c5SAndroid Build Coastguard Worker             return KEY_END;
81*8975f5c5SAndroid Build Coastguard Worker         case VK_HOME:
82*8975f5c5SAndroid Build Coastguard Worker             return KEY_HOME;
83*8975f5c5SAndroid Build Coastguard Worker         case VK_INSERT:
84*8975f5c5SAndroid Build Coastguard Worker             return KEY_INSERT;
85*8975f5c5SAndroid Build Coastguard Worker         case VK_DELETE:
86*8975f5c5SAndroid Build Coastguard Worker             return KEY_DELETE;
87*8975f5c5SAndroid Build Coastguard Worker         case VK_ADD:
88*8975f5c5SAndroid Build Coastguard Worker             return KEY_ADD;
89*8975f5c5SAndroid Build Coastguard Worker         case VK_SUBTRACT:
90*8975f5c5SAndroid Build Coastguard Worker             return KEY_SUBTRACT;
91*8975f5c5SAndroid Build Coastguard Worker         case VK_MULTIPLY:
92*8975f5c5SAndroid Build Coastguard Worker             return KEY_MULTIPLY;
93*8975f5c5SAndroid Build Coastguard Worker         case VK_DIVIDE:
94*8975f5c5SAndroid Build Coastguard Worker             return KEY_DIVIDE;
95*8975f5c5SAndroid Build Coastguard Worker         case VK_PAUSE:
96*8975f5c5SAndroid Build Coastguard Worker             return KEY_PAUSE;
97*8975f5c5SAndroid Build Coastguard Worker         case VK_F1:
98*8975f5c5SAndroid Build Coastguard Worker             return KEY_F1;
99*8975f5c5SAndroid Build Coastguard Worker         case VK_F2:
100*8975f5c5SAndroid Build Coastguard Worker             return KEY_F2;
101*8975f5c5SAndroid Build Coastguard Worker         case VK_F3:
102*8975f5c5SAndroid Build Coastguard Worker             return KEY_F3;
103*8975f5c5SAndroid Build Coastguard Worker         case VK_F4:
104*8975f5c5SAndroid Build Coastguard Worker             return KEY_F4;
105*8975f5c5SAndroid Build Coastguard Worker         case VK_F5:
106*8975f5c5SAndroid Build Coastguard Worker             return KEY_F5;
107*8975f5c5SAndroid Build Coastguard Worker         case VK_F6:
108*8975f5c5SAndroid Build Coastguard Worker             return KEY_F6;
109*8975f5c5SAndroid Build Coastguard Worker         case VK_F7:
110*8975f5c5SAndroid Build Coastguard Worker             return KEY_F7;
111*8975f5c5SAndroid Build Coastguard Worker         case VK_F8:
112*8975f5c5SAndroid Build Coastguard Worker             return KEY_F8;
113*8975f5c5SAndroid Build Coastguard Worker         case VK_F9:
114*8975f5c5SAndroid Build Coastguard Worker             return KEY_F9;
115*8975f5c5SAndroid Build Coastguard Worker         case VK_F10:
116*8975f5c5SAndroid Build Coastguard Worker             return KEY_F10;
117*8975f5c5SAndroid Build Coastguard Worker         case VK_F11:
118*8975f5c5SAndroid Build Coastguard Worker             return KEY_F11;
119*8975f5c5SAndroid Build Coastguard Worker         case VK_F12:
120*8975f5c5SAndroid Build Coastguard Worker             return KEY_F12;
121*8975f5c5SAndroid Build Coastguard Worker         case VK_F13:
122*8975f5c5SAndroid Build Coastguard Worker             return KEY_F13;
123*8975f5c5SAndroid Build Coastguard Worker         case VK_F14:
124*8975f5c5SAndroid Build Coastguard Worker             return KEY_F14;
125*8975f5c5SAndroid Build Coastguard Worker         case VK_F15:
126*8975f5c5SAndroid Build Coastguard Worker             return KEY_F15;
127*8975f5c5SAndroid Build Coastguard Worker         case VK_LEFT:
128*8975f5c5SAndroid Build Coastguard Worker             return KEY_LEFT;
129*8975f5c5SAndroid Build Coastguard Worker         case VK_RIGHT:
130*8975f5c5SAndroid Build Coastguard Worker             return KEY_RIGHT;
131*8975f5c5SAndroid Build Coastguard Worker         case VK_UP:
132*8975f5c5SAndroid Build Coastguard Worker             return KEY_UP;
133*8975f5c5SAndroid Build Coastguard Worker         case VK_DOWN:
134*8975f5c5SAndroid Build Coastguard Worker             return KEY_DOWN;
135*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD0:
136*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD0;
137*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD1:
138*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD1;
139*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD2:
140*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD2;
141*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD3:
142*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD3;
143*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD4:
144*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD4;
145*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD5:
146*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD5;
147*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD6:
148*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD6;
149*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD7:
150*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD7;
151*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD8:
152*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD8;
153*8975f5c5SAndroid Build Coastguard Worker         case VK_NUMPAD9:
154*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUMPAD9;
155*8975f5c5SAndroid Build Coastguard Worker         case 'A':
156*8975f5c5SAndroid Build Coastguard Worker             return KEY_A;
157*8975f5c5SAndroid Build Coastguard Worker         case 'Z':
158*8975f5c5SAndroid Build Coastguard Worker             return KEY_Z;
159*8975f5c5SAndroid Build Coastguard Worker         case 'E':
160*8975f5c5SAndroid Build Coastguard Worker             return KEY_E;
161*8975f5c5SAndroid Build Coastguard Worker         case 'R':
162*8975f5c5SAndroid Build Coastguard Worker             return KEY_R;
163*8975f5c5SAndroid Build Coastguard Worker         case 'T':
164*8975f5c5SAndroid Build Coastguard Worker             return KEY_T;
165*8975f5c5SAndroid Build Coastguard Worker         case 'Y':
166*8975f5c5SAndroid Build Coastguard Worker             return KEY_Y;
167*8975f5c5SAndroid Build Coastguard Worker         case 'U':
168*8975f5c5SAndroid Build Coastguard Worker             return KEY_U;
169*8975f5c5SAndroid Build Coastguard Worker         case 'I':
170*8975f5c5SAndroid Build Coastguard Worker             return KEY_I;
171*8975f5c5SAndroid Build Coastguard Worker         case 'O':
172*8975f5c5SAndroid Build Coastguard Worker             return KEY_O;
173*8975f5c5SAndroid Build Coastguard Worker         case 'P':
174*8975f5c5SAndroid Build Coastguard Worker             return KEY_P;
175*8975f5c5SAndroid Build Coastguard Worker         case 'Q':
176*8975f5c5SAndroid Build Coastguard Worker             return KEY_Q;
177*8975f5c5SAndroid Build Coastguard Worker         case 'S':
178*8975f5c5SAndroid Build Coastguard Worker             return KEY_S;
179*8975f5c5SAndroid Build Coastguard Worker         case 'D':
180*8975f5c5SAndroid Build Coastguard Worker             return KEY_D;
181*8975f5c5SAndroid Build Coastguard Worker         case 'F':
182*8975f5c5SAndroid Build Coastguard Worker             return KEY_F;
183*8975f5c5SAndroid Build Coastguard Worker         case 'G':
184*8975f5c5SAndroid Build Coastguard Worker             return KEY_G;
185*8975f5c5SAndroid Build Coastguard Worker         case 'H':
186*8975f5c5SAndroid Build Coastguard Worker             return KEY_H;
187*8975f5c5SAndroid Build Coastguard Worker         case 'J':
188*8975f5c5SAndroid Build Coastguard Worker             return KEY_J;
189*8975f5c5SAndroid Build Coastguard Worker         case 'K':
190*8975f5c5SAndroid Build Coastguard Worker             return KEY_K;
191*8975f5c5SAndroid Build Coastguard Worker         case 'L':
192*8975f5c5SAndroid Build Coastguard Worker             return KEY_L;
193*8975f5c5SAndroid Build Coastguard Worker         case 'M':
194*8975f5c5SAndroid Build Coastguard Worker             return KEY_M;
195*8975f5c5SAndroid Build Coastguard Worker         case 'W':
196*8975f5c5SAndroid Build Coastguard Worker             return KEY_W;
197*8975f5c5SAndroid Build Coastguard Worker         case 'X':
198*8975f5c5SAndroid Build Coastguard Worker             return KEY_X;
199*8975f5c5SAndroid Build Coastguard Worker         case 'C':
200*8975f5c5SAndroid Build Coastguard Worker             return KEY_C;
201*8975f5c5SAndroid Build Coastguard Worker         case 'V':
202*8975f5c5SAndroid Build Coastguard Worker             return KEY_V;
203*8975f5c5SAndroid Build Coastguard Worker         case 'B':
204*8975f5c5SAndroid Build Coastguard Worker             return KEY_B;
205*8975f5c5SAndroid Build Coastguard Worker         case 'N':
206*8975f5c5SAndroid Build Coastguard Worker             return KEY_N;
207*8975f5c5SAndroid Build Coastguard Worker         case '0':
208*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM0;
209*8975f5c5SAndroid Build Coastguard Worker         case '1':
210*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM1;
211*8975f5c5SAndroid Build Coastguard Worker         case '2':
212*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM2;
213*8975f5c5SAndroid Build Coastguard Worker         case '3':
214*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM3;
215*8975f5c5SAndroid Build Coastguard Worker         case '4':
216*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM4;
217*8975f5c5SAndroid Build Coastguard Worker         case '5':
218*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM5;
219*8975f5c5SAndroid Build Coastguard Worker         case '6':
220*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM6;
221*8975f5c5SAndroid Build Coastguard Worker         case '7':
222*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM7;
223*8975f5c5SAndroid Build Coastguard Worker         case '8':
224*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM8;
225*8975f5c5SAndroid Build Coastguard Worker         case '9':
226*8975f5c5SAndroid Build Coastguard Worker             return KEY_NUM9;
227*8975f5c5SAndroid Build Coastguard Worker     }
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker     return Key(0);
230*8975f5c5SAndroid Build Coastguard Worker }
231*8975f5c5SAndroid Build Coastguard Worker 
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)232*8975f5c5SAndroid Build Coastguard Worker LRESULT CALLBACK Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
233*8975f5c5SAndroid Build Coastguard Worker {
234*8975f5c5SAndroid Build Coastguard Worker     switch (message)
235*8975f5c5SAndroid Build Coastguard Worker     {
236*8975f5c5SAndroid Build Coastguard Worker         case WM_NCCREATE:
237*8975f5c5SAndroid Build Coastguard Worker         {
238*8975f5c5SAndroid Build Coastguard Worker             LPCREATESTRUCT pCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
239*8975f5c5SAndroid Build Coastguard Worker             SetWindowLongPtr(hWnd, GWLP_USERDATA,
240*8975f5c5SAndroid Build Coastguard Worker                              reinterpret_cast<LONG_PTR>(pCreateStruct->lpCreateParams));
241*8975f5c5SAndroid Build Coastguard Worker             return DefWindowProcA(hWnd, message, wParam, lParam);
242*8975f5c5SAndroid Build Coastguard Worker         }
243*8975f5c5SAndroid Build Coastguard Worker     }
244*8975f5c5SAndroid Build Coastguard Worker 
245*8975f5c5SAndroid Build Coastguard Worker     Win32Window *window = reinterpret_cast<Win32Window *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
246*8975f5c5SAndroid Build Coastguard Worker     if (window)
247*8975f5c5SAndroid Build Coastguard Worker     {
248*8975f5c5SAndroid Build Coastguard Worker         switch (message)
249*8975f5c5SAndroid Build Coastguard Worker         {
250*8975f5c5SAndroid Build Coastguard Worker             case WM_DESTROY:
251*8975f5c5SAndroid Build Coastguard Worker             case WM_CLOSE:
252*8975f5c5SAndroid Build Coastguard Worker             {
253*8975f5c5SAndroid Build Coastguard Worker                 Event event;
254*8975f5c5SAndroid Build Coastguard Worker                 event.Type = Event::EVENT_CLOSED;
255*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
256*8975f5c5SAndroid Build Coastguard Worker                 break;
257*8975f5c5SAndroid Build Coastguard Worker             }
258*8975f5c5SAndroid Build Coastguard Worker 
259*8975f5c5SAndroid Build Coastguard Worker             case WM_MOVE:
260*8975f5c5SAndroid Build Coastguard Worker             {
261*8975f5c5SAndroid Build Coastguard Worker                 RECT winRect;
262*8975f5c5SAndroid Build Coastguard Worker                 GetClientRect(hWnd, &winRect);
263*8975f5c5SAndroid Build Coastguard Worker 
264*8975f5c5SAndroid Build Coastguard Worker                 POINT topLeft;
265*8975f5c5SAndroid Build Coastguard Worker                 topLeft.x = winRect.left;
266*8975f5c5SAndroid Build Coastguard Worker                 topLeft.y = winRect.top;
267*8975f5c5SAndroid Build Coastguard Worker                 ClientToScreen(hWnd, &topLeft);
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker                 Event event;
270*8975f5c5SAndroid Build Coastguard Worker                 event.Type   = Event::EVENT_MOVED;
271*8975f5c5SAndroid Build Coastguard Worker                 event.Move.X = topLeft.x;
272*8975f5c5SAndroid Build Coastguard Worker                 event.Move.Y = topLeft.y;
273*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker                 break;
276*8975f5c5SAndroid Build Coastguard Worker             }
277*8975f5c5SAndroid Build Coastguard Worker 
278*8975f5c5SAndroid Build Coastguard Worker             case WM_SIZE:
279*8975f5c5SAndroid Build Coastguard Worker             {
280*8975f5c5SAndroid Build Coastguard Worker                 if (window->mIgnoreSizeEvents)
281*8975f5c5SAndroid Build Coastguard Worker                     break;
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker                 RECT winRect;
284*8975f5c5SAndroid Build Coastguard Worker                 GetClientRect(hWnd, &winRect);
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker                 POINT topLeft;
287*8975f5c5SAndroid Build Coastguard Worker                 topLeft.x = winRect.left;
288*8975f5c5SAndroid Build Coastguard Worker                 topLeft.y = winRect.top;
289*8975f5c5SAndroid Build Coastguard Worker                 ClientToScreen(hWnd, &topLeft);
290*8975f5c5SAndroid Build Coastguard Worker 
291*8975f5c5SAndroid Build Coastguard Worker                 POINT botRight;
292*8975f5c5SAndroid Build Coastguard Worker                 botRight.x = winRect.right;
293*8975f5c5SAndroid Build Coastguard Worker                 botRight.y = winRect.bottom;
294*8975f5c5SAndroid Build Coastguard Worker                 ClientToScreen(hWnd, &botRight);
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker                 Event event;
297*8975f5c5SAndroid Build Coastguard Worker                 event.Type        = Event::EVENT_RESIZED;
298*8975f5c5SAndroid Build Coastguard Worker                 event.Size.Width  = botRight.x - topLeft.x;
299*8975f5c5SAndroid Build Coastguard Worker                 event.Size.Height = botRight.y - topLeft.y;
300*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
301*8975f5c5SAndroid Build Coastguard Worker 
302*8975f5c5SAndroid Build Coastguard Worker                 break;
303*8975f5c5SAndroid Build Coastguard Worker             }
304*8975f5c5SAndroid Build Coastguard Worker 
305*8975f5c5SAndroid Build Coastguard Worker             case WM_SETFOCUS:
306*8975f5c5SAndroid Build Coastguard Worker             {
307*8975f5c5SAndroid Build Coastguard Worker                 Event event;
308*8975f5c5SAndroid Build Coastguard Worker                 event.Type = Event::EVENT_GAINED_FOCUS;
309*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
310*8975f5c5SAndroid Build Coastguard Worker                 break;
311*8975f5c5SAndroid Build Coastguard Worker             }
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker             case WM_KILLFOCUS:
314*8975f5c5SAndroid Build Coastguard Worker             {
315*8975f5c5SAndroid Build Coastguard Worker                 Event event;
316*8975f5c5SAndroid Build Coastguard Worker                 event.Type = Event::EVENT_LOST_FOCUS;
317*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
318*8975f5c5SAndroid Build Coastguard Worker                 break;
319*8975f5c5SAndroid Build Coastguard Worker             }
320*8975f5c5SAndroid Build Coastguard Worker 
321*8975f5c5SAndroid Build Coastguard Worker             case WM_KEYDOWN:
322*8975f5c5SAndroid Build Coastguard Worker             case WM_SYSKEYDOWN:
323*8975f5c5SAndroid Build Coastguard Worker             case WM_KEYUP:
324*8975f5c5SAndroid Build Coastguard Worker             case WM_SYSKEYUP:
325*8975f5c5SAndroid Build Coastguard Worker             {
326*8975f5c5SAndroid Build Coastguard Worker                 bool down = (message == WM_KEYDOWN || message == WM_SYSKEYDOWN);
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker                 Event event;
329*8975f5c5SAndroid Build Coastguard Worker                 event.Type        = down ? Event::EVENT_KEY_PRESSED : Event::EVENT_KEY_RELEASED;
330*8975f5c5SAndroid Build Coastguard Worker                 event.Key.Alt     = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
331*8975f5c5SAndroid Build Coastguard Worker                 event.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
332*8975f5c5SAndroid Build Coastguard Worker                 event.Key.Shift   = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
333*8975f5c5SAndroid Build Coastguard Worker                 event.Key.System =
334*8975f5c5SAndroid Build Coastguard Worker                     HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
335*8975f5c5SAndroid Build Coastguard Worker                 event.Key.Code = VirtualKeyCodeToKey(wParam, lParam);
336*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
337*8975f5c5SAndroid Build Coastguard Worker 
338*8975f5c5SAndroid Build Coastguard Worker                 break;
339*8975f5c5SAndroid Build Coastguard Worker             }
340*8975f5c5SAndroid Build Coastguard Worker 
341*8975f5c5SAndroid Build Coastguard Worker             case WM_MOUSEWHEEL:
342*8975f5c5SAndroid Build Coastguard Worker             {
343*8975f5c5SAndroid Build Coastguard Worker                 Event event;
344*8975f5c5SAndroid Build Coastguard Worker                 event.Type             = Event::EVENT_MOUSE_WHEEL_MOVED;
345*8975f5c5SAndroid Build Coastguard Worker                 event.MouseWheel.Delta = static_cast<short>(HIWORD(wParam)) / 120;
346*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
347*8975f5c5SAndroid Build Coastguard Worker                 break;
348*8975f5c5SAndroid Build Coastguard Worker             }
349*8975f5c5SAndroid Build Coastguard Worker 
350*8975f5c5SAndroid Build Coastguard Worker             case WM_LBUTTONDOWN:
351*8975f5c5SAndroid Build Coastguard Worker             case WM_LBUTTONDBLCLK:
352*8975f5c5SAndroid Build Coastguard Worker             {
353*8975f5c5SAndroid Build Coastguard Worker                 Event event;
354*8975f5c5SAndroid Build Coastguard Worker                 event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
355*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Button = MOUSEBUTTON_LEFT;
356*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
357*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
358*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
359*8975f5c5SAndroid Build Coastguard Worker                 break;
360*8975f5c5SAndroid Build Coastguard Worker             }
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker             case WM_LBUTTONUP:
363*8975f5c5SAndroid Build Coastguard Worker             {
364*8975f5c5SAndroid Build Coastguard Worker                 Event event;
365*8975f5c5SAndroid Build Coastguard Worker                 event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
366*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Button = MOUSEBUTTON_LEFT;
367*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
368*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
369*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
370*8975f5c5SAndroid Build Coastguard Worker                 break;
371*8975f5c5SAndroid Build Coastguard Worker             }
372*8975f5c5SAndroid Build Coastguard Worker 
373*8975f5c5SAndroid Build Coastguard Worker             case WM_RBUTTONDOWN:
374*8975f5c5SAndroid Build Coastguard Worker             case WM_RBUTTONDBLCLK:
375*8975f5c5SAndroid Build Coastguard Worker             {
376*8975f5c5SAndroid Build Coastguard Worker                 Event event;
377*8975f5c5SAndroid Build Coastguard Worker                 event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
378*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Button = MOUSEBUTTON_RIGHT;
379*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
380*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
381*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
382*8975f5c5SAndroid Build Coastguard Worker                 break;
383*8975f5c5SAndroid Build Coastguard Worker             }
384*8975f5c5SAndroid Build Coastguard Worker 
385*8975f5c5SAndroid Build Coastguard Worker             // Mouse right button up event
386*8975f5c5SAndroid Build Coastguard Worker             case WM_RBUTTONUP:
387*8975f5c5SAndroid Build Coastguard Worker             {
388*8975f5c5SAndroid Build Coastguard Worker                 Event event;
389*8975f5c5SAndroid Build Coastguard Worker                 event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
390*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Button = MOUSEBUTTON_RIGHT;
391*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
392*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
393*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
394*8975f5c5SAndroid Build Coastguard Worker                 break;
395*8975f5c5SAndroid Build Coastguard Worker             }
396*8975f5c5SAndroid Build Coastguard Worker 
397*8975f5c5SAndroid Build Coastguard Worker             // Mouse wheel button down event
398*8975f5c5SAndroid Build Coastguard Worker             case WM_MBUTTONDOWN:
399*8975f5c5SAndroid Build Coastguard Worker             case WM_MBUTTONDBLCLK:
400*8975f5c5SAndroid Build Coastguard Worker             {
401*8975f5c5SAndroid Build Coastguard Worker                 Event event;
402*8975f5c5SAndroid Build Coastguard Worker                 event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
403*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
404*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
405*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
406*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
407*8975f5c5SAndroid Build Coastguard Worker                 break;
408*8975f5c5SAndroid Build Coastguard Worker             }
409*8975f5c5SAndroid Build Coastguard Worker 
410*8975f5c5SAndroid Build Coastguard Worker             // Mouse wheel button up event
411*8975f5c5SAndroid Build Coastguard Worker             case WM_MBUTTONUP:
412*8975f5c5SAndroid Build Coastguard Worker             {
413*8975f5c5SAndroid Build Coastguard Worker                 Event event;
414*8975f5c5SAndroid Build Coastguard Worker                 event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
415*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
416*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
417*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
418*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
419*8975f5c5SAndroid Build Coastguard Worker                 break;
420*8975f5c5SAndroid Build Coastguard Worker             }
421*8975f5c5SAndroid Build Coastguard Worker 
422*8975f5c5SAndroid Build Coastguard Worker             // Mouse X button down event
423*8975f5c5SAndroid Build Coastguard Worker             case WM_XBUTTONDOWN:
424*8975f5c5SAndroid Build Coastguard Worker             case WM_XBUTTONDBLCLK:
425*8975f5c5SAndroid Build Coastguard Worker             {
426*8975f5c5SAndroid Build Coastguard Worker                 Event event;
427*8975f5c5SAndroid Build Coastguard Worker                 event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
428*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Button =
429*8975f5c5SAndroid Build Coastguard Worker                     (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
430*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.X = static_cast<short>(LOWORD(lParam));
431*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
432*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
433*8975f5c5SAndroid Build Coastguard Worker                 break;
434*8975f5c5SAndroid Build Coastguard Worker             }
435*8975f5c5SAndroid Build Coastguard Worker 
436*8975f5c5SAndroid Build Coastguard Worker             // Mouse X button up event
437*8975f5c5SAndroid Build Coastguard Worker             case WM_XBUTTONUP:
438*8975f5c5SAndroid Build Coastguard Worker             {
439*8975f5c5SAndroid Build Coastguard Worker                 Event event;
440*8975f5c5SAndroid Build Coastguard Worker                 event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
441*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Button =
442*8975f5c5SAndroid Build Coastguard Worker                     (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
443*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.X = static_cast<short>(LOWORD(lParam));
444*8975f5c5SAndroid Build Coastguard Worker                 event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
445*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
446*8975f5c5SAndroid Build Coastguard Worker                 break;
447*8975f5c5SAndroid Build Coastguard Worker             }
448*8975f5c5SAndroid Build Coastguard Worker 
449*8975f5c5SAndroid Build Coastguard Worker             case WM_MOUSEMOVE:
450*8975f5c5SAndroid Build Coastguard Worker             {
451*8975f5c5SAndroid Build Coastguard Worker                 if (!window->mIsMouseInWindow)
452*8975f5c5SAndroid Build Coastguard Worker                 {
453*8975f5c5SAndroid Build Coastguard Worker                     window->mIsMouseInWindow = true;
454*8975f5c5SAndroid Build Coastguard Worker                     Event event;
455*8975f5c5SAndroid Build Coastguard Worker                     event.Type = Event::EVENT_MOUSE_ENTERED;
456*8975f5c5SAndroid Build Coastguard Worker                     window->pushEvent(event);
457*8975f5c5SAndroid Build Coastguard Worker                 }
458*8975f5c5SAndroid Build Coastguard Worker 
459*8975f5c5SAndroid Build Coastguard Worker                 int mouseX = static_cast<short>(LOWORD(lParam));
460*8975f5c5SAndroid Build Coastguard Worker                 int mouseY = static_cast<short>(HIWORD(lParam));
461*8975f5c5SAndroid Build Coastguard Worker 
462*8975f5c5SAndroid Build Coastguard Worker                 Event event;
463*8975f5c5SAndroid Build Coastguard Worker                 event.Type        = Event::EVENT_MOUSE_MOVED;
464*8975f5c5SAndroid Build Coastguard Worker                 event.MouseMove.X = mouseX;
465*8975f5c5SAndroid Build Coastguard Worker                 event.MouseMove.Y = mouseY;
466*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
467*8975f5c5SAndroid Build Coastguard Worker                 break;
468*8975f5c5SAndroid Build Coastguard Worker             }
469*8975f5c5SAndroid Build Coastguard Worker 
470*8975f5c5SAndroid Build Coastguard Worker             case WM_MOUSELEAVE:
471*8975f5c5SAndroid Build Coastguard Worker             {
472*8975f5c5SAndroid Build Coastguard Worker                 Event event;
473*8975f5c5SAndroid Build Coastguard Worker                 event.Type = Event::EVENT_MOUSE_LEFT;
474*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(event);
475*8975f5c5SAndroid Build Coastguard Worker                 window->mIsMouseInWindow = false;
476*8975f5c5SAndroid Build Coastguard Worker                 break;
477*8975f5c5SAndroid Build Coastguard Worker             }
478*8975f5c5SAndroid Build Coastguard Worker 
479*8975f5c5SAndroid Build Coastguard Worker             case WM_USER:
480*8975f5c5SAndroid Build Coastguard Worker             {
481*8975f5c5SAndroid Build Coastguard Worker                 Event testEvent;
482*8975f5c5SAndroid Build Coastguard Worker                 testEvent.Type = Event::EVENT_TEST;
483*8975f5c5SAndroid Build Coastguard Worker                 window->pushEvent(testEvent);
484*8975f5c5SAndroid Build Coastguard Worker                 break;
485*8975f5c5SAndroid Build Coastguard Worker             }
486*8975f5c5SAndroid Build Coastguard Worker         }
487*8975f5c5SAndroid Build Coastguard Worker     }
488*8975f5c5SAndroid Build Coastguard Worker     return DefWindowProcA(hWnd, message, wParam, lParam);
489*8975f5c5SAndroid Build Coastguard Worker }
490*8975f5c5SAndroid Build Coastguard Worker 
Win32Window()491*8975f5c5SAndroid Build Coastguard Worker Win32Window::Win32Window()
492*8975f5c5SAndroid Build Coastguard Worker     : mIsVisible(false),
493*8975f5c5SAndroid Build Coastguard Worker       mIsMouseInWindow(false),
494*8975f5c5SAndroid Build Coastguard Worker       mNativeWindow(0),
495*8975f5c5SAndroid Build Coastguard Worker       mParentWindow(0),
496*8975f5c5SAndroid Build Coastguard Worker       mNativeDisplay(0)
497*8975f5c5SAndroid Build Coastguard Worker {}
498*8975f5c5SAndroid Build Coastguard Worker 
~Win32Window()499*8975f5c5SAndroid Build Coastguard Worker Win32Window::~Win32Window()
500*8975f5c5SAndroid Build Coastguard Worker {
501*8975f5c5SAndroid Build Coastguard Worker     destroy();
502*8975f5c5SAndroid Build Coastguard Worker }
503*8975f5c5SAndroid Build Coastguard Worker 
initializeImpl(const std::string & name,int width,int height)504*8975f5c5SAndroid Build Coastguard Worker bool Win32Window::initializeImpl(const std::string &name, int width, int height)
505*8975f5c5SAndroid Build Coastguard Worker {
506*8975f5c5SAndroid Build Coastguard Worker     destroy();
507*8975f5c5SAndroid Build Coastguard Worker 
508*8975f5c5SAndroid Build Coastguard Worker     // Use a new window class name for ever window to ensure that a new window can be created
509*8975f5c5SAndroid Build Coastguard Worker     // even if the last one was not properly destroyed
510*8975f5c5SAndroid Build Coastguard Worker     static size_t windowIdx = 0;
511*8975f5c5SAndroid Build Coastguard Worker     std::ostringstream nameStream;
512*8975f5c5SAndroid Build Coastguard Worker     nameStream << name << "_" << windowIdx++;
513*8975f5c5SAndroid Build Coastguard Worker 
514*8975f5c5SAndroid Build Coastguard Worker     mParentClassName = nameStream.str();
515*8975f5c5SAndroid Build Coastguard Worker     mChildClassName  = mParentClassName + "_Child";
516*8975f5c5SAndroid Build Coastguard Worker 
517*8975f5c5SAndroid Build Coastguard Worker     // Work around compile error from not defining "UNICODE" while Chromium does
518*8975f5c5SAndroid Build Coastguard Worker     const LPSTR idcArrow = MAKEINTRESOURCEA(32512);
519*8975f5c5SAndroid Build Coastguard Worker 
520*8975f5c5SAndroid Build Coastguard Worker     WNDCLASSEXA parentWindowClass   = {};
521*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.cbSize        = sizeof(WNDCLASSEXA);
522*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.style         = 0;
523*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.lpfnWndProc   = WndProc;
524*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.cbClsExtra    = 0;
525*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.cbWndExtra    = 0;
526*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.hInstance     = GetModuleHandle(nullptr);
527*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.hIcon         = nullptr;
528*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.hCursor       = LoadCursorA(nullptr, idcArrow);
529*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.hbrBackground = 0;
530*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.lpszMenuName  = nullptr;
531*8975f5c5SAndroid Build Coastguard Worker     parentWindowClass.lpszClassName = mParentClassName.c_str();
532*8975f5c5SAndroid Build Coastguard Worker     if (!RegisterClassExA(&parentWindowClass))
533*8975f5c5SAndroid Build Coastguard Worker     {
534*8975f5c5SAndroid Build Coastguard Worker         return false;
535*8975f5c5SAndroid Build Coastguard Worker     }
536*8975f5c5SAndroid Build Coastguard Worker 
537*8975f5c5SAndroid Build Coastguard Worker     WNDCLASSEXA childWindowClass   = {};
538*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.cbSize        = sizeof(WNDCLASSEXA);
539*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.style         = CS_OWNDC;
540*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.lpfnWndProc   = WndProc;
541*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.cbClsExtra    = 0;
542*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.cbWndExtra    = 0;
543*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.hInstance     = GetModuleHandle(nullptr);
544*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.hIcon         = nullptr;
545*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.hCursor       = LoadCursorA(nullptr, idcArrow);
546*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.hbrBackground = 0;
547*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.lpszMenuName  = nullptr;
548*8975f5c5SAndroid Build Coastguard Worker     childWindowClass.lpszClassName = mChildClassName.c_str();
549*8975f5c5SAndroid Build Coastguard Worker     if (!RegisterClassExA(&childWindowClass))
550*8975f5c5SAndroid Build Coastguard Worker     {
551*8975f5c5SAndroid Build Coastguard Worker         return false;
552*8975f5c5SAndroid Build Coastguard Worker     }
553*8975f5c5SAndroid Build Coastguard Worker 
554*8975f5c5SAndroid Build Coastguard Worker     DWORD parentStyle = WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
555*8975f5c5SAndroid Build Coastguard Worker     DWORD parentExtendedStyle = WS_EX_APPWINDOW | WS_EX_TOOLWINDOW;
556*8975f5c5SAndroid Build Coastguard Worker 
557*8975f5c5SAndroid Build Coastguard Worker     RECT sizeRect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
558*8975f5c5SAndroid Build Coastguard Worker     AdjustWindowRectEx(&sizeRect, parentStyle, FALSE, parentExtendedStyle);
559*8975f5c5SAndroid Build Coastguard Worker 
560*8975f5c5SAndroid Build Coastguard Worker     mParentWindow = CreateWindowExA(parentExtendedStyle, mParentClassName.c_str(), name.c_str(),
561*8975f5c5SAndroid Build Coastguard Worker                                     parentStyle, CW_USEDEFAULT, CW_USEDEFAULT,
562*8975f5c5SAndroid Build Coastguard Worker                                     sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top,
563*8975f5c5SAndroid Build Coastguard Worker                                     nullptr, nullptr, GetModuleHandle(nullptr), this);
564*8975f5c5SAndroid Build Coastguard Worker 
565*8975f5c5SAndroid Build Coastguard Worker     mNativeWindow = CreateWindowExA(0, mChildClassName.c_str(), name.c_str(), WS_CHILD, 0, 0,
566*8975f5c5SAndroid Build Coastguard Worker                                     static_cast<int>(width), static_cast<int>(height),
567*8975f5c5SAndroid Build Coastguard Worker                                     mParentWindow, nullptr, GetModuleHandle(nullptr), this);
568*8975f5c5SAndroid Build Coastguard Worker 
569*8975f5c5SAndroid Build Coastguard Worker     mNativeDisplay = GetDC(mNativeWindow);
570*8975f5c5SAndroid Build Coastguard Worker     if (!mNativeDisplay)
571*8975f5c5SAndroid Build Coastguard Worker     {
572*8975f5c5SAndroid Build Coastguard Worker         destroy();
573*8975f5c5SAndroid Build Coastguard Worker         return false;
574*8975f5c5SAndroid Build Coastguard Worker     }
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker     return true;
577*8975f5c5SAndroid Build Coastguard Worker }
578*8975f5c5SAndroid Build Coastguard Worker 
disableErrorMessageDialog()579*8975f5c5SAndroid Build Coastguard Worker void Win32Window::disableErrorMessageDialog()
580*8975f5c5SAndroid Build Coastguard Worker {
581*8975f5c5SAndroid Build Coastguard Worker     _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
582*8975f5c5SAndroid Build Coastguard Worker     _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
583*8975f5c5SAndroid Build Coastguard Worker }
584*8975f5c5SAndroid Build Coastguard Worker 
destroy()585*8975f5c5SAndroid Build Coastguard Worker void Win32Window::destroy()
586*8975f5c5SAndroid Build Coastguard Worker {
587*8975f5c5SAndroid Build Coastguard Worker     if (mNativeDisplay)
588*8975f5c5SAndroid Build Coastguard Worker     {
589*8975f5c5SAndroid Build Coastguard Worker         ReleaseDC(mNativeWindow, mNativeDisplay);
590*8975f5c5SAndroid Build Coastguard Worker         mNativeDisplay = 0;
591*8975f5c5SAndroid Build Coastguard Worker     }
592*8975f5c5SAndroid Build Coastguard Worker 
593*8975f5c5SAndroid Build Coastguard Worker     if (mNativeWindow)
594*8975f5c5SAndroid Build Coastguard Worker     {
595*8975f5c5SAndroid Build Coastguard Worker         DestroyWindow(mNativeWindow);
596*8975f5c5SAndroid Build Coastguard Worker         mNativeWindow = 0;
597*8975f5c5SAndroid Build Coastguard Worker     }
598*8975f5c5SAndroid Build Coastguard Worker 
599*8975f5c5SAndroid Build Coastguard Worker     if (mParentWindow)
600*8975f5c5SAndroid Build Coastguard Worker     {
601*8975f5c5SAndroid Build Coastguard Worker         DestroyWindow(mParentWindow);
602*8975f5c5SAndroid Build Coastguard Worker         mParentWindow = 0;
603*8975f5c5SAndroid Build Coastguard Worker     }
604*8975f5c5SAndroid Build Coastguard Worker 
605*8975f5c5SAndroid Build Coastguard Worker     UnregisterClassA(mParentClassName.c_str(), nullptr);
606*8975f5c5SAndroid Build Coastguard Worker     UnregisterClassA(mChildClassName.c_str(), nullptr);
607*8975f5c5SAndroid Build Coastguard Worker }
608*8975f5c5SAndroid Build Coastguard Worker 
takeScreenshot(uint8_t * pixelData)609*8975f5c5SAndroid Build Coastguard Worker bool Win32Window::takeScreenshot(uint8_t *pixelData)
610*8975f5c5SAndroid Build Coastguard Worker {
611*8975f5c5SAndroid Build Coastguard Worker     if (mIsVisible)
612*8975f5c5SAndroid Build Coastguard Worker     {
613*8975f5c5SAndroid Build Coastguard Worker         return false;
614*8975f5c5SAndroid Build Coastguard Worker     }
615*8975f5c5SAndroid Build Coastguard Worker 
616*8975f5c5SAndroid Build Coastguard Worker     bool error = false;
617*8975f5c5SAndroid Build Coastguard Worker 
618*8975f5c5SAndroid Build Coastguard Worker     // Hack for DWM: There is no way to wait for DWM animations to finish, so we just have to wait
619*8975f5c5SAndroid Build Coastguard Worker     // for a while before issuing screenshot if window was just made visible.
620*8975f5c5SAndroid Build Coastguard Worker     {
621*8975f5c5SAndroid Build Coastguard Worker         static const double WAIT_WINDOW_VISIBLE_MS = 0.5;  // Half a second for the animation
622*8975f5c5SAndroid Build Coastguard Worker         double timeSinceVisible                    = mSetVisibleTimer.getElapsedWallClockTime();
623*8975f5c5SAndroid Build Coastguard Worker 
624*8975f5c5SAndroid Build Coastguard Worker         if (timeSinceVisible < WAIT_WINDOW_VISIBLE_MS)
625*8975f5c5SAndroid Build Coastguard Worker         {
626*8975f5c5SAndroid Build Coastguard Worker             Sleep(static_cast<DWORD>((WAIT_WINDOW_VISIBLE_MS - timeSinceVisible) * 1000));
627*8975f5c5SAndroid Build Coastguard Worker         }
628*8975f5c5SAndroid Build Coastguard Worker     }
629*8975f5c5SAndroid Build Coastguard Worker 
630*8975f5c5SAndroid Build Coastguard Worker     HDC screenDC      = nullptr;
631*8975f5c5SAndroid Build Coastguard Worker     HDC windowDC      = nullptr;
632*8975f5c5SAndroid Build Coastguard Worker     HDC tmpDC         = nullptr;
633*8975f5c5SAndroid Build Coastguard Worker     HBITMAP tmpBitmap = nullptr;
634*8975f5c5SAndroid Build Coastguard Worker 
635*8975f5c5SAndroid Build Coastguard Worker     if (!error)
636*8975f5c5SAndroid Build Coastguard Worker     {
637*8975f5c5SAndroid Build Coastguard Worker         screenDC = GetDC(HWND_DESKTOP);
638*8975f5c5SAndroid Build Coastguard Worker         error    = screenDC == nullptr;
639*8975f5c5SAndroid Build Coastguard Worker     }
640*8975f5c5SAndroid Build Coastguard Worker 
641*8975f5c5SAndroid Build Coastguard Worker     if (!error)
642*8975f5c5SAndroid Build Coastguard Worker     {
643*8975f5c5SAndroid Build Coastguard Worker         windowDC = GetDC(mNativeWindow);
644*8975f5c5SAndroid Build Coastguard Worker         error    = windowDC == nullptr;
645*8975f5c5SAndroid Build Coastguard Worker     }
646*8975f5c5SAndroid Build Coastguard Worker 
647*8975f5c5SAndroid Build Coastguard Worker     if (!error)
648*8975f5c5SAndroid Build Coastguard Worker     {
649*8975f5c5SAndroid Build Coastguard Worker         tmpDC = CreateCompatibleDC(screenDC);
650*8975f5c5SAndroid Build Coastguard Worker         error = tmpDC == nullptr;
651*8975f5c5SAndroid Build Coastguard Worker     }
652*8975f5c5SAndroid Build Coastguard Worker 
653*8975f5c5SAndroid Build Coastguard Worker     if (!error)
654*8975f5c5SAndroid Build Coastguard Worker     {
655*8975f5c5SAndroid Build Coastguard Worker         tmpBitmap = CreateCompatibleBitmap(screenDC, mWidth, mHeight);
656*8975f5c5SAndroid Build Coastguard Worker         error     = tmpBitmap == nullptr;
657*8975f5c5SAndroid Build Coastguard Worker     }
658*8975f5c5SAndroid Build Coastguard Worker 
659*8975f5c5SAndroid Build Coastguard Worker     POINT topLeft = {0, 0};
660*8975f5c5SAndroid Build Coastguard Worker     if (!error)
661*8975f5c5SAndroid Build Coastguard Worker     {
662*8975f5c5SAndroid Build Coastguard Worker         error = (MapWindowPoints(mNativeWindow, HWND_DESKTOP, &topLeft, 1) == 0);
663*8975f5c5SAndroid Build Coastguard Worker     }
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker     if (!error)
666*8975f5c5SAndroid Build Coastguard Worker     {
667*8975f5c5SAndroid Build Coastguard Worker         error = SelectObject(tmpDC, tmpBitmap) == nullptr;
668*8975f5c5SAndroid Build Coastguard Worker     }
669*8975f5c5SAndroid Build Coastguard Worker 
670*8975f5c5SAndroid Build Coastguard Worker     if (!error)
671*8975f5c5SAndroid Build Coastguard Worker     {
672*8975f5c5SAndroid Build Coastguard Worker         error = BitBlt(tmpDC, 0, 0, mWidth, mHeight, screenDC, topLeft.x, topLeft.y, SRCCOPY) == 0;
673*8975f5c5SAndroid Build Coastguard Worker     }
674*8975f5c5SAndroid Build Coastguard Worker 
675*8975f5c5SAndroid Build Coastguard Worker     if (!error)
676*8975f5c5SAndroid Build Coastguard Worker     {
677*8975f5c5SAndroid Build Coastguard Worker         BITMAPINFOHEADER bitmapInfo;
678*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biSize          = sizeof(BITMAPINFOHEADER);
679*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biWidth         = mWidth;
680*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biHeight        = -mHeight;
681*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biPlanes        = 1;
682*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biBitCount      = 32;
683*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biCompression   = BI_RGB;
684*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biSizeImage     = 0;
685*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biXPelsPerMeter = 0;
686*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biYPelsPerMeter = 0;
687*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biClrUsed       = 0;
688*8975f5c5SAndroid Build Coastguard Worker         bitmapInfo.biClrImportant  = 0;
689*8975f5c5SAndroid Build Coastguard Worker         int getBitsResult          = GetDIBits(screenDC, tmpBitmap, 0, mHeight, pixelData,
690*8975f5c5SAndroid Build Coastguard Worker                                       reinterpret_cast<BITMAPINFO *>(&bitmapInfo), DIB_RGB_COLORS);
691*8975f5c5SAndroid Build Coastguard Worker         error                      = (getBitsResult == 0);
692*8975f5c5SAndroid Build Coastguard Worker     }
693*8975f5c5SAndroid Build Coastguard Worker 
694*8975f5c5SAndroid Build Coastguard Worker     if (tmpBitmap != nullptr)
695*8975f5c5SAndroid Build Coastguard Worker     {
696*8975f5c5SAndroid Build Coastguard Worker         DeleteObject(tmpBitmap);
697*8975f5c5SAndroid Build Coastguard Worker     }
698*8975f5c5SAndroid Build Coastguard Worker     if (tmpDC != nullptr)
699*8975f5c5SAndroid Build Coastguard Worker     {
700*8975f5c5SAndroid Build Coastguard Worker         DeleteDC(tmpDC);
701*8975f5c5SAndroid Build Coastguard Worker     }
702*8975f5c5SAndroid Build Coastguard Worker     if (screenDC != nullptr)
703*8975f5c5SAndroid Build Coastguard Worker     {
704*8975f5c5SAndroid Build Coastguard Worker         ReleaseDC(nullptr, screenDC);
705*8975f5c5SAndroid Build Coastguard Worker     }
706*8975f5c5SAndroid Build Coastguard Worker     if (windowDC != nullptr)
707*8975f5c5SAndroid Build Coastguard Worker     {
708*8975f5c5SAndroid Build Coastguard Worker         ReleaseDC(mNativeWindow, windowDC);
709*8975f5c5SAndroid Build Coastguard Worker     }
710*8975f5c5SAndroid Build Coastguard Worker 
711*8975f5c5SAndroid Build Coastguard Worker     return !error;
712*8975f5c5SAndroid Build Coastguard Worker }
713*8975f5c5SAndroid Build Coastguard Worker 
resetNativeWindow()714*8975f5c5SAndroid Build Coastguard Worker void Win32Window::resetNativeWindow() {}
715*8975f5c5SAndroid Build Coastguard Worker 
getNativeWindow() const716*8975f5c5SAndroid Build Coastguard Worker EGLNativeWindowType Win32Window::getNativeWindow() const
717*8975f5c5SAndroid Build Coastguard Worker {
718*8975f5c5SAndroid Build Coastguard Worker     return mNativeWindow;
719*8975f5c5SAndroid Build Coastguard Worker }
720*8975f5c5SAndroid Build Coastguard Worker 
getNativeDisplay() const721*8975f5c5SAndroid Build Coastguard Worker EGLNativeDisplayType Win32Window::getNativeDisplay() const
722*8975f5c5SAndroid Build Coastguard Worker {
723*8975f5c5SAndroid Build Coastguard Worker     return mNativeDisplay;
724*8975f5c5SAndroid Build Coastguard Worker }
725*8975f5c5SAndroid Build Coastguard Worker 
messageLoop()726*8975f5c5SAndroid Build Coastguard Worker void Win32Window::messageLoop()
727*8975f5c5SAndroid Build Coastguard Worker {
728*8975f5c5SAndroid Build Coastguard Worker     MSG msg;
729*8975f5c5SAndroid Build Coastguard Worker     while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
730*8975f5c5SAndroid Build Coastguard Worker     {
731*8975f5c5SAndroid Build Coastguard Worker         TranslateMessage(&msg);
732*8975f5c5SAndroid Build Coastguard Worker         DispatchMessage(&msg);
733*8975f5c5SAndroid Build Coastguard Worker     }
734*8975f5c5SAndroid Build Coastguard Worker }
735*8975f5c5SAndroid Build Coastguard Worker 
setMousePosition(int x,int y)736*8975f5c5SAndroid Build Coastguard Worker void Win32Window::setMousePosition(int x, int y)
737*8975f5c5SAndroid Build Coastguard Worker {
738*8975f5c5SAndroid Build Coastguard Worker     RECT winRect;
739*8975f5c5SAndroid Build Coastguard Worker     GetClientRect(mNativeWindow, &winRect);
740*8975f5c5SAndroid Build Coastguard Worker 
741*8975f5c5SAndroid Build Coastguard Worker     POINT topLeft;
742*8975f5c5SAndroid Build Coastguard Worker     topLeft.x = winRect.left;
743*8975f5c5SAndroid Build Coastguard Worker     topLeft.y = winRect.top;
744*8975f5c5SAndroid Build Coastguard Worker     ClientToScreen(mNativeWindow, &topLeft);
745*8975f5c5SAndroid Build Coastguard Worker 
746*8975f5c5SAndroid Build Coastguard Worker     SetCursorPos(topLeft.x + x, topLeft.y + y);
747*8975f5c5SAndroid Build Coastguard Worker }
748*8975f5c5SAndroid Build Coastguard Worker 
setOrientation(int width,int height)749*8975f5c5SAndroid Build Coastguard Worker bool Win32Window::setOrientation(int width, int height)
750*8975f5c5SAndroid Build Coastguard Worker {
751*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
752*8975f5c5SAndroid Build Coastguard Worker     return false;
753*8975f5c5SAndroid Build Coastguard Worker }
754*8975f5c5SAndroid Build Coastguard Worker 
setPosition(int x,int y)755*8975f5c5SAndroid Build Coastguard Worker bool Win32Window::setPosition(int x, int y)
756*8975f5c5SAndroid Build Coastguard Worker {
757*8975f5c5SAndroid Build Coastguard Worker     if (mX == x && mY == y)
758*8975f5c5SAndroid Build Coastguard Worker     {
759*8975f5c5SAndroid Build Coastguard Worker         return true;
760*8975f5c5SAndroid Build Coastguard Worker     }
761*8975f5c5SAndroid Build Coastguard Worker 
762*8975f5c5SAndroid Build Coastguard Worker     RECT windowRect;
763*8975f5c5SAndroid Build Coastguard Worker     if (!GetWindowRect(mParentWindow, &windowRect))
764*8975f5c5SAndroid Build Coastguard Worker     {
765*8975f5c5SAndroid Build Coastguard Worker         return false;
766*8975f5c5SAndroid Build Coastguard Worker     }
767*8975f5c5SAndroid Build Coastguard Worker 
768*8975f5c5SAndroid Build Coastguard Worker     if (!MoveWindow(mParentWindow, x, y, windowRect.right - windowRect.left,
769*8975f5c5SAndroid Build Coastguard Worker                     windowRect.bottom - windowRect.top, TRUE))
770*8975f5c5SAndroid Build Coastguard Worker     {
771*8975f5c5SAndroid Build Coastguard Worker         return false;
772*8975f5c5SAndroid Build Coastguard Worker     }
773*8975f5c5SAndroid Build Coastguard Worker 
774*8975f5c5SAndroid Build Coastguard Worker     return true;
775*8975f5c5SAndroid Build Coastguard Worker }
776*8975f5c5SAndroid Build Coastguard Worker 
resize(int width,int height)777*8975f5c5SAndroid Build Coastguard Worker bool Win32Window::resize(int width, int height)
778*8975f5c5SAndroid Build Coastguard Worker {
779*8975f5c5SAndroid Build Coastguard Worker     if (width == mWidth && height == mHeight)
780*8975f5c5SAndroid Build Coastguard Worker     {
781*8975f5c5SAndroid Build Coastguard Worker         return true;
782*8975f5c5SAndroid Build Coastguard Worker     }
783*8975f5c5SAndroid Build Coastguard Worker 
784*8975f5c5SAndroid Build Coastguard Worker     RECT windowRect;
785*8975f5c5SAndroid Build Coastguard Worker     if (!GetWindowRect(mParentWindow, &windowRect))
786*8975f5c5SAndroid Build Coastguard Worker     {
787*8975f5c5SAndroid Build Coastguard Worker         return false;
788*8975f5c5SAndroid Build Coastguard Worker     }
789*8975f5c5SAndroid Build Coastguard Worker 
790*8975f5c5SAndroid Build Coastguard Worker     RECT clientRect;
791*8975f5c5SAndroid Build Coastguard Worker     if (!GetClientRect(mParentWindow, &clientRect))
792*8975f5c5SAndroid Build Coastguard Worker     {
793*8975f5c5SAndroid Build Coastguard Worker         return false;
794*8975f5c5SAndroid Build Coastguard Worker     }
795*8975f5c5SAndroid Build Coastguard Worker 
796*8975f5c5SAndroid Build Coastguard Worker     LONG diffX = (windowRect.right - windowRect.left) - clientRect.right;
797*8975f5c5SAndroid Build Coastguard Worker     LONG diffY = (windowRect.bottom - windowRect.top) - clientRect.bottom;
798*8975f5c5SAndroid Build Coastguard Worker     if (!MoveWindow(mParentWindow, windowRect.left, windowRect.top, width + diffX, height + diffY,
799*8975f5c5SAndroid Build Coastguard Worker                     TRUE))
800*8975f5c5SAndroid Build Coastguard Worker     {
801*8975f5c5SAndroid Build Coastguard Worker         return false;
802*8975f5c5SAndroid Build Coastguard Worker     }
803*8975f5c5SAndroid Build Coastguard Worker 
804*8975f5c5SAndroid Build Coastguard Worker     if (!MoveWindow(mNativeWindow, 0, 0, width, height, FALSE))
805*8975f5c5SAndroid Build Coastguard Worker     {
806*8975f5c5SAndroid Build Coastguard Worker         return false;
807*8975f5c5SAndroid Build Coastguard Worker     }
808*8975f5c5SAndroid Build Coastguard Worker 
809*8975f5c5SAndroid Build Coastguard Worker     return true;
810*8975f5c5SAndroid Build Coastguard Worker }
811*8975f5c5SAndroid Build Coastguard Worker 
setVisible(bool isVisible)812*8975f5c5SAndroid Build Coastguard Worker void Win32Window::setVisible(bool isVisible)
813*8975f5c5SAndroid Build Coastguard Worker {
814*8975f5c5SAndroid Build Coastguard Worker     int flag = (isVisible ? SW_SHOW : SW_HIDE);
815*8975f5c5SAndroid Build Coastguard Worker 
816*8975f5c5SAndroid Build Coastguard Worker     ShowWindow(mParentWindow, flag);
817*8975f5c5SAndroid Build Coastguard Worker     ShowWindow(mNativeWindow, flag);
818*8975f5c5SAndroid Build Coastguard Worker 
819*8975f5c5SAndroid Build Coastguard Worker     if (isVisible)
820*8975f5c5SAndroid Build Coastguard Worker     {
821*8975f5c5SAndroid Build Coastguard Worker         mSetVisibleTimer.stop();
822*8975f5c5SAndroid Build Coastguard Worker         mSetVisibleTimer.start();
823*8975f5c5SAndroid Build Coastguard Worker     }
824*8975f5c5SAndroid Build Coastguard Worker }
825*8975f5c5SAndroid Build Coastguard Worker 
pushEvent(Event event)826*8975f5c5SAndroid Build Coastguard Worker void Win32Window::pushEvent(Event event)
827*8975f5c5SAndroid Build Coastguard Worker {
828*8975f5c5SAndroid Build Coastguard Worker     OSWindow::pushEvent(event);
829*8975f5c5SAndroid Build Coastguard Worker 
830*8975f5c5SAndroid Build Coastguard Worker     switch (event.Type)
831*8975f5c5SAndroid Build Coastguard Worker     {
832*8975f5c5SAndroid Build Coastguard Worker         case Event::EVENT_RESIZED:
833*8975f5c5SAndroid Build Coastguard Worker             MoveWindow(mNativeWindow, 0, 0, mWidth, mHeight, FALSE);
834*8975f5c5SAndroid Build Coastguard Worker             break;
835*8975f5c5SAndroid Build Coastguard Worker         default:
836*8975f5c5SAndroid Build Coastguard Worker             break;
837*8975f5c5SAndroid Build Coastguard Worker     }
838*8975f5c5SAndroid Build Coastguard Worker }
839*8975f5c5SAndroid Build Coastguard Worker 
signalTestEvent()840*8975f5c5SAndroid Build Coastguard Worker void Win32Window::signalTestEvent()
841*8975f5c5SAndroid Build Coastguard Worker {
842*8975f5c5SAndroid Build Coastguard Worker     PostMessage(mNativeWindow, WM_USER, 0, 0);
843*8975f5c5SAndroid Build Coastguard Worker }
844*8975f5c5SAndroid Build Coastguard Worker 
845*8975f5c5SAndroid Build Coastguard Worker // static
New()846*8975f5c5SAndroid Build Coastguard Worker OSWindow *OSWindow::New()
847*8975f5c5SAndroid Build Coastguard Worker {
848*8975f5c5SAndroid Build Coastguard Worker     return new Win32Window();
849*8975f5c5SAndroid Build Coastguard Worker }
850