1 #ifdef _WIN32
2 /*
3 Copyright (c) 2012 Advanced Micro Devices, Inc.
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 //Originally written by Erwin Coumans
16 
17 #include "Win32Window.h"
18 
19 #include "OpenGLInclude.h"
20 
21 #include <wchar.h>
22 static InternalData2* sData = 0;
23 
24 #include "Win32InternalWindowData.h"
25 
26 enum
27 {
28 	INTERNAL_SHIFT_MODIFIER = 1,
29 	INTERNAL_ALT_MODIFIER = 2,
30 	INTERNAL_CONTROL_MODIFIER = 4,
31 };
32 
pumpMessage()33 void Win32Window::pumpMessage()
34 {
35 	MSG msg;
36 	// check for messages
37 	//'if' instead of 'while' can make mainloop smoother.
38 	//@todo: use separate threads for input and rendering
39 	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
40 	{
41 		// handle or dispatch messages
42 		if (msg.message == WM_QUIT)
43 		{
44 			m_data->m_quit = TRUE;
45 		}
46 		else
47 		{
48 			TranslateMessage(&msg);
49 			DispatchMessage(&msg);
50 		}
51 
52 		//			gDemoApplication->displayCallback();
53 	};
54 }
55 
getSpecialKeyFromVirtualKeycode(int virtualKeyCode)56 int getSpecialKeyFromVirtualKeycode(int virtualKeyCode)
57 {
58 	int keycode = -1;
59 	if (virtualKeyCode >= 'A' && virtualKeyCode <= 'Z')
60 	{
61 		return virtualKeyCode + 32;  //todo: fix the ascii A vs a input
62 	}
63 	if (virtualKeyCode >= '0' && virtualKeyCode <= '9')
64 	{
65 		return virtualKeyCode;
66 	}
67 
68 	switch (virtualKeyCode)
69 	{
70 		case VK_SPACE:
71 		{
72 			keycode = B3G_SPACE;
73 			break;
74 		}
75 		case VK_RETURN:
76 		{
77 			keycode = B3G_RETURN;
78 			break;
79 		};
80 		case VK_ESCAPE:
81 		{
82 			keycode = B3G_ESCAPE;
83 			break;
84 		};
85 		case VK_F1:
86 		{
87 			keycode = B3G_F1;
88 			break;
89 		}
90 		case VK_F2:
91 		{
92 			keycode = B3G_F2;
93 			break;
94 		}
95 		case VK_F3:
96 		{
97 			keycode = B3G_F3;
98 			break;
99 		}
100 		case VK_F4:
101 		{
102 			keycode = B3G_F4;
103 			break;
104 		}
105 		case VK_F5:
106 		{
107 			keycode = B3G_F5;
108 			break;
109 		}
110 		case VK_F6:
111 		{
112 			keycode = B3G_F6;
113 			break;
114 		}
115 		case VK_F7:
116 		{
117 			keycode = B3G_F7;
118 			break;
119 		}
120 		case VK_F8:
121 		{
122 			keycode = B3G_F8;
123 			break;
124 		}
125 		case VK_F9:
126 		{
127 			keycode = B3G_F9;
128 			break;
129 		}
130 		case VK_F10:
131 		{
132 			keycode = B3G_F10;
133 			break;
134 		}
135 
136 			//case VK_SPACE: {keycode= ' '; break;}
137 
138 		case VK_NEXT:
139 		{
140 			keycode = B3G_PAGE_DOWN;
141 			break;
142 		}
143 		case VK_PRIOR:
144 		{
145 			keycode = B3G_PAGE_UP;
146 			break;
147 		}
148 
149 		case VK_INSERT:
150 		{
151 			keycode = B3G_INSERT;
152 			break;
153 		}
154 		case VK_BACK:
155 		{
156 			keycode = B3G_BACKSPACE;
157 			break;
158 		}
159 		case VK_DELETE:
160 		{
161 			keycode = B3G_DELETE;
162 			break;
163 		}
164 
165 		case VK_END:
166 		{
167 			keycode = B3G_END;
168 			break;
169 		}
170 		case VK_HOME:
171 		{
172 			keycode = B3G_HOME;
173 			break;
174 		}
175 		case VK_LEFT:
176 		{
177 			keycode = B3G_LEFT_ARROW;
178 			break;
179 		}
180 		case VK_UP:
181 		{
182 			keycode = B3G_UP_ARROW;
183 			break;
184 		}
185 		case VK_RIGHT:
186 		{
187 			keycode = B3G_RIGHT_ARROW;
188 			break;
189 		}
190 		case VK_DOWN:
191 		{
192 			keycode = B3G_DOWN_ARROW;
193 			break;
194 		}
195 		case VK_SHIFT:
196 		{
197 			keycode = B3G_SHIFT;
198 			break;
199 		}
200 		case VK_MENU:
201 		{
202 			keycode = B3G_ALT;
203 			break;
204 		}
205 		case VK_CONTROL:
206 		{
207 			keycode = B3G_CONTROL;
208 			break;
209 		}
210 		default:
211 		{
212 			//keycode = MapVirtualKey( virtualKeyCode, MAPVK_VK_TO_CHAR ) & 0x0000FFFF;
213 		}
214 	};
215 
216 	return keycode;
217 }
218 
getAsciiCodeFromVirtualKeycode(int virtualKeyCode)219 int getAsciiCodeFromVirtualKeycode(int virtualKeyCode)
220 {
221 	int keycode = 0xffffffff;
222 
223 	if (virtualKeyCode >= 'a' && virtualKeyCode <= 'z')
224 	{
225 		return virtualKeyCode;
226 	}
227 
228 	if (virtualKeyCode >= 'A' && virtualKeyCode <= 'Z')
229 	{
230 		return virtualKeyCode + 32;  //todo: fix the ascii A vs a input
231 	}
232 
233 	return keycode;
234 }
235 
isModifierKeyPressed(int key)236 bool Win32Window::isModifierKeyPressed(int key)
237 {
238 	bool isPressed = false;
239 
240 	switch (key)
241 	{
242 		case B3G_ALT:
243 		{
244 			isPressed = ((sData->m_internalKeyModifierFlags & INTERNAL_ALT_MODIFIER) != 0);
245 			break;
246 		};
247 		case B3G_SHIFT:
248 		{
249 			isPressed = ((sData->m_internalKeyModifierFlags & INTERNAL_SHIFT_MODIFIER) != 0);
250 			break;
251 		};
252 		case B3G_CONTROL:
253 		{
254 			isPressed = ((sData->m_internalKeyModifierFlags & INTERNAL_CONTROL_MODIFIER) != 0);
255 			break;
256 		};
257 
258 		default:
259 		{
260 		}
261 	};
262 	return isPressed;  //m_internalKeyModifierFlags
263 }
264 
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)265 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
266 {
267 	//printf("msg = %d\n", message);
268 	switch (message)
269 	{
270 		case WM_PAINT:
271 		{
272 			PAINTSTRUCT ps;
273 			BeginPaint(hWnd, &ps);
274 			EndPaint(hWnd, &ps);
275 		}
276 			return 1;
277 
278 		case WM_ERASEBKGND:
279 			return 1;
280 
281 		case WM_CLOSE:
282 			if (sData)
283 				sData->m_quit = true;
284 			//PostQuitMessage(0);
285 			return 1;
286 
287 		case WM_DESTROY:
288 			if (sData)
289 				sData->m_quit = true;
290 			//PostQuitMessage(0);
291 			return 1;
292 
293 		case WM_SYSKEYUP:
294 		case WM_KEYUP:
295 		{
296 			int keycode = getSpecialKeyFromVirtualKeycode(wParam);
297 			switch (keycode)
298 			{
299 				case B3G_ALT:
300 				{
301 					sData->m_internalKeyModifierFlags &= ~INTERNAL_ALT_MODIFIER;
302 					break;
303 				};
304 				case B3G_SHIFT:
305 				{
306 					sData->m_internalKeyModifierFlags &= ~INTERNAL_SHIFT_MODIFIER;
307 					break;
308 				};
309 				case B3G_CONTROL:
310 				{
311 					sData->m_internalKeyModifierFlags &= ~INTERNAL_CONTROL_MODIFIER;
312 					break;
313 				};
314 			}
315 
316 			if (keycode >= 0 && sData && sData->m_keyboardCallback)
317 			{
318 				int state = 0;
319 				(*sData->m_keyboardCallback)(keycode, state);
320 			}
321 			return 0;
322 		}
323 		case WM_CHAR:
324 		{
325 #if 0
326 			//skip 'enter' key, it is processed in WM_KEYUP/WM_KEYDOWN
327 			int keycode = getAsciiCodeFromVirtualKeycode(wParam);
328 			if (keycode < 0)
329 			{
330 				if (sData && sData->m_keyboardCallback && ((HIWORD(lParam) & KF_REPEAT) == 0))
331 				{
332 					int state = 1;
333 					(*sData->m_keyboardCallback)(wParam, state);
334 				}
335 			}
336 #endif
337 			return 0;
338 		}
339 		case WM_SYSKEYDOWN:
340 		case WM_KEYDOWN:
341 		{
342 			int keycode = getSpecialKeyFromVirtualKeycode(wParam);
343 			switch (keycode)
344 			{
345 				case B3G_ALT:
346 				{
347 					sData->m_internalKeyModifierFlags |= INTERNAL_ALT_MODIFIER;
348 					break;
349 				};
350 				case B3G_SHIFT:
351 				{
352 					sData->m_internalKeyModifierFlags |= INTERNAL_SHIFT_MODIFIER;
353 					break;
354 				};
355 				case B3G_CONTROL:
356 				{
357 					sData->m_internalKeyModifierFlags |= INTERNAL_CONTROL_MODIFIER;
358 					break;
359 				};
360 			}
361 			if (keycode >= 0 && sData && sData->m_keyboardCallback && ((HIWORD(lParam) & KF_REPEAT) == 0))
362 			{
363 				int state = 1;
364 				(*sData->m_keyboardCallback)(keycode, state);
365 				return 1;
366 			}
367 			return 0;
368 		}
369 
370 		case WM_MBUTTONUP:
371 		{
372 			int xPos = LOWORD(lParam);
373 			int yPos = HIWORD(lParam);
374 			if (sData)
375 			{
376 				sData->m_mouseMButton = 0;
377 				sData->m_mouseXpos = xPos;
378 				sData->m_mouseYpos = yPos;
379 				if (sData && sData->m_mouseButtonCallback)
380 					(*sData->m_mouseButtonCallback)(1, 0, xPos, yPos);
381 			}
382 			break;
383 		}
384 		case WM_MBUTTONDOWN:
385 		{
386 			int xPos = LOWORD(lParam);
387 			int yPos = HIWORD(lParam);
388 			if (sData)
389 			{
390 				sData->m_mouseMButton = 1;
391 				sData->m_mouseXpos = xPos;
392 				sData->m_mouseYpos = yPos;
393 				if (sData && sData->m_mouseButtonCallback)
394 					(*sData->m_mouseButtonCallback)(1, 1, xPos, yPos);
395 			}
396 			break;
397 		}
398 
399 		case WM_LBUTTONUP:
400 		{
401 			int xPos = LOWORD(lParam);
402 			int yPos = HIWORD(lParam);
403 			if (sData)
404 			{
405 				sData->m_mouseLButton = 0;
406 				sData->m_mouseXpos = xPos;
407 				sData->m_mouseYpos = yPos;
408 
409 				if (sData && sData->m_mouseButtonCallback)
410 					(*sData->m_mouseButtonCallback)(0, 0, xPos, yPos);
411 			}
412 			//	gDemoApplication->mouseFunc(0,1,xPos,yPos);
413 			break;
414 		}
415 		case WM_LBUTTONDOWN:
416 		{
417 			int xPos = LOWORD(lParam);
418 			int yPos = HIWORD(lParam);
419 			if (sData)
420 			{
421 				sData->m_mouseLButton = 1;
422 				sData->m_mouseXpos = xPos;
423 				sData->m_mouseYpos = yPos;
424 
425 				if (sData && sData->m_mouseButtonCallback)
426 					(*sData->m_mouseButtonCallback)(0, 1, xPos, yPos);
427 			}
428 			break;
429 		}
430 
431 		case 0x020e:  //WM_MOUSEWHEEL_LEFT_RIGHT
432 		{
433 			int zDelta = (short)HIWORD(wParam);
434 			int xPos = LOWORD(lParam);
435 			int yPos = HIWORD(lParam);
436 			//m_cameraDistance -= zDelta*0.01;
437 			if (sData && sData->m_wheelCallback)
438 				(*sData->m_wheelCallback)(-float(zDelta) * 0.05f, 0);
439 			return 1;
440 			break;
441 		}
442 		case 0x020A:  //WM_MOUSEWHEEL:
443 		{
444 			int zDelta = (short)HIWORD(wParam);
445 			int xPos = LOWORD(lParam);
446 			int yPos = HIWORD(lParam);
447 			//m_cameraDistance -= zDelta*0.01;
448 			if (sData && sData->m_wheelCallback)
449 				(*sData->m_wheelCallback)(0, float(zDelta) * 0.05f);
450 			return 1;
451 			break;
452 		}
453 
454 		case WM_MOUSEMOVE:
455 		{
456 			int xPos = LOWORD(lParam);
457 			int yPos = HIWORD(lParam);
458 			sData->m_mouseXpos = xPos;
459 			sData->m_mouseYpos = yPos;
460 
461 			if (sData && sData->m_mouseMoveCallback)
462 				(*sData->m_mouseMoveCallback)(xPos, yPos);
463 
464 			break;
465 		}
466 		case WM_RBUTTONUP:
467 		{
468 			int xPos = LOWORD(lParam);
469 			int yPos = HIWORD(lParam);
470 			sData->m_mouseRButton = 1;
471 
472 			if (sData && sData->m_mouseButtonCallback)
473 				(*sData->m_mouseButtonCallback)(2, 0, sData->m_mouseXpos, sData->m_mouseYpos);
474 
475 			//gDemoApplication->mouseFunc(2,1,xPos,yPos);
476 			break;
477 		}
478 		case WM_RBUTTONDOWN:
479 		{
480 			int xPos = LOWORD(lParam);
481 			int yPos = HIWORD(lParam);
482 			sData->m_mouseRButton = 0;
483 			if (sData && sData->m_mouseButtonCallback)
484 				(*sData->m_mouseButtonCallback)(2, 1, sData->m_mouseXpos, sData->m_mouseYpos);
485 
486 			break;
487 		}
488 		case WM_QUIT:
489 		{
490 			return 0;
491 			break;
492 		}
493 		case WM_SIZE:  // Size Action Has Taken Place
494 
495 			RECT clientRect;
496 			GetClientRect(hWnd, &clientRect);
497 
498 			switch (wParam)  // Evaluate Size Action
499 			{
500 				case SIZE_MINIMIZED:  // Was Window Minimized?
501 					return 0;         // Return
502 
503 				case SIZE_MAXIMIZED:  // Was Window Maximized?
504 				case SIZE_RESTORED:   // Was Window Restored?
505 					RECT wr;
506 					GetWindowRect(hWnd, &wr);
507 
508 					sData->m_fullWindowWidth = wr.right - wr.left;
509 					sData->m_fullWindowHeight = wr.bottom - wr.top;  //LOWORD (lParam) HIWORD (lParam);
510 					sData->m_openglViewportWidth = clientRect.right;
511 					sData->m_openglViewportHeight = clientRect.bottom;
512 
513 					if (sData->m_resizeCallback)
514 					{
515 						glViewport(0, 0, sData->m_openglViewportWidth, sData->m_openglViewportHeight);
516 						(*sData->m_resizeCallback)(sData->m_openglViewportWidth, sData->m_openglViewportHeight);
517 					}
518 					//if (sOpenGLInitialized)
519 					//{
520 					//	//gDemoApplication->reshape(sWidth,sHeight);
521 					//}
522 					return 0;  // Return
523 			}
524 			break;
525 
526 		default:
527 		{
528 		}
529 	};
530 
531 	return DefWindowProc(hWnd, message, wParam, lParam);
532 }
533 
setWindowTitle(const char * titleChar)534 void Win32Window::setWindowTitle(const char* titleChar)
535 {
536 #ifdef _WIN64
537 	SetWindowTextA(m_data->m_hWnd, titleChar);
538 #else
539 #ifdef UNICODE
540 	DWORD dwResult;
541 	SendMessageTimeoutA(m_data->m_hWnd, WM_SETTEXT, 0,
542 		reinterpret_cast<LPARAM>(titleChar),
543 		SMTO_ABORTIFHUNG, 2000, &dwResult);
544 #else
545 	DWORD dwResult;
546 	SendMessageTimeout(m_data->m_hWnd, WM_SETTEXT, 0,
547 		reinterpret_cast<LPARAM>(titleChar),
548 		SMTO_ABORTIFHUNG, 2000, &dwResult);
549 
550 #endif
551 #endif
552 }
553 
createWindow(const b3gWindowConstructionInfo & ci)554 void Win32Window::createWindow(const b3gWindowConstructionInfo& ci)
555 {
556 	int oglViewportWidth = ci.m_width;
557 	int oglViewportHeight = ci.m_height;
558 	bool fullscreen = ci.m_fullscreen;
559 	int colorBitsPerPixel = ci.m_colorBitsPerPixel;
560 	void* windowHandle = ci.m_windowHandle;
561 
562 	// get handle to exe file
563 	HINSTANCE hInstance = GetModuleHandle(0);
564 
565 	// create the window if we need to and we do not use the null device
566 	if (!windowHandle)
567 	{
568 #ifdef UNICODE
569 		const wchar_t* ClassName = L"DeviceWin32";
570 		const wchar_t* emptyString = L"";
571 #else
572 		const char* ClassName = "DeviceWin32";
573 		const char* emptyString = "";
574 #endif
575 		// Register Class
576 		WNDCLASSEX wcex;
577 		wcex.cbSize = sizeof(WNDCLASSEX);
578 		wcex.style = CS_HREDRAW | CS_VREDRAW;
579 		wcex.lpfnWndProc = WndProc;
580 		wcex.cbClsExtra = 0;
581 		wcex.cbWndExtra = 0;
582 		wcex.hInstance = hInstance;
583 		wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);  //(HICON)LoadImage(hInstance, "bullet_ico.ico", IMAGE_ICON, 0,0, LR_LOADTRANSPARENT);//LR_LOADFROMFILE);
584 		wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
585 		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
586 		wcex.lpszMenuName = 0;
587 		wcex.lpszClassName = ClassName;
588 		wcex.hIconSm = 0;
589 
590 		// if there is an icon, load it
591 		//		wcex.hIcon = (HICON)LoadImage(hInstance, "bullet.ico", IMAGE_ICON, 0,0, LR_LOADFROMFILE);
592 
593 		RegisterClassEx(&wcex);
594 
595 		// calculate client size
596 
597 		RECT clientSize;
598 		clientSize.top = 0;
599 		clientSize.left = 0;
600 		clientSize.right = oglViewportWidth;
601 		clientSize.bottom = oglViewportHeight;
602 
603 		DWORD style = WS_POPUP;
604 
605 		if (!fullscreen)
606 			style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX;
607 
608 		AdjustWindowRect(&clientSize, style, false);
609 
610 		m_data->m_fullWindowWidth = clientSize.right - clientSize.left;
611 		m_data->m_fullWindowHeight = clientSize.bottom - clientSize.top;
612 
613 		int windowLeft = (GetSystemMetrics(SM_CXSCREEN) - m_data->m_fullWindowWidth) / 2;
614 		int windowTop = (GetSystemMetrics(SM_CYSCREEN) - m_data->m_fullWindowHeight) / 2;
615 
616 		if (fullscreen)
617 		{
618 			windowLeft = 0;
619 			windowTop = 0;
620 		}
621 
622 		// create window
623 
624 		m_data->m_hWnd = CreateWindow(ClassName, emptyString, style, windowLeft, windowTop,
625 									  m_data->m_fullWindowWidth, m_data->m_fullWindowHeight, NULL, NULL, hInstance, NULL);
626 
627 		RECT clientRect;
628 		GetClientRect(m_data->m_hWnd, &clientRect);
629 
630 		ShowWindow(m_data->m_hWnd, SW_SHOW);
631 		UpdateWindow(m_data->m_hWnd);
632 
633 		MoveWindow(m_data->m_hWnd, windowLeft, windowTop, m_data->m_fullWindowWidth, m_data->m_fullWindowHeight, TRUE);
634 
635 		GetClientRect(m_data->m_hWnd, &clientRect);
636 		int w = clientRect.right - clientRect.left;
637 		int h = clientRect.bottom - clientRect.top;
638 		//		printf("actual client OpenGL viewport width / height = %d, %d\n",w,h);
639 		m_data->m_openglViewportHeight = h;
640 		m_data->m_openglViewportWidth = w;
641 	}
642 	else if (windowHandle)
643 	{
644 		// attach external window
645 		m_data->m_hWnd = static_cast<HWND>(windowHandle);
646 		RECT r;
647 		GetWindowRect(m_data->m_hWnd, &r);
648 		m_data->m_fullWindowWidth = r.right - r.left;
649 		m_data->m_fullWindowHeight = r.bottom - r.top;
650 
651 		//sFullScreen = false;
652 		//sExternalWindow = true;
653 	}
654 
655 	if (fullscreen)
656 	{
657 		DEVMODE dm;
658 		memset(&dm, 0, sizeof(dm));
659 		dm.dmSize = sizeof(dm);
660 		// use default values from current setting
661 		EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
662 		m_data->m_oldScreenWidth = dm.dmPelsWidth;
663 		m_data->m_oldHeight = dm.dmPelsHeight;
664 		m_data->m_oldBitsPerPel = dm.dmBitsPerPel;
665 
666 		dm.dmPelsWidth = oglViewportWidth;
667 		dm.dmPelsHeight = oglViewportHeight;
668 		if (colorBitsPerPixel)
669 		{
670 			dm.dmBitsPerPel = colorBitsPerPixel;
671 		}
672 		dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
673 
674 		LONG res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
675 		if (res != DISP_CHANGE_SUCCESSFUL)
676 		{  // try again without forcing display frequency
677 			dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
678 			res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
679 		}
680 	}
681 }
682 
switchFullScreen(bool fullscreen,int width,int height,int colorBitsPerPixel)683 void Win32Window::switchFullScreen(bool fullscreen, int width, int height, int colorBitsPerPixel)
684 {
685 	LONG res;
686 	DEVMODE dm;
687 	memset(&dm, 0, sizeof(dm));
688 	dm.dmSize = sizeof(dm);
689 	// use default values from current setting
690 	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
691 
692 	dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
693 
694 	if (fullscreen && !m_data->m_oldScreenWidth)
695 	{
696 		m_data->m_oldScreenWidth = dm.dmPelsWidth;
697 		m_data->m_oldHeight = dm.dmPelsHeight;
698 		m_data->m_oldBitsPerPel = dm.dmBitsPerPel;
699 
700 		if (width && height)
701 		{
702 			dm.dmPelsWidth = width;
703 			dm.dmPelsHeight = height;
704 		}
705 		else
706 		{
707 			dm.dmPelsWidth = m_data->m_fullWindowWidth;
708 			dm.dmPelsHeight = m_data->m_fullWindowHeight;
709 		}
710 		if (colorBitsPerPixel)
711 		{
712 			dm.dmBitsPerPel = colorBitsPerPixel;
713 		}
714 	}
715 	else
716 	{
717 		if (m_data->m_oldScreenWidth)
718 		{
719 			dm.dmPelsWidth = m_data->m_oldScreenWidth;
720 			dm.dmPelsHeight = m_data->m_oldHeight;
721 			dm.dmBitsPerPel = m_data->m_oldBitsPerPel;
722 		}
723 	}
724 
725 	if (fullscreen)
726 	{
727 		res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
728 		if (!res)
729 		{
730 			dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
731 			res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
732 		}
733 
734 		DWORD style = WS_POPUP;
735 		SetWindowLong(m_data->m_hWnd, GWL_STYLE, style);
736 
737 		MoveWindow(m_data->m_hWnd, 0, 0, m_data->m_fullWindowWidth, m_data->m_fullWindowHeight, TRUE);
738 
739 		SetWindowPos(m_data->m_hWnd, NULL, 0, 0, (int)width, (int)height,
740 					 SWP_FRAMECHANGED | SWP_SHOWWINDOW);  //|SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOREPOSITION | SWP_NOZORDER);
741 	}
742 	else
743 	{
744 		res = ChangeDisplaySettings(&dm, 0);
745 
746 		DWORD style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX;
747 		SetWindowLong(m_data->m_hWnd, GWL_STYLE, style);
748 
749 		SetWindowPos(m_data->m_hWnd, NULL, 0, 0, (int)width, (int)height,
750 					 SWP_FRAMECHANGED | SWP_SHOWWINDOW);
751 		//|SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOREPOSITION | SWP_NOZORDER);
752 	}
753 }
754 
Win32Window()755 Win32Window::Win32Window()
756 {
757 	m_data = new InternalData2();
758 	sData = m_data;
759 }
760 
~Win32Window()761 Win32Window::~Win32Window()
762 {
763 	setKeyboardCallback(0);
764 	setMouseMoveCallback(0);
765 	setMouseButtonCallback(0);
766 	setWheelCallback(0);
767 	setResizeCallback(0);
768 
769 	sData = 0;
770 	delete m_data;
771 }
772 
setRenderCallback(b3RenderCallback renderCallback)773 void Win32Window::setRenderCallback(b3RenderCallback renderCallback)
774 {
775 }
776 
closeWindow()777 void Win32Window::closeWindow()
778 {
779 	setKeyboardCallback(0);
780 	setMouseMoveCallback(0);
781 	setMouseButtonCallback(0);
782 	setWheelCallback(0);
783 	setResizeCallback(0);
784 	setRenderCallback(0);
785 
786 	DestroyWindow(this->m_data->m_hWnd);
787 }
788 
getMouseCoordinates(int & x,int & y)789 void Win32Window::getMouseCoordinates(int& x, int& y)
790 {
791 	x = m_data->m_mouseXpos;
792 	y = m_data->m_mouseYpos;
793 }
794 
runMainLoop()795 void Win32Window::runMainLoop()
796 {
797 }
798 
startRendering()799 void Win32Window::startRendering()
800 {
801 	pumpMessage();
802 }
803 
renderAllObjects()804 void Win32Window::renderAllObjects()
805 {
806 }
807 
endRendering()808 void Win32Window::endRendering()
809 {
810 	SwapBuffers(m_data->m_hDC);
811 }
812 
getTimeInSeconds()813 float Win32Window::getTimeInSeconds()
814 {
815 	return 0.f;
816 }
817 
setDebugMessage(int x,int y,const char * message)818 void Win32Window::setDebugMessage(int x, int y, const char* message)
819 {
820 }
821 
setRequestExit()822 void Win32Window::setRequestExit()
823 {
824 	m_data->m_quit = true;
825 }
requestedExit() const826 bool Win32Window::requestedExit() const
827 {
828 	return m_data->m_quit;
829 }
830 
setWheelCallback(b3WheelCallback wheelCallback)831 void Win32Window::setWheelCallback(b3WheelCallback wheelCallback)
832 {
833 	m_data->m_wheelCallback = wheelCallback;
834 }
835 
setMouseMoveCallback(b3MouseMoveCallback mouseCallback)836 void Win32Window::setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
837 {
838 	m_data->m_mouseMoveCallback = mouseCallback;
839 }
840 
setMouseButtonCallback(b3MouseButtonCallback mouseCallback)841 void Win32Window::setMouseButtonCallback(b3MouseButtonCallback mouseCallback)
842 {
843 	m_data->m_mouseButtonCallback = mouseCallback;
844 }
845 
setResizeCallback(b3ResizeCallback resizeCallback)846 void Win32Window::setResizeCallback(b3ResizeCallback resizeCallback)
847 {
848 	m_data->m_resizeCallback = resizeCallback;
849 	if (m_data->m_resizeCallback)
850 		(*m_data->m_resizeCallback)(m_data->m_openglViewportWidth, m_data->m_openglViewportHeight);
851 }
852 
setKeyboardCallback(b3KeyboardCallback keyboardCallback)853 void Win32Window::setKeyboardCallback(b3KeyboardCallback keyboardCallback)
854 {
855 	m_data->m_keyboardCallback = keyboardCallback;
856 }
857 
getKeyboardCallback()858 b3KeyboardCallback Win32Window::getKeyboardCallback()
859 {
860 	return m_data->m_keyboardCallback;
861 }
862 
getMouseMoveCallback()863 b3MouseMoveCallback Win32Window::getMouseMoveCallback()
864 {
865 	return m_data->m_mouseMoveCallback;
866 }
getMouseButtonCallback()867 b3MouseButtonCallback Win32Window::getMouseButtonCallback()
868 {
869 	return m_data->m_mouseButtonCallback;
870 }
getResizeCallback()871 b3ResizeCallback Win32Window::getResizeCallback()
872 {
873 	return m_data->m_resizeCallback;
874 }
getWheelCallback()875 b3WheelCallback Win32Window::getWheelCallback()
876 {
877 	return m_data->m_wheelCallback;
878 }
879 #endif
880