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)
41 : m_window (DE_NULL)
42 {
43 try
44 {
45 static const char s_className[] = "dEQP Test Process Class";
46 static const char s_windowName[] = "dEQP Test Process";
47
48 {
49 WNDCLASS wndClass;
50 memset(&wndClass, 0, sizeof(wndClass));
51 wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
52 wndClass.lpfnWndProc = windowProcCallback;
53 wndClass.cbClsExtra = 0;
54 wndClass.cbWndExtra = 0;
55 wndClass.hInstance = instance;
56 wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
57 wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
58 wndClass.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
59 wndClass.lpszMenuName = NULL;
60 wndClass.lpszClassName = s_className;
61
62 RegisterClass(&wndClass);
63 }
64
65 m_window = CreateWindow(s_className, s_windowName,
66 WS_CLIPCHILDREN | WS_POPUP,
67 CW_USEDEFAULT, CW_USEDEFAULT,
68 width, height,
69 NULL, NULL, instance, NULL);
70
71 if (!m_window)
72 TCU_THROW(ResourceError, "Failed to create Win32 window");
73
74 // Store this as userdata
75 SetWindowLongPtr(m_window, GWLP_USERDATA, (LONG_PTR)this);
76
77 setSize(width, height);
78 }
79 catch (...)
80 {
81 if (m_window)
82 DestroyWindow(m_window);
83
84 throw;
85 }
86 }
87
~Window(void)88 Window::~Window (void)
89 {
90 if (m_window)
91 {
92 // Clear this pointer from windowproc
93 SetWindowLongPtr(m_window, GWLP_USERDATA, 0);
94 }
95
96 DestroyWindow(m_window);
97 }
98
setVisible(bool visible)99 void Window::setVisible (bool visible)
100 {
101 ShowWindow(m_window, visible ? SW_SHOW : SW_HIDE);
102 processEvents();
103 }
104
setForeground(void)105 void Window::setForeground(void)
106 {
107 SetForegroundWindow(m_window);
108 processEvents();
109 }
110
setSize(int width,int height)111 void Window::setSize (int width, int height)
112 {
113 RECT rc;
114
115 rc.left = 0;
116 rc.top = 0;
117 rc.right = width;
118 rc.bottom = height;
119
120 if (!AdjustWindowRect(&rc, GetWindowLong(m_window, GWL_STYLE), GetMenu(m_window) != NULL))
121 TCU_THROW(TestError, "AdjustWindowRect() failed");
122
123 if (!SetWindowPos(m_window, NULL, 0, 0,
124 rc.right - rc.left, rc.bottom - rc.top,
125 SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER))
126 TCU_THROW(TestError, "SetWindowPos() failed");
127 }
128
setMinimized(bool minimize)129 void Window::setMinimized(bool minimize)
130 {
131 ShowWindow(m_window, minimize ? SW_MINIMIZE : SW_RESTORE);
132 processEvents();
133 }
134
getSize(void) const135 IVec2 Window::getSize (void) const
136 {
137 RECT rc;
138 if (!GetClientRect(m_window, &rc))
139 TCU_THROW(TestError, "GetClientRect() failed");
140
141 return IVec2(rc.right - rc.left,
142 rc.bottom - rc.top);
143 }
144
processEvents(void)145 void Window::processEvents (void)
146 {
147 MSG msg;
148 while (PeekMessage(&msg, m_window, 0, 0, PM_REMOVE))
149 DispatchMessage(&msg);
150 }
151
windowProc(UINT uMsg,WPARAM wParam,LPARAM lParam)152 LRESULT Window::windowProc (UINT uMsg, WPARAM wParam, LPARAM lParam)
153 {
154 switch (uMsg)
155 {
156 // \todo [2014-03-12 pyry] Handle WM_SIZE?
157
158 case WM_DESTROY:
159 PostQuitMessage(0);
160 return 0;
161
162 case WM_KEYDOWN:
163 if (wParam == VK_ESCAPE)
164 {
165 PostQuitMessage(0);
166 return 0;
167 }
168 // fall-through
169
170 default:
171 return DefWindowProc(m_window, uMsg, wParam, lParam);
172 }
173 }
174
175 } // win32
176 } // tcu
177