• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 void Window::setForeground(void)
102 {
103     SetForegroundWindow(m_window);
104     processEvents();
105 }
106 
setSize(int width,int height)107 void Window::setSize(int width, int height)
108 {
109     RECT rc;
110 
111     rc.left   = 0;
112     rc.top    = 0;
113     rc.right  = width;
114     rc.bottom = height;
115 
116     if (!AdjustWindowRect(&rc, GetWindowLong(m_window, GWL_STYLE), GetMenu(m_window) != NULL))
117         TCU_THROW(TestError, "AdjustWindowRect() failed");
118 
119     if (!SetWindowPos(m_window, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
120                       SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER))
121         TCU_THROW(TestError, "SetWindowPos() failed");
122 }
123 
setMinimized(bool minimize)124 void Window::setMinimized(bool minimize)
125 {
126     ShowWindow(m_window, minimize ? SW_MINIMIZE : SW_RESTORE);
127     processEvents();
128 }
129 
getSize(void) const130 IVec2 Window::getSize(void) const
131 {
132     RECT rc;
133     if (!GetClientRect(m_window, &rc))
134         TCU_THROW(TestError, "GetClientRect() failed");
135 
136     return IVec2(rc.right - rc.left, rc.bottom - rc.top);
137 }
138 
processEvents(void)139 void Window::processEvents(void)
140 {
141     MSG msg;
142     while (PeekMessage(&msg, m_window, 0, 0, PM_REMOVE))
143         DispatchMessage(&msg);
144 }
145 
windowProc(UINT uMsg,WPARAM wParam,LPARAM lParam)146 LRESULT Window::windowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
147 {
148     switch (uMsg)
149     {
150         // \todo [2014-03-12 pyry] Handle WM_SIZE?
151 
152     case WM_DESTROY:
153         PostQuitMessage(0);
154         return 0;
155 
156     case WM_KEYDOWN:
157         if (wParam == VK_ESCAPE)
158         {
159             PostQuitMessage(0);
160             return 0;
161         }
162         // fall-through
163 
164     default:
165         return DefWindowProc(m_window, uMsg, wParam, lParam);
166     }
167 }
168 
169 } // namespace win32
170 } // namespace tcu
171