Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / samples / angle / sample_util / win32 / Win32Window.cpp
1 //
2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "win32/Win32Window.h"
8
9 Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags)
10 {
11     switch (key)
12     {
13         // Check the scancode to distinguish between left and right shift
14       case VK_SHIFT:
15         {
16             static unsigned int lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
17             unsigned int scancode = static_cast<unsigned int>((flags & (0xFF << 16)) >> 16);
18             return scancode == lShift ? KEY_LSHIFT : KEY_RSHIFT;
19         }
20
21         // Check the "extended" flag to distinguish between left and right alt
22       case VK_MENU:       return (HIWORD(flags) & KF_EXTENDED) ? KEY_RALT : KEY_LALT;
23
24         // Check the "extended" flag to distinguish between left and right control
25       case VK_CONTROL:    return (HIWORD(flags) & KF_EXTENDED) ? KEY_RCONTROL : KEY_LCONTROL;
26
27         // Other keys are reported properly
28       case VK_LWIN:       return KEY_LSYSTEM;
29       case VK_RWIN:       return KEY_RSYSTEM;
30       case VK_APPS:       return KEY_MENU;
31       case VK_OEM_1:      return KEY_SEMICOLON;
32       case VK_OEM_2:      return KEY_SLASH;
33       case VK_OEM_PLUS:   return KEY_EQUAL;
34       case VK_OEM_MINUS:  return KEY_DASH;
35       case VK_OEM_4:      return KEY_LBRACKET;
36       case VK_OEM_6:      return KEY_RBRACKET;
37       case VK_OEM_COMMA:  return KEY_COMMA;
38       case VK_OEM_PERIOD: return KEY_PERIOD;
39       case VK_OEM_7:      return KEY_QUOTE;
40       case VK_OEM_5:      return KEY_BACKSLASH;
41       case VK_OEM_3:      return KEY_TILDE;
42       case VK_ESCAPE:     return KEY_ESCAPE;
43       case VK_SPACE:      return KEY_SPACE;
44       case VK_RETURN:     return KEY_RETURN;
45       case VK_BACK:       return KEY_BACK;
46       case VK_TAB:        return KEY_TAB;
47       case VK_PRIOR:      return KEY_PAGEUP;
48       case VK_NEXT:       return KEY_PAGEDOWN;
49       case VK_END:        return KEY_END;
50       case VK_HOME:       return KEY_HOME;
51       case VK_INSERT:     return KEY_INSERT;
52       case VK_DELETE:     return KEY_DELETE;
53       case VK_ADD:        return KEY_ADD;
54       case VK_SUBTRACT:   return KEY_SUBTRACT;
55       case VK_MULTIPLY:   return KEY_MULTIPLY;
56       case VK_DIVIDE:     return KEY_DIVIDE;
57       case VK_PAUSE:      return KEY_PAUSE;
58       case VK_F1:         return KEY_F1;
59       case VK_F2:         return KEY_F2;
60       case VK_F3:         return KEY_F3;
61       case VK_F4:         return KEY_F4;
62       case VK_F5:         return KEY_F5;
63       case VK_F6:         return KEY_F6;
64       case VK_F7:         return KEY_F7;
65       case VK_F8:         return KEY_F8;
66       case VK_F9:         return KEY_F9;
67       case VK_F10:        return KEY_F10;
68       case VK_F11:        return KEY_F11;
69       case VK_F12:        return KEY_F12;
70       case VK_F13:        return KEY_F13;
71       case VK_F14:        return KEY_F14;
72       case VK_F15:        return KEY_F15;
73       case VK_LEFT:       return KEY_LEFT;
74       case VK_RIGHT:      return KEY_RIGHT;
75       case VK_UP:         return KEY_UP;
76       case VK_DOWN:       return KEY_DOWN;
77       case VK_NUMPAD0:    return KEY_NUMPAD0;
78       case VK_NUMPAD1:    return KEY_NUMPAD1;
79       case VK_NUMPAD2:    return KEY_NUMPAD2;
80       case VK_NUMPAD3:    return KEY_NUMPAD3;
81       case VK_NUMPAD4:    return KEY_NUMPAD4;
82       case VK_NUMPAD5:    return KEY_NUMPAD5;
83       case VK_NUMPAD6:    return KEY_NUMPAD6;
84       case VK_NUMPAD7:    return KEY_NUMPAD7;
85       case VK_NUMPAD8:    return KEY_NUMPAD8;
86       case VK_NUMPAD9:    return KEY_NUMPAD9;
87       case 'A':           return KEY_A;
88       case 'Z':           return KEY_Z;
89       case 'E':           return KEY_E;
90       case 'R':           return KEY_R;
91       case 'T':           return KEY_T;
92       case 'Y':           return KEY_Y;
93       case 'U':           return KEY_U;
94       case 'I':           return KEY_I;
95       case 'O':           return KEY_O;
96       case 'P':           return KEY_P;
97       case 'Q':           return KEY_Q;
98       case 'S':           return KEY_S;
99       case 'D':           return KEY_D;
100       case 'F':           return KEY_F;
101       case 'G':           return KEY_G;
102       case 'H':           return KEY_H;
103       case 'J':           return KEY_J;
104       case 'K':           return KEY_K;
105       case 'L':           return KEY_L;
106       case 'M':           return KEY_M;
107       case 'W':           return KEY_W;
108       case 'X':           return KEY_X;
109       case 'C':           return KEY_C;
110       case 'V':           return KEY_V;
111       case 'B':           return KEY_B;
112       case 'N':           return KEY_N;
113       case '0':           return KEY_NUM0;
114       case '1':           return KEY_NUM1;
115       case '2':           return KEY_NUM2;
116       case '3':           return KEY_NUM3;
117       case '4':           return KEY_NUM4;
118       case '5':           return KEY_NUM5;
119       case '6':           return KEY_NUM6;
120       case '7':           return KEY_NUM7;
121       case '8':           return KEY_NUM8;
122       case '9':           return KEY_NUM9;
123     }
124
125     return Key(0);
126 }
127
128 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
129 {
130     switch(message)
131     {
132       case WM_NCCREATE:
133         {
134             LPCREATESTRUCT pCreateStruct = (LPCREATESTRUCT)lParam;
135             SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pCreateStruct->lpCreateParams);
136             return DefWindowProcA(hWnd, message, wParam, lParam);
137         }
138     }
139
140     Window *window = (Window*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
141     if (window)
142     {
143         switch (message)
144         {
145           case WM_DESTROY:
146           case WM_CLOSE:
147             {
148                 Event event;
149                 event.Type = Event::EVENT_CLOSED;
150                 window->pushEvent(event);
151                 break;
152             }
153
154           case WM_MOVE:
155             {
156                 RECT winRect;
157                 GetClientRect(hWnd, &winRect);
158
159                 POINT topLeft;
160                 topLeft.x = winRect.left;
161                 topLeft.y = winRect.top;
162                 ClientToScreen(hWnd, &topLeft);
163
164                 Event event;
165                 event.Type        = Event::EVENT_MOVED;
166                 event.Move.X      = topLeft.x;
167                 event.Move.Y      = topLeft.y;
168                 window->pushEvent(event);
169
170                 break;
171             }
172
173           case WM_SIZE:
174             {
175                 RECT winRect;
176                 GetClientRect(hWnd, &winRect);
177
178                 POINT topLeft;
179                 topLeft.x = winRect.left;
180                 topLeft.y = winRect.top;
181                 ClientToScreen(hWnd, &topLeft);
182
183                 POINT botRight;
184                 botRight.x = winRect.right;
185                 botRight.y = winRect.bottom;
186                 ClientToScreen(hWnd, &botRight);
187
188                 Event event;
189                 event.Type        = Event::EVENT_RESIZED;
190                 event.Size.Width  = botRight.x - topLeft.x;
191                 event.Size.Height = botRight.y - topLeft.y;
192                 window->pushEvent(event);
193
194                 break;
195             }
196
197           case WM_SETFOCUS:
198             {
199                 Event event;
200                 event.Type = Event::EVENT_GAINED_FOCUS;
201                 window->pushEvent(event);
202                 break;
203             }
204
205           case WM_KILLFOCUS:
206             {
207                 Event event;
208                 event.Type = Event::EVENT_LOST_FOCUS;
209                 window->pushEvent(event);
210                 break;
211             }
212
213           case WM_KEYDOWN:
214           case WM_SYSKEYDOWN:
215           case WM_KEYUP:
216           case WM_SYSKEYUP:
217             {
218                 bool down = (message == WM_KEYDOWN || message == WM_SYSKEYDOWN);
219
220                 Event event;
221                 event.Type        = down ? Event::EVENT_KEY_PRESSED : Event::EVENT_KEY_RELEASED;
222                 event.Key.Alt     = HIWORD(GetAsyncKeyState(VK_MENU))    != 0;
223                 event.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
224                 event.Key.Shift   = HIWORD(GetAsyncKeyState(VK_SHIFT))   != 0;
225                 event.Key.System  = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
226                 event.Key.Code    = VirtualKeyCodeToKey(wParam, lParam);
227                 window->pushEvent(event);
228
229                 break;
230             }
231
232           case WM_MOUSEWHEEL:
233             {
234                 Event event;
235                 event.Type = Event::EVENT_MOUSE_WHEEL_MOVED;
236                 event.MouseWheel.Delta = static_cast<short>(HIWORD(wParam)) / 120;
237                 window->pushEvent(event);
238                 break;
239             }
240
241           case WM_LBUTTONDOWN:
242           case WM_LBUTTONDBLCLK:
243             {
244                 Event event;
245                 event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
246                 event.MouseButton.Button = MOUSEBUTTON_LEFT;
247                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
248                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
249                 window->pushEvent(event);
250                 break;
251             }
252
253           case WM_LBUTTONUP:
254             {
255                 Event event;
256                 event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
257                 event.MouseButton.Button = MOUSEBUTTON_LEFT;
258                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
259                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
260                 window->pushEvent(event);
261                 break;
262             }
263
264           case WM_RBUTTONDOWN:
265           case WM_RBUTTONDBLCLK:
266             {
267                 Event event;
268                 event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
269                 event.MouseButton.Button = MOUSEBUTTON_RIGHT;
270                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
271                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
272                 window->pushEvent(event);
273                 break;
274             }
275
276             // Mouse right button up event
277           case WM_RBUTTONUP:
278             {
279                 Event event;
280                 event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
281                 event.MouseButton.Button = MOUSEBUTTON_RIGHT;
282                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
283                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
284                 window->pushEvent(event);
285                 break;
286             }
287
288             // Mouse wheel button down event
289           case WM_MBUTTONDOWN:
290           case WM_MBUTTONDBLCLK:
291             {
292                 Event event;
293                 event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
294                 event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
295                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
296                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
297                 window->pushEvent(event);
298                 break;
299             }
300
301             // Mouse wheel button up event
302           case WM_MBUTTONUP:
303             {
304                 Event event;
305                 event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
306                 event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
307                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
308                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
309                 window->pushEvent(event);
310                 break;
311             }
312
313             // Mouse X button down event
314           case WM_XBUTTONDOWN:
315           case WM_XBUTTONDBLCLK:
316             {
317                 Event event;
318                 event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
319                 event.MouseButton.Button = (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
320                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
321                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
322                 window->pushEvent(event);
323                 break;
324             }
325
326             // Mouse X button up event
327           case WM_XBUTTONUP:
328             {
329                 Event event;
330                 event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
331                 event.MouseButton.Button = (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
332                 event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
333                 event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
334                 window->pushEvent(event);
335                 break;
336             }
337
338           case WM_MOUSEMOVE:
339             {
340                 int mouseX = static_cast<short>(LOWORD(lParam));
341                 int mouseY = static_cast<short>(HIWORD(lParam));
342
343                 Event event;
344                 event.Type        = Event::EVENT_MOUSE_MOVED;
345                 event.MouseMove.X = mouseX;
346                 event.MouseMove.Y = mouseY;
347                 window->pushEvent(event);
348                 break;
349             }
350
351           case WM_MOUSELEAVE:
352             {
353                 Event event;
354                 event.Type = Event::EVENT_MOUSE_LEFT;
355                 window->pushEvent(event);
356                 break;
357             }
358         }
359
360     }
361     return DefWindowProcA(hWnd, message, wParam, lParam);
362 }
363
364 Win32Window::Win32Window()
365     : mClassName(),
366       mNativeWindow(0),
367       mNativeDisplay(0)
368 {
369 }
370
371 Win32Window::~Win32Window()
372 {
373     destroy();
374 }
375
376 bool Win32Window::initialize(const std::string &name, size_t width, size_t height)
377 {
378     destroy();
379
380     mClassName = name;
381
382     WNDCLASSEXA windowClass = { 0 };
383     windowClass.cbSize = sizeof(WNDCLASSEXA);
384     windowClass.style = CS_OWNDC;
385     windowClass.lpfnWndProc = WndProc;
386     windowClass.cbClsExtra = 0;
387     windowClass.cbWndExtra = 0;
388     windowClass.hInstance = GetModuleHandle(NULL);
389     windowClass.hIcon = NULL;
390     windowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
391     windowClass.hbrBackground = 0;
392     windowClass.lpszMenuName = NULL;
393     windowClass.lpszClassName = mClassName.c_str();
394     if (!RegisterClassExA(&windowClass))
395     {
396         return false;
397     }
398
399     DWORD style = WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_SYSMENU;
400     DWORD extendedStyle = WS_EX_APPWINDOW;
401
402     RECT sizeRect = { 0, 0, width, height };
403     AdjustWindowRectEx(&sizeRect, style, false, extendedStyle);
404
405     mNativeWindow = CreateWindowExA(extendedStyle, mClassName.c_str(), name.c_str(), style, CW_USEDEFAULT, CW_USEDEFAULT,
406                                     sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top, NULL, NULL,
407                                     GetModuleHandle(NULL), this);
408
409     SetWindowLongPtrA(mNativeWindow, GWLP_USERDATA, reinterpret_cast<LONG>(this));
410
411     ShowWindow(mNativeWindow, SW_SHOW);
412
413     mNativeDisplay = GetDC(mNativeWindow);
414     if (!mNativeDisplay)
415     {
416         destroy();
417         return false;
418     }
419
420     return true;
421 }
422
423 void Win32Window::destroy()
424 {
425     if (mNativeDisplay)
426     {
427         ReleaseDC(mNativeWindow, mNativeDisplay);
428         mNativeDisplay = 0;
429     }
430
431     if (mNativeWindow)
432     {
433         DestroyWindow(mNativeWindow);
434         mNativeWindow = 0;
435     }
436
437     UnregisterClassA(mClassName.c_str(), NULL);
438 }
439
440 EGLNativeWindowType Win32Window::getNativeWindow() const
441 {
442     return mNativeWindow;
443 }
444
445 EGLNativeDisplayType Win32Window::getNativeDisplay() const
446 {
447     return mNativeDisplay;
448 }
449
450 void Win32Window::messageLoop()
451 {
452     MSG msg;
453     while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
454     {
455         TranslateMessage(&msg);
456         DispatchMessage(&msg);
457     }
458 }
459
460 void Win32Window::setMousePosition(int x, int y)
461 {
462     RECT winRect;
463     GetClientRect(mNativeWindow, &winRect);
464
465     POINT topLeft;
466     topLeft.x = winRect.left;
467     topLeft.y = winRect.top;
468     ClientToScreen(mNativeWindow, &topLeft);
469
470     SetCursorPos(topLeft.x + x, topLeft.y + y);
471 }