| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Copyright 2013 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | #include <windows.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "Core/ConfigManager.h"
 | 
					
						
							|  |  |  | #include "Core/Core.h"
 | 
					
						
							|  |  |  | #include "Core/Host.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "VideoCommon/EmuWindow.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/Fifo.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/VideoBackendBase.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/VideoConfig.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | namespace EmuWindow | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | HWND m_hWnd = nullptr; | 
					
						
							|  |  |  | HWND m_hParent = nullptr; | 
					
						
							|  |  |  | HINSTANCE m_hInstance = nullptr; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | WNDCLASSEX wndClass; | 
					
						
							|  |  |  | const TCHAR m_szClassName[] = _T("DolphinEmuWnd"); | 
					
						
							|  |  |  | int g_winstyle; | 
					
						
							|  |  |  | static volatile bool s_sizing; | 
					
						
							| 
									
										
										
										
											2011-12-19 15:13:26 -08:00
										 |  |  | static const int WM_SETTEXT_CUSTOM = WM_USER + WM_SETTEXT; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | bool IsSizing() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return s_sizing; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | HWND GetWnd() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return m_hWnd; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | HWND GetParentWnd() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return m_hParent; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-09-06 13:36:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam ) | 
					
						
							| 
									
										
										
										
											2010-03-03 19:21:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	switch ( iMsg ) | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 	case WM_PAINT: | 
					
						
							| 
									
										
										
										
											2009-09-13 08:21:35 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			HDC hdc; | 
					
						
							|  |  |  | 			PAINTSTRUCT ps; | 
					
						
							|  |  |  | 			hdc = BeginPaint(hWnd, &ps); | 
					
						
							|  |  |  | 			EndPaint(hWnd, &ps); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-02-25 06:12:35 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	case WM_ENTERSIZEMOVE: | 
					
						
							|  |  |  | 		s_sizing = true; | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	case WM_EXITSIZEMOVE: | 
					
						
							|  |  |  | 		s_sizing = false; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-19 09:21:45 -04:00
										 |  |  | 	/* Post the mouse events to the main window, it's necessary, because the difference between the
 | 
					
						
							|  |  |  | 	   keyboard inputs is that these events only appear here, not in the parent window or any other WndProc()*/ | 
					
						
							| 
									
										
										
										
											2009-09-06 13:36:05 +00:00
										 |  |  | 	case WM_LBUTTONDOWN: | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 		if (g_ActiveConfig.backend_info.bSupports3DVision && g_ActiveConfig.b3DVision) | 
					
						
							| 
									
										
										
										
											2011-04-29 23:02:06 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			// This basically throws away the left button down input when b3DVision is activated so WX
 | 
					
						
							|  |  |  | 			// can't get access to it, stopping focus pulling on mouse click.
 | 
					
						
							|  |  |  | 			// (Input plugins use a different system so it doesn't cause too much weirdness)
 | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-09-06 13:36:05 +00:00
										 |  |  | 	case WM_LBUTTONUP: | 
					
						
							|  |  |  | 	case WM_LBUTTONDBLCLK: | 
					
						
							| 
									
										
										
										
											2009-09-06 19:30:24 +00:00
										 |  |  | 		PostMessage(GetParentWnd(), iMsg, wParam, lParam); | 
					
						
							| 
									
										
										
										
											2009-09-13 08:21:35 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-09-06 13:36:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	// This is called when we close the window when we render to a separate window
 | 
					
						
							|  |  |  | 	case WM_CLOSE: | 
					
						
							|  |  |  | 		// When the user closes the window, we post an event to the main window to call Stop()
 | 
					
						
							| 
									
										
										
										
											2011-02-14 02:18:03 +00:00
										 |  |  | 		// Which then handles all the necessary steps to Shutdown the core
 | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 		if (m_hParent == nullptr) | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			// Stop the game
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 			//PostMessage(m_hParent, WM_USER, WM_USER_STOP, 0);
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 	case WM_USER: | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 	// Called when a screensaver wants to show up while this window is active
 | 
					
						
							|  |  |  | 	case WM_SYSCOMMAND: | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		switch (wParam) | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 		case SC_SCREENSAVE: | 
					
						
							|  |  |  | 		case SC_MONITORPOWER: | 
					
						
							| 
									
										
										
										
											2011-08-25 14:44:13 -05:00
										 |  |  | 		if (SConfig::GetInstance().m_LocalCoreStartupParameter.bDisableScreenSaver) | 
					
						
							| 
									
										
										
										
											2010-02-25 06:12:35 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			return DefWindowProc(hWnd, iMsg, wParam, lParam); | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2010-04-12 01:33:10 +00:00
										 |  |  | 	case WM_SETCURSOR: | 
					
						
							|  |  |  | 		PostMessage(m_hParent, WM_USER, WM_USER_SETCURSOR, 0); | 
					
						
							|  |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-19 15:13:26 -08:00
										 |  |  | 	case WM_SETTEXT_CUSTOM: | 
					
						
							|  |  |  | 		SendMessage(hWnd, WM_SETTEXT, wParam, lParam); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-25 06:12:35 +00:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		return DefWindowProc(hWnd, iMsg, wParam, lParam); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-25 06:12:35 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	wndClass.cbSize = sizeof( wndClass ); | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	wndClass.style  = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 	wndClass.lpfnWndProc = WndProc; | 
					
						
							|  |  |  | 	wndClass.cbClsExtra = 0; | 
					
						
							|  |  |  | 	wndClass.cbWndExtra = 0; | 
					
						
							|  |  |  | 	wndClass.hInstance = hInstance; | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 	wndClass.hIcon = LoadIcon( nullptr, IDI_APPLICATION ); | 
					
						
							|  |  |  | 	wndClass.hCursor = nullptr; | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 	wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 	wndClass.lpszMenuName = nullptr; | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 	wndClass.lpszClassName = m_szClassName; | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 	wndClass.hIconSm = LoadIcon( nullptr, IDI_APPLICATION ); | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	m_hInstance = hInstance; | 
					
						
							|  |  |  | 	RegisterClassEx( &wndClass ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 01:33:10 +00:00
										 |  |  | 	m_hParent = parent; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	m_hWnd = CreateWindow(m_szClassName, title, (g_ActiveConfig.backend_info.bSupports3DVision && g_ActiveConfig.b3DVision) ? WS_EX_TOPMOST | WS_POPUP : WS_CHILD, | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 		0, 0, width, height, m_hParent, nullptr, hInstance, nullptr); | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return m_hWnd; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Show() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ShowWindow(m_hWnd, SW_SHOW); | 
					
						
							|  |  |  | 	BringWindowToTop(m_hWnd); | 
					
						
							|  |  |  | 	UpdateWindow(m_hWnd); | 
					
						
							| 
									
										
										
										
											2011-03-22 19:05:08 +00:00
										 |  |  | 	SetFocus(m_hParent); | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	// TODO:
 | 
					
						
							|  |  |  | 	// 1. Remove redundant window manipulation,
 | 
					
						
							| 
									
										
										
										
											2014-01-29 14:39:13 -05:00
										 |  |  | 	// 2. Request window sizes which actually make the client area map to a common resolution
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	HWND Ret; | 
					
						
							| 
									
										
										
										
											2010-04-12 01:33:10 +00:00
										 |  |  | 	int x=0, y=0, width=640, height=480; | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	Host_GetRenderWindowSize(x, y, width, height); | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	 // TODO: Don't show if fullscreen
 | 
					
						
							|  |  |  | 	Ret = OpenWindow(hParent, hInstance, width, height, title); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (Ret) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		Show(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return Ret; | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Close() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-24 10:18:59 +00:00
										 |  |  | 	DestroyWindow(m_hWnd); | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 	UnregisterClass(m_szClassName, m_hInstance); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SetSize(int width, int height) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	RECT rc = {0, 0, width, height}; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE); | 
					
						
							|  |  |  | 	AdjustWindowRect(&rc, style, false); | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int w = rc.right - rc.left; | 
					
						
							|  |  |  | 	int h = rc.bottom - rc.top; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rc.left = (1280 - w)/2; | 
					
						
							|  |  |  | 	rc.right = rc.left + w; | 
					
						
							|  |  |  | 	rc.top = (1024 - h)/2; | 
					
						
							|  |  |  | 	rc.bottom = rc.top + h; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | 	MoveWindow(m_hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE); | 
					
						
							| 
									
										
										
										
											2009-02-21 12:53:10 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-04 21:53:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | void SetWindowText(const std::string& text) | 
					
						
							| 
									
										
										
										
											2011-12-19 15:13:26 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	// the OS doesn't allow posting WM_SETTEXT,
 | 
					
						
							|  |  |  | 	// so we post our own message and convert it to that in WndProc
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 	PostMessage(m_hWnd, WM_SETTEXT_CUSTOM, 0, (LPARAM)text.c_str()); | 
					
						
							| 
									
										
										
										
											2011-12-19 15:13:26 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 19:43:18 +00:00
										 |  |  | } |