1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
4 *
5 * Copyright 2016 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Generic Win32 window class.
22 *//*--------------------------------------------------------------------*/
23
24 #include "tcuWin32Window.hpp"
25
26 namespace tcu
27 {
28 namespace win32
29 {
30
windowProcCallback(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)31 static LRESULT CALLBACK windowProcCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
32 {
33 Window *window = reinterpret_cast<Window *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
34 if (window)
35 return window->windowProc(uMsg, wParam, lParam);
36 else
37 return DefWindowProc(hWnd, uMsg, wParam, lParam);
38 }
39
Window(HINSTANCE instance,int width,int height)40 Window::Window(HINSTANCE instance, int width, int height) : m_window(DE_NULL)
41 {
42 try
43 {
44 static const char s_className[] = "dEQP Test Process Class";
45 static const char s_windowName[] = "dEQP Test Process";
46
47 {
48 WNDCLASS wndClass;
49 memset(&wndClass, 0, sizeof(wndClass));
50 wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
51 wndClass.lpfnWndProc = windowProcCallback;
52 wndClass.cbClsExtra = 0;
53 wndClass.cbWndExtra = 0;
54 wndClass.hInstance = instance;
55 wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
56 wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
57 wndClass.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
58 wndClass.lpszMenuName = NULL;
59 wndClass.lpszClassName = s_className;
60
61 RegisterClass(&wndClass);
62 }
63
64 m_window = CreateWindow(s_className, s_windowName, WS_CLIPCHILDREN | WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
65 width, height, NULL, NULL, instance, NULL);
66
67 if (!m_window)
68 TCU_THROW(ResourceError, "Failed to create Win32 window");
69
70 // Store this as userdata
71 SetWindowLongPtr(m_window, GWLP_USERDATA, (LONG_PTR)this);
72
73 setSize(width, height);
74 }
75 catch (...)
76 {
77 if (m_window)
78 DestroyWindow(m_window);
79
80 throw;
81 }
82 }
83
~Window(void)84 Window::~Window(void)
85 {
86 if (m_window)
87 {
88 // Clear this pointer from windowproc
89 SetWindowLongPtr(m_window, GWLP_USERDATA, 0);
90 }
91
92 DestroyWindow(m_window);
93 }
94
setVisible(bool visible)95 void Window::setVisible(bool visible)
96 {
97 ShowWindow(m_window, visible ? SW_SHOW : SW_HIDE);
98 processEvents();
99 }
100
setForeground(void)101 bool Window::setForeground(void)
102 {
103 const bool result = SetForegroundWindow(m_window);
104 processEvents();
105 return result;
106 }
107
setSize(int width,int height)108 void Window::setSize(int width, int height)
109 {
110 RECT rc;
111
112 rc.left = 0;
113 rc.top = 0;
114 rc.right = width;
115 rc.bottom = height;
116
117 if (!AdjustWindowRect(&rc, GetWindowLong(m_window, GWL_STYLE), GetMenu(m_window) != NULL))
118 TCU_THROW(TestError, "AdjustWindowRect() failed");
119
120 if (!SetWindowPos(m_window, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
121 SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER))
122 TCU_THROW(TestError, "SetWindowPos() failed");
123 }
124
setMinimized(bool minimize)125 void Window::setMinimized(bool minimize)
126 {
127 ShowWindow(m_window, minimize ? SW_MINIMIZE : SW_RESTORE);
128 processEvents();
129 }
130
getSize(void) const131 IVec2 Window::getSize(void) const
132 {
133 RECT rc;
134 if (!GetClientRect(m_window, &rc))
135 TCU_THROW(TestError, "GetClientRect() failed");
136
137 return IVec2(rc.right - rc.left, rc.bottom - rc.top);
138 }
139
processEvents(void)140 void Window::processEvents(void)
141 {
142 MSG msg;
143 while (PeekMessage(&msg, m_window, 0, 0, PM_REMOVE))
144 DispatchMessage(&msg);
145 }
146
windowProc(UINT uMsg,WPARAM wParam,LPARAM lParam)147 LRESULT Window::windowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
148 {
149 switch (uMsg)
150 {
151 // \todo [2014-03-12 pyry] Handle WM_SIZE?
152
153 case WM_DESTROY:
154 PostQuitMessage(0);
155 return 0;
156
157 case WM_KEYDOWN:
158 if (wParam == VK_ESCAPE)
159 {
160 PostQuitMessage(0);
161 return 0;
162 }
163 // fall-through
164
165 default:
166 return DefWindowProc(m_window, uMsg, wParam, lParam);
167 }
168 }
169
170 } // namespace win32
171 } // namespace tcu
172