summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/angle/samples/angle/sample_util/win32/Win32Window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/angle/samples/angle/sample_util/win32/Win32Window.cpp')
-rw-r--r--chromium/third_party/angle/samples/angle/sample_util/win32/Win32Window.cpp510
1 files changed, 510 insertions, 0 deletions
diff --git a/chromium/third_party/angle/samples/angle/sample_util/win32/Win32Window.cpp b/chromium/third_party/angle/samples/angle/sample_util/win32/Win32Window.cpp
new file mode 100644
index 00000000000..49eaa378a42
--- /dev/null
+++ b/chromium/third_party/angle/samples/angle/sample_util/win32/Win32Window.cpp
@@ -0,0 +1,510 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "win32/Win32Window.h"
+
+Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags)
+{
+ switch (key)
+ {
+ // Check the scancode to distinguish between left and right shift
+ case VK_SHIFT:
+ {
+ static unsigned int lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
+ unsigned int scancode = static_cast<unsigned int>((flags & (0xFF << 16)) >> 16);
+ return scancode == lShift ? KEY_LSHIFT : KEY_RSHIFT;
+ }
+
+ // Check the "extended" flag to distinguish between left and right alt
+ case VK_MENU: return (HIWORD(flags) & KF_EXTENDED) ? KEY_RALT : KEY_LALT;
+
+ // Check the "extended" flag to distinguish between left and right control
+ case VK_CONTROL: return (HIWORD(flags) & KF_EXTENDED) ? KEY_RCONTROL : KEY_LCONTROL;
+
+ // Other keys are reported properly
+ case VK_LWIN: return KEY_LSYSTEM;
+ case VK_RWIN: return KEY_RSYSTEM;
+ case VK_APPS: return KEY_MENU;
+ case VK_OEM_1: return KEY_SEMICOLON;
+ case VK_OEM_2: return KEY_SLASH;
+ case VK_OEM_PLUS: return KEY_EQUAL;
+ case VK_OEM_MINUS: return KEY_DASH;
+ case VK_OEM_4: return KEY_LBRACKET;
+ case VK_OEM_6: return KEY_RBRACKET;
+ case VK_OEM_COMMA: return KEY_COMMA;
+ case VK_OEM_PERIOD: return KEY_PERIOD;
+ case VK_OEM_7: return KEY_QUOTE;
+ case VK_OEM_5: return KEY_BACKSLASH;
+ case VK_OEM_3: return KEY_TILDE;
+ case VK_ESCAPE: return KEY_ESCAPE;
+ case VK_SPACE: return KEY_SPACE;
+ case VK_RETURN: return KEY_RETURN;
+ case VK_BACK: return KEY_BACK;
+ case VK_TAB: return KEY_TAB;
+ case VK_PRIOR: return KEY_PAGEUP;
+ case VK_NEXT: return KEY_PAGEDOWN;
+ case VK_END: return KEY_END;
+ case VK_HOME: return KEY_HOME;
+ case VK_INSERT: return KEY_INSERT;
+ case VK_DELETE: return KEY_DELETE;
+ case VK_ADD: return KEY_ADD;
+ case VK_SUBTRACT: return KEY_SUBTRACT;
+ case VK_MULTIPLY: return KEY_MULTIPLY;
+ case VK_DIVIDE: return KEY_DIVIDE;
+ case VK_PAUSE: return KEY_PAUSE;
+ case VK_F1: return KEY_F1;
+ case VK_F2: return KEY_F2;
+ case VK_F3: return KEY_F3;
+ case VK_F4: return KEY_F4;
+ case VK_F5: return KEY_F5;
+ case VK_F6: return KEY_F6;
+ case VK_F7: return KEY_F7;
+ case VK_F8: return KEY_F8;
+ case VK_F9: return KEY_F9;
+ case VK_F10: return KEY_F10;
+ case VK_F11: return KEY_F11;
+ case VK_F12: return KEY_F12;
+ case VK_F13: return KEY_F13;
+ case VK_F14: return KEY_F14;
+ case VK_F15: return KEY_F15;
+ case VK_LEFT: return KEY_LEFT;
+ case VK_RIGHT: return KEY_RIGHT;
+ case VK_UP: return KEY_UP;
+ case VK_DOWN: return KEY_DOWN;
+ case VK_NUMPAD0: return KEY_NUMPAD0;
+ case VK_NUMPAD1: return KEY_NUMPAD1;
+ case VK_NUMPAD2: return KEY_NUMPAD2;
+ case VK_NUMPAD3: return KEY_NUMPAD3;
+ case VK_NUMPAD4: return KEY_NUMPAD4;
+ case VK_NUMPAD5: return KEY_NUMPAD5;
+ case VK_NUMPAD6: return KEY_NUMPAD6;
+ case VK_NUMPAD7: return KEY_NUMPAD7;
+ case VK_NUMPAD8: return KEY_NUMPAD8;
+ case VK_NUMPAD9: return KEY_NUMPAD9;
+ case 'A': return KEY_A;
+ case 'Z': return KEY_Z;
+ case 'E': return KEY_E;
+ case 'R': return KEY_R;
+ case 'T': return KEY_T;
+ case 'Y': return KEY_Y;
+ case 'U': return KEY_U;
+ case 'I': return KEY_I;
+ case 'O': return KEY_O;
+ case 'P': return KEY_P;
+ case 'Q': return KEY_Q;
+ case 'S': return KEY_S;
+ case 'D': return KEY_D;
+ case 'F': return KEY_F;
+ case 'G': return KEY_G;
+ case 'H': return KEY_H;
+ case 'J': return KEY_J;
+ case 'K': return KEY_K;
+ case 'L': return KEY_L;
+ case 'M': return KEY_M;
+ case 'W': return KEY_W;
+ case 'X': return KEY_X;
+ case 'C': return KEY_C;
+ case 'V': return KEY_V;
+ case 'B': return KEY_B;
+ case 'N': return KEY_N;
+ case '0': return KEY_NUM0;
+ case '1': return KEY_NUM1;
+ case '2': return KEY_NUM2;
+ case '3': return KEY_NUM3;
+ case '4': return KEY_NUM4;
+ case '5': return KEY_NUM5;
+ case '6': return KEY_NUM6;
+ case '7': return KEY_NUM7;
+ case '8': return KEY_NUM8;
+ case '9': return KEY_NUM9;
+ }
+
+ return Key(0);
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case WM_NCCREATE:
+ {
+ LPCREATESTRUCT pCreateStruct = (LPCREATESTRUCT)lParam;
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pCreateStruct->lpCreateParams);
+ return DefWindowProcA(hWnd, message, wParam, lParam);
+ }
+ }
+
+ Window *window = (Window*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ if (window)
+ {
+ switch (message)
+ {
+ case WM_DESTROY:
+ case WM_CLOSE:
+ {
+ Event event;
+ event.Type = Event::EVENT_CLOSED;
+ window->pushEvent(event);
+ break;
+ }
+
+ case WM_MOVE:
+ {
+ RECT winRect;
+ GetClientRect(hWnd, &winRect);
+
+ POINT topLeft;
+ topLeft.x = winRect.left;
+ topLeft.y = winRect.top;
+ ClientToScreen(hWnd, &topLeft);
+
+ Event event;
+ event.Type = Event::EVENT_MOVED;
+ event.Move.X = topLeft.x;
+ event.Move.Y = topLeft.y;
+ window->pushEvent(event);
+
+ break;
+ }
+
+ case WM_SIZE:
+ {
+ RECT winRect;
+ GetClientRect(hWnd, &winRect);
+
+ POINT topLeft;
+ topLeft.x = winRect.left;
+ topLeft.y = winRect.top;
+ ClientToScreen(hWnd, &topLeft);
+
+ POINT botRight;
+ botRight.x = winRect.right;
+ botRight.y = winRect.bottom;
+ ClientToScreen(hWnd, &botRight);
+
+ Event event;
+ event.Type = Event::EVENT_RESIZED;
+ event.Size.Width = botRight.x - topLeft.x;
+ event.Size.Height = botRight.y - topLeft.y;
+ window->pushEvent(event);
+
+ break;
+ }
+
+ case WM_SETFOCUS:
+ {
+ Event event;
+ event.Type = Event::EVENT_GAINED_FOCUS;
+ window->pushEvent(event);
+ break;
+ }
+
+ case WM_KILLFOCUS:
+ {
+ Event event;
+ event.Type = Event::EVENT_LOST_FOCUS;
+ window->pushEvent(event);
+ break;
+ }
+
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ {
+ bool down = (message == WM_KEYDOWN || message == WM_SYSKEYDOWN);
+
+ Event event;
+ event.Type = down ? Event::EVENT_KEY_PRESSED : Event::EVENT_KEY_RELEASED;
+ event.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
+ event.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
+ event.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
+ event.Key.System = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
+ event.Key.Code = VirtualKeyCodeToKey(wParam, lParam);
+ window->pushEvent(event);
+
+ break;
+ }
+
+ case WM_MOUSEWHEEL:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_WHEEL_MOVED;
+ event.MouseWheel.Delta = static_cast<short>(HIWORD(wParam)) / 120;
+ window->pushEvent(event);
+ break;
+ }
+
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
+ event.MouseButton.Button = MOUSEBUTTON_LEFT;
+ event.MouseButton.X = static_cast<short>(LOWORD(lParam));
+ event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
+ window->pushEvent(event);
+ break;
+ }
+
+ case WM_LBUTTONUP:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
+ event.MouseButton.Button = MOUSEBUTTON_LEFT;
+ event.MouseButton.X = static_cast<short>(LOWORD(lParam));
+ event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
+ window->pushEvent(event);
+ break;
+ }
+
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONDBLCLK:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
+ event.MouseButton.Button = MOUSEBUTTON_RIGHT;
+ event.MouseButton.X = static_cast<short>(LOWORD(lParam));
+ event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
+ window->pushEvent(event);
+ break;
+ }
+
+ // Mouse right button up event
+ case WM_RBUTTONUP:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
+ event.MouseButton.Button = MOUSEBUTTON_RIGHT;
+ event.MouseButton.X = static_cast<short>(LOWORD(lParam));
+ event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
+ window->pushEvent(event);
+ break;
+ }
+
+ // Mouse wheel button down event
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONDBLCLK:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
+ event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
+ event.MouseButton.X = static_cast<short>(LOWORD(lParam));
+ event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
+ window->pushEvent(event);
+ break;
+ }
+
+ // Mouse wheel button up event
+ case WM_MBUTTONUP:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
+ event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
+ event.MouseButton.X = static_cast<short>(LOWORD(lParam));
+ event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
+ window->pushEvent(event);
+ break;
+ }
+
+ // Mouse X button down event
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONDBLCLK:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
+ event.MouseButton.Button = (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
+ event.MouseButton.X = static_cast<short>(LOWORD(lParam));
+ event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
+ window->pushEvent(event);
+ break;
+ }
+
+ // Mouse X button up event
+ case WM_XBUTTONUP:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
+ event.MouseButton.Button = (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
+ event.MouseButton.X = static_cast<short>(LOWORD(lParam));
+ event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
+ window->pushEvent(event);
+ break;
+ }
+
+ case WM_MOUSEMOVE:
+ {
+ int mouseX = static_cast<short>(LOWORD(lParam));
+ int mouseY = static_cast<short>(HIWORD(lParam));
+
+ Event event;
+ event.Type = Event::EVENT_MOUSE_MOVED;
+ event.MouseMove.X = mouseX;
+ event.MouseMove.Y = mouseY;
+ window->pushEvent(event);
+ break;
+ }
+
+ case WM_MOUSELEAVE:
+ {
+ Event event;
+ event.Type = Event::EVENT_MOUSE_LEFT;
+ window->pushEvent(event);
+ break;
+ }
+ }
+
+ }
+ return DefWindowProcA(hWnd, message, wParam, lParam);
+}
+
+Win32Window::Win32Window()
+ : mClassName(),
+ mDisplay(0),
+ mNativeWindow(0),
+ mNativeDisplay(0)
+{
+}
+
+Win32Window::~Win32Window()
+{
+ destroy();
+}
+
+bool Win32Window::initialize(const std::string &name, size_t width, size_t height, RendererType requestedRenderer)
+{
+ destroy();
+
+ mClassName = name;
+
+ WNDCLASSEXA windowClass = { 0 };
+ windowClass.cbSize = sizeof(WNDCLASSEXA);
+ windowClass.style = CS_OWNDC;
+ windowClass.lpfnWndProc = WndProc;
+ windowClass.cbClsExtra = 0;
+ windowClass.cbWndExtra = 0;
+ windowClass.hInstance = GetModuleHandle(NULL);
+ windowClass.hIcon = NULL;
+ windowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
+ windowClass.hbrBackground = 0;
+ windowClass.lpszMenuName = NULL;
+ windowClass.lpszClassName = mClassName.c_str();
+ if (!RegisterClassExA(&windowClass))
+ {
+ return false;
+ }
+
+ DWORD style = WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_SYSMENU;
+ DWORD extendedStyle = WS_EX_APPWINDOW;
+
+ RECT sizeRect = { 0, 0, width, height };
+ AdjustWindowRectEx(&sizeRect, style, false, extendedStyle);
+
+ mNativeWindow = CreateWindowExA(extendedStyle, mClassName.c_str(), name.c_str(), style, CW_USEDEFAULT, CW_USEDEFAULT,
+ sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top, NULL, NULL,
+ GetModuleHandle(NULL), this);
+
+ SetWindowLongPtrA(mNativeWindow, GWLP_USERDATA, reinterpret_cast<LONG>(this));
+
+ ShowWindow(mNativeWindow, SW_SHOW);
+
+ mNativeDisplay = GetDC(mNativeWindow);
+ if (!mNativeDisplay)
+ {
+ destroy();
+ return false;
+ }
+
+ EGLNativeDisplayType requestedDisplay = mNativeDisplay;
+ if (requestedRenderer == RENDERER_D3D11)
+ {
+ requestedDisplay = EGL_D3D11_ONLY_DISPLAY_ANGLE;
+ }
+
+ mDisplay = eglGetDisplay(requestedDisplay);
+ if (mDisplay == EGL_NO_DISPLAY)
+ {
+ mDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
+ }
+
+ EGLint majorVersion, minorVersion;
+ if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
+ {
+ destroy();
+ return false;
+ }
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ if (eglGetError() != EGL_SUCCESS)
+ {
+ destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void Win32Window::destroy()
+{
+ if (mDisplay != EGL_NO_DISPLAY)
+ {
+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate(mDisplay);
+ mDisplay = EGL_NO_DISPLAY;
+ }
+
+ if (mNativeDisplay)
+ {
+ ReleaseDC(mNativeWindow, mNativeDisplay);
+ mNativeDisplay = 0;
+ }
+
+ if (mNativeWindow)
+ {
+ DestroyWindow(mNativeWindow);
+ mNativeWindow = 0;
+ }
+
+ UnregisterClassA(mClassName.c_str(), NULL);
+}
+
+EGLDisplay Win32Window::getDisplay() const
+{
+ return mDisplay;
+}
+
+EGLNativeWindowType Win32Window::getNativeWindow() const
+{
+ return mNativeWindow;
+}
+
+EGLNativeDisplayType Win32Window::getNativeDisplay() const
+{
+ return mNativeDisplay;
+}
+
+void Win32Window::messageLoop()
+{
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+void Win32Window::setMousePosition(int x, int y)
+{
+ RECT winRect;
+ GetClientRect(mNativeWindow, &winRect);
+
+ POINT topLeft;
+ topLeft.x = winRect.left;
+ topLeft.y = winRect.top;
+ ClientToScreen(mNativeWindow, &topLeft);
+
+ SetCursorPos(topLeft.x + x, topLeft.y + y);
+}