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