15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*-------------------------------------------------------------------------
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * drawElements Quality Program Tester Core
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ----------------------------------------
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2014 The Android Open Source Project
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you may not use this file except in compliance with the License.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *//*!
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \file
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \brief Generic Win32 window class.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *//*--------------------------------------------------------------------*/
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "tcuWin32Window.hpp"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tcu
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static LRESULT CALLBACK win32WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	Win32Window* window = reinterpret_cast<Win32Window*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (window)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return window->windowProc(uMsg, wParam, lParam);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return DefWindowProc(hWnd, uMsg, wParam, lParam);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Win32Window::Win32Window (HINSTANCE instance, int width, int height)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	: m_window		(DE_NULL)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	try
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)		static const char	s_className[]	= "dEQP Tester Core Class";
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		static const char	s_windowName[]	= "dEQP Tester Core";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			WNDCLASS wndClass;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			memset(&wndClass, 0, sizeof(wndClass));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.lpfnWndProc	= win32WindowProc;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.cbClsExtra		= 0;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.cbWndExtra		= 0;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.hInstance		= instance;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.hCursor		= LoadCursor(NULL, IDC_ARROW);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.hbrBackground	= CreateSolidBrush(RGB(0, 0, 0));
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.lpszMenuName	= NULL;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wndClass.lpszClassName	= s_className;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)			RegisterClass(&wndClass);
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)		m_window = CreateWindow(s_className, s_windowName,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)								WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW,
65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)								CW_USEDEFAULT, CW_USEDEFAULT,
66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)								width, height,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)								NULL, NULL, instance, NULL);
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)		if (!m_window)
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)			throw ResourceError("Failed to create Win32 window", "", __FILE__, __LINE__);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		// Store this as userdata
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SetWindowLongPtr(m_window, GWLP_USERDATA, (LONG_PTR)this);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		setSize(width, height);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	catch (...)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (m_window)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			DestroyWindow(m_window);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		throw;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Win32Window::~Win32Window (void)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (m_window)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		// Clear this pointer from windowproc
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SetWindowLongPtr(m_window, GWLP_USERDATA, 0);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	DestroyWindow(m_window);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Win32Window::setVisible (bool visible)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ShowWindow(m_window, visible ? SW_SHOW : SW_HIDE);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Win32Window::setSize (int width, int height)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	RECT rc;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rc.left		= 0;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rc.top		= 0;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rc.right	= width;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rc.bottom	= height;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!AdjustWindowRect(&rc, GetWindowLong(m_window, GWL_STYLE), GetMenu(m_window) != NULL))
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		throw tcu::TestError("AdjustWindowRect() failed", DE_NULL, __FILE__, __LINE__);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!SetWindowPos(m_window, NULL, 0, 0,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  rc.right - rc.left, rc.bottom - rc.top,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER))
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		throw tcu::TestError("SetWindowPos() failed", DE_NULL, __FILE__, __LINE__);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IVec2 Win32Window::getSize (void) const
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	RECT rc;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!GetClientRect(m_window, &rc))
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		throw tcu::TestError("GetClientRect() failed", DE_NULL, __FILE__, __LINE__);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return IVec2(rc.right - rc.left,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 rc.bottom - rc.top);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Win32Window::processEvents (void)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)	MSG msg;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (PeekMessage(&msg, m_window, 0, 0, PM_REMOVE))
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		DispatchMessage(&msg);
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LRESULT Win32Window::windowProc (UINT uMsg, WPARAM wParam, LPARAM lParam)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (uMsg)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		// \todo [2014-03-12 pyry] Handle WM_SIZE?
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case WM_DESTROY:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PostQuitMessage(0);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return 0;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case WM_KEYDOWN:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (wParam == VK_ESCAPE)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				PostQuitMessage(0);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				return 0;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			// fall-through
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return DefWindowProc(m_window, uMsg, wParam, lParam);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // tcu
161