xref: /aosp_15_r20/external/deqp/framework/platform/win32/tcuWin32Window.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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