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