| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  os_windows.cpp                                                       */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							|  |  |  | /*                    http://www.godotengine.org                         */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | #include "drivers/gles2/rasterizer_gles2.h"
 | 
					
						
							| 
									
										
										
										
											2015-01-10 17:35:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "os_windows.h"
 | 
					
						
							|  |  |  | #include "drivers/nedmalloc/memory_pool_static_nedmalloc.h"
 | 
					
						
							|  |  |  | #include "drivers/unix/memory_pool_static_malloc.h"
 | 
					
						
							|  |  |  | #include "os/memory_pool_dynamic_static.h"
 | 
					
						
							|  |  |  | #include "drivers/windows/thread_windows.h"
 | 
					
						
							|  |  |  | #include "drivers/windows/semaphore_windows.h"
 | 
					
						
							|  |  |  | #include "drivers/windows/mutex_windows.h"
 | 
					
						
							|  |  |  | #include "main/main.h"
 | 
					
						
							|  |  |  | #include "drivers/windows/file_access_windows.h"
 | 
					
						
							|  |  |  | #include "drivers/windows/dir_access_windows.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "servers/visual/visual_server_raster.h"
 | 
					
						
							|  |  |  | #include "servers/audio/audio_server_sw.h"
 | 
					
						
							|  |  |  | #include "servers/visual/visual_server_wrap_mt.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "tcp_server_winsock.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | #include "packet_peer_udp_winsock.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "stream_peer_winsock.h"
 | 
					
						
							|  |  |  | #include "os/pc_joystick_map.h"
 | 
					
						
							|  |  |  | #include "lang_table.h"
 | 
					
						
							|  |  |  | #include "os/memory_pool_dynamic_prealloc.h"
 | 
					
						
							|  |  |  | #include "globals.h"
 | 
					
						
							|  |  |  | #include "io/marshalls.h"
 | 
					
						
							| 
									
										
										
										
											2014-12-02 14:02:41 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "shlobj.h"
 | 
					
						
							| 
									
										
										
										
											2015-02-12 04:17:29 +01:00
										 |  |  | #include <regstr.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | static const WORD MAX_CONSOLE_LINES = 1500; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-17 02:48:35 +01:00
										 |  |  | extern "C" { | 
					
						
							| 
									
										
										
										
											2015-01-18 02:06:29 +08:00
										 |  |  | #ifdef _MSC_VER
 | 
					
						
							| 
									
										
										
										
											2015-01-17 02:48:35 +01:00
										 |  |  | 	_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; | 
					
						
							| 
									
										
										
										
											2015-01-18 02:06:29 +08:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	__attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-17 02:48:35 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-02 14:02:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | //#define STDOUT_FILE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern HINSTANCE godot_hinstance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RedirectIOToConsole() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int hConHandle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	intptr_t lStdHandle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CONSOLE_SCREEN_BUFFER_INFO coninfo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// allocate a console for this app
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	AllocConsole(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set the screen buffer to be big enough to let us scroll text
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	&coninfo); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	coninfo.dwSize.Y = MAX_CONSOLE_LINES; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	coninfo.dwSize); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// redirect unbuffered STDOUT to the console
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lStdHandle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fp = _fdopen( hConHandle, "w" ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*stdout = *fp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	setvbuf( stdout, NULL, _IONBF, 0 ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// redirect unbuffered STDIN to the console
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lStdHandle = (intptr_t)GetStdHandle(STD_INPUT_HANDLE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fp = _fdopen( hConHandle, "r" ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*stdin = *fp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	setvbuf( stdin, NULL, _IONBF, 0 ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// redirect unbuffered STDERR to the console
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lStdHandle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fp = _fdopen( hConHandle, "w" ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*stderr = *fp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	setvbuf( stderr, NULL, _IONBF, 0 ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// point to console as well
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int OS_Windows::get_video_driver_count() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-10 17:35:26 -03:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | const char * OS_Windows::get_video_driver_name(int p_driver) const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 11:43:31 -03:00
										 |  |  | 	return "GLES2"; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OS::VideoMode OS_Windows::get_default_video_mode() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return VideoMode(800,600,false);	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int OS_Windows::get_audio_driver_count() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return AudioDriverManagerSW::get_driver_count(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | const char * OS_Windows::get_audio_driver_name(int p_driver) const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	AudioDriverSW* driver = AudioDriverManagerSW::get_driver(p_driver); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V( !driver, "" ); | 
					
						
							|  |  |  | 	return AudioDriverManagerSW::get_driver(p_driver)->get_name(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static MemoryPoolStatic *mempool_static=NULL; | 
					
						
							|  |  |  | static MemoryPoolDynamic *mempool_dynamic=NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::initialize_core() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	last_button_state=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//RedirectIOToConsole();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ThreadWindows::make_default();	 | 
					
						
							|  |  |  | 	SemaphoreWindows::make_default();	 | 
					
						
							|  |  |  | 	MutexWindows::make_default();	 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES); | 
					
						
							|  |  |  | 	FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA); | 
					
						
							|  |  |  | 	FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM); | 
					
						
							|  |  |  | 	//FileAccessBufferedFA<FileAccessWindows>::make_default();
 | 
					
						
							|  |  |  | 	DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_RESOURCES); | 
					
						
							|  |  |  | 	DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA); | 
					
						
							|  |  |  | 	DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	TCPServerWinsock::make_default(); | 
					
						
							|  |  |  | 	StreamPeerWinsock::make_default(); | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | 	PacketPeerUDPWinsock::make_default(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	mempool_static = new MemoryPoolStaticMalloc; | 
					
						
							|  |  |  | #if 1
 | 
					
						
							|  |  |  | 	mempool_dynamic = memnew( MemoryPoolDynamicStatic ); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define DYNPOOL_SIZE 4*1024*1024
 | 
					
						
							|  |  |  | 	void * buffer = malloc( DYNPOOL_SIZE ); | 
					
						
							|  |  |  | 	mempool_dynamic = memnew( MemoryPoolDynamicPrealloc(buffer,DYNPOOL_SIZE) ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	   // We need to know how often the clock is updated
 | 
					
						
							|  |  |  | 	if( !QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second) ) | 
					
						
							|  |  |  | 		ticks_per_second = 1000; | 
					
						
							|  |  |  | 	// If timeAtGameStart is 0 then we get the time since
 | 
					
						
							|  |  |  | 	// the start of the computer when we call GetGameTime()
 | 
					
						
							|  |  |  | 	ticks_start = 0; | 
					
						
							|  |  |  | 	ticks_start = get_ticks_usec(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	process_map = memnew((Map<ProcessID, ProcessInfo>)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	IP_Unix::make_default(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cursor_shape=CURSOR_ARROW; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool OS_Windows::can_draw() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return !minimized; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | #define MI_WP_SIGNATURE 0xFF515700
 | 
					
						
							|  |  |  | #define SIGNATURE_MASK 0xFFFFFF00
 | 
					
						
							|  |  |  | #define IsPenEvent(dw) (((dw) & SIGNATURE_MASK) == MI_WP_SIGNATURE)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) { | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	InputEvent event; | 
					
						
							|  |  |  | 	event.type = InputEvent::SCREEN_TOUCH; | 
					
						
							|  |  |  | 	event.ID=++last_id; | 
					
						
							|  |  |  | 	event.screen_touch.index = idx; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 	event.screen_touch.pressed = p_pressed; | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 	event.screen_touch.x=p_x; | 
					
						
							|  |  |  | 	event.screen_touch.y=p_y; | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (main_loop) { | 
					
						
							|  |  |  | 		input->parse_input_event(event); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | void OS_Windows::_drag_event(int p_x, int p_y, int idx) { | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	InputEvent event; | 
					
						
							|  |  |  | 	event.type = InputEvent::SCREEN_DRAG; | 
					
						
							|  |  |  | 	event.ID=++last_id; | 
					
						
							|  |  |  | 	event.screen_drag.index = idx; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 	event.screen_drag.x=p_x; | 
					
						
							|  |  |  | 	event.screen_drag.y=p_y; | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (main_loop) | 
					
						
							|  |  |  | 		input->parse_input_event(event); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM	wParam,	LPARAM	lParam) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch (uMsg)									// Check For Windows Messages
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		case WM_ACTIVATE:							// Watch For Window Activate Message
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			minimized = HIWORD(wParam) != 0; | 
					
						
							|  |  |  | 			if (!main_loop) { | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); | 
					
						
							|  |  |  | 				alt_mem=false; | 
					
						
							|  |  |  | 				control_mem=false; | 
					
						
							|  |  |  | 				shift_mem=false; | 
					
						
							|  |  |  | 				if (mouse_mode==MOUSE_MODE_CAPTURED) { | 
					
						
							|  |  |  | 					RECT clipRect; | 
					
						
							|  |  |  | 					GetClientRect(hWnd, &clipRect); | 
					
						
							|  |  |  | 					ClientToScreen(hWnd, (POINT*) &clipRect.left); | 
					
						
							|  |  |  | 					ClientToScreen(hWnd, (POINT*) &clipRect.right); | 
					
						
							|  |  |  | 					ClipCursor(&clipRect); | 
					
						
							|  |  |  | 					SetCapture(hWnd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); | 
					
						
							|  |  |  | 				alt_mem=false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return 0;								// Return To The Message Loop
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_PAINT: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Main::force_redraw(); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_SYSCOMMAND:							// Intercept System Commands
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			switch (wParam)							// Check System Calls
 | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				case SC_SCREENSAVE:					// Screensaver Trying To Start?
 | 
					
						
							|  |  |  | 				case SC_MONITORPOWER:				// Monitor Trying To Enter Powersave?
 | 
					
						
							|  |  |  | 				return 0;							// Prevent From Happening
 | 
					
						
							|  |  |  | 				case SC_KEYMENU: | 
					
						
							|  |  |  | 					if ((lParam>>16)<=0) | 
					
						
							|  |  |  | 						return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break;									// Exit
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_CLOSE:								// Did We Receive A Close Message?
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (main_loop) | 
					
						
							|  |  |  | 				main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); | 
					
						
							|  |  |  | 			//force_quit=true;
 | 
					
						
							|  |  |  | 			return 0;								// Jump Back
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case WM_MOUSELEAVE: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 			old_invalid=true; | 
					
						
							|  |  |  | 			outside=true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case WM_MOUSEMOVE: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 			if (outside) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 				CursorShape c=cursor_shape; | 
					
						
							|  |  |  | 				cursor_shape=CURSOR_MAX; | 
					
						
							|  |  |  | 				set_cursor_shape(c); | 
					
						
							|  |  |  | 				outside=false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				//Once-Off notification, must call again....
 | 
					
						
							|  |  |  | 				TRACKMOUSEEVENT tme; | 
					
						
							|  |  |  | 				tme.cbSize=sizeof(TRACKMOUSEEVENT); | 
					
						
							|  |  |  | 				tme.dwFlags=TME_LEAVE; | 
					
						
							|  |  |  | 				tme.hwndTrack=hWnd; | 
					
						
							|  |  |  | 				tme.dwHoverTime=HOVER_DEFAULT; | 
					
						
							|  |  |  | 				TrackMouseEvent(&tme); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 			/*
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 			LPARAM extra = GetMessageExtraInfo(); | 
					
						
							|  |  |  | 			if (IsPenEvent(extra)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				int idx = extra & 0x7f; | 
					
						
							|  |  |  | 				_drag_event(idx, uMsg, wParam, lParam); | 
					
						
							|  |  |  | 				if (idx != 0) { | 
					
						
							|  |  |  | 					return 0; | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				// fallthrough for mouse event
 | 
					
						
							|  |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 			*/ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			InputEvent event; | 
					
						
							|  |  |  | 			event.type=InputEvent::MOUSE_MOTION; | 
					
						
							|  |  |  | 			event.ID=++last_id; | 
					
						
							|  |  |  | 			InputEventMouseMotion &mm=event.mouse_motion; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mm.mod.control=(wParam&MK_CONTROL)!=0; | 
					
						
							|  |  |  | 			mm.mod.shift=(wParam&MK_SHIFT)!=0; | 
					
						
							|  |  |  | 			mm.mod.alt=alt_mem; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mm.button_mask|=(wParam&MK_LBUTTON)?(1<<0):0; | 
					
						
							|  |  |  | 			mm.button_mask|=(wParam&MK_RBUTTON)?(1<<1):0; | 
					
						
							|  |  |  | 			mm.button_mask|=(wParam&MK_MBUTTON)?(1<<2):0; | 
					
						
							|  |  |  | 			last_button_state=mm.button_mask; | 
					
						
							|  |  |  | 			/*mm.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0;
 | 
					
						
							|  |  |  | 			mm.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ | 
					
						
							|  |  |  | 			mm.x=GET_X_LPARAM(lParam); | 
					
						
							|  |  |  | 			mm.y=GET_Y_LPARAM(lParam); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (mouse_mode==MOUSE_MODE_CAPTURED) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Point2i c(video_mode.width/2,video_mode.height/2); | 
					
						
							|  |  |  | 				if (Point2i(mm.x,mm.y)==c) { | 
					
						
							|  |  |  | 					center=c; | 
					
						
							|  |  |  | 					return 0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Point2i ncenter(mm.x,mm.y); | 
					
						
							|  |  |  | 				mm.x = old_x + (mm.x-center.x); | 
					
						
							|  |  |  | 				mm.y = old_y + (mm.y-center.y); | 
					
						
							|  |  |  | 				center=ncenter; | 
					
						
							|  |  |  | 				POINT pos = { (int) c.x, (int) c.y }; | 
					
						
							|  |  |  | 				ClientToScreen(hWnd, &pos); | 
					
						
							|  |  |  | 				SetCursorPos(pos.x, pos.y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			input->set_mouse_pos(Point2(mm.x,mm.y)); | 
					
						
							|  |  |  | 			mm.speed_x=input->get_mouse_speed().x; | 
					
						
							|  |  |  | 			mm.speed_y=input->get_mouse_speed().y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (old_invalid) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				old_x=mm.x; | 
					
						
							|  |  |  | 				old_y=mm.y; | 
					
						
							|  |  |  | 				old_invalid=false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mm.relative_x=mm.x-old_x; | 
					
						
							|  |  |  | 			mm.relative_y=mm.y-old_y; | 
					
						
							|  |  |  | 			old_x=mm.x; | 
					
						
							|  |  |  | 			old_y=mm.y; | 
					
						
							|  |  |  | 			if (main_loop) | 
					
						
							|  |  |  | 				input->parse_input_event(event); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case WM_LBUTTONDOWN: | 
					
						
							|  |  |  | 		case WM_LBUTTONUP: | 
					
						
							|  |  |  | 		case WM_MBUTTONDOWN: | 
					
						
							|  |  |  | 		case WM_MBUTTONUP: | 
					
						
							|  |  |  | 		case WM_RBUTTONDOWN: | 
					
						
							|  |  |  | 		case WM_RBUTTONUP: | 
					
						
							|  |  |  | 		case WM_MOUSEWHEEL: | 
					
						
							|  |  |  | 		case WM_LBUTTONDBLCLK: | 
					
						
							|  |  |  | 		/*case WM_XBUTTONDOWN:
 | 
					
						
							|  |  |  | 		case WM_XBUTTONUP: */{ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 			/*
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 			LPARAM extra = GetMessageExtraInfo(); | 
					
						
							|  |  |  | 			if (IsPenEvent(extra)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				int idx = extra & 0x7f; | 
					
						
							|  |  |  | 				_touch_event(idx, uMsg, wParam, lParam); | 
					
						
							|  |  |  | 				if (idx != 0) { | 
					
						
							|  |  |  | 					return 0; | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				// fallthrough for mouse event
 | 
					
						
							|  |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 			*/ | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			InputEvent event; | 
					
						
							|  |  |  | 			event.type=InputEvent::MOUSE_BUTTON; | 
					
						
							|  |  |  | 			event.ID=++last_id; | 
					
						
							|  |  |  | 			InputEventMouseButton &mb=event.mouse_button; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			switch (uMsg) { | 
					
						
							|  |  |  | 				case WM_LBUTTONDOWN: { | 
					
						
							|  |  |  | 					mb.pressed=true; | 
					
						
							|  |  |  | 					mb.button_index=1; | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case WM_LBUTTONUP: { | 
					
						
							|  |  |  | 					mb.pressed=false; | 
					
						
							|  |  |  | 					mb.button_index=1; | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case WM_MBUTTONDOWN: { | 
					
						
							|  |  |  | 					mb.pressed=true; | 
					
						
							|  |  |  | 					mb.button_index=3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case WM_MBUTTONUP: { | 
					
						
							|  |  |  | 					mb.pressed=false; | 
					
						
							|  |  |  | 					mb.button_index=3;					 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case WM_RBUTTONDOWN: { | 
					
						
							|  |  |  | 					mb.pressed=true; | 
					
						
							|  |  |  | 					mb.button_index=2; | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case WM_RBUTTONUP: { | 
					
						
							|  |  |  | 					mb.pressed=false; | 
					
						
							|  |  |  | 					mb.button_index=2; | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case WM_LBUTTONDBLCLK: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					mb.pressed=true; | 
					
						
							|  |  |  | 					mb.button_index=1; | 
					
						
							|  |  |  | 					mb.doubleclick = true; | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case WM_MOUSEWHEEL: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					mb.pressed=true; | 
					
						
							|  |  |  | 					int motion = (short)HIWORD(wParam); | 
					
						
							|  |  |  | 					if (!motion) | 
					
						
							|  |  |  | 						return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (motion>0) | 
					
						
							|  |  |  | 						mb.button_index=4; | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						mb.button_index=5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 					/*
 | 
					
						
							|  |  |  | 				case WM_XBUTTONDOWN: { | 
					
						
							|  |  |  | 					mb.pressed=true; | 
					
						
							|  |  |  | 					mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7; | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case WM_XBUTTONUP: | 
					
						
							|  |  |  | 					mb.pressed=true; | 
					
						
							|  |  |  | 					mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7; | 
					
						
							|  |  |  | 				} break;*/ | 
					
						
							|  |  |  | 				default: { return 0; } | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mb.mod.control=(wParam&MK_CONTROL)!=0; | 
					
						
							|  |  |  | 			mb.mod.shift=(wParam&MK_SHIFT)!=0; | 
					
						
							|  |  |  | 			mb.mod.alt=alt_mem; | 
					
						
							|  |  |  | 			//mb.mod.alt=(wParam&MK_MENU)!=0;
 | 
					
						
							|  |  |  | 			mb.button_mask|=(wParam&MK_LBUTTON)?(1<<0):0; | 
					
						
							|  |  |  | 			mb.button_mask|=(wParam&MK_RBUTTON)?(1<<1):0; | 
					
						
							|  |  |  | 			mb.button_mask|=(wParam&MK_MBUTTON)?(1<<2):0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			last_button_state=mb.button_mask; | 
					
						
							|  |  |  | 			/*
 | 
					
						
							|  |  |  | 			mb.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0; | 
					
						
							|  |  |  | 			mb.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ | 
					
						
							|  |  |  | 			mb.x=GET_X_LPARAM(lParam); | 
					
						
							|  |  |  | 			mb.y=GET_Y_LPARAM(lParam);			 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (mouse_mode==MOUSE_MODE_CAPTURED) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				mb.x=old_x; | 
					
						
							|  |  |  | 				mb.y=old_y; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mb.global_x=mb.x; | 
					
						
							|  |  |  | 			mb.global_y=mb.y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (uMsg != WM_MOUSEWHEEL) { | 
					
						
							|  |  |  | 				if (mb.pressed) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (++pressrc>0) | 
					
						
							|  |  |  | 						SetCapture(hWnd); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (--pressrc<=0) { | 
					
						
							|  |  |  | 						ReleaseCapture(); | 
					
						
							|  |  |  | 						pressrc=0; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if (mouse_mode!=MOUSE_MODE_CAPTURED) { | 
					
						
							|  |  |  | 				// for reasons unknown to mankind, wheel comes in screen cordinates
 | 
					
						
							|  |  |  | 				RECT rect; | 
					
						
							|  |  |  | 				GetWindowRect(hWnd,&rect); | 
					
						
							|  |  |  | 				mb.x-=rect.left; | 
					
						
							|  |  |  | 				mb.y-=rect.top; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (main_loop) { | 
					
						
							|  |  |  | 				input->parse_input_event(event); | 
					
						
							|  |  |  | 				if (mb.pressed && mb.button_index>3) { | 
					
						
							|  |  |  | 					//send release for mouse wheel
 | 
					
						
							|  |  |  | 					mb.pressed=false; | 
					
						
							|  |  |  | 					event.ID=++last_id; | 
					
						
							|  |  |  | 					input->parse_input_event(event); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_SIZE: { | 
					
						
							|  |  |  | 			video_mode.width=LOWORD(lParam); | 
					
						
							|  |  |  | 			video_mode.height=HIWORD(lParam); | 
					
						
							|  |  |  | 			//return 0;								// Jump Back
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case WM_SYSKEYDOWN: | 
					
						
							|  |  |  | 		case WM_SYSKEYUP: | 
					
						
							|  |  |  | 		case WM_KEYUP: | 
					
						
							|  |  |  | 		case WM_KEYDOWN: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (wParam==VK_SHIFT) | 
					
						
							|  |  |  | 				shift_mem=uMsg==WM_KEYDOWN; | 
					
						
							|  |  |  | 			if (wParam==VK_CONTROL) | 
					
						
							|  |  |  | 				control_mem=uMsg==WM_KEYDOWN; | 
					
						
							|  |  |  | 			if (wParam==VK_MENU) { | 
					
						
							|  |  |  | 				alt_mem=(uMsg==WM_KEYDOWN || uMsg==WM_SYSKEYDOWN); | 
					
						
							|  |  |  | 				if (lParam&(1<<24)) | 
					
						
							|  |  |  | 					gr_mem=alt_mem; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			//if (wParam==VK_WIN) TODO wtf is this?
 | 
					
						
							|  |  |  | 			//	meta_mem=uMsg==WM_KEYDOWN;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} //fallthrough
 | 
					
						
							|  |  |  | 		case WM_CHAR: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-17 23:06:20 -08:00
										 |  |  | 			// Make sure we don't include modifiers for the modifier key itself.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			KeyEvent ke; | 
					
						
							| 
									
										
										
										
											2015-01-17 22:40:01 -08:00
										 |  |  | 			ke.mod_state.shift= (wParam != VK_SHIFT) ? shift_mem : false; | 
					
						
							|  |  |  | 			ke.mod_state.alt= (! (wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false; | 
					
						
							|  |  |  | 			ke.mod_state.control= (wParam != VK_CONTROL) ? control_mem : false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			ke.mod_state.meta=meta_mem; | 
					
						
							|  |  |  | 			ke.uMsg=uMsg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (ke.uMsg==WM_SYSKEYDOWN) | 
					
						
							|  |  |  | 				ke.uMsg=WM_KEYDOWN; | 
					
						
							|  |  |  | 			if (ke.uMsg==WM_SYSKEYUP) | 
					
						
							|  |  |  | 				ke.uMsg=WM_KEYUP; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/*if (ke.uMsg==WM_KEYDOWN && alt_mem && uMsg!=WM_SYSKEYDOWN) {
 | 
					
						
							|  |  |  | 				//altgr hack for intl keyboards, not sure how good it is
 | 
					
						
							|  |  |  | 				//windows is weeeeird
 | 
					
						
							|  |  |  | 				ke.mod_state.alt=false; | 
					
						
							|  |  |  | 				ke.mod_state.control=false; | 
					
						
							|  |  |  | 				print_line("") | 
					
						
							|  |  |  | 			}*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ke.wParam=wParam; | 
					
						
							|  |  |  | 			ke.lParam=lParam; | 
					
						
							|  |  |  | 			key_event_buffer[key_event_pos++]=ke; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case WM_INPUTLANGCHANGEREQUEST: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			print_line("input lang change"); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		#if WINVER >= 0x0700 // for windows 7
 | 
					
						
							|  |  |  | 		case WM_TOUCH: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BOOL bHandled = FALSE; | 
					
						
							|  |  |  | 			UINT cInputs = LOWORD(wParam); | 
					
						
							|  |  |  | 			PTOUCHINPUT pInputs = memnew_arr(TOUCHINPUT, cInputs); | 
					
						
							|  |  |  | 			if (pInputs){ | 
					
						
							|  |  |  | 				if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))){ | 
					
						
							|  |  |  | 					for (UINT i=0; i < cInputs; i++){ | 
					
						
							|  |  |  | 						TOUCHINPUT ti = pInputs[i]; | 
					
						
							|  |  |  | 						//do something with each touch input entry
 | 
					
						
							|  |  |  | 						if (ti.dwFlags & TOUCHEVENTF_MOVE) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							_drag_event(ti.x / 100, ti.y / 100, ti.dwID); | 
					
						
							|  |  |  | 						} else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							_touch_event(ti.dwFlags & TOUCHEVENTF_DOWN != 0, ti.x / 100, ti.y / 100, ti.dwID); | 
					
						
							|  |  |  | 						}; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					bHandled = TRUE; | 
					
						
							|  |  |  | 				}else{ | 
					
						
							|  |  |  | 					 /* handle the error here */ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				memdelete_arr(pInputs); | 
					
						
							|  |  |  | 			}else{ | 
					
						
							|  |  |  | 				/* handle the error here, probably out of memory */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (bHandled) { | 
					
						
							|  |  |  | 				CloseTouchInputHandle((HTOUCHINPUT)lParam); | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		default: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (user_proc) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return DefWindowProcW(hWnd,uMsg,wParam,lParam); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LRESULT CALLBACK WndProc(HWND	hWnd,UINT uMsg,	WPARAM	wParam,	LPARAM	lParam)	{ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	OS_Windows *os_win = static_cast<OS_Windows*>(OS::get_singleton()); | 
					
						
							|  |  |  | 	if (os_win) | 
					
						
							|  |  |  | 		return os_win->WndProc(hWnd,uMsg,wParam,lParam); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return DefWindowProcW(hWnd,uMsg,wParam,lParam); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 04:17:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | String OS_Windows::get_joystick_name(int id, JOYCAPS jcaps) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char buffer [256]; | 
					
						
							|  |  |  | 	char OEM [256]; | 
					
						
							|  |  |  | 	HKEY hKey; | 
					
						
							|  |  |  | 	DWORD sz; | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_snprintf(buffer, sizeof(buffer), "%s\\%s\\%s", | 
					
						
							|  |  |  | 				REGSTR_PATH_JOYCONFIG, jcaps.szRegKey, | 
					
						
							|  |  |  | 				REGSTR_KEY_JOYCURR ); | 
					
						
							|  |  |  | 	res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey); | 
					
						
							|  |  |  | 	if (res != ERROR_SUCCESS) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		res = RegOpenKeyEx(HKEY_CURRENT_USER, buffer, 0, KEY_QUERY_VALUE, &hKey); | 
					
						
							|  |  |  | 		if (res != ERROR_SUCCESS)  | 
					
						
							|  |  |  | 			return ""; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sz = sizeof(OEM); | 
					
						
							|  |  |  | 	_snprintf( buffer, sizeof(buffer), "Joystick%d%s", id + 1, REGSTR_VAL_JOYOEMNAME); | 
					
						
							|  |  |  | 	res = RegQueryValueEx ( hKey, buffer, 0, 0, (LPBYTE) OEM, &sz); | 
					
						
							|  |  |  | 	RegCloseKey ( hKey ); | 
					
						
							|  |  |  | 	if (res != ERROR_SUCCESS)  | 
					
						
							|  |  |  | 		return ""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_snprintf( buffer, sizeof(buffer), "%s\\%s", REGSTR_PATH_JOYOEM, OEM); | 
					
						
							| 
									
										
										
										
											2015-02-25 16:33:08 +01:00
										 |  |  | 	res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey); | 
					
						
							|  |  |  | 	if (res != ERROR_SUCCESS) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		res = RegOpenKeyEx(HKEY_CURRENT_USER, buffer, 0, KEY_QUERY_VALUE, &hKey); | 
					
						
							|  |  |  | 		if (res != ERROR_SUCCESS) | 
					
						
							|  |  |  | 			return ""; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2015-02-12 04:17:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	sz = sizeof(buffer); | 
					
						
							|  |  |  | 	res = RegQueryValueEx(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buffer, | 
					
						
							|  |  |  | 						  &sz); | 
					
						
							|  |  |  | 	RegCloseKey(hKey); | 
					
						
							|  |  |  | 	if (res != ERROR_SUCCESS)  | 
					
						
							|  |  |  | 		return ""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return String(buffer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void OS_Windows::probe_joysticks() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 	static uint32_t last_attached = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	int device_count = joyGetNumDevs(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	JOYINFOEX jinfo; | 
					
						
							|  |  |  | 	jinfo.dwSize = sizeof(JOYINFOEX); | 
					
						
							|  |  |  | 	jinfo.dwFlags = JOY_RETURNALL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i=0; i<JOYSTICKS_MAX; i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 		Joystick joy; | 
					
						
							|  |  |  | 		joy.id = i; | 
					
						
							|  |  |  | 		joy.attached = (device_count > 0) && (joyGetPosEx(JOYSTICKID1 + i, &jinfo) == JOYERR_NOERROR); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 		if (joy.attached == (last_attached & (1 << i) != 0)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 		// there's been a change since last call
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (joy.attached) | 
					
						
							|  |  |  | 			last_attached = last_attached | (1 << i); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			last_attached &= ~(1 << i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (joy.attached) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 			joy.last_buttons = jinfo.dwButtons; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			joy.last_axis[0] = jinfo.dwXpos; | 
					
						
							|  |  |  | 			joy.last_axis[1] = jinfo.dwYpos; | 
					
						
							|  |  |  | 			joy.last_axis[2] = jinfo.dwZpos; | 
					
						
							|  |  |  | 			joy.last_axis[3] = jinfo.dwRpos; | 
					
						
							|  |  |  | 			joy.last_axis[4] = jinfo.dwUpos; | 
					
						
							|  |  |  | 			joy.last_axis[5] = jinfo.dwVpos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			JOYCAPS jcaps; | 
					
						
							|  |  |  | 			MMRESULT res = joyGetDevCaps(JOYSTICKID1 + i, &jcaps, sizeof(jcaps)); | 
					
						
							|  |  |  | 			if (res == JOYERR_NOERROR) { | 
					
						
							| 
									
										
										
										
											2015-02-12 04:17:29 +01:00
										 |  |  | 				String name = get_joystick_name(JOYSTICKID1 + i, jcaps); | 
					
						
							|  |  |  | 				if ( name == "") | 
					
						
							|  |  |  | 					joy.name = jcaps.szPname; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					joy.name = name; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 					 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 			}; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		joystick_change_queue.push_back(joy); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::process_key_events() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(int i=0;i<key_event_pos;i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		KeyEvent &ke = key_event_buffer[i]; | 
					
						
							|  |  |  | 		switch(ke.uMsg) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case WM_CHAR: { | 
					
						
							| 
									
										
										
										
											2014-03-11 13:21:18 +08:00
										 |  |  |                 if ((i==0 && ke.uMsg==WM_CHAR) || (i>0 && key_event_buffer[i-1].uMsg==WM_CHAR)) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  | 				    InputEvent event; | 
					
						
							|  |  |  | 				    event.type=InputEvent::KEY; | 
					
						
							|  |  |  | 				    event.ID=++last_id; | 
					
						
							|  |  |  | 				    InputEventKey &k=event.key; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				    k.mod=ke.mod_state; | 
					
						
							|  |  |  | 				    k.pressed=true; | 
					
						
							|  |  |  | 				    k.scancode=KeyMappingWindows::get_keysym(ke.wParam); | 
					
						
							|  |  |  |                     k.unicode=ke.wParam; | 
					
						
							|  |  |  | 				    if (k.unicode && gr_mem) { | 
					
						
							|  |  |  | 					    k.mod.alt=false; | 
					
						
							|  |  |  | 					    k.mod.control=false; | 
					
						
							|  |  |  | 				    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				    if (k.unicode<32) | 
					
						
							|  |  |  | 					    k.unicode=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				    input->parse_input_event(event); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				//do nothing
 | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case WM_KEYUP: | 
					
						
							|  |  |  | 			case WM_KEYDOWN: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				InputEvent event; | 
					
						
							|  |  |  | 				event.type=InputEvent::KEY; | 
					
						
							|  |  |  | 				event.ID=++last_id; | 
					
						
							|  |  |  | 				InputEventKey &k=event.key; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				k.mod=ke.mod_state; | 
					
						
							|  |  |  | 				k.pressed=(ke.uMsg==WM_KEYDOWN); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				k.scancode=KeyMappingWindows::get_keysym(ke.wParam); | 
					
						
							|  |  |  | 				if (i+1 < key_event_pos && key_event_buffer[i+1].uMsg==WM_CHAR) | 
					
						
							|  |  |  | 					k.unicode=key_event_buffer[i+1].wParam; | 
					
						
							|  |  |  | 				if (k.unicode && gr_mem) { | 
					
						
							|  |  |  | 					k.mod.alt=false; | 
					
						
							|  |  |  | 					k.mod.control=false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (k.unicode<32) | 
					
						
							|  |  |  | 					k.unicode=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				k.echo=(ke.uMsg==WM_KEYDOWN && (ke.lParam&(1<<30))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				input->parse_input_event(event); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	key_event_pos=0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::_post_dpad(DWORD p_dpad, int p_device, bool p_pressed) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	InputEvent ievent; | 
					
						
							|  |  |  | 	ievent.device = p_device; | 
					
						
							|  |  |  | 	ievent.type = InputEvent::JOYSTICK_BUTTON; | 
					
						
							|  |  |  | 	ievent.joy_button.pressed = p_pressed; | 
					
						
							|  |  |  | 	ievent.joy_button.pressure = p_pressed ? 1.0 : 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_dpad == 0) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_UP; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (p_dpad == 4500) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_UP; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_RIGHT; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (p_dpad == 9000) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_RIGHT; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (p_dpad == 13500) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_RIGHT; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_DOWN; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (p_dpad == 18000) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_DOWN; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (p_dpad == 22500) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_DOWN; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_LEFT; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (p_dpad == 27000) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_LEFT; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (p_dpad == 31500) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_LEFT; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.joy_button.button_index = JOY_DPAD_UP; | 
					
						
							|  |  |  | 		ievent.ID = ++last_id; | 
					
						
							|  |  |  | 		input->parse_input_event(ievent); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::process_joysticks() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!main_loop) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	InputEvent ievent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	JOYINFOEX jinfo; | 
					
						
							|  |  |  | 	jinfo.dwSize = sizeof(JOYINFOEX); | 
					
						
							|  |  |  | 	jinfo.dwFlags = JOY_RETURNALL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i=0; i<JOYSTICKS_MAX; i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!joysticks[i].attached) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (joyGetPosEx(JOYSTICKID1 + i, &jinfo) != JOYERR_NOERROR) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.device = i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#define CHECK_AXIS(n, var) \
 | 
					
						
							|  |  |  | 			if (joysticks[i].last_axis[n] != var) {\ | 
					
						
							|  |  |  | 				ievent.type = InputEvent::JOYSTICK_MOTION;\ | 
					
						
							|  |  |  | 				ievent.ID = ++last_id;\ | 
					
						
							|  |  |  | 				ievent.joy_motion.axis = n;\ | 
					
						
							|  |  |  | 				ievent.joy_motion.axis_value = (float)((int)var - MAX_JOY_AXIS) / (float)MAX_JOY_AXIS;\ | 
					
						
							|  |  |  | 				joysticks[i].last_axis[n] = var;\ | 
					
						
							|  |  |  | 				input->parse_input_event(ievent);\ | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		CHECK_AXIS(0, jinfo.dwXpos); | 
					
						
							|  |  |  | 		CHECK_AXIS(1, jinfo.dwYpos); | 
					
						
							|  |  |  | 		CHECK_AXIS(2, jinfo.dwZpos); | 
					
						
							|  |  |  | 		CHECK_AXIS(3, jinfo.dwRpos); | 
					
						
							|  |  |  | 		CHECK_AXIS(4, jinfo.dwUpos); | 
					
						
							|  |  |  | 		CHECK_AXIS(5, jinfo.dwVpos); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (joysticks[i].last_pov != jinfo.dwPOV) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (joysticks[i].last_pov != JOY_POVCENTERED) | 
					
						
							|  |  |  | 				_post_dpad(joysticks[i].last_pov, i, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (jinfo.dwPOV != JOY_POVCENTERED) | 
					
						
							|  |  |  | 				_post_dpad(jinfo.dwPOV, i, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			joysticks[i].last_pov = jinfo.dwPOV; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (joysticks[i].last_buttons == jinfo.dwButtons) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ievent.type = InputEvent::JOYSTICK_BUTTON; | 
					
						
							|  |  |  | 		for (int j=0; j<32; j++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if ( (joysticks[i].last_buttons & (1<<j)) != (jinfo.dwButtons & (1<<j)) ) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 21:20:42 -03:00
										 |  |  | 				ievent.joy_button.button_index = j; //_pc_joystick_get_native_button(j);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				ievent.joy_button.pressed = jinfo.dwButtons & 1<<j; | 
					
						
							|  |  |  | 				ievent.ID = ++last_id; | 
					
						
							|  |  |  | 				input->parse_input_event(ievent); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		joysticks[i].last_buttons = jinfo.dwButtons; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     main_loop=NULL; | 
					
						
							|  |  |  |     outside=true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	WNDCLASSEXW	wc; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	video_mode=p_desired; | 
					
						
							|  |  |  | 	//printf("**************** desired %s, mode %s\n", p_desired.fullscreen?"true":"false", video_mode.fullscreen?"true":"false");
 | 
					
						
							|  |  |  | 	RECT WindowRect; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	WindowRect.left=0; | 
					
						
							|  |  |  | 	WindowRect.right=video_mode.width; | 
					
						
							|  |  |  | 	WindowRect.top=0; | 
					
						
							|  |  |  | 	WindowRect.bottom=video_mode.height; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset(&wc,0,sizeof(WNDCLASSEXW)); | 
					
						
							|  |  |  | 	wc.cbSize=sizeof(WNDCLASSEXW); | 
					
						
							|  |  |  | 	wc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS; | 
					
						
							|  |  |  | 	wc.lpfnWndProc = (WNDPROC)::WndProc; | 
					
						
							|  |  |  | 	wc.cbClsExtra = 0; | 
					
						
							|  |  |  | 	wc.cbWndExtra= 0; | 
					
						
							|  |  |  | 	//wc.hInstance = hInstance;
 | 
					
						
							|  |  |  | 	wc.hInstance = godot_hinstance ? godot_hinstance : GetModuleHandle(NULL); | 
					
						
							|  |  |  | 	wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);		 | 
					
						
							|  |  |  | 	wc.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW);
 | 
					
						
							|  |  |  | 	wc.hbrBackground = NULL; | 
					
						
							|  |  |  | 	wc.lpszMenuName	= NULL;	 | 
					
						
							|  |  |  | 	wc.lpszClassName	= L"Engine"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!RegisterClassExW(&wc)) { | 
					
						
							|  |  |  | 		MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION); | 
					
						
							|  |  |  | 		return;											// Return 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (video_mode.fullscreen) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		DEVMODE current; | 
					
						
							|  |  |  | 		memset(¤t,0,sizeof(current)); | 
					
						
							|  |  |  | 		EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, ¤t); | 
					
						
							| 
									
										
										
										
											2014-10-28 19:55:12 +01:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		WindowRect.right  = current.dmPelsWidth; | 
					
						
							|  |  |  | 		WindowRect.bottom = current.dmPelsHeight; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 19:55:12 +01:00
										 |  |  | /*  DEVMODE dmScreenSettings;
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); | 
					
						
							|  |  |  | 		dmScreenSettings.dmSize=sizeof(dmScreenSettings); | 
					
						
							|  |  |  | 		dmScreenSettings.dmPelsWidth	= video_mode.width; | 
					
						
							|  |  |  | 		dmScreenSettings.dmPelsHeight	= video_mode.height; | 
					
						
							|  |  |  | 		dmScreenSettings.dmBitsPerPel	= current.dmBitsPerPel; | 
					
						
							|  |  |  | 		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		LONG err = ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN); | 
					
						
							|  |  |  | 		if (err!=DISP_CHANGE_SUCCESSFUL) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			video_mode.fullscreen=false; | 
					
						
							| 
									
										
										
										
											2014-10-28 19:55:12 +01:00
										 |  |  | 		}*/ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DWORD		dwExStyle; | 
					
						
							|  |  |  | 	DWORD		dwStyle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (video_mode.fullscreen) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dwExStyle=WS_EX_APPWINDOW; | 
					
						
							|  |  |  | 		dwStyle=WS_POPUP; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; | 
					
						
							|  |  |  | 		dwStyle=WS_OVERLAPPEDWINDOW; | 
					
						
							| 
									
										
										
										
											2014-03-27 20:09:18 +08:00
										 |  |  | 		if (!video_mode.resizable) { | 
					
						
							|  |  |  | 			dwStyle &= ~WS_THICKFRAME; | 
					
						
							|  |  |  | 			dwStyle &= ~WS_MAXIMIZEBOX; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	char* windowid = getenv("GODOT_WINDOWID"); | 
					
						
							|  |  |  | 	if (windowid) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// strtoull on mingw
 | 
					
						
							|  |  |  | 		#ifdef MINGW_ENABLED
 | 
					
						
							|  |  |  | 		hWnd = (HWND)strtoull(windowid, NULL, 0); | 
					
						
							|  |  |  | 		#else
 | 
					
						
							|  |  |  | 		hWnd = (HWND)_strtoui64(windowid, NULL, 0); | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 		SetLastError(0); | 
					
						
							|  |  |  | 		user_proc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC); | 
					
						
							|  |  |  | 		SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)(WNDPROC)::WndProc); | 
					
						
							|  |  |  | 		DWORD le = GetLastError(); | 
					
						
							|  |  |  | 		if (user_proc == 0 && le != 0) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			printf("Error setting WNDPROC: %li\n", le); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		LONG_PTR proc = GetWindowLongPtr(hWnd, GWLP_WNDPROC); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		RECT rect; | 
					
						
							|  |  |  | 		if (!GetClientRect(hWnd, &rect)) { | 
					
						
							|  |  |  | 			MessageBoxW(NULL,L"Window Creation Error.",L"ERROR",MB_OK|MB_ICONEXCLAMATION); | 
					
						
							|  |  |  | 			return;								// Return FALSE
 | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		video_mode.width = rect.right; | 
					
						
							|  |  |  | 		video_mode.height = rect.bottom; | 
					
						
							|  |  |  | 		video_mode.fullscreen = false; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!(hWnd=CreateWindowExW(dwExStyle,L"Engine",L"", dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, 0, 0,WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top, NULL,NULL,	hInstance,NULL))) { | 
					
						
							|  |  |  | 			MessageBoxW(NULL,L"Window Creation Error.",L"ERROR",MB_OK|MB_ICONEXCLAMATION); | 
					
						
							|  |  |  | 			return;								// Return FALSE
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | #if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED) || defined(LEGACYGL_ENABLED)
 | 
					
						
							|  |  |  | 	gl_context = memnew( ContextGL_Win(hWnd,false) ); | 
					
						
							|  |  |  | 	gl_context->initialize(); | 
					
						
							|  |  |  | 	rasterizer = memnew( RasterizerGLES2 ); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |  #ifdef DX9_ENABLED
 | 
					
						
							|  |  |  | 	rasterizer = memnew( RasterizerDX9(hWnd) ); | 
					
						
							|  |  |  |  #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	visual_server = memnew( VisualServerRaster(rasterizer) ); | 
					
						
							|  |  |  | 	if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	physics_server = memnew( PhysicsServerSW ); | 
					
						
							|  |  |  | 	physics_server->init(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	physics_2d_server = memnew( Physics2DServerSW ); | 
					
						
							|  |  |  | 	physics_2d_server->init(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!is_no_window_mode_enabled()) { | 
					
						
							|  |  |  | 		ShowWindow(hWnd,SW_SHOW);						// Show The Window
 | 
					
						
							|  |  |  | 		SetForegroundWindow(hWnd);						// Slightly Higher Priority
 | 
					
						
							|  |  |  | 		SetFocus(hWnd);									// Sets Keyboard Focus To
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | 		DEVMODE dmScreenSettings;					// Device Mode
 | 
					
						
							|  |  |  | 		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));		// Makes Sure Memory's Cleared
 | 
					
						
							|  |  |  | 		dmScreenSettings.dmSize=sizeof(dmScreenSettings);		// Size Of The Devmode Structure
 | 
					
						
							|  |  |  | 		dmScreenSettings.dmPelsWidth	= width;			// Selected Screen Width
 | 
					
						
							|  |  |  | 		dmScreenSettings.dmPelsHeight	= height;			// Selected Screen Height
 | 
					
						
							|  |  |  | 		dmScreenSettings.dmBitsPerPel	= bits;				// Selected Bits Per Pixel
 | 
					
						
							|  |  |  | 		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; | 
					
						
							|  |  |  | 		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | 	visual_server->init();	 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	input = memnew( InputDefault ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ERR_PRINT("Initializing audio failed."); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sample_manager = memnew( SampleManagerMallocSW ); | 
					
						
							|  |  |  | 	audio_server = memnew( AudioServerSW(sample_manager) ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	audio_server->init(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spatial_sound_server = memnew( SpatialSoundServerSW ); | 
					
						
							|  |  |  | 	spatial_sound_server->init(); | 
					
						
							|  |  |  | 	spatial_sound_2d_server = memnew( SpatialSound2DServerSW ); | 
					
						
							|  |  |  | 	spatial_sound_2d_server->init(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 	probe_joysticks(); // todo: move this to a thread
 | 
					
						
							|  |  |  | 	while (joystick_change_queue.size() > 0) { | 
					
						
							|  |  |  | 		Joystick joy = joystick_change_queue.front()->get(); | 
					
						
							|  |  |  | 		joystick_change_queue.pop_front(); | 
					
						
							|  |  |  | 		joysticks[joy.id] = joy; | 
					
						
							|  |  |  | 		input->joy_connection_changed(joy.id, joy.attached, joy.name); | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	TRACKMOUSEEVENT tme; | 
					
						
							|  |  |  | 	tme.cbSize=sizeof(TRACKMOUSEEVENT); | 
					
						
							|  |  |  | 	tme.dwFlags=TME_LEAVE; | 
					
						
							|  |  |  | 	tme.hwndTrack=hWnd; | 
					
						
							|  |  |  | 	tme.dwHoverTime=HOVER_DEFAULT; | 
					
						
							|  |  |  | 	TrackMouseEvent(&tme); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:50:48 -03:00
										 |  |  | 	//RegisterTouchWindow(hWnd, 0); // Windows 7
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	_ensure_data_dir(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::set_clipboard(const String& p_text) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!OpenClipboard(hWnd)) { | 
					
						
							|  |  |  | 		ERR_EXPLAIN("Unable to open clipboard."); | 
					
						
							|  |  |  | 		ERR_FAIL(); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	EmptyClipboard(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (p_text.length() + 1) * sizeof(CharType)); | 
					
						
							|  |  |  | 	if (mem == NULL) { | 
					
						
							|  |  |  | 		ERR_EXPLAIN("Unable to allocate memory for clipboard contents."); | 
					
						
							|  |  |  | 		ERR_FAIL(); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	LPWSTR lptstrCopy = (LPWSTR)GlobalLock(mem); | 
					
						
							|  |  |  | 	memcpy(lptstrCopy, p_text.c_str(), (p_text.length() + 1) * sizeof(CharType)); | 
					
						
							|  |  |  | 	//memset((lptstrCopy + p_text.length()), 0, sizeof(CharType));
 | 
					
						
							|  |  |  | 	GlobalUnlock(mem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SetClipboardData(CF_UNICODETEXT, mem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set the CF_TEXT version (not needed?)
 | 
					
						
							|  |  |  | 	CharString utf8 = p_text.utf8(); | 
					
						
							|  |  |  | 	mem = GlobalAlloc(GMEM_MOVEABLE, utf8.length() + 1); | 
					
						
							|  |  |  | 	if (mem == NULL) { | 
					
						
							|  |  |  | 		ERR_EXPLAIN("Unable to allocate memory for clipboard contents."); | 
					
						
							|  |  |  | 		ERR_FAIL(); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	LPTSTR ptr = (LPTSTR)GlobalLock(mem); | 
					
						
							|  |  |  | 	memcpy(ptr, utf8.get_data(), utf8.length()); | 
					
						
							|  |  |  | 	ptr[utf8.length()] = 0; | 
					
						
							|  |  |  | 	GlobalUnlock(mem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SetClipboardData(CF_TEXT, mem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CloseClipboard(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String OS_Windows::get_clipboard() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String ret; | 
					
						
							|  |  |  | 	if (!OpenClipboard(hWnd)) { | 
					
						
							|  |  |  | 		ERR_EXPLAIN("Unable to open clipboard."); | 
					
						
							|  |  |  | 		ERR_FAIL_V(""); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		HGLOBAL mem = GetClipboardData(CF_UNICODETEXT); | 
					
						
							|  |  |  | 		if (mem != NULL) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			LPWSTR ptr = (LPWSTR)GlobalLock(mem); | 
					
						
							|  |  |  | 			if (ptr != NULL) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				ret = String((CharType*)ptr); | 
					
						
							|  |  |  | 				GlobalUnlock(mem); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (IsClipboardFormatAvailable(CF_TEXT)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		HGLOBAL mem = GetClipboardData(CF_UNICODETEXT); | 
					
						
							|  |  |  | 		if (mem != NULL) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			LPTSTR ptr = (LPTSTR)GlobalLock(mem); | 
					
						
							|  |  |  | 			if (ptr != NULL) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				ret.parse_utf8((const char*)ptr); | 
					
						
							|  |  |  | 				GlobalUnlock(mem); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CloseClipboard(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::delete_main_loop() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (main_loop) | 
					
						
							|  |  |  | 		memdelete(main_loop); | 
					
						
							|  |  |  | 	main_loop=NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::set_main_loop( MainLoop * p_main_loop ) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	input->set_main_loop(p_main_loop); | 
					
						
							|  |  |  | 	main_loop=p_main_loop; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::finalize() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(main_loop) | 
					
						
							|  |  |  | 		memdelete(main_loop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	main_loop=NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	visual_server->finish(); | 
					
						
							|  |  |  | 	memdelete(visual_server); | 
					
						
							|  |  |  | #ifdef OPENGL_ENABLED
 | 
					
						
							|  |  |  | 	if (gl_context) | 
					
						
							|  |  |  | 		memdelete(gl_context); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	if (rasterizer) | 
					
						
							|  |  |  | 		memdelete(rasterizer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (user_proc) { | 
					
						
							|  |  |  | 		SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spatial_sound_server->finish(); | 
					
						
							|  |  |  | 	memdelete(spatial_sound_server); | 
					
						
							|  |  |  | 	spatial_sound_2d_server->finish(); | 
					
						
							|  |  |  | 	memdelete(spatial_sound_2d_server); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//if (debugger_connection_console) {
 | 
					
						
							|  |  |  | //		memdelete(debugger_connection_console);
 | 
					
						
							|  |  |  | //}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	audio_server->finish(); | 
					
						
							|  |  |  | 	memdelete(audio_server); | 
					
						
							|  |  |  | 	memdelete(sample_manager); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memdelete(input); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	physics_server->finish(); | 
					
						
							|  |  |  | 	memdelete(physics_server); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	physics_2d_server->finish(); | 
					
						
							|  |  |  | 	memdelete(physics_2d_server); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void OS_Windows::finalize_core() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memdelete(process_map); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mempool_dynamic) | 
					
						
							|  |  |  | 		memdelete( mempool_dynamic ); | 
					
						
							|  |  |  | 	if (mempool_static) | 
					
						
							|  |  |  | 		delete mempool_static; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	TCPServerWinsock::cleanup(); | 
					
						
							|  |  |  | 	StreamPeerWinsock::cleanup(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::vprint(const char* p_format, va_list p_list, bool p_stderr) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	char buf[16384+1]; | 
					
						
							|  |  |  | 	int len = vsnprintf(buf,16384,p_format,p_list); | 
					
						
							|  |  |  | 	if (len<=0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	buf[len]=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int wlen = MultiByteToWideChar(CP_UTF8,0,buf,len,NULL,0); | 
					
						
							|  |  |  | 	if (wlen<0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wchar_t *wbuf = (wchar_t*)malloc((len+1)*sizeof(wchar_t)); | 
					
						
							|  |  |  | 	MultiByteToWideChar(CP_UTF8,0,buf,len,wbuf,wlen); | 
					
						
							|  |  |  | 	wbuf[wlen]=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_stderr) | 
					
						
							|  |  |  | 		fwprintf(stderr,L"%s",wbuf); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		wprintf(L"%s",wbuf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef STDOUT_FILE
 | 
					
						
							|  |  |  | 	//vwfprintf(stdo,p_format,p_list);
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	free(wbuf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fflush(stdout); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::alert(const String& p_alert,const String& p_title) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!is_no_window_mode_enabled()) | 
					
						
							|  |  |  | 		MessageBoxW(NULL,p_alert.c_str(),p_title.c_str(),MB_OK|MB_ICONEXCLAMATION); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		print_line("ALERT: "+p_alert); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::set_mouse_mode(MouseMode p_mode) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mouse_mode==p_mode) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	ShowCursor(p_mode==MOUSE_MODE_VISIBLE); | 
					
						
							|  |  |  | 	mouse_mode=p_mode; | 
					
						
							|  |  |  | 	if (p_mode==MOUSE_MODE_CAPTURED) { | 
					
						
							|  |  |  | 		RECT clipRect; | 
					
						
							|  |  |  | 		GetClientRect(hWnd, &clipRect); | 
					
						
							|  |  |  | 		ClientToScreen(hWnd, (POINT*) &clipRect.left); | 
					
						
							|  |  |  | 		ClientToScreen(hWnd, (POINT*) &clipRect.right); | 
					
						
							|  |  |  | 		ClipCursor(&clipRect); | 
					
						
							|  |  |  | 		SetCapture(hWnd); | 
					
						
							|  |  |  | 		center=Point2i(video_mode.width/2,video_mode.height/2); | 
					
						
							|  |  |  | 		POINT pos = { (int) center.x, (int) center.y }; | 
					
						
							|  |  |  | 		ClientToScreen(hWnd, &pos); | 
					
						
							|  |  |  | 		SetCursorPos(pos.x, pos.y); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ReleaseCapture(); | 
					
						
							|  |  |  | 		ClipCursor(NULL); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OS_Windows::MouseMode OS_Windows::get_mouse_mode() const{ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-19 21:01:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return mouse_mode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-19 21:01:41 -03:00
										 |  |  | void OS_Windows::warp_mouse_pos(const Point2& p_to) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-21 01:43:42 -03:00
										 |  |  | 	if (mouse_mode==MOUSE_MODE_CAPTURED) { | 
					
						
							| 
									
										
										
										
											2014-09-19 21:01:41 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		old_x=p_to.x; | 
					
						
							|  |  |  | 		old_y=p_to.y; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 19:22:06 -03:00
										 |  |  | 		POINT p; | 
					
						
							|  |  |  | 		p.x=p_to.x; | 
					
						
							|  |  |  | 		p.y=p_to.y; | 
					
						
							|  |  |  | 		ClientToScreen(hWnd,&p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		SetCursorPos(p.x,p.y); | 
					
						
							| 
									
										
										
										
											2014-09-19 21:01:41 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | Point2 OS_Windows::get_mouse_pos() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Point2(old_x, old_y); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int OS_Windows::get_mouse_button_state() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return last_button_state; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::set_window_title(const String& p_title) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SetWindowTextW(hWnd,p_title.c_str()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::set_video_mode(const VideoMode& p_video_mode,int p_screen) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-16 22:31:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-16 22:31:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | OS::VideoMode OS_Windows::get_video_mode(int p_screen) const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return video_mode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void OS_Windows::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); | 
					
						
							|  |  |  | 	if (!hCon || hCon==INVALID_HANDLE_VALUE) { | 
					
						
							|  |  |  | 		if (p_rationale && p_rationale[0]) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale); | 
					
						
							|  |  |  | 			print("\E[0;31;40m   At: %s:%i.\E[0;0;37m\n",p_file,p_line); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_code); | 
					
						
							|  |  |  | 			print("\E[0;31;40m   At: %s:%i.\E[0;0;37m\n",p_file,p_line); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		CONSOLE_SCREEN_BUFFER_INFO sbi; //original
 | 
					
						
							|  |  |  | 		GetConsoleScreenBufferInfo(hCon,&sbi); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		SetConsoleTextAttribute(hCon,sbi.wAttributes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		uint32_t basecol=0; | 
					
						
							|  |  |  | 		switch(p_type) { | 
					
						
							|  |  |  | 			case ERR_ERROR: basecol = FOREGROUND_RED; break; | 
					
						
							|  |  |  | 			case ERR_WARNING: basecol = FOREGROUND_RED|FOREGROUND_GREEN; break; | 
					
						
							|  |  |  | 			case ERR_SCRIPT: basecol = FOREGROUND_GREEN; break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (p_rationale && p_rationale[0]) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			SetConsoleTextAttribute(hCon,basecol|FOREGROUND_INTENSITY); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			switch(p_type) { | 
					
						
							|  |  |  | 				case ERR_ERROR: print("ERROR: "); break; | 
					
						
							|  |  |  | 				case ERR_WARNING: print("WARNING: "); break; | 
					
						
							|  |  |  | 				case ERR_SCRIPT: print("SCRIPT ERROR: "); break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY); | 
					
						
							|  |  |  | 			print(" %s\n",p_rationale); | 
					
						
							|  |  |  | 			SetConsoleTextAttribute(hCon,basecol); | 
					
						
							|  |  |  | 			print("At: "); | 
					
						
							|  |  |  | 			SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN); | 
					
						
							|  |  |  | 			print(" %s:%i\n",p_file,p_line); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			SetConsoleTextAttribute(hCon,basecol|FOREGROUND_INTENSITY); | 
					
						
							|  |  |  | 			switch(p_type) { | 
					
						
							|  |  |  | 				case ERR_ERROR: print("ERROR: %s: ",p_function); break; | 
					
						
							|  |  |  | 				case ERR_WARNING: print("WARNING: %s: ",p_function); break; | 
					
						
							|  |  |  | 				case ERR_SCRIPT: print("SCRIPT ERROR: %s: ",p_function); break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY); | 
					
						
							|  |  |  | 			print(" %s\n",p_code); | 
					
						
							|  |  |  | 			SetConsoleTextAttribute(hCon,basecol); | 
					
						
							|  |  |  | 			print("At: "); | 
					
						
							|  |  |  | 			SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN); | 
					
						
							|  |  |  | 			print(" %s:%i\n",p_file,p_line); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		SetConsoleTextAttribute(hCon,sbi.wAttributes); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String OS_Windows::get_name() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return "Windows"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OS::Date OS_Windows::get_date() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SYSTEMTIME systemtime; | 
					
						
							|  |  |  | 	GetSystemTime(&systemtime); | 
					
						
							|  |  |  | 	Date date; | 
					
						
							|  |  |  | 	date.day=systemtime.wDay; | 
					
						
							|  |  |  | 	date.month=Month(systemtime.wMonth); | 
					
						
							|  |  |  | 	date.weekday=Weekday(systemtime.wDayOfWeek); | 
					
						
							|  |  |  | 	date.year=systemtime.wYear; | 
					
						
							|  |  |  | 	date.dst=false; | 
					
						
							|  |  |  | 	return date; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | OS::Time OS_Windows::get_time() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SYSTEMTIME systemtime; | 
					
						
							| 
									
										
										
										
											2014-11-19 11:33:15 -03:00
										 |  |  | 	GetLocalTime(&systemtime); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Time time; | 
					
						
							|  |  |  | 	time.hour=systemtime.wHour; | 
					
						
							|  |  |  | 	time.min=systemtime.wMinute; | 
					
						
							|  |  |  | 	time.sec=systemtime.wSecond; | 
					
						
							|  |  |  | 	return time; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint64_t OS_Windows::get_unix_time() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FILETIME ft; | 
					
						
							|  |  |  | 	SYSTEMTIME st; | 
					
						
							|  |  |  | 	GetSystemTime(&st); | 
					
						
							|  |  |  | 	SystemTimeToFileTime(&st, &ft); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SYSTEMTIME ep; | 
					
						
							|  |  |  | 	ep.wYear = 1970; | 
					
						
							|  |  |  | 	ep.wMonth = 1; | 
					
						
							|  |  |  | 	ep.wDayOfWeek = 4; | 
					
						
							|  |  |  | 	ep.wDay = 1; | 
					
						
							|  |  |  | 	ep.wHour = 0; | 
					
						
							|  |  |  | 	ep.wMinute = 0; | 
					
						
							|  |  |  | 	ep.wSecond = 0; | 
					
						
							|  |  |  | 	ep.wMilliseconds = 0; | 
					
						
							|  |  |  | 	FILETIME fep; | 
					
						
							|  |  |  | 	SystemTimeToFileTime(&ep, &fep); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (*(uint64_t*)&ft - *(uint64_t*)&fep) / 10000000; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::delay_usec(uint32_t p_usec) const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (p_usec < 1000) | 
					
						
							|  |  |  |                 Sleep(1); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |                 Sleep(p_usec / 1000); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | uint64_t OS_Windows::get_ticks_usec() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       	uint64_t ticks; | 
					
						
							|  |  |  |         uint64_t time;  | 
					
						
							|  |  |  |         // This is the number of clock ticks since start
 | 
					
						
							|  |  |  |         if( !QueryPerformanceCounter((LARGE_INTEGER *)&ticks) ) | 
					
						
							|  |  |  |                 ticks = (UINT64)timeGetTime(); | 
					
						
							|  |  |  |         // Divide by frequency to get the time in seconds
 | 
					
						
							|  |  |  |         time = ticks * 1000000L / ticks_per_second; | 
					
						
							|  |  |  |         // Subtract the time at game start to get  
 | 
					
						
							|  |  |  |         // the time since the game started
 | 
					
						
							|  |  |  |         time -= ticks_start; | 
					
						
							|  |  |  |         return time; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::process_events() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	MSG msg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	process_joysticks(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	while(PeekMessageW(&msg,NULL,0,0,PM_REMOVE)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		TranslateMessage(&msg); | 
					
						
							|  |  |  | 		DispatchMessageW(&msg); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	process_key_events(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::set_cursor_shape(CursorShape p_shape) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX(p_shape,CURSOR_MAX); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cursor_shape==p_shape) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static const LPCTSTR win_cursors[CURSOR_MAX]={ | 
					
						
							|  |  |  | 		IDC_ARROW, | 
					
						
							|  |  |  | 		IDC_IBEAM, | 
					
						
							|  |  |  | 		IDC_HAND,//finger
 | 
					
						
							|  |  |  | 		IDC_CROSS, | 
					
						
							|  |  |  | 		IDC_WAIT, | 
					
						
							|  |  |  | 		IDC_APPSTARTING, | 
					
						
							|  |  |  | 		IDC_ARROW, | 
					
						
							|  |  |  | 		IDC_ARROW, | 
					
						
							|  |  |  | 		IDC_NO, | 
					
						
							|  |  |  | 		IDC_SIZENS, | 
					
						
							|  |  |  | 		IDC_SIZEWE, | 
					
						
							|  |  |  | 		IDC_SIZENESW, | 
					
						
							|  |  |  | 		IDC_SIZENWSE, | 
					
						
							|  |  |  | 		IDC_SIZEALL, | 
					
						
							|  |  |  | 		IDC_SIZENS, | 
					
						
							|  |  |  | 		IDC_SIZEWE, | 
					
						
							|  |  |  | 		IDC_HELP | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SetCursor(LoadCursor(hInstance,win_cursors[p_shape])); | 
					
						
							|  |  |  | 	cursor_shape=p_shape; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error OS_Windows::execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id,String* r_pipe,int *r_exitcode) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_blocking && r_pipe) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		String argss; | 
					
						
							|  |  |  | 		argss="\"\""+p_path+"\""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for(int i=0;i<p_arguments.size();i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			argss+=String(" \"")+p_arguments[i]+"\""; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //		print_line("ARGS: "+argss);
 | 
					
						
							|  |  |  | 		//argss+"\"";
 | 
					
						
							|  |  |  | 		//argss+=" 2>nul";
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		FILE* f=_wpopen(argss.c_str(),L"r"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(!f,ERR_CANT_OPEN); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		char buf[65535]; | 
					
						
							|  |  |  | 		while(fgets(buf,65535,f)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			(*r_pipe)+=buf; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		int rv = _pclose(f); | 
					
						
							|  |  |  | 		if (r_exitcode) | 
					
						
							|  |  |  | 			*r_exitcode=rv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return OK; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String cmdline = "\""+p_path+"\""; | 
					
						
							|  |  |  | 	const List<String>::Element* I = p_arguments.front(); | 
					
						
							|  |  |  | 	while (I) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		cmdline += " \""+I->get() + "\""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		I = I->next(); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//cmdline+="\"";
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ProcessInfo pi; | 
					
						
							|  |  |  | 	ZeroMemory( &pi.si, sizeof(pi.si) ); | 
					
						
							|  |  |  | 	pi.si.cb = sizeof(pi.si); | 
					
						
							|  |  |  | 	ZeroMemory( &pi.pi, sizeof(pi.pi) ); | 
					
						
							| 
									
										
										
										
											2014-02-15 02:01:39 -03:00
										 |  |  | 	LPSTARTUPINFOW si_w = (LPSTARTUPINFOW) &pi.si; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	print_line("running cmdline: "+cmdline); | 
					
						
							| 
									
										
										
										
											2014-02-15 02:01:39 -03:00
										 |  |  | 	Vector<CharType> modstr; //windows wants to change this no idea why
 | 
					
						
							|  |  |  | 	modstr.resize(cmdline.size()); | 
					
						
							|  |  |  | 	for(int i=0;i<cmdline.size();i++) | 
					
						
							|  |  |  | 		modstr[i]=cmdline[i]; | 
					
						
							|  |  |  | 	int ret = CreateProcessW(NULL, modstr.ptr(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, si_w, &pi.pi); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_blocking) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		DWORD ret = WaitForSingleObject(pi.pi.hProcess, INFINITE); | 
					
						
							|  |  |  | 		if (r_exitcode) | 
					
						
							|  |  |  | 			*r_exitcode=ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ProcessID pid = pi.pi.dwProcessId; | 
					
						
							|  |  |  | 		if (r_child_id) { | 
					
						
							|  |  |  | 			*r_child_id = pid; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		process_map->insert(pid, pi); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error OS_Windows::kill(const ProcessID& p_pid) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HANDLE h; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (process_map->has(p_pid)) { | 
					
						
							|  |  |  | 		h = (*process_map)[p_pid].pi.hProcess; | 
					
						
							|  |  |  | 		process_map->erase(p_pid); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int ret = TerminateProcess(h, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret != 0?OK:FAILED; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error OS_Windows::set_cwd(const String& p_cwd) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (_wchdir(p_cwd.c_str())!=0) | 
					
						
							|  |  |  | 		return ERR_CANT_OPEN; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 02:01:39 -03:00
										 |  |  | String OS_Windows::get_executable_path() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wchar_t bufname[4096]; | 
					
						
							|  |  |  | 	GetModuleFileNameW(NULL,bufname,4096); | 
					
						
							|  |  |  | 	String s= bufname; | 
					
						
							|  |  |  | 	print_line("EXEC PATHPó: "+s); | 
					
						
							|  |  |  | 	return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void OS_Windows::set_icon(const Image& p_icon) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Image icon=p_icon; | 
					
						
							|  |  |  | 	if (icon.get_format()!=Image::FORMAT_RGBA) | 
					
						
							|  |  |  | 		icon.convert(Image::FORMAT_RGBA); | 
					
						
							|  |  |  | 	int w = icon.get_width(); | 
					
						
							|  |  |  | 	int h = icon.get_height(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Create temporary bitmap buffer */ | 
					
						
							|  |  |  | 	int icon_len = 40 + h * w * 4; | 
					
						
							| 
									
										
										
										
											2014-02-13 18:03:28 -03:00
										 |  |  | 	Vector<BYTE> v; | 
					
						
							|  |  |  | 	v.resize(icon_len); | 
					
						
							|  |  |  | 	BYTE *icon_bmp = &v[0]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	encode_uint32(40,&icon_bmp[0]); | 
					
						
							|  |  |  | 	encode_uint32(w,&icon_bmp[4]); | 
					
						
							|  |  |  | 	encode_uint32(h*2,&icon_bmp[8]); | 
					
						
							|  |  |  | 	encode_uint16(1,&icon_bmp[12]); | 
					
						
							|  |  |  | 	encode_uint16(32,&icon_bmp[14]); | 
					
						
							|  |  |  | 	encode_uint32(BI_RGB,&icon_bmp[16]); | 
					
						
							|  |  |  | 	encode_uint32(w*h*4,&icon_bmp[20]); | 
					
						
							|  |  |  | 	encode_uint32(0,&icon_bmp[24]); | 
					
						
							|  |  |  | 	encode_uint32(0,&icon_bmp[28]); | 
					
						
							|  |  |  | 	encode_uint32(0,&icon_bmp[32]); | 
					
						
							|  |  |  | 	encode_uint32(0,&icon_bmp[36]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uint8_t *wr=&icon_bmp[40]; | 
					
						
							|  |  |  | 	DVector<uint8_t>::Read r= icon.get_data().read(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(int i=0;i<h;i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for(int j=0;j<w;j++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const uint8_t *rpx = &r[((h-i-1)*w+j)*4]; | 
					
						
							|  |  |  | 			uint8_t *wpx = &wr[(i*w+j)*4]; | 
					
						
							|  |  |  | 			wpx[0]=rpx[2]; | 
					
						
							|  |  |  | 			wpx[1]=rpx[1]; | 
					
						
							|  |  |  | 			wpx[2]=rpx[0]; | 
					
						
							|  |  |  | 			wpx[3]=rpx[3]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HICON hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set the icon for the window */ | 
					
						
							|  |  |  | 	SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set the icon in the task manager (should we do this?) */ | 
					
						
							|  |  |  | 	SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hicon); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool OS_Windows::has_environment(const String& p_var) const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return getenv(p_var.utf8().get_data()) != NULL; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String OS_Windows::get_environment(const String& p_var) const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-13 18:03:28 -03:00
										 |  |  | 	char* val = getenv(p_var.utf8().get_data()); | 
					
						
							|  |  |  | 	if (val) | 
					
						
							|  |  |  | 		return val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ""; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String OS_Windows::get_stdin_string(bool p_block) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_block) { | 
					
						
							|  |  |  | 		char buff[1024]; | 
					
						
							|  |  |  | 		return fgets(buff,1024,stdin); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return String(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::move_window_to_foreground() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SetForegroundWindow(hWnd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-18 11:43:54 -03:00
										 |  |  | Error OS_Windows::shell_open(String p_uri) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ShellExecuteW(NULL, L"open", p_uri.c_str(), NULL, NULL, SW_SHOWNORMAL); | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | String OS_Windows::get_locale() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const _WinLocale *wl = &_win_locales[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LANGID langid = GetUserDefaultUILanguage(); | 
					
						
							|  |  |  | 	String neutral; | 
					
						
							|  |  |  | 	int lang = langid&((1<<9)-1); | 
					
						
							|  |  |  | 	int sublang = langid&~((1<<9)-1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(wl->locale) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (wl->main_lang==lang && wl->sublang==SUBLANG_NEUTRAL) | 
					
						
							|  |  |  | 			neutral=wl->locale; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (lang==wl->main_lang && sublang==wl->sublang) | 
					
						
							|  |  |  | 			return wl->locale; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		wl++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (neutral!="") | 
					
						
							|  |  |  | 		return neutral; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return "en"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::release_rendering_thread() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gl_context->release_current(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::make_rendering_thread() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gl_context->make_current(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::swap_buffers() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gl_context->swap_buffers(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OS_Windows::run() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!main_loop) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	main_loop->init(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	uint64_t last_ticks=get_ticks_usec(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	int frames=0; | 
					
						
							|  |  |  | 	uint64_t frame=0; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	while (!force_quit) { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		process_events(); // get rid of pending events
 | 
					
						
							|  |  |  | 		if (Main::iteration()==true) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	main_loop->finish(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MainLoop *OS_Windows::get_main_loop() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return main_loop; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-02 14:02:41 -03:00
										 |  |  | String OS_Windows::get_system_dir(SystemDir p_dir) const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch(p_dir) { | 
					
						
							|  |  |  | 		case SYSTEM_DIR_DESKTOP: { | 
					
						
							|  |  |  | 			id=CSIDL_DESKTOPDIRECTORY; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case SYSTEM_DIR_DCIM: { | 
					
						
							|  |  |  | 			id=CSIDL_MYPICTURES; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case SYSTEM_DIR_DOCUMENTS: { | 
					
						
							|  |  |  | 			id=0x000C; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case SYSTEM_DIR_DOWNLOADS: { | 
					
						
							|  |  |  | 			id=0x000C ; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case SYSTEM_DIR_MOVIES: { | 
					
						
							|  |  |  | 			id=CSIDL_MYVIDEO; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case SYSTEM_DIR_MUSIC: { | 
					
						
							|  |  |  | 			id=CSIDL_MYMUSIC; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case SYSTEM_DIR_PICTURES: { | 
					
						
							|  |  |  | 			id=CSIDL_MYPICTURES; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case SYSTEM_DIR_RINGTONES: { | 
					
						
							|  |  |  | 			id=CSIDL_MYMUSIC; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	WCHAR szPath[MAX_PATH]; | 
					
						
							|  |  |  | 	HRESULT res = SHGetFolderPathW(NULL,id,NULL,0,szPath); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(res!=S_OK,String()); | 
					
						
							|  |  |  | 	return String(szPath); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-02 14:02:41 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | String OS_Windows::get_data_dir() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String an = Globals::get_singleton()->get("application/name"); | 
					
						
							|  |  |  | 	if (an!="") { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (has_environment("APPDATA")) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-19 18:39:50 -03:00
										 |  |  | 			bool use_godot = Globals::get_singleton()->get("application/use_shared_user_dir"); | 
					
						
							| 
									
										
										
										
											2014-09-19 21:01:41 -03:00
										 |  |  | 			if (!use_godot) | 
					
						
							| 
									
										
										
										
											2014-09-19 18:39:50 -03:00
										 |  |  | 				return (OS::get_singleton()->get_environment("APPDATA")+"/"+an).replace("\\","/"); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				return (OS::get_singleton()->get_environment("APPDATA")+"/Godot/app_userdata/"+an).replace("\\","/"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Globals::get_singleton()->get_resource_path(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OS_Windows::OS_Windows(HINSTANCE _hInstance) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	key_event_pos=0; | 
					
						
							|  |  |  | 	force_quit=false; | 
					
						
							|  |  |  | 	alt_mem=false; | 
					
						
							|  |  |  | 	gr_mem=false; | 
					
						
							|  |  |  | 	shift_mem=false; | 
					
						
							|  |  |  | 	control_mem=false; | 
					
						
							|  |  |  | 	meta_mem=false; | 
					
						
							|  |  |  | 	minimized = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hInstance=_hInstance; | 
					
						
							|  |  |  | 	pressrc=0; | 
					
						
							|  |  |  | 	old_invalid=true; | 
					
						
							|  |  |  | 	last_id=0; | 
					
						
							|  |  |  | 	mouse_mode=MOUSE_MODE_VISIBLE; | 
					
						
							|  |  |  | #ifdef STDOUT_FILE
 | 
					
						
							|  |  |  | 	stdo=fopen("stdout.txt","wb"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	user_proc = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef RTAUDIO_ENABLED
 | 
					
						
							|  |  |  | 	AudioDriverManagerSW::add_driver(&driver_rtaudio); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OS_Windows::~OS_Windows()  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef STDOUT_FILE
 | 
					
						
							|  |  |  | 	fclose(stdo); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |