ruby-glfw 0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +1 -0
- data/README.API +73 -0
- data/Rakefile +120 -0
- data/examples/boing.rb +519 -0
- data/examples/gears.rb +327 -0
- data/examples/keytest.rb +117 -0
- data/examples/listmodes.rb +20 -0
- data/examples/mipmaps.rb +104 -0
- data/examples/mipmaps.tga +0 -0
- data/examples/particles.rb +837 -0
- data/examples/pong3d.rb +741 -0
- data/examples/pong3d_field.tga +0 -0
- data/examples/pong3d_instr.tga +0 -0
- data/examples/pong3d_menu.tga +0 -0
- data/examples/pong3d_title.tga +0 -0
- data/examples/pong3d_winner1.tga +0 -0
- data/examples/pong3d_winner2.tga +0 -0
- data/examples/splitview.rb +432 -0
- data/examples/triangle.rb +89 -0
- data/examples/wave.rb +294 -0
- data/ext/glfw/glfw.c +1094 -0
- data/ext/glfw/mkrf_conf.rb +70 -0
- data/glfw-src/Makefile +220 -0
- data/glfw-src/compile.ami +61 -0
- data/glfw-src/compile.bat +217 -0
- data/glfw-src/compile.sh +607 -0
- data/glfw-src/docs/Makefile +57 -0
- data/glfw-src/docs/Reference.pdf +0 -0
- data/glfw-src/docs/UsersGuide.pdf +0 -0
- data/glfw-src/docs/cleanup.bat +22 -0
- data/glfw-src/docs/glfwdoc.sty +80 -0
- data/glfw-src/docs/glfwrm.tex +3034 -0
- data/glfw-src/docs/glfwug.tex +2024 -0
- data/glfw-src/docs/readme.txt +80 -0
- data/glfw-src/examples/Makefile.amigaos.gcc +70 -0
- data/glfw-src/examples/Makefile.amigaos.vbcc +70 -0
- data/glfw-src/examples/Makefile.dos.djgpp +71 -0
- data/glfw-src/examples/Makefile.macosx.gcc +96 -0
- data/glfw-src/examples/Makefile.win32.bcc +75 -0
- data/glfw-src/examples/Makefile.win32.cross-mgw +79 -0
- data/glfw-src/examples/Makefile.win32.cygwin +79 -0
- data/glfw-src/examples/Makefile.win32.lcc +74 -0
- data/glfw-src/examples/Makefile.win32.mgw +75 -0
- data/glfw-src/examples/Makefile.win32.msvc +74 -0
- data/glfw-src/examples/Makefile.win32.ow +74 -0
- data/glfw-src/examples/Makefile.win32.pellesc +74 -0
- data/glfw-src/examples/Makefile.x11.in +54 -0
- data/glfw-src/examples/boing.c +606 -0
- data/glfw-src/examples/bundle.sh +46 -0
- data/glfw-src/examples/gears.c +382 -0
- data/glfw-src/examples/keytest.c +264 -0
- data/glfw-src/examples/listmodes.c +48 -0
- data/glfw-src/examples/mipmaps.c +126 -0
- data/glfw-src/examples/mipmaps.tga +0 -0
- data/glfw-src/examples/mtbench.c +301 -0
- data/glfw-src/examples/mthello.c +48 -0
- data/glfw-src/examples/particles.c +1148 -0
- data/glfw-src/examples/pong3d.c +839 -0
- data/glfw-src/examples/pong3d_field.tga +0 -0
- data/glfw-src/examples/pong3d_instr.tga +0 -0
- data/glfw-src/examples/pong3d_menu.tga +0 -0
- data/glfw-src/examples/pong3d_title.tga +0 -0
- data/glfw-src/examples/pong3d_winner1.tga +0 -0
- data/glfw-src/examples/pong3d_winner2.tga +0 -0
- data/glfw-src/examples/splitview.c +506 -0
- data/glfw-src/examples/triangle.c +108 -0
- data/glfw-src/examples/wave.c +397 -0
- data/glfw-src/images/opengl.gif +0 -0
- data/glfw-src/images/osicert.gif +0 -0
- data/glfw-src/include/GL/glfw.h +486 -0
- data/glfw-src/lib/amigaos/Makefile.amigaos.gcc +128 -0
- data/glfw-src/lib/amigaos/Makefile.amigaos.vbcc +128 -0
- data/glfw-src/lib/amigaos/SDI_compiler.h +94 -0
- data/glfw-src/lib/amigaos/amigaos_enable.c +51 -0
- data/glfw-src/lib/amigaos/amigaos_fullscreen.c +319 -0
- data/glfw-src/lib/amigaos/amigaos_glext.c +61 -0
- data/glfw-src/lib/amigaos/amigaos_init.c +284 -0
- data/glfw-src/lib/amigaos/amigaos_joystick.c +359 -0
- data/glfw-src/lib/amigaos/amigaos_thread.c +494 -0
- data/glfw-src/lib/amigaos/amigaos_time.c +206 -0
- data/glfw-src/lib/amigaos/amigaos_window.c +830 -0
- data/glfw-src/lib/amigaos/platform.h +337 -0
- data/glfw-src/lib/dos/Makefile.dos.djgpp +146 -0
- data/glfw-src/lib/dos/dos_enable.c +51 -0
- data/glfw-src/lib/dos/dos_events.c +173 -0
- data/glfw-src/lib/dos/dos_fullscreen.c +101 -0
- data/glfw-src/lib/dos/dos_glext.c +59 -0
- data/glfw-src/lib/dos/dos_init.c +105 -0
- data/glfw-src/lib/dos/dos_irq.s +246 -0
- data/glfw-src/lib/dos/dos_joystick.c +94 -0
- data/glfw-src/lib/dos/dos_keyboard.c +694 -0
- data/glfw-src/lib/dos/dos_mouse.c +337 -0
- data/glfw-src/lib/dos/dos_thread.c +267 -0
- data/glfw-src/lib/dos/dos_time.c +309 -0
- data/glfw-src/lib/dos/dos_window.c +563 -0
- data/glfw-src/lib/dos/platform.h +341 -0
- data/glfw-src/lib/enable.c +295 -0
- data/glfw-src/lib/fullscreen.c +95 -0
- data/glfw-src/lib/glext.c +201 -0
- data/glfw-src/lib/image.c +629 -0
- data/glfw-src/lib/init.c +108 -0
- data/glfw-src/lib/input.c +280 -0
- data/glfw-src/lib/internal.h +210 -0
- data/glfw-src/lib/joystick.c +101 -0
- data/glfw-src/lib/macosx/Makefile.macosx.gcc +172 -0
- data/glfw-src/lib/macosx/Makefile.macosx.gcc.universal +166 -0
- data/glfw-src/lib/macosx/libglfw.pc.in +11 -0
- data/glfw-src/lib/macosx/macosx_enable.c +42 -0
- data/glfw-src/lib/macosx/macosx_fullscreen.c +126 -0
- data/glfw-src/lib/macosx/macosx_glext.c +52 -0
- data/glfw-src/lib/macosx/macosx_init.c +194 -0
- data/glfw-src/lib/macosx/macosx_joystick.c +50 -0
- data/glfw-src/lib/macosx/macosx_thread.c +414 -0
- data/glfw-src/lib/macosx/macosx_time.c +112 -0
- data/glfw-src/lib/macosx/macosx_window.c +1279 -0
- data/glfw-src/lib/macosx/platform.h +349 -0
- data/glfw-src/lib/stream.c +194 -0
- data/glfw-src/lib/tga.c +405 -0
- data/glfw-src/lib/thread.c +340 -0
- data/glfw-src/lib/time.c +83 -0
- data/glfw-src/lib/win32/Makefile.win32.bcc +265 -0
- data/glfw-src/lib/win32/Makefile.win32.cross-mgw +274 -0
- data/glfw-src/lib/win32/Makefile.win32.cygwin +279 -0
- data/glfw-src/lib/win32/Makefile.win32.lcc +246 -0
- data/glfw-src/lib/win32/Makefile.win32.mgw +243 -0
- data/glfw-src/lib/win32/Makefile.win32.msvc +242 -0
- data/glfw-src/lib/win32/Makefile.win32.ow +242 -0
- data/glfw-src/lib/win32/Makefile.win32.pellesc +242 -0
- data/glfw-src/lib/win32/glfwdll.def +67 -0
- data/glfw-src/lib/win32/glfwdll_mgw1.def +67 -0
- data/glfw-src/lib/win32/glfwdll_mgw2.def +67 -0
- data/glfw-src/lib/win32/glfwdll_pellesc.def +65 -0
- data/glfw-src/lib/win32/libglfw.pc.in +11 -0
- data/glfw-src/lib/win32/platform.h +474 -0
- data/glfw-src/lib/win32/win32_dllmain.c +60 -0
- data/glfw-src/lib/win32/win32_enable.c +155 -0
- data/glfw-src/lib/win32/win32_fullscreen.c +317 -0
- data/glfw-src/lib/win32/win32_glext.c +85 -0
- data/glfw-src/lib/win32/win32_init.c +356 -0
- data/glfw-src/lib/win32/win32_joystick.c +234 -0
- data/glfw-src/lib/win32/win32_thread.c +511 -0
- data/glfw-src/lib/win32/win32_time.c +146 -0
- data/glfw-src/lib/win32/win32_window.c +1714 -0
- data/glfw-src/lib/window.c +727 -0
- data/glfw-src/lib/x11/Makefile.x11.in +243 -0
- data/glfw-src/lib/x11/platform.h +415 -0
- data/glfw-src/lib/x11/x11_enable.c +51 -0
- data/glfw-src/lib/x11/x11_fullscreen.c +524 -0
- data/glfw-src/lib/x11/x11_glext.c +69 -0
- data/glfw-src/lib/x11/x11_init.c +275 -0
- data/glfw-src/lib/x11/x11_joystick.c +371 -0
- data/glfw-src/lib/x11/x11_keysym2unicode.c +902 -0
- data/glfw-src/lib/x11/x11_thread.c +507 -0
- data/glfw-src/lib/x11/x11_time.c +154 -0
- data/glfw-src/lib/x11/x11_window.c +1746 -0
- data/glfw-src/license.txt +21 -0
- data/glfw-src/readme.html +927 -0
- data/glfw-src/support/d/examples/Makefile +59 -0
- data/glfw-src/support/d/examples/boing.d +610 -0
- data/glfw-src/support/d/examples/gears.d +379 -0
- data/glfw-src/support/d/examples/keytest.d +272 -0
- data/glfw-src/support/d/examples/listmodes.d +48 -0
- data/glfw-src/support/d/examples/mipmaps.d +126 -0
- data/glfw-src/support/d/examples/mtbench.d +304 -0
- data/glfw-src/support/d/examples/mthello.d +54 -0
- data/glfw-src/support/d/examples/particles.d +1150 -0
- data/glfw-src/support/d/examples/pong3d.d +840 -0
- data/glfw-src/support/d/examples/splitview.d +486 -0
- data/glfw-src/support/d/examples/triangle.d +108 -0
- data/glfw-src/support/d/examples/wave.d +400 -0
- data/glfw-src/support/d/imports/gl.d +4539 -0
- data/glfw-src/support/d/imports/glfw.d +349 -0
- data/glfw-src/support/d/imports/glu.d +328 -0
- data/glfw-src/support/d/lib/glfwdll.def +64 -0
- data/glfw-src/support/d/lib/glu32.def +56 -0
- data/glfw-src/support/d/lib/makefile +12 -0
- data/glfw-src/support/d/lib/opengl32.def +372 -0
- data/glfw-src/support/d/readme.html +83 -0
- data/glfw-src/support/delphi/examples/Triangle.dpr +105 -0
- data/glfw-src/support/delphi/lib/glfw.pas +437 -0
- data/glfw-src/support/delphi/readme.html +97 -0
- data/glfw-src/support/lua/examples/gears.lua +383 -0
- data/glfw-src/support/lua/examples/test1.lua +68 -0
- data/glfw-src/support/lua/readme.html +128 -0
- data/glfw-src/support/lua/src/luaglfw.c +1179 -0
- data/glfw-src/support/lua/src/luaglfw.h +48 -0
- data/glfw-src/support/lua/src/runlua.c +82 -0
- data/glfw-src/support/masm/examples/fpc.mac +47 -0
- data/glfw-src/support/masm/examples/makeit.bat +66 -0
- data/glfw-src/support/masm/examples/triangle.asm +232 -0
- data/glfw-src/support/masm/include/glfw.inc +326 -0
- data/glfw-src/support/masm/include/glu32.inc +55 -0
- data/glfw-src/support/masm/include/opengl32.inc +372 -0
- data/glfw-src/support/masm/lib/glfwdll.lib +0 -0
- data/glfw-src/support/masm/readme.html +170 -0
- data/glfw-src/support/msvc80/GLFW.sln +26 -0
- data/glfw-src/support/msvc80/GLFW.vcproj +257 -0
- data/glfw-src/support/msvc80/GLFWDLL.vcproj +287 -0
- data/glfw-src/support/visualbasic/bindings/glfw.bas +320 -0
- data/glfw-src/support/visualbasic/bindings/glu32.bas +284 -0
- data/glfw-src/support/visualbasic/bindings/opengl32.bas +999 -0
- data/glfw-src/support/visualbasic/examples/Triangle.bas +101 -0
- data/glfw-src/support/visualbasic/readme.html +164 -0
- data/website/index.html +84 -0
- data/website/style.css +110 -0
- metadata +301 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
//========================================================================
|
|
2
|
+
// GLFW - An OpenGL framework
|
|
3
|
+
// File: win32_time.c
|
|
4
|
+
// Platform: Windows
|
|
5
|
+
// API version: 2.6
|
|
6
|
+
// WWW: http://glfw.sourceforge.net
|
|
7
|
+
//------------------------------------------------------------------------
|
|
8
|
+
// Copyright (c) 2002-2006 Camilla Berglund
|
|
9
|
+
//
|
|
10
|
+
// This software is provided 'as-is', without any express or implied
|
|
11
|
+
// warranty. In no event will the authors be held liable for any damages
|
|
12
|
+
// arising from the use of this software.
|
|
13
|
+
//
|
|
14
|
+
// Permission is granted to anyone to use this software for any purpose,
|
|
15
|
+
// including commercial applications, and to alter it and redistribute it
|
|
16
|
+
// freely, subject to the following restrictions:
|
|
17
|
+
//
|
|
18
|
+
// 1. The origin of this software must not be misrepresented; you must not
|
|
19
|
+
// claim that you wrote the original software. If you use this software
|
|
20
|
+
// in a product, an acknowledgment in the product documentation would
|
|
21
|
+
// be appreciated but is not required.
|
|
22
|
+
//
|
|
23
|
+
// 2. Altered source versions must be plainly marked as such, and must not
|
|
24
|
+
// be misrepresented as being the original software.
|
|
25
|
+
//
|
|
26
|
+
// 3. This notice may not be removed or altered from any source
|
|
27
|
+
// distribution.
|
|
28
|
+
//
|
|
29
|
+
//========================================================================
|
|
30
|
+
|
|
31
|
+
#include "internal.h"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
//************************************************************************
|
|
35
|
+
//**** GLFW internal functions ****
|
|
36
|
+
//************************************************************************
|
|
37
|
+
|
|
38
|
+
//========================================================================
|
|
39
|
+
// _glfwInitTimer() - Initialise timer
|
|
40
|
+
//========================================================================
|
|
41
|
+
|
|
42
|
+
void _glfwInitTimer( void )
|
|
43
|
+
{
|
|
44
|
+
__int64 freq;
|
|
45
|
+
|
|
46
|
+
// Check if we have a performance counter
|
|
47
|
+
if( QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ) )
|
|
48
|
+
{
|
|
49
|
+
// Performance counter is available => use it!
|
|
50
|
+
_glfwLibrary.Timer.HasPerformanceCounter = GL_TRUE;
|
|
51
|
+
|
|
52
|
+
// Counter resolution is 1 / counter frequency
|
|
53
|
+
_glfwLibrary.Timer.Resolution = 1.0 / (double)freq;
|
|
54
|
+
|
|
55
|
+
// Set start time for timer
|
|
56
|
+
QueryPerformanceCounter( (LARGE_INTEGER *)&_glfwLibrary.Timer.t0_64 );
|
|
57
|
+
}
|
|
58
|
+
else
|
|
59
|
+
{
|
|
60
|
+
// No performace counter available => use the tick counter
|
|
61
|
+
_glfwLibrary.Timer.HasPerformanceCounter = GL_FALSE;
|
|
62
|
+
|
|
63
|
+
// Counter resolution is 1 ms
|
|
64
|
+
_glfwLibrary.Timer.Resolution = 0.001;
|
|
65
|
+
|
|
66
|
+
// Set start time for timer
|
|
67
|
+
_glfwLibrary.Timer.t0_32 = _glfw_timeGetTime();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
//************************************************************************
|
|
73
|
+
//**** Platform implementation functions ****
|
|
74
|
+
//************************************************************************
|
|
75
|
+
|
|
76
|
+
//========================================================================
|
|
77
|
+
// Return timer value in seconds
|
|
78
|
+
//========================================================================
|
|
79
|
+
|
|
80
|
+
double _glfwPlatformGetTime( void )
|
|
81
|
+
{
|
|
82
|
+
double t;
|
|
83
|
+
__int64 t_64;
|
|
84
|
+
|
|
85
|
+
if( _glfwLibrary.Timer.HasPerformanceCounter )
|
|
86
|
+
{
|
|
87
|
+
QueryPerformanceCounter( (LARGE_INTEGER *)&t_64 );
|
|
88
|
+
t = (double)(t_64 - _glfwLibrary.Timer.t0_64);
|
|
89
|
+
}
|
|
90
|
+
else
|
|
91
|
+
{
|
|
92
|
+
t = (double)(_glfw_timeGetTime() - _glfwLibrary.Timer.t0_32);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Calculate the current time in seconds
|
|
96
|
+
return t * _glfwLibrary.Timer.Resolution;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
//========================================================================
|
|
101
|
+
// Set timer value in seconds
|
|
102
|
+
//========================================================================
|
|
103
|
+
|
|
104
|
+
void _glfwPlatformSetTime( double t )
|
|
105
|
+
{
|
|
106
|
+
__int64 t_64;
|
|
107
|
+
|
|
108
|
+
if( _glfwLibrary.Timer.HasPerformanceCounter )
|
|
109
|
+
{
|
|
110
|
+
QueryPerformanceCounter( (LARGE_INTEGER *)&t_64 );
|
|
111
|
+
_glfwLibrary.Timer.t0_64 = t_64 - (__int64)(t/_glfwLibrary.Timer.Resolution);
|
|
112
|
+
}
|
|
113
|
+
else
|
|
114
|
+
{
|
|
115
|
+
_glfwLibrary.Timer.t0_32 = _glfw_timeGetTime() - (int)(t*1000.0);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
//========================================================================
|
|
121
|
+
// Put a thread to sleep for a specified amount of time
|
|
122
|
+
//========================================================================
|
|
123
|
+
|
|
124
|
+
void _glfwPlatformSleep( double time )
|
|
125
|
+
{
|
|
126
|
+
DWORD t;
|
|
127
|
+
|
|
128
|
+
if( time == 0.0 )
|
|
129
|
+
{
|
|
130
|
+
t = 0;
|
|
131
|
+
}
|
|
132
|
+
else if( time < 0.001 )
|
|
133
|
+
{
|
|
134
|
+
t = 1;
|
|
135
|
+
}
|
|
136
|
+
else if( time > 2147483647.0 )
|
|
137
|
+
{
|
|
138
|
+
t = 2147483647;
|
|
139
|
+
}
|
|
140
|
+
else
|
|
141
|
+
{
|
|
142
|
+
t = (DWORD)(time*1000.0 + 0.5);
|
|
143
|
+
}
|
|
144
|
+
Sleep( t );
|
|
145
|
+
}
|
|
146
|
+
|
|
@@ -0,0 +1,1714 @@
|
|
|
1
|
+
//========================================================================
|
|
2
|
+
// GLFW - An OpenGL framework
|
|
3
|
+
// File: win32_window.c
|
|
4
|
+
// Platform: Windows
|
|
5
|
+
// API version: 2.6
|
|
6
|
+
// WWW: http://glfw.sourceforge.net
|
|
7
|
+
//------------------------------------------------------------------------
|
|
8
|
+
// Copyright (c) 2002-2006 Camilla Berglund
|
|
9
|
+
//
|
|
10
|
+
// This software is provided 'as-is', without any express or implied
|
|
11
|
+
// warranty. In no event will the authors be held liable for any damages
|
|
12
|
+
// arising from the use of this software.
|
|
13
|
+
//
|
|
14
|
+
// Permission is granted to anyone to use this software for any purpose,
|
|
15
|
+
// including commercial applications, and to alter it and redistribute it
|
|
16
|
+
// freely, subject to the following restrictions:
|
|
17
|
+
//
|
|
18
|
+
// 1. The origin of this software must not be misrepresented; you must not
|
|
19
|
+
// claim that you wrote the original software. If you use this software
|
|
20
|
+
// in a product, an acknowledgment in the product documentation would
|
|
21
|
+
// be appreciated but is not required.
|
|
22
|
+
//
|
|
23
|
+
// 2. Altered source versions must be plainly marked as such, and must not
|
|
24
|
+
// be misrepresented as being the original software.
|
|
25
|
+
//
|
|
26
|
+
// 3. This notice may not be removed or altered from any source
|
|
27
|
+
// distribution.
|
|
28
|
+
//
|
|
29
|
+
//========================================================================
|
|
30
|
+
|
|
31
|
+
#include "internal.h"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
//************************************************************************
|
|
36
|
+
//**** GLFW internal functions ****
|
|
37
|
+
//************************************************************************
|
|
38
|
+
|
|
39
|
+
#define _GLFW_WNDCLASSNAME "GLFW26"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
//========================================================================
|
|
43
|
+
// Enable/disable minimize/restore animations
|
|
44
|
+
//========================================================================
|
|
45
|
+
|
|
46
|
+
static int _glfwMinMaxAnimations( int enable )
|
|
47
|
+
{
|
|
48
|
+
ANIMATIONINFO AI;
|
|
49
|
+
int old_enable;
|
|
50
|
+
|
|
51
|
+
// Get old animation setting
|
|
52
|
+
AI.cbSize = sizeof( ANIMATIONINFO );
|
|
53
|
+
SystemParametersInfo( SPI_GETANIMATION, AI.cbSize, &AI, 0 );
|
|
54
|
+
old_enable = AI.iMinAnimate;
|
|
55
|
+
|
|
56
|
+
// If requested, change setting
|
|
57
|
+
if( old_enable != enable )
|
|
58
|
+
{
|
|
59
|
+
AI.iMinAnimate = enable;
|
|
60
|
+
SystemParametersInfo( SPI_SETANIMATION, AI.cbSize, &AI,
|
|
61
|
+
SPIF_SENDCHANGE );
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return old_enable;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
//========================================================================
|
|
69
|
+
// Function for bringing a window into focus and placing it on top of the
|
|
70
|
+
// window z stack. Due to some nastiness with how Win98/ME/2k/XP handles
|
|
71
|
+
// SetForegroundWindow, we have to go through some really bizarre measures to
|
|
72
|
+
// achieve this (thanks again, MS, for making life so much easier)!
|
|
73
|
+
//========================================================================
|
|
74
|
+
|
|
75
|
+
static void _glfwSetForegroundWindow( HWND hWnd )
|
|
76
|
+
{
|
|
77
|
+
int try_count = 0;
|
|
78
|
+
int old_animate;
|
|
79
|
+
|
|
80
|
+
// Try the standard approach first...
|
|
81
|
+
BringWindowToTop( hWnd );
|
|
82
|
+
SetForegroundWindow( hWnd );
|
|
83
|
+
|
|
84
|
+
// If it worked, return now
|
|
85
|
+
if( hWnd == GetForegroundWindow() )
|
|
86
|
+
{
|
|
87
|
+
// Try to modify the system settings (since this is the foreground
|
|
88
|
+
// process, we are allowed to do this)
|
|
89
|
+
SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0,
|
|
90
|
+
SPIF_SENDCHANGE );
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// For other Windows versions than 95 & NT4.0, the standard approach
|
|
95
|
+
// may not work, so if we failed we have to "trick" Windows into
|
|
96
|
+
// making our window the foureground window: Iconify and restore
|
|
97
|
+
// again. It is ugly, but it seems to work (we turn off those annoying
|
|
98
|
+
// zoom animations to make it look a bit better at least).
|
|
99
|
+
|
|
100
|
+
// Turn off minimize/restore animations
|
|
101
|
+
old_animate = _glfwMinMaxAnimations( 0 );
|
|
102
|
+
|
|
103
|
+
// We try this a few times, just to be on the safe side of things...
|
|
104
|
+
do
|
|
105
|
+
{
|
|
106
|
+
// Iconify & restore
|
|
107
|
+
ShowWindow( hWnd, SW_HIDE );
|
|
108
|
+
ShowWindow( hWnd, SW_SHOWMINIMIZED );
|
|
109
|
+
ShowWindow( hWnd, SW_SHOWNORMAL );
|
|
110
|
+
|
|
111
|
+
// Try to get focus
|
|
112
|
+
BringWindowToTop( hWnd );
|
|
113
|
+
SetForegroundWindow( hWnd );
|
|
114
|
+
|
|
115
|
+
// We do not want to keep going on forever, so we keep track of
|
|
116
|
+
// how many times we tried
|
|
117
|
+
try_count ++;
|
|
118
|
+
}
|
|
119
|
+
while( hWnd != GetForegroundWindow() && try_count <= 3 );
|
|
120
|
+
|
|
121
|
+
// Restore the system minimize/restore animation setting
|
|
122
|
+
(void) _glfwMinMaxAnimations( old_animate );
|
|
123
|
+
|
|
124
|
+
// Try to modify the system settings (since this is now hopefully the
|
|
125
|
+
// foreground process, we are probably allowed to do this)
|
|
126
|
+
SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0,
|
|
127
|
+
SPIF_SENDCHANGE );
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
//========================================================================
|
|
132
|
+
// Sets the device context pixel format using a PFD
|
|
133
|
+
//========================================================================
|
|
134
|
+
|
|
135
|
+
static int _glfwSetPixelFormatPFD( int redbits, int greenbits, int bluebits,
|
|
136
|
+
int alphabits, int depthbits, int stencilbits,
|
|
137
|
+
int mode, _GLFWhints* hints )
|
|
138
|
+
{
|
|
139
|
+
int PixelFormat;
|
|
140
|
+
PIXELFORMATDESCRIPTOR pfd;
|
|
141
|
+
|
|
142
|
+
// Set required pixel format
|
|
143
|
+
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
|
144
|
+
pfd.nVersion = 1;
|
|
145
|
+
pfd.dwFlags = PFD_DRAW_TO_WINDOW | // Draw to window
|
|
146
|
+
PFD_SUPPORT_OPENGL | // Support OpenGL
|
|
147
|
+
PFD_DOUBLEBUFFER; // Double buffered window
|
|
148
|
+
pfd.iPixelType = PFD_TYPE_RGBA; // Request an RGBA format
|
|
149
|
+
pfd.cColorBits = (BYTE) (redbits +
|
|
150
|
+
greenbits +
|
|
151
|
+
bluebits); // Color bits (ex. alpha)
|
|
152
|
+
pfd.cRedBits = (BYTE) redbits; // Red bits
|
|
153
|
+
pfd.cRedShift = 0; // Red shift ignored
|
|
154
|
+
pfd.cGreenBits = (BYTE) greenbits; // Green bits
|
|
155
|
+
pfd.cGreenShift = 0; // Green shift ignored
|
|
156
|
+
pfd.cBlueBits = (BYTE) bluebits; // Blue bits
|
|
157
|
+
pfd.cBlueShift = 0; // Blue shift ignored
|
|
158
|
+
pfd.cAlphaBits = (BYTE) alphabits; // Alpha bits
|
|
159
|
+
pfd.cAlphaShift = 0; // Alpha shift ignored
|
|
160
|
+
pfd.cAccumBits = (BYTE) (hints->AccumRedBits +
|
|
161
|
+
hints->AccumGreenBits +
|
|
162
|
+
hints->AccumBlueBits +
|
|
163
|
+
hints->AccumAlphaBits); // Accum. bits
|
|
164
|
+
pfd.cAccumRedBits = (BYTE) hints->AccumRedBits; // Accum. red bits
|
|
165
|
+
pfd.cAccumGreenBits = (BYTE) hints->AccumGreenBits; // Accum. green bits
|
|
166
|
+
pfd.cAccumBlueBits = (BYTE) hints->AccumBlueBits; // Accum. blue bits
|
|
167
|
+
pfd.cAccumAlphaBits = (BYTE) hints->AccumAlphaBits; // Accum. alpha bits
|
|
168
|
+
pfd.cDepthBits = (BYTE) depthbits; // Depth buffer bits
|
|
169
|
+
pfd.cStencilBits = (BYTE) stencilbits; // Stencil buffer bits
|
|
170
|
+
pfd.cAuxBuffers = (BYTE) hints->AuxBuffers; // No. of aux buffers
|
|
171
|
+
pfd.iLayerType = PFD_MAIN_PLANE; // Drawing layer: main
|
|
172
|
+
pfd.bReserved = 0; // (reserved)
|
|
173
|
+
pfd.dwLayerMask = 0; // Ignored
|
|
174
|
+
pfd.dwVisibleMask = 0; // "
|
|
175
|
+
pfd.dwDamageMask = 0; // "
|
|
176
|
+
|
|
177
|
+
if( depthbits <= 0 )
|
|
178
|
+
{
|
|
179
|
+
// We do not need a depth buffer
|
|
180
|
+
pfd.dwFlags |= PFD_DEPTH_DONTCARE;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if( hints->Stereo )
|
|
184
|
+
{
|
|
185
|
+
// Request a stereo mode
|
|
186
|
+
pfd.dwFlags |= PFD_STEREO;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Find a matching pixel format
|
|
190
|
+
PixelFormat = _glfw_ChoosePixelFormat( _glfwWin.DC, &pfd );
|
|
191
|
+
if( !PixelFormat )
|
|
192
|
+
{
|
|
193
|
+
return GL_FALSE;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Get actual pixel format description
|
|
197
|
+
if( !_glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat, sizeof(pfd), &pfd ) )
|
|
198
|
+
{
|
|
199
|
+
return GL_FALSE;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// "stereo" is a strict requirement
|
|
203
|
+
if( hints->Stereo && !(pfd.dwFlags & PFD_STEREO) )
|
|
204
|
+
{
|
|
205
|
+
return GL_FALSE;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Set the pixel-format
|
|
209
|
+
if( !_glfw_SetPixelFormat( _glfwWin.DC, PixelFormat, &pfd ) )
|
|
210
|
+
{
|
|
211
|
+
return GL_FALSE;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return GL_TRUE;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
//========================================================================
|
|
219
|
+
// Sets the device context pixel format using attributes
|
|
220
|
+
//========================================================================
|
|
221
|
+
|
|
222
|
+
#define _glfwSetWGLAttribute( _glfwName, _glfwValue ) \
|
|
223
|
+
attribs[ count++ ] = _glfwName; \
|
|
224
|
+
attribs[ count++ ] = _glfwValue;
|
|
225
|
+
|
|
226
|
+
static int _glfwSetPixelFormatAttrib( int redbits, int greenbits, int bluebits,
|
|
227
|
+
int alphabits, int depthbits, int stencilbits,
|
|
228
|
+
int mode, _GLFWhints* hints )
|
|
229
|
+
{
|
|
230
|
+
int PixelFormat, dummy, count = 0;
|
|
231
|
+
int attribs[128];
|
|
232
|
+
PIXELFORMATDESCRIPTOR pfd;
|
|
233
|
+
|
|
234
|
+
int accumredbits = hints->AccumRedBits;
|
|
235
|
+
int accumgreenbits = hints->AccumGreenBits;
|
|
236
|
+
int accumbluebits = hints->AccumBlueBits;
|
|
237
|
+
int accumalphabits = hints->AccumAlphaBits;
|
|
238
|
+
|
|
239
|
+
_glfwSetWGLAttribute( WGL_DRAW_TO_WINDOW_ARB, GL_TRUE );
|
|
240
|
+
_glfwSetWGLAttribute( WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB );
|
|
241
|
+
_glfwSetWGLAttribute( WGL_SUPPORT_OPENGL_ARB, GL_TRUE );
|
|
242
|
+
_glfwSetWGLAttribute( WGL_DOUBLE_BUFFER_ARB, GL_TRUE );
|
|
243
|
+
_glfwSetWGLAttribute( WGL_COLOR_BITS_ARB, redbits + greenbits + bluebits );
|
|
244
|
+
_glfwSetWGLAttribute( WGL_RED_BITS_ARB, redbits );
|
|
245
|
+
_glfwSetWGLAttribute( WGL_GREEN_BITS_ARB, greenbits );
|
|
246
|
+
_glfwSetWGLAttribute( WGL_BLUE_BITS_ARB, bluebits );
|
|
247
|
+
_glfwSetWGLAttribute( WGL_ALPHA_BITS_ARB, alphabits );
|
|
248
|
+
_glfwSetWGLAttribute( WGL_DEPTH_BITS_ARB, depthbits );
|
|
249
|
+
_glfwSetWGLAttribute( WGL_STENCIL_BITS_ARB, stencilbits );
|
|
250
|
+
_glfwSetWGLAttribute( WGL_AUX_BUFFERS_ARB, hints->AuxBuffers );
|
|
251
|
+
|
|
252
|
+
if( accumredbits || accumgreenbits || accumbluebits || accumalphabits )
|
|
253
|
+
{
|
|
254
|
+
_glfwSetWGLAttribute( WGL_ACCUM_BITS_ARB, accumredbits +
|
|
255
|
+
accumgreenbits +
|
|
256
|
+
accumbluebits +
|
|
257
|
+
accumalphabits );
|
|
258
|
+
|
|
259
|
+
_glfwSetWGLAttribute( WGL_ACCUM_RED_BITS_ARB, accumredbits );
|
|
260
|
+
_glfwSetWGLAttribute( WGL_ACCUM_GREEN_BITS_ARB, accumgreenbits );
|
|
261
|
+
_glfwSetWGLAttribute( WGL_ACCUM_BLUE_BITS_ARB, accumbluebits );
|
|
262
|
+
_glfwSetWGLAttribute( WGL_ACCUM_ALPHA_BITS_ARB, accumalphabits );
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if( hints->Stereo )
|
|
266
|
+
{
|
|
267
|
+
_glfwSetWGLAttribute( WGL_STEREO_ARB, GL_TRUE );
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if( hints->Samples > 0 )
|
|
271
|
+
{
|
|
272
|
+
_glfwSetWGLAttribute( WGL_SAMPLE_BUFFERS_ARB, 1 );
|
|
273
|
+
_glfwSetWGLAttribute( WGL_SAMPLES_ARB, hints->Samples );
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
_glfwSetWGLAttribute( 0, 0 );
|
|
277
|
+
|
|
278
|
+
if( !_glfwWin.ChoosePixelFormat( _glfwWin.DC, attribs, NULL, 1, &PixelFormat, &dummy ) )
|
|
279
|
+
{
|
|
280
|
+
return GL_FALSE;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if( !_glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat, sizeof(pfd), &pfd ) )
|
|
284
|
+
{
|
|
285
|
+
return GL_FALSE;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Set the pixel-format
|
|
289
|
+
if( !_glfw_SetPixelFormat( _glfwWin.DC, PixelFormat, &pfd ) )
|
|
290
|
+
{
|
|
291
|
+
return GL_FALSE;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return GL_TRUE;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
#undef _glfwSetWGLAttribute
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
//========================================================================
|
|
301
|
+
// Translates a Windows key to the corresponding GLFW key
|
|
302
|
+
//========================================================================
|
|
303
|
+
|
|
304
|
+
static int _glfwTranslateKey( WPARAM wParam, LPARAM lParam )
|
|
305
|
+
{
|
|
306
|
+
MSG next_msg;
|
|
307
|
+
DWORD msg_time;
|
|
308
|
+
DWORD scan_code;
|
|
309
|
+
|
|
310
|
+
// Check which key was pressed or released
|
|
311
|
+
switch( wParam )
|
|
312
|
+
{
|
|
313
|
+
// The SHIFT keys require special handling
|
|
314
|
+
case VK_SHIFT:
|
|
315
|
+
// Compare scan code for this key with that of VK_RSHIFT in
|
|
316
|
+
// order to determine which shift key was pressed (left or
|
|
317
|
+
// right)
|
|
318
|
+
scan_code = MapVirtualKey( VK_RSHIFT, 0 );
|
|
319
|
+
if( ((lParam & 0x01ff0000) >> 16) == scan_code )
|
|
320
|
+
{
|
|
321
|
+
return GLFW_KEY_RSHIFT;
|
|
322
|
+
}
|
|
323
|
+
return GLFW_KEY_LSHIFT;
|
|
324
|
+
|
|
325
|
+
// The CTRL keys require special handling
|
|
326
|
+
case VK_CONTROL:
|
|
327
|
+
// Is this an extended key (i.e. right key)?
|
|
328
|
+
if( lParam & 0x01000000 )
|
|
329
|
+
{
|
|
330
|
+
return GLFW_KEY_RCTRL;
|
|
331
|
+
}
|
|
332
|
+
// Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only
|
|
333
|
+
// want the RALT message, so we try to see if the next message
|
|
334
|
+
// is a RALT message. In that case, this is a false LCTRL!
|
|
335
|
+
msg_time = GetMessageTime();
|
|
336
|
+
if( PeekMessage( &next_msg, NULL, 0, 0, PM_NOREMOVE ) )
|
|
337
|
+
{
|
|
338
|
+
if( next_msg.message == WM_KEYDOWN ||
|
|
339
|
+
next_msg.message == WM_SYSKEYDOWN )
|
|
340
|
+
{
|
|
341
|
+
if( next_msg.wParam == VK_MENU &&
|
|
342
|
+
(next_msg.lParam & 0x01000000) &&
|
|
343
|
+
next_msg.time == msg_time )
|
|
344
|
+
{
|
|
345
|
+
// Next message is a RALT down message, which
|
|
346
|
+
// means that this is NOT a proper LCTRL message!
|
|
347
|
+
return GLFW_KEY_UNKNOWN;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return GLFW_KEY_LCTRL;
|
|
352
|
+
|
|
353
|
+
// The ALT keys require special handling
|
|
354
|
+
case VK_MENU:
|
|
355
|
+
// Is this an extended key (i.e. right key)?
|
|
356
|
+
if( lParam & 0x01000000 )
|
|
357
|
+
{
|
|
358
|
+
return GLFW_KEY_RALT;
|
|
359
|
+
}
|
|
360
|
+
return GLFW_KEY_LALT;
|
|
361
|
+
|
|
362
|
+
// The ENTER keys require special handling
|
|
363
|
+
case VK_RETURN:
|
|
364
|
+
// Is this an extended key (i.e. right key)?
|
|
365
|
+
if( lParam & 0x01000000 )
|
|
366
|
+
{
|
|
367
|
+
return GLFW_KEY_KP_ENTER;
|
|
368
|
+
}
|
|
369
|
+
return GLFW_KEY_ENTER;
|
|
370
|
+
|
|
371
|
+
// Special keys (non character keys)
|
|
372
|
+
case VK_ESCAPE: return GLFW_KEY_ESC;
|
|
373
|
+
case VK_TAB: return GLFW_KEY_TAB;
|
|
374
|
+
case VK_BACK: return GLFW_KEY_BACKSPACE;
|
|
375
|
+
case VK_HOME: return GLFW_KEY_HOME;
|
|
376
|
+
case VK_END: return GLFW_KEY_END;
|
|
377
|
+
case VK_PRIOR: return GLFW_KEY_PAGEUP;
|
|
378
|
+
case VK_NEXT: return GLFW_KEY_PAGEDOWN;
|
|
379
|
+
case VK_INSERT: return GLFW_KEY_INSERT;
|
|
380
|
+
case VK_DELETE: return GLFW_KEY_DEL;
|
|
381
|
+
case VK_LEFT: return GLFW_KEY_LEFT;
|
|
382
|
+
case VK_UP: return GLFW_KEY_UP;
|
|
383
|
+
case VK_RIGHT: return GLFW_KEY_RIGHT;
|
|
384
|
+
case VK_DOWN: return GLFW_KEY_DOWN;
|
|
385
|
+
case VK_F1: return GLFW_KEY_F1;
|
|
386
|
+
case VK_F2: return GLFW_KEY_F2;
|
|
387
|
+
case VK_F3: return GLFW_KEY_F3;
|
|
388
|
+
case VK_F4: return GLFW_KEY_F4;
|
|
389
|
+
case VK_F5: return GLFW_KEY_F5;
|
|
390
|
+
case VK_F6: return GLFW_KEY_F6;
|
|
391
|
+
case VK_F7: return GLFW_KEY_F7;
|
|
392
|
+
case VK_F8: return GLFW_KEY_F8;
|
|
393
|
+
case VK_F9: return GLFW_KEY_F9;
|
|
394
|
+
case VK_F10: return GLFW_KEY_F10;
|
|
395
|
+
case VK_F11: return GLFW_KEY_F11;
|
|
396
|
+
case VK_F12: return GLFW_KEY_F12;
|
|
397
|
+
case VK_F13: return GLFW_KEY_F13;
|
|
398
|
+
case VK_F14: return GLFW_KEY_F14;
|
|
399
|
+
case VK_F15: return GLFW_KEY_F15;
|
|
400
|
+
case VK_F16: return GLFW_KEY_F16;
|
|
401
|
+
case VK_F17: return GLFW_KEY_F17;
|
|
402
|
+
case VK_F18: return GLFW_KEY_F18;
|
|
403
|
+
case VK_F19: return GLFW_KEY_F19;
|
|
404
|
+
case VK_F20: return GLFW_KEY_F20;
|
|
405
|
+
case VK_F21: return GLFW_KEY_F21;
|
|
406
|
+
case VK_F22: return GLFW_KEY_F22;
|
|
407
|
+
case VK_F23: return GLFW_KEY_F23;
|
|
408
|
+
case VK_F24: return GLFW_KEY_F24;
|
|
409
|
+
case VK_SPACE: return GLFW_KEY_SPACE;
|
|
410
|
+
|
|
411
|
+
// Numeric keypad
|
|
412
|
+
case VK_NUMPAD0: return GLFW_KEY_KP_0;
|
|
413
|
+
case VK_NUMPAD1: return GLFW_KEY_KP_1;
|
|
414
|
+
case VK_NUMPAD2: return GLFW_KEY_KP_2;
|
|
415
|
+
case VK_NUMPAD3: return GLFW_KEY_KP_3;
|
|
416
|
+
case VK_NUMPAD4: return GLFW_KEY_KP_4;
|
|
417
|
+
case VK_NUMPAD5: return GLFW_KEY_KP_5;
|
|
418
|
+
case VK_NUMPAD6: return GLFW_KEY_KP_6;
|
|
419
|
+
case VK_NUMPAD7: return GLFW_KEY_KP_7;
|
|
420
|
+
case VK_NUMPAD8: return GLFW_KEY_KP_8;
|
|
421
|
+
case VK_NUMPAD9: return GLFW_KEY_KP_9;
|
|
422
|
+
case VK_DIVIDE: return GLFW_KEY_KP_DIVIDE;
|
|
423
|
+
case VK_MULTIPLY: return GLFW_KEY_KP_MULTIPLY;
|
|
424
|
+
case VK_SUBTRACT: return GLFW_KEY_KP_SUBTRACT;
|
|
425
|
+
case VK_ADD: return GLFW_KEY_KP_ADD;
|
|
426
|
+
case VK_DECIMAL: return GLFW_KEY_KP_DECIMAL;
|
|
427
|
+
|
|
428
|
+
// The rest (should be printable keys)
|
|
429
|
+
default:
|
|
430
|
+
// Convert to printable character (ISO-8859-1 or Unicode)
|
|
431
|
+
wParam = MapVirtualKey( (UINT) wParam, 2 ) & 0x0000FFFF;
|
|
432
|
+
|
|
433
|
+
// Make sure that the character is uppercase
|
|
434
|
+
if( _glfwLibrary.Sys.HasUnicode )
|
|
435
|
+
{
|
|
436
|
+
wParam = (WPARAM) CharUpperW( (LPWSTR) wParam );
|
|
437
|
+
}
|
|
438
|
+
else
|
|
439
|
+
{
|
|
440
|
+
wParam = (WPARAM) CharUpperA( (LPSTR) wParam );
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Valid ISO-8859-1 character?
|
|
444
|
+
if( (wParam >= 32 && wParam <= 126) ||
|
|
445
|
+
(wParam >= 160 && wParam <= 255) )
|
|
446
|
+
{
|
|
447
|
+
return (int) wParam;
|
|
448
|
+
}
|
|
449
|
+
return GLFW_KEY_UNKNOWN;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
//========================================================================
|
|
455
|
+
// Translates a windows key to Unicode
|
|
456
|
+
//========================================================================
|
|
457
|
+
|
|
458
|
+
static void _glfwTranslateChar( DWORD wParam, DWORD lParam, int action )
|
|
459
|
+
{
|
|
460
|
+
BYTE keyboard_state[ 256 ];
|
|
461
|
+
UCHAR char_buf[ 10 ];
|
|
462
|
+
WCHAR unicode_buf[ 10 ];
|
|
463
|
+
UINT scan_code;
|
|
464
|
+
int i, num_chars, unicode;
|
|
465
|
+
|
|
466
|
+
// Get keyboard state
|
|
467
|
+
GetKeyboardState( keyboard_state );
|
|
468
|
+
|
|
469
|
+
// Derive scan code from lParam and action
|
|
470
|
+
scan_code = (lParam & 0x01ff0000) >> 16;
|
|
471
|
+
if( action == GLFW_RELEASE )
|
|
472
|
+
{
|
|
473
|
+
scan_code |= 0x8000000;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Do we have Unicode support?
|
|
477
|
+
if( _glfwLibrary.Sys.HasUnicode )
|
|
478
|
+
{
|
|
479
|
+
// Convert to Unicode
|
|
480
|
+
num_chars = ToUnicode(
|
|
481
|
+
wParam, // virtual-key code
|
|
482
|
+
scan_code, // scan code
|
|
483
|
+
keyboard_state, // key-state array
|
|
484
|
+
unicode_buf, // buffer for translated key
|
|
485
|
+
10, // size of translated key buffer
|
|
486
|
+
0 // active-menu flag
|
|
487
|
+
);
|
|
488
|
+
unicode = 1;
|
|
489
|
+
}
|
|
490
|
+
else
|
|
491
|
+
{
|
|
492
|
+
// Convert to ISO-8859-1
|
|
493
|
+
num_chars = ToAscii(
|
|
494
|
+
wParam, // virtual-key code
|
|
495
|
+
scan_code, // scan code
|
|
496
|
+
keyboard_state, // key-state array
|
|
497
|
+
(LPWORD) char_buf, // buffer for translated key
|
|
498
|
+
0 // active-menu flag
|
|
499
|
+
);
|
|
500
|
+
unicode = 0;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Report characters
|
|
504
|
+
for( i = 0; i < num_chars; i++ )
|
|
505
|
+
{
|
|
506
|
+
// Get next character from buffer
|
|
507
|
+
if( unicode )
|
|
508
|
+
{
|
|
509
|
+
_glfwInputChar( (int) unicode_buf[ i ], action );
|
|
510
|
+
}
|
|
511
|
+
else
|
|
512
|
+
{
|
|
513
|
+
_glfwInputChar( (int) char_buf[ i ], action );
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
//========================================================================
|
|
520
|
+
// Window callback function (handles window events)
|
|
521
|
+
//========================================================================
|
|
522
|
+
|
|
523
|
+
static LRESULT CALLBACK _glfwWindowCallback( HWND hWnd, UINT uMsg,
|
|
524
|
+
WPARAM wParam, LPARAM lParam )
|
|
525
|
+
{
|
|
526
|
+
int WheelDelta, Iconified;
|
|
527
|
+
|
|
528
|
+
// Handle certain window messages
|
|
529
|
+
switch( uMsg )
|
|
530
|
+
{
|
|
531
|
+
// Window activate message? (iconification?)
|
|
532
|
+
case WM_ACTIVATE:
|
|
533
|
+
{
|
|
534
|
+
_glfwWin.Active = LOWORD(wParam) != WA_INACTIVE ? GL_TRUE : GL_FALSE;
|
|
535
|
+
|
|
536
|
+
Iconified = HIWORD(wParam) ? GL_TRUE : GL_FALSE;
|
|
537
|
+
|
|
538
|
+
// Were we deactivated/iconified?
|
|
539
|
+
if( (!_glfwWin.Active || Iconified) && !_glfwWin.Iconified )
|
|
540
|
+
{
|
|
541
|
+
_glfwInputDeactivation();
|
|
542
|
+
|
|
543
|
+
// If we are in fullscreen mode we need to iconify
|
|
544
|
+
if( _glfwWin.Opened && _glfwWin.Fullscreen )
|
|
545
|
+
{
|
|
546
|
+
// Do we need to manually iconify?
|
|
547
|
+
if( !Iconified )
|
|
548
|
+
{
|
|
549
|
+
// Minimize window
|
|
550
|
+
CloseWindow( _glfwWin.Wnd );
|
|
551
|
+
|
|
552
|
+
// The window is now iconified
|
|
553
|
+
Iconified = GL_TRUE;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Change display settings to the desktop resolution
|
|
557
|
+
ChangeDisplaySettings( NULL, CDS_FULLSCREEN );
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Unlock mouse
|
|
561
|
+
if( !_glfwWin.OldMouseLockValid )
|
|
562
|
+
{
|
|
563
|
+
_glfwWin.OldMouseLock = _glfwWin.MouseLock;
|
|
564
|
+
_glfwWin.OldMouseLockValid = GL_TRUE;
|
|
565
|
+
glfwEnable( GLFW_MOUSE_CURSOR );
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
else if( _glfwWin.Active || !Iconified )
|
|
569
|
+
{
|
|
570
|
+
// If we are in fullscreen mode we need to maximize
|
|
571
|
+
if( _glfwWin.Opened && _glfwWin.Fullscreen && _glfwWin.Iconified )
|
|
572
|
+
{
|
|
573
|
+
// Change display settings to the user selected mode
|
|
574
|
+
_glfwSetVideoModeMODE( _glfwWin.ModeID );
|
|
575
|
+
|
|
576
|
+
// Do we need to manually restore window?
|
|
577
|
+
if( Iconified )
|
|
578
|
+
{
|
|
579
|
+
// Restore window
|
|
580
|
+
OpenIcon( _glfwWin.Wnd );
|
|
581
|
+
|
|
582
|
+
// The window is no longer iconified
|
|
583
|
+
Iconified = GL_FALSE;
|
|
584
|
+
|
|
585
|
+
// Activate window
|
|
586
|
+
ShowWindow( hWnd, SW_SHOW );
|
|
587
|
+
_glfwSetForegroundWindow( _glfwWin.Wnd );
|
|
588
|
+
SetFocus( _glfwWin.Wnd );
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Lock mouse, if necessary
|
|
593
|
+
if( _glfwWin.OldMouseLockValid && _glfwWin.OldMouseLock )
|
|
594
|
+
{
|
|
595
|
+
glfwDisable( GLFW_MOUSE_CURSOR );
|
|
596
|
+
}
|
|
597
|
+
_glfwWin.OldMouseLockValid = GL_FALSE;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
_glfwWin.Iconified = Iconified;
|
|
601
|
+
return 0;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Intercept system commands (forbid certain actions/events)
|
|
605
|
+
case WM_SYSCOMMAND:
|
|
606
|
+
{
|
|
607
|
+
switch( wParam )
|
|
608
|
+
{
|
|
609
|
+
// Screensaver trying to start or monitor trying to enter
|
|
610
|
+
// powersave?
|
|
611
|
+
case SC_SCREENSAVE:
|
|
612
|
+
case SC_MONITORPOWER:
|
|
613
|
+
if( _glfwWin.Fullscreen )
|
|
614
|
+
{
|
|
615
|
+
return 0;
|
|
616
|
+
}
|
|
617
|
+
else
|
|
618
|
+
{
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// User trying to access application menu using ALT?
|
|
623
|
+
case SC_KEYMENU:
|
|
624
|
+
return 0;
|
|
625
|
+
}
|
|
626
|
+
break;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Did we receive a close message?
|
|
630
|
+
case WM_CLOSE:
|
|
631
|
+
PostQuitMessage( 0 );
|
|
632
|
+
return 0;
|
|
633
|
+
|
|
634
|
+
// Is a key being pressed?
|
|
635
|
+
case WM_KEYDOWN:
|
|
636
|
+
case WM_SYSKEYDOWN:
|
|
637
|
+
{
|
|
638
|
+
// Translate and report key press
|
|
639
|
+
_glfwInputKey( _glfwTranslateKey( wParam, lParam ),
|
|
640
|
+
GLFW_PRESS );
|
|
641
|
+
|
|
642
|
+
// Translate and report character input
|
|
643
|
+
if( _glfwWin.CharCallback )
|
|
644
|
+
{
|
|
645
|
+
_glfwTranslateChar( (DWORD) wParam, (DWORD) lParam, GLFW_PRESS );
|
|
646
|
+
}
|
|
647
|
+
return 0;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Is a key being released?
|
|
651
|
+
case WM_KEYUP:
|
|
652
|
+
case WM_SYSKEYUP:
|
|
653
|
+
{
|
|
654
|
+
// Special trick: release both shift keys on SHIFT up event
|
|
655
|
+
if( wParam == VK_SHIFT )
|
|
656
|
+
{
|
|
657
|
+
_glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE );
|
|
658
|
+
_glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE );
|
|
659
|
+
}
|
|
660
|
+
else
|
|
661
|
+
{
|
|
662
|
+
// Translate and report key release
|
|
663
|
+
_glfwInputKey( _glfwTranslateKey( wParam, lParam ),
|
|
664
|
+
GLFW_RELEASE );
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Translate and report character input
|
|
668
|
+
if( _glfwWin.CharCallback )
|
|
669
|
+
{
|
|
670
|
+
_glfwTranslateChar( (DWORD) wParam, (DWORD) lParam, GLFW_RELEASE );
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
return 0;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Were any of the mouse-buttons pressed?
|
|
677
|
+
case WM_LBUTTONDOWN:
|
|
678
|
+
SetCapture(hWnd);
|
|
679
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );
|
|
680
|
+
return 0;
|
|
681
|
+
case WM_RBUTTONDOWN:
|
|
682
|
+
SetCapture(hWnd);
|
|
683
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );
|
|
684
|
+
return 0;
|
|
685
|
+
case WM_MBUTTONDOWN:
|
|
686
|
+
SetCapture(hWnd);
|
|
687
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS );
|
|
688
|
+
return 0;
|
|
689
|
+
case WM_XBUTTONDOWN:
|
|
690
|
+
{
|
|
691
|
+
if( HIWORD(wParam) == XBUTTON1 )
|
|
692
|
+
{
|
|
693
|
+
SetCapture(hWnd);
|
|
694
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_PRESS );
|
|
695
|
+
}
|
|
696
|
+
else if( HIWORD(wParam) == XBUTTON2 )
|
|
697
|
+
{
|
|
698
|
+
SetCapture(hWnd);
|
|
699
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_PRESS );
|
|
700
|
+
}
|
|
701
|
+
return 1;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// Were any of the mouse-buttons released?
|
|
705
|
+
case WM_LBUTTONUP:
|
|
706
|
+
ReleaseCapture();
|
|
707
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE );
|
|
708
|
+
return 0;
|
|
709
|
+
case WM_RBUTTONUP:
|
|
710
|
+
ReleaseCapture();
|
|
711
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE );
|
|
712
|
+
return 0;
|
|
713
|
+
case WM_MBUTTONUP:
|
|
714
|
+
ReleaseCapture();
|
|
715
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE );
|
|
716
|
+
return 0;
|
|
717
|
+
case WM_XBUTTONUP:
|
|
718
|
+
{
|
|
719
|
+
if( HIWORD(wParam) == XBUTTON1 )
|
|
720
|
+
{
|
|
721
|
+
ReleaseCapture();
|
|
722
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_RELEASE );
|
|
723
|
+
}
|
|
724
|
+
else if( HIWORD(wParam) == XBUTTON2 )
|
|
725
|
+
{
|
|
726
|
+
ReleaseCapture();
|
|
727
|
+
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_RELEASE );
|
|
728
|
+
}
|
|
729
|
+
return 1;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// Did the mouse move?
|
|
733
|
+
case WM_MOUSEMOVE:
|
|
734
|
+
{
|
|
735
|
+
{
|
|
736
|
+
int NewMouseX, NewMouseY;
|
|
737
|
+
|
|
738
|
+
// Get signed (!) mouse position
|
|
739
|
+
NewMouseX = (int)((short)LOWORD(lParam));
|
|
740
|
+
NewMouseY = (int)((short)HIWORD(lParam));
|
|
741
|
+
|
|
742
|
+
if( NewMouseX != _glfwInput.OldMouseX ||
|
|
743
|
+
NewMouseY != _glfwInput.OldMouseY )
|
|
744
|
+
{
|
|
745
|
+
if( _glfwWin.MouseLock )
|
|
746
|
+
{
|
|
747
|
+
_glfwInput.MousePosX += NewMouseX -
|
|
748
|
+
_glfwInput.OldMouseX;
|
|
749
|
+
_glfwInput.MousePosY += NewMouseY -
|
|
750
|
+
_glfwInput.OldMouseY;
|
|
751
|
+
}
|
|
752
|
+
else
|
|
753
|
+
{
|
|
754
|
+
_glfwInput.MousePosX = NewMouseX;
|
|
755
|
+
_glfwInput.MousePosY = NewMouseY;
|
|
756
|
+
}
|
|
757
|
+
_glfwInput.OldMouseX = NewMouseX;
|
|
758
|
+
_glfwInput.OldMouseY = NewMouseY;
|
|
759
|
+
_glfwInput.MouseMoved = GL_TRUE;
|
|
760
|
+
|
|
761
|
+
// Call user callback function
|
|
762
|
+
if( _glfwWin.MousePosCallback )
|
|
763
|
+
{
|
|
764
|
+
_glfwWin.MousePosCallback( _glfwInput.MousePosX,
|
|
765
|
+
_glfwInput.MousePosY );
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return 0;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// Mouse wheel action?
|
|
773
|
+
case WM_MOUSEWHEEL:
|
|
774
|
+
{
|
|
775
|
+
// WM_MOUSEWHEEL is not supported under Windows 95
|
|
776
|
+
if( _glfwLibrary.Sys.WinVer != _GLFW_WIN_95 )
|
|
777
|
+
{
|
|
778
|
+
WheelDelta = (((int)wParam) >> 16) / WHEEL_DELTA;
|
|
779
|
+
_glfwInput.WheelPos += WheelDelta;
|
|
780
|
+
if( _glfwWin.MouseWheelCallback )
|
|
781
|
+
{
|
|
782
|
+
_glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
|
|
783
|
+
}
|
|
784
|
+
return 0;
|
|
785
|
+
}
|
|
786
|
+
break;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// Resize the window?
|
|
790
|
+
case WM_SIZE:
|
|
791
|
+
{
|
|
792
|
+
// get the new size
|
|
793
|
+
_glfwWin.Width = LOWORD(lParam);
|
|
794
|
+
_glfwWin.Height = HIWORD(lParam);
|
|
795
|
+
|
|
796
|
+
// If the mouse is locked, update the clipping rect
|
|
797
|
+
if( _glfwWin.MouseLock )
|
|
798
|
+
{
|
|
799
|
+
RECT ClipWindowRect;
|
|
800
|
+
if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) )
|
|
801
|
+
{
|
|
802
|
+
ClipCursor( &ClipWindowRect );
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// Call the user-supplied callback, if it exists
|
|
807
|
+
if( _glfwWin.WindowSizeCallback )
|
|
808
|
+
{
|
|
809
|
+
_glfwWin.WindowSizeCallback( LOWORD(lParam),
|
|
810
|
+
HIWORD(lParam) );
|
|
811
|
+
}
|
|
812
|
+
return 0;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// Move the window?
|
|
816
|
+
case WM_MOVE:
|
|
817
|
+
{
|
|
818
|
+
// If the mouse is locked, update the clipping rect
|
|
819
|
+
if( _glfwWin.MouseLock )
|
|
820
|
+
{
|
|
821
|
+
RECT ClipWindowRect;
|
|
822
|
+
if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) )
|
|
823
|
+
{
|
|
824
|
+
ClipCursor( &ClipWindowRect );
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
return 0;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// Was the window contents damaged?
|
|
831
|
+
case WM_PAINT:
|
|
832
|
+
{
|
|
833
|
+
// Call user callback function
|
|
834
|
+
if( _glfwWin.WindowRefreshCallback )
|
|
835
|
+
{
|
|
836
|
+
_glfwWin.WindowRefreshCallback();
|
|
837
|
+
}
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
case WM_DISPLAYCHANGE:
|
|
842
|
+
{
|
|
843
|
+
// TODO: Do stuff here.
|
|
844
|
+
|
|
845
|
+
break;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// Pass all unhandled messages to DefWindowProc
|
|
850
|
+
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
//========================================================================
|
|
855
|
+
// Translate client window size to full window size (including window borders)
|
|
856
|
+
//========================================================================
|
|
857
|
+
|
|
858
|
+
static void _glfwGetFullWindowSize( int w, int h, int *w2, int *h2 )
|
|
859
|
+
{
|
|
860
|
+
RECT rect;
|
|
861
|
+
|
|
862
|
+
// Create a window rectangle
|
|
863
|
+
rect.left = (long)0;
|
|
864
|
+
rect.right = (long)w-1;
|
|
865
|
+
rect.top = (long)0;
|
|
866
|
+
rect.bottom = (long)h-1;
|
|
867
|
+
|
|
868
|
+
// Adjust according to window styles
|
|
869
|
+
AdjustWindowRectEx( &rect, _glfwWin.dwStyle, FALSE,
|
|
870
|
+
_glfwWin.dwExStyle );
|
|
871
|
+
|
|
872
|
+
// Calculate width and height of full window
|
|
873
|
+
*w2 = rect.right-rect.left+1;
|
|
874
|
+
*h2 = rect.bottom-rect.top+1;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
//========================================================================
|
|
879
|
+
// Initialize WGL-specific extensions
|
|
880
|
+
//========================================================================
|
|
881
|
+
|
|
882
|
+
static void _glfwInitWGLExtensions( void )
|
|
883
|
+
{
|
|
884
|
+
GLubyte *extensions;
|
|
885
|
+
int has_swap_control, has_pixel_format;
|
|
886
|
+
|
|
887
|
+
_glfwWin.GetExtensionsStringEXT = (WGLGETEXTENSIONSSTRINGEXT_T)
|
|
888
|
+
wglGetProcAddress( "wglGetExtensionsStringEXT" );
|
|
889
|
+
if( !_glfwWin.GetExtensionsStringEXT )
|
|
890
|
+
{
|
|
891
|
+
// Try wglGetExtensionsStringARB
|
|
892
|
+
_glfwWin.GetExtensionsStringARB = (WGLGETEXTENSIONSSTRINGARB_T)
|
|
893
|
+
wglGetProcAddress( "wglGetExtensionsStringARB" );
|
|
894
|
+
if( !_glfwWin.GetExtensionsStringARB )
|
|
895
|
+
{
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
// Initialize OpenGL extension: WGL_EXT_swap_control
|
|
901
|
+
has_swap_control = GL_FALSE;
|
|
902
|
+
has_pixel_format = GL_FALSE;
|
|
903
|
+
extensions = (GLubyte *) glGetString( GL_EXTENSIONS );
|
|
904
|
+
|
|
905
|
+
if( extensions != NULL )
|
|
906
|
+
{
|
|
907
|
+
has_swap_control = _glfwStringInExtensionString(
|
|
908
|
+
"WGL_EXT_swap_control",
|
|
909
|
+
extensions
|
|
910
|
+
);
|
|
911
|
+
has_pixel_format = _glfwStringInExtensionString(
|
|
912
|
+
"WGL_ARB_pixel_format",
|
|
913
|
+
extensions
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
if( !has_swap_control )
|
|
918
|
+
{
|
|
919
|
+
has_swap_control = _glfwPlatformExtensionSupported(
|
|
920
|
+
"WGL_EXT_swap_control"
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
if( !has_pixel_format )
|
|
925
|
+
{
|
|
926
|
+
has_pixel_format = _glfwPlatformExtensionSupported(
|
|
927
|
+
"WGL_ARB_pixel_format"
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
if( has_swap_control )
|
|
932
|
+
{
|
|
933
|
+
_glfwWin.SwapInterval = (WGLSWAPINTERVALEXT_T)
|
|
934
|
+
wglGetProcAddress( "wglSwapIntervalEXT" );
|
|
935
|
+
}
|
|
936
|
+
else
|
|
937
|
+
{
|
|
938
|
+
_glfwWin.SwapInterval = NULL;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
if( has_pixel_format )
|
|
942
|
+
{
|
|
943
|
+
_glfwWin.ChoosePixelFormat = (WGLCHOOSEPIXELFORMATARB_T)
|
|
944
|
+
wglGetProcAddress( "wglChoosePixelFormatARB" );
|
|
945
|
+
_glfwWin.GetPixelFormatAttribiv = (WGLGETPIXELFORMATATTRIBIVARB_T)
|
|
946
|
+
wglGetProcAddress( "wglGetPixelFormatAttribivARB" );
|
|
947
|
+
}
|
|
948
|
+
else
|
|
949
|
+
{
|
|
950
|
+
_glfwWin.ChoosePixelFormat = NULL;
|
|
951
|
+
_glfwWin.GetPixelFormatAttribiv = NULL;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
//========================================================================
|
|
957
|
+
// Creates the GLFW window and rendering context
|
|
958
|
+
//========================================================================
|
|
959
|
+
|
|
960
|
+
static int _glfwCreateWindow( int redbits, int greenbits, int bluebits,
|
|
961
|
+
int alphabits, int depthbits, int stencilbits,
|
|
962
|
+
int mode, _GLFWhints* hints )
|
|
963
|
+
{
|
|
964
|
+
int full_width, full_height;
|
|
965
|
+
RECT wa;
|
|
966
|
+
POINT pos;
|
|
967
|
+
|
|
968
|
+
_glfwWin.DC = NULL;
|
|
969
|
+
_glfwWin.RC = NULL;
|
|
970
|
+
_glfwWin.Wnd = NULL;
|
|
971
|
+
|
|
972
|
+
// Set window size to true requested size (adjust for window borders)
|
|
973
|
+
_glfwGetFullWindowSize( _glfwWin.Width, _glfwWin.Height, &full_width,
|
|
974
|
+
&full_height );
|
|
975
|
+
|
|
976
|
+
// Adjust window position to working area (e.g. if the task bar is at
|
|
977
|
+
// the top of the display). Fullscreen windows are always opened in
|
|
978
|
+
// the upper left corner regardless of the desktop working area.
|
|
979
|
+
if( _glfwWin.Fullscreen )
|
|
980
|
+
{
|
|
981
|
+
wa.left = wa.top = 0;
|
|
982
|
+
}
|
|
983
|
+
else
|
|
984
|
+
{
|
|
985
|
+
SystemParametersInfo( SPI_GETWORKAREA, 0, &wa, 0 );
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// Create window
|
|
989
|
+
_glfwWin.Wnd = CreateWindowEx(
|
|
990
|
+
_glfwWin.dwExStyle, // Extended style
|
|
991
|
+
_GLFW_WNDCLASSNAME, // Class name
|
|
992
|
+
"GLFW Window", // Window title
|
|
993
|
+
_glfwWin.dwStyle, // Defined window style
|
|
994
|
+
wa.left, wa.top, // Window position
|
|
995
|
+
full_width, // Decorated window width
|
|
996
|
+
full_height, // Decorated window height
|
|
997
|
+
NULL, // No parent window
|
|
998
|
+
NULL, // No menu
|
|
999
|
+
_glfwLibrary.Instance, // Instance
|
|
1000
|
+
NULL ); // Nothing to WM_CREATE
|
|
1001
|
+
|
|
1002
|
+
if( !_glfwWin.Wnd )
|
|
1003
|
+
{
|
|
1004
|
+
return GL_FALSE;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// Get a device context
|
|
1008
|
+
_glfwWin.DC = GetDC( _glfwWin.Wnd );
|
|
1009
|
+
if( !_glfwWin.DC )
|
|
1010
|
+
{
|
|
1011
|
+
return GL_FALSE;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
if( _glfwWin.ChoosePixelFormat )
|
|
1015
|
+
{
|
|
1016
|
+
if( !_glfwSetPixelFormatAttrib( redbits, greenbits, bluebits, alphabits,
|
|
1017
|
+
depthbits, stencilbits, mode, hints ) )
|
|
1018
|
+
{
|
|
1019
|
+
return GL_FALSE;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
else
|
|
1023
|
+
{
|
|
1024
|
+
if( !_glfwSetPixelFormatPFD( redbits, greenbits, bluebits, alphabits,
|
|
1025
|
+
depthbits, stencilbits, mode, hints ) )
|
|
1026
|
+
{
|
|
1027
|
+
return GL_FALSE;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// Get a rendering context
|
|
1032
|
+
_glfwWin.RC = wglCreateContext( _glfwWin.DC );
|
|
1033
|
+
if( !_glfwWin.RC )
|
|
1034
|
+
{
|
|
1035
|
+
return GL_FALSE;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// Activate the OpenGL rendering context
|
|
1039
|
+
if( !wglMakeCurrent( _glfwWin.DC, _glfwWin.RC ) )
|
|
1040
|
+
{
|
|
1041
|
+
return GL_FALSE;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
// Initialize WGL-specific OpenGL extensions
|
|
1045
|
+
_glfwInitWGLExtensions();
|
|
1046
|
+
|
|
1047
|
+
// Initialize mouse position
|
|
1048
|
+
GetCursorPos( &pos );
|
|
1049
|
+
ScreenToClient( _glfwWin.Wnd, &pos );
|
|
1050
|
+
_glfwInput.OldMouseX = _glfwInput.MousePosX = pos.x;
|
|
1051
|
+
_glfwInput.OldMouseY = _glfwInput.MousePosY = pos.y;
|
|
1052
|
+
|
|
1053
|
+
return GL_TRUE;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
//========================================================================
|
|
1058
|
+
// Destroys the GLFW window and rendering context
|
|
1059
|
+
//========================================================================
|
|
1060
|
+
|
|
1061
|
+
static void _glfwDestroyWindow( void )
|
|
1062
|
+
{
|
|
1063
|
+
// Do we have a rendering context?
|
|
1064
|
+
if( _glfwWin.RC )
|
|
1065
|
+
{
|
|
1066
|
+
// Release the DC and RC contexts
|
|
1067
|
+
wglMakeCurrent( NULL, NULL );
|
|
1068
|
+
|
|
1069
|
+
// Delete the rendering context
|
|
1070
|
+
wglDeleteContext( _glfwWin.RC );
|
|
1071
|
+
_glfwWin.RC = NULL;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// Do we have a device context?
|
|
1075
|
+
if( _glfwWin.DC )
|
|
1076
|
+
{
|
|
1077
|
+
// Release the device context
|
|
1078
|
+
ReleaseDC( _glfwWin.Wnd, _glfwWin.DC );
|
|
1079
|
+
_glfwWin.DC = NULL;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
// Do we have a window?
|
|
1083
|
+
if( _glfwWin.Wnd )
|
|
1084
|
+
{
|
|
1085
|
+
// Destroy the window
|
|
1086
|
+
if( _glfwLibrary.Sys.WinVer <= _GLFW_WIN_NT4 )
|
|
1087
|
+
{
|
|
1088
|
+
// Note: Hiding the window first fixes an annoying W98/NT4
|
|
1089
|
+
// remaining icon bug for fullscreen displays
|
|
1090
|
+
ShowWindow( _glfwWin.Wnd, SW_HIDE );
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
DestroyWindow( _glfwWin.Wnd );
|
|
1094
|
+
_glfwWin.Wnd = NULL;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
//************************************************************************
|
|
1101
|
+
//**** Platform implementation functions ****
|
|
1102
|
+
//************************************************************************
|
|
1103
|
+
|
|
1104
|
+
//========================================================================
|
|
1105
|
+
// Here is where the window is created, and the OpenGL rendering context is
|
|
1106
|
+
// created
|
|
1107
|
+
//========================================================================
|
|
1108
|
+
|
|
1109
|
+
int _glfwPlatformOpenWindow( int width, int height,
|
|
1110
|
+
int redbits, int greenbits, int bluebits,
|
|
1111
|
+
int alphabits, int depthbits, int stencilbits,
|
|
1112
|
+
int mode, _GLFWhints* hints )
|
|
1113
|
+
{
|
|
1114
|
+
WNDCLASS wc;
|
|
1115
|
+
DWORD dwStyle, dwExStyle;
|
|
1116
|
+
|
|
1117
|
+
// Clear platform specific GLFW window state
|
|
1118
|
+
_glfwWin.ClassAtom = 0;
|
|
1119
|
+
_glfwWin.OldMouseLockValid = GL_FALSE;
|
|
1120
|
+
_glfwWin.ChoosePixelFormat = NULL;
|
|
1121
|
+
_glfwWin.GetPixelFormatAttribiv = NULL;
|
|
1122
|
+
|
|
1123
|
+
// Remember desired refresh rate for this window (used only in
|
|
1124
|
+
// fullscreen mode)
|
|
1125
|
+
_glfwWin.DesiredRefreshRate = hints->RefreshRate;
|
|
1126
|
+
|
|
1127
|
+
// Set window class parameters
|
|
1128
|
+
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on...
|
|
1129
|
+
wc.lpfnWndProc = (WNDPROC)_glfwWindowCallback; // Message handler
|
|
1130
|
+
wc.cbClsExtra = 0; // No extra class data
|
|
1131
|
+
wc.cbWndExtra = 0; // No extra window data
|
|
1132
|
+
wc.hInstance = _glfwLibrary.Instance; // Set instance
|
|
1133
|
+
wc.hCursor = LoadCursor( NULL, IDC_ARROW ); // Load arrow pointer
|
|
1134
|
+
wc.hbrBackground = NULL; // No background
|
|
1135
|
+
wc.lpszMenuName = NULL; // No menu
|
|
1136
|
+
wc.lpszClassName = _GLFW_WNDCLASSNAME; // Set class name
|
|
1137
|
+
|
|
1138
|
+
// Load user-provided icon if available
|
|
1139
|
+
wc.hIcon = LoadIcon( _glfwLibrary.Instance, "GLFW_ICON" );
|
|
1140
|
+
if( !wc.hIcon )
|
|
1141
|
+
{
|
|
1142
|
+
// Load default icon
|
|
1143
|
+
wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// Register the window class
|
|
1147
|
+
_glfwWin.ClassAtom = RegisterClass( &wc );
|
|
1148
|
+
if( !_glfwWin.ClassAtom )
|
|
1149
|
+
{
|
|
1150
|
+
_glfwPlatformCloseWindow();
|
|
1151
|
+
return GL_FALSE;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// Do we want full-screen mode?
|
|
1155
|
+
if( _glfwWin.Fullscreen )
|
|
1156
|
+
{
|
|
1157
|
+
_glfwSetVideoMode( &_glfwWin.Width, &_glfwWin.Height,
|
|
1158
|
+
redbits, greenbits, bluebits,
|
|
1159
|
+
hints->RefreshRate );
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// Set common window styles
|
|
1163
|
+
dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
|
|
1164
|
+
dwExStyle = WS_EX_APPWINDOW;
|
|
1165
|
+
|
|
1166
|
+
// Set window style, depending on fullscreen mode
|
|
1167
|
+
if( _glfwWin.Fullscreen )
|
|
1168
|
+
{
|
|
1169
|
+
dwStyle |= WS_POPUP;
|
|
1170
|
+
|
|
1171
|
+
// Here's a trick for helping us getting window focus
|
|
1172
|
+
// (SetForegroundWindow doesn't work properly under
|
|
1173
|
+
// Win98/ME/2K/.NET/+)
|
|
1174
|
+
/*
|
|
1175
|
+
if( _glfwLibrary.Sys.WinVer != _GLFW_WIN_95 &&
|
|
1176
|
+
_glfwLibrary.Sys.WinVer != _GLFW_WIN_NT4 &&
|
|
1177
|
+
_glfwLibrary.Sys.WinVer != _GLFW_WIN_XP )
|
|
1178
|
+
{
|
|
1179
|
+
dwStyle |= WS_MINIMIZE;
|
|
1180
|
+
}
|
|
1181
|
+
*/
|
|
1182
|
+
}
|
|
1183
|
+
else
|
|
1184
|
+
{
|
|
1185
|
+
dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
|
1186
|
+
|
|
1187
|
+
if( !hints->WindowNoResize )
|
|
1188
|
+
{
|
|
1189
|
+
dwStyle |= ( WS_MAXIMIZEBOX | WS_SIZEBOX );
|
|
1190
|
+
dwExStyle |= WS_EX_WINDOWEDGE;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
// Remember window styles (used by _glfwGetFullWindowSize)
|
|
1195
|
+
_glfwWin.dwStyle = dwStyle;
|
|
1196
|
+
_glfwWin.dwExStyle = dwExStyle;
|
|
1197
|
+
|
|
1198
|
+
if( !_glfwCreateWindow( redbits, greenbits, bluebits, alphabits,
|
|
1199
|
+
depthbits, stencilbits, mode, hints ) )
|
|
1200
|
+
{
|
|
1201
|
+
_glfwPlatformCloseWindow();
|
|
1202
|
+
return GL_FALSE;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
if( _glfwWin.ChoosePixelFormat && hints->Samples > 0 )
|
|
1206
|
+
{
|
|
1207
|
+
// Iteratively try to create a context with a decreasing number of
|
|
1208
|
+
// FSAA samples (requires window recreation).
|
|
1209
|
+
|
|
1210
|
+
for (;;)
|
|
1211
|
+
{
|
|
1212
|
+
_glfwDestroyWindow();
|
|
1213
|
+
|
|
1214
|
+
if( _glfwCreateWindow( redbits, greenbits, bluebits, alphabits,
|
|
1215
|
+
depthbits, stencilbits, mode, hints ) )
|
|
1216
|
+
{
|
|
1217
|
+
break;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
if( hints->Samples > 0 )
|
|
1221
|
+
{
|
|
1222
|
+
hints->Samples--;
|
|
1223
|
+
}
|
|
1224
|
+
else
|
|
1225
|
+
{
|
|
1226
|
+
_glfwPlatformCloseWindow();
|
|
1227
|
+
return GL_FALSE;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// Make sure that our window ends up on top of things
|
|
1233
|
+
if( _glfwWin.Fullscreen )
|
|
1234
|
+
{
|
|
1235
|
+
// Place the window above all topmost windows
|
|
1236
|
+
SetWindowPos( _glfwWin.Wnd, HWND_TOPMOST, 0,0,0,0,
|
|
1237
|
+
SWP_NOMOVE | SWP_NOSIZE );
|
|
1238
|
+
}
|
|
1239
|
+
_glfwSetForegroundWindow( _glfwWin.Wnd );
|
|
1240
|
+
SetFocus( _glfwWin.Wnd );
|
|
1241
|
+
|
|
1242
|
+
// Start by clearing the front buffer to black (avoid ugly desktop
|
|
1243
|
+
// remains in our OpenGL window)
|
|
1244
|
+
glClear( GL_COLOR_BUFFER_BIT );
|
|
1245
|
+
_glfw_SwapBuffers( _glfwWin.DC );
|
|
1246
|
+
|
|
1247
|
+
return GL_TRUE;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
//========================================================================
|
|
1252
|
+
// Properly kill the window / video display
|
|
1253
|
+
//========================================================================
|
|
1254
|
+
|
|
1255
|
+
void _glfwPlatformCloseWindow( void )
|
|
1256
|
+
{
|
|
1257
|
+
_glfwDestroyWindow();
|
|
1258
|
+
|
|
1259
|
+
// Do we have an instance?
|
|
1260
|
+
if( _glfwWin.ClassAtom )
|
|
1261
|
+
{
|
|
1262
|
+
// Unregister class
|
|
1263
|
+
UnregisterClass( _GLFW_WNDCLASSNAME, _glfwLibrary.Instance );
|
|
1264
|
+
_glfwWin.ClassAtom = 0;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// Are we in fullscreen mode?
|
|
1268
|
+
if( _glfwWin.Fullscreen )
|
|
1269
|
+
{
|
|
1270
|
+
// Switch back to desktop resolution
|
|
1271
|
+
ChangeDisplaySettings( NULL, CDS_FULLSCREEN );
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
|
|
1276
|
+
//========================================================================
|
|
1277
|
+
// Set the window title
|
|
1278
|
+
//========================================================================
|
|
1279
|
+
|
|
1280
|
+
void _glfwPlatformSetWindowTitle( const char *title )
|
|
1281
|
+
{
|
|
1282
|
+
// Set window title
|
|
1283
|
+
(void) SetWindowText( _glfwWin.Wnd, title );
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
//========================================================================
|
|
1288
|
+
// Set the window size.
|
|
1289
|
+
//========================================================================
|
|
1290
|
+
|
|
1291
|
+
void _glfwPlatformSetWindowSize( int width, int height )
|
|
1292
|
+
{
|
|
1293
|
+
int bpp, mode = 0, refresh;
|
|
1294
|
+
int sizechanged = GL_FALSE;
|
|
1295
|
+
GLint drawbuffer;
|
|
1296
|
+
GLfloat clearcolor[4];
|
|
1297
|
+
|
|
1298
|
+
// If we are in fullscreen mode, get some info about the current mode
|
|
1299
|
+
if( _glfwWin.Fullscreen )
|
|
1300
|
+
{
|
|
1301
|
+
DEVMODE dm;
|
|
1302
|
+
|
|
1303
|
+
// Get current BPP settings
|
|
1304
|
+
dm.dmSize = sizeof( DEVMODE );
|
|
1305
|
+
if( EnumDisplaySettings( NULL, _glfwWin.ModeID, &dm ) )
|
|
1306
|
+
{
|
|
1307
|
+
// Get bpp
|
|
1308
|
+
bpp = dm.dmBitsPerPel;
|
|
1309
|
+
|
|
1310
|
+
// Get closest match for target video mode
|
|
1311
|
+
refresh = _glfwWin.DesiredRefreshRate;
|
|
1312
|
+
mode = _glfwGetClosestVideoModeBPP( &width, &height, &bpp,
|
|
1313
|
+
&refresh );
|
|
1314
|
+
}
|
|
1315
|
+
else
|
|
1316
|
+
{
|
|
1317
|
+
mode = _glfwWin.ModeID;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
else
|
|
1321
|
+
{
|
|
1322
|
+
// If we are in windowed mode, adjust the window size to
|
|
1323
|
+
// compensate for window decorations
|
|
1324
|
+
_glfwGetFullWindowSize( width, height, &width, &height );
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
// Change window size before changing fullscreen mode?
|
|
1328
|
+
if( _glfwWin.Fullscreen && (width > _glfwWin.Width) )
|
|
1329
|
+
{
|
|
1330
|
+
SetWindowPos( _glfwWin.Wnd, HWND_TOP, 0, 0, width, height,
|
|
1331
|
+
SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER );
|
|
1332
|
+
sizechanged = GL_TRUE;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
// Change fullscreen video mode?
|
|
1336
|
+
if( _glfwWin.Fullscreen && mode != _glfwWin.ModeID )
|
|
1337
|
+
{
|
|
1338
|
+
// Change video mode
|
|
1339
|
+
_glfwSetVideoModeMODE( mode );
|
|
1340
|
+
|
|
1341
|
+
// Clear the front buffer to black (avoid ugly desktop remains in
|
|
1342
|
+
// our OpenGL window)
|
|
1343
|
+
glGetIntegerv( GL_DRAW_BUFFER, &drawbuffer );
|
|
1344
|
+
glGetFloatv( GL_COLOR_CLEAR_VALUE, clearcolor );
|
|
1345
|
+
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
|
|
1346
|
+
glClear( GL_COLOR_BUFFER_BIT );
|
|
1347
|
+
if( drawbuffer == GL_BACK )
|
|
1348
|
+
{
|
|
1349
|
+
_glfw_SwapBuffers( _glfwWin.DC );
|
|
1350
|
+
}
|
|
1351
|
+
glClearColor( clearcolor[0], clearcolor[1], clearcolor[2],
|
|
1352
|
+
clearcolor[3] );
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
// Set window size (if not already changed)
|
|
1356
|
+
if( !sizechanged )
|
|
1357
|
+
{
|
|
1358
|
+
SetWindowPos( _glfwWin.Wnd, HWND_TOP, 0, 0, width, height,
|
|
1359
|
+
SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER );
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
|
|
1364
|
+
//========================================================================
|
|
1365
|
+
// Set the window position
|
|
1366
|
+
//========================================================================
|
|
1367
|
+
|
|
1368
|
+
void _glfwPlatformSetWindowPos( int x, int y )
|
|
1369
|
+
{
|
|
1370
|
+
// Set window position
|
|
1371
|
+
(void) SetWindowPos( _glfwWin.Wnd, HWND_TOP, x, y, 0, 0,
|
|
1372
|
+
SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER );
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
|
|
1376
|
+
//========================================================================
|
|
1377
|
+
// Window iconification
|
|
1378
|
+
//========================================================================
|
|
1379
|
+
|
|
1380
|
+
void _glfwPlatformIconifyWindow( void )
|
|
1381
|
+
{
|
|
1382
|
+
// Iconify window
|
|
1383
|
+
CloseWindow( _glfwWin.Wnd );
|
|
1384
|
+
|
|
1385
|
+
// Window is now iconified
|
|
1386
|
+
_glfwWin.Iconified = GL_TRUE;
|
|
1387
|
+
|
|
1388
|
+
// If we are in fullscreen mode we need to change video modes
|
|
1389
|
+
if( _glfwWin.Fullscreen )
|
|
1390
|
+
{
|
|
1391
|
+
// Change display settings to the desktop resolution
|
|
1392
|
+
ChangeDisplaySettings( NULL, CDS_FULLSCREEN );
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
// Unlock mouse
|
|
1396
|
+
if( !_glfwWin.OldMouseLockValid )
|
|
1397
|
+
{
|
|
1398
|
+
_glfwWin.OldMouseLock = _glfwWin.MouseLock;
|
|
1399
|
+
_glfwWin.OldMouseLockValid = GL_TRUE;
|
|
1400
|
+
glfwEnable( GLFW_MOUSE_CURSOR );
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
//========================================================================
|
|
1406
|
+
// Window un-iconification
|
|
1407
|
+
//========================================================================
|
|
1408
|
+
|
|
1409
|
+
void _glfwPlatformRestoreWindow( void )
|
|
1410
|
+
{
|
|
1411
|
+
// If we are in fullscreen mode we need to change video modes
|
|
1412
|
+
if( _glfwWin.Fullscreen )
|
|
1413
|
+
{
|
|
1414
|
+
// Change display settings to the user selected mode
|
|
1415
|
+
_glfwSetVideoModeMODE( _glfwWin.ModeID );
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
// Un-iconify window
|
|
1419
|
+
OpenIcon( _glfwWin.Wnd );
|
|
1420
|
+
|
|
1421
|
+
// Make sure that our window ends up on top of things
|
|
1422
|
+
ShowWindow( _glfwWin.Wnd, SW_SHOW );
|
|
1423
|
+
_glfwSetForegroundWindow( _glfwWin.Wnd );
|
|
1424
|
+
SetFocus( _glfwWin.Wnd );
|
|
1425
|
+
|
|
1426
|
+
// Window is no longer iconified
|
|
1427
|
+
_glfwWin.Iconified = GL_FALSE;
|
|
1428
|
+
|
|
1429
|
+
// Lock mouse, if necessary
|
|
1430
|
+
if( _glfwWin.OldMouseLockValid && _glfwWin.OldMouseLock )
|
|
1431
|
+
{
|
|
1432
|
+
glfwDisable( GLFW_MOUSE_CURSOR );
|
|
1433
|
+
}
|
|
1434
|
+
_glfwWin.OldMouseLockValid = GL_FALSE;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
//========================================================================
|
|
1439
|
+
// Swap buffers (double-buffering)
|
|
1440
|
+
//========================================================================
|
|
1441
|
+
|
|
1442
|
+
void _glfwPlatformSwapBuffers( void )
|
|
1443
|
+
{
|
|
1444
|
+
_glfw_SwapBuffers( _glfwWin.DC );
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
//========================================================================
|
|
1449
|
+
// Set double buffering swap interval
|
|
1450
|
+
//========================================================================
|
|
1451
|
+
|
|
1452
|
+
void _glfwPlatformSwapInterval( int interval )
|
|
1453
|
+
{
|
|
1454
|
+
if( _glfwWin.SwapInterval )
|
|
1455
|
+
{
|
|
1456
|
+
_glfwWin.SwapInterval( interval );
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
|
|
1461
|
+
//========================================================================
|
|
1462
|
+
// Write back window parameters into GLFW window structure
|
|
1463
|
+
//========================================================================
|
|
1464
|
+
|
|
1465
|
+
void _glfwPlatformRefreshWindowParams( void )
|
|
1466
|
+
{
|
|
1467
|
+
PIXELFORMATDESCRIPTOR pfd;
|
|
1468
|
+
DEVMODE dm;
|
|
1469
|
+
int PixelFormat, mode;
|
|
1470
|
+
|
|
1471
|
+
// Obtain a detailed description of current pixel format
|
|
1472
|
+
PixelFormat = _glfw_GetPixelFormat( _glfwWin.DC );
|
|
1473
|
+
|
|
1474
|
+
if( !_glfwWin.GetPixelFormatAttribiv )
|
|
1475
|
+
{
|
|
1476
|
+
_glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat,
|
|
1477
|
+
sizeof(PIXELFORMATDESCRIPTOR), &pfd );
|
|
1478
|
+
|
|
1479
|
+
// Is current OpenGL context accelerated?
|
|
1480
|
+
_glfwWin.Accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||
|
|
1481
|
+
!(pfd.dwFlags & PFD_GENERIC_FORMAT) ? 1 : 0;
|
|
1482
|
+
|
|
1483
|
+
// "Standard" window parameters
|
|
1484
|
+
_glfwWin.RedBits = pfd.cRedBits;
|
|
1485
|
+
_glfwWin.GreenBits = pfd.cGreenBits;
|
|
1486
|
+
_glfwWin.BlueBits = pfd.cBlueBits;
|
|
1487
|
+
_glfwWin.AlphaBits = pfd.cAlphaBits;
|
|
1488
|
+
_glfwWin.DepthBits = pfd.cDepthBits;
|
|
1489
|
+
_glfwWin.StencilBits = pfd.cStencilBits;
|
|
1490
|
+
_glfwWin.AccumRedBits = pfd.cAccumRedBits;
|
|
1491
|
+
_glfwWin.AccumGreenBits = pfd.cAccumGreenBits;
|
|
1492
|
+
_glfwWin.AccumBlueBits = pfd.cAccumBlueBits;
|
|
1493
|
+
_glfwWin.AccumAlphaBits = pfd.cAccumAlphaBits;
|
|
1494
|
+
_glfwWin.AuxBuffers = pfd.cAuxBuffers;
|
|
1495
|
+
_glfwWin.Stereo = pfd.dwFlags & PFD_STEREO ? 1 : 0;
|
|
1496
|
+
_glfwWin.Samples = 0;
|
|
1497
|
+
}
|
|
1498
|
+
else
|
|
1499
|
+
{
|
|
1500
|
+
const int attribs[] = {
|
|
1501
|
+
WGL_ACCELERATION_ARB,
|
|
1502
|
+
WGL_RED_BITS_ARB,
|
|
1503
|
+
WGL_GREEN_BITS_ARB,
|
|
1504
|
+
WGL_BLUE_BITS_ARB,
|
|
1505
|
+
WGL_ALPHA_BITS_ARB,
|
|
1506
|
+
WGL_DEPTH_BITS_ARB,
|
|
1507
|
+
WGL_STENCIL_BITS_ARB,
|
|
1508
|
+
WGL_ACCUM_RED_BITS_ARB,
|
|
1509
|
+
WGL_ACCUM_GREEN_BITS_ARB,
|
|
1510
|
+
WGL_ACCUM_BLUE_BITS_ARB,
|
|
1511
|
+
WGL_ACCUM_ALPHA_BITS_ARB,
|
|
1512
|
+
WGL_AUX_BUFFERS_ARB,
|
|
1513
|
+
WGL_STEREO_ARB,
|
|
1514
|
+
WGL_SAMPLES_ARB
|
|
1515
|
+
};
|
|
1516
|
+
|
|
1517
|
+
int values[sizeof(attribs) / sizeof(attribs[0])];
|
|
1518
|
+
|
|
1519
|
+
_glfwWin.GetPixelFormatAttribiv( _glfwWin.DC, PixelFormat, 0,
|
|
1520
|
+
sizeof(attribs) / sizeof(attribs[0]),
|
|
1521
|
+
attribs, values);
|
|
1522
|
+
|
|
1523
|
+
// Is current OpenGL context accelerated?
|
|
1524
|
+
_glfwWin.Accelerated = (values[0] == WGL_FULL_ACCELERATION_ARB);
|
|
1525
|
+
|
|
1526
|
+
// "Standard" window parameters
|
|
1527
|
+
_glfwWin.RedBits = values[1];
|
|
1528
|
+
_glfwWin.GreenBits = values[2];
|
|
1529
|
+
_glfwWin.BlueBits = values[3];
|
|
1530
|
+
_glfwWin.AlphaBits = values[4];
|
|
1531
|
+
_glfwWin.DepthBits = values[5];
|
|
1532
|
+
_glfwWin.StencilBits = values[6];
|
|
1533
|
+
_glfwWin.AccumRedBits = values[7];
|
|
1534
|
+
_glfwWin.AccumGreenBits = values[8];
|
|
1535
|
+
_glfwWin.AccumBlueBits = values[9];
|
|
1536
|
+
_glfwWin.AccumAlphaBits = values[10];
|
|
1537
|
+
_glfwWin.AuxBuffers = values[11];
|
|
1538
|
+
_glfwWin.Stereo = values[12];
|
|
1539
|
+
_glfwWin.Samples = values[13];
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
// Get refresh rate
|
|
1543
|
+
mode = _glfwWin.Fullscreen ? _glfwWin.ModeID : ENUM_CURRENT_SETTINGS;
|
|
1544
|
+
dm.dmSize = sizeof( DEVMODE );
|
|
1545
|
+
|
|
1546
|
+
if( EnumDisplaySettings( NULL, mode, &dm ) )
|
|
1547
|
+
{
|
|
1548
|
+
_glfwWin.RefreshRate = dm.dmDisplayFrequency;
|
|
1549
|
+
if( _glfwWin.RefreshRate <= 1 )
|
|
1550
|
+
{
|
|
1551
|
+
_glfwWin.RefreshRate = 0;
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
else
|
|
1555
|
+
{
|
|
1556
|
+
_glfwWin.RefreshRate = 0;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
|
|
1561
|
+
//========================================================================
|
|
1562
|
+
// Poll for new window and input events
|
|
1563
|
+
//========================================================================
|
|
1564
|
+
|
|
1565
|
+
void _glfwPlatformPollEvents( void )
|
|
1566
|
+
{
|
|
1567
|
+
MSG msg;
|
|
1568
|
+
int winclosed = GL_FALSE;
|
|
1569
|
+
|
|
1570
|
+
// Flag: mouse was not moved (will be changed by _glfwGetNextEvent if
|
|
1571
|
+
// there was a mouse move event)
|
|
1572
|
+
_glfwInput.MouseMoved = GL_FALSE;
|
|
1573
|
+
if( _glfwWin.MouseLock )
|
|
1574
|
+
{
|
|
1575
|
+
_glfwInput.OldMouseX = _glfwWin.Width/2;
|
|
1576
|
+
_glfwInput.OldMouseY = _glfwWin.Height/2;
|
|
1577
|
+
}
|
|
1578
|
+
else
|
|
1579
|
+
{
|
|
1580
|
+
_glfwInput.OldMouseX = _glfwInput.MousePosX;
|
|
1581
|
+
_glfwInput.OldMouseY = _glfwInput.MousePosY;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
// Check for new window messages
|
|
1585
|
+
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
|
|
1586
|
+
{
|
|
1587
|
+
switch( msg.message )
|
|
1588
|
+
{
|
|
1589
|
+
// QUIT-message (from close window)?
|
|
1590
|
+
case WM_QUIT:
|
|
1591
|
+
winclosed = GL_TRUE;
|
|
1592
|
+
break;
|
|
1593
|
+
|
|
1594
|
+
// Ok, send it to the window message handler
|
|
1595
|
+
default:
|
|
1596
|
+
DispatchMessage( &msg );
|
|
1597
|
+
break;
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
// LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)
|
|
1602
|
+
// This is the only async event handling in GLFW, but it solves some
|
|
1603
|
+
// nasty problems.
|
|
1604
|
+
// Caveat: Does not work under Win 9x/ME.
|
|
1605
|
+
if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 )
|
|
1606
|
+
{
|
|
1607
|
+
int lshift_down, rshift_down;
|
|
1608
|
+
|
|
1609
|
+
// Get current state of left and right shift keys
|
|
1610
|
+
lshift_down = (GetAsyncKeyState( VK_LSHIFT ) >> 15) & 1;
|
|
1611
|
+
rshift_down = (GetAsyncKeyState( VK_RSHIFT ) >> 15) & 1;
|
|
1612
|
+
|
|
1613
|
+
// See if this differs from our belief of what has happened
|
|
1614
|
+
// (we only have to check for lost key up events)
|
|
1615
|
+
if( !lshift_down && _glfwInput.Key[ GLFW_KEY_LSHIFT ] == 1 )
|
|
1616
|
+
{
|
|
1617
|
+
_glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE );
|
|
1618
|
+
}
|
|
1619
|
+
if( !rshift_down && _glfwInput.Key[ GLFW_KEY_RSHIFT ] == 1 )
|
|
1620
|
+
{
|
|
1621
|
+
_glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE );
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
// Did we have mouse movement in locked cursor mode?
|
|
1626
|
+
if( _glfwInput.MouseMoved && _glfwWin.MouseLock )
|
|
1627
|
+
{
|
|
1628
|
+
_glfwPlatformSetMouseCursorPos( _glfwWin.Width / 2,
|
|
1629
|
+
_glfwWin.Height / 2 );
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
// Was there a window close request?
|
|
1633
|
+
if( winclosed && _glfwWin.WindowCloseCallback )
|
|
1634
|
+
{
|
|
1635
|
+
// Check if the program wants us to close the window
|
|
1636
|
+
winclosed = _glfwWin.WindowCloseCallback();
|
|
1637
|
+
}
|
|
1638
|
+
if( winclosed )
|
|
1639
|
+
{
|
|
1640
|
+
glfwCloseWindow();
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
|
|
1645
|
+
//========================================================================
|
|
1646
|
+
// _glfwPlatformWaitEvents() - Wait for new window and input events
|
|
1647
|
+
//========================================================================
|
|
1648
|
+
|
|
1649
|
+
void _glfwPlatformWaitEvents( void )
|
|
1650
|
+
{
|
|
1651
|
+
// Wait for new events
|
|
1652
|
+
WaitMessage();
|
|
1653
|
+
|
|
1654
|
+
// Poll new events
|
|
1655
|
+
_glfwPlatformPollEvents();
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
|
|
1659
|
+
//========================================================================
|
|
1660
|
+
// Hide mouse cursor (lock it)
|
|
1661
|
+
//========================================================================
|
|
1662
|
+
|
|
1663
|
+
void _glfwPlatformHideMouseCursor( void )
|
|
1664
|
+
{
|
|
1665
|
+
RECT ClipWindowRect;
|
|
1666
|
+
|
|
1667
|
+
// Hide cursor
|
|
1668
|
+
ShowCursor( FALSE );
|
|
1669
|
+
|
|
1670
|
+
// Clip cursor to the window
|
|
1671
|
+
if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) )
|
|
1672
|
+
{
|
|
1673
|
+
ClipCursor( &ClipWindowRect );
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
// Capture cursor to user window
|
|
1677
|
+
SetCapture( _glfwWin.Wnd );
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
|
|
1681
|
+
//========================================================================
|
|
1682
|
+
// Show mouse cursor (unlock it)
|
|
1683
|
+
//========================================================================
|
|
1684
|
+
|
|
1685
|
+
void _glfwPlatformShowMouseCursor( void )
|
|
1686
|
+
{
|
|
1687
|
+
// Un-capture cursor
|
|
1688
|
+
ReleaseCapture();
|
|
1689
|
+
|
|
1690
|
+
// Disable cursor clipping
|
|
1691
|
+
ClipCursor( NULL );
|
|
1692
|
+
|
|
1693
|
+
// Show cursor
|
|
1694
|
+
ShowCursor( TRUE );
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
|
|
1698
|
+
//========================================================================
|
|
1699
|
+
// Set physical mouse cursor position
|
|
1700
|
+
//========================================================================
|
|
1701
|
+
|
|
1702
|
+
void _glfwPlatformSetMouseCursorPos( int x, int y )
|
|
1703
|
+
{
|
|
1704
|
+
POINT pos;
|
|
1705
|
+
|
|
1706
|
+
// Convert client coordinates to screen coordinates
|
|
1707
|
+
pos.x = x;
|
|
1708
|
+
pos.y = y;
|
|
1709
|
+
ClientToScreen( _glfwWin.Wnd, &pos );
|
|
1710
|
+
|
|
1711
|
+
// Change cursor position
|
|
1712
|
+
SetCursorPos( pos.x, pos.y );
|
|
1713
|
+
}
|
|
1714
|
+
|