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.
Files changed (206) hide show
  1. data/README +1 -0
  2. data/README.API +73 -0
  3. data/Rakefile +120 -0
  4. data/examples/boing.rb +519 -0
  5. data/examples/gears.rb +327 -0
  6. data/examples/keytest.rb +117 -0
  7. data/examples/listmodes.rb +20 -0
  8. data/examples/mipmaps.rb +104 -0
  9. data/examples/mipmaps.tga +0 -0
  10. data/examples/particles.rb +837 -0
  11. data/examples/pong3d.rb +741 -0
  12. data/examples/pong3d_field.tga +0 -0
  13. data/examples/pong3d_instr.tga +0 -0
  14. data/examples/pong3d_menu.tga +0 -0
  15. data/examples/pong3d_title.tga +0 -0
  16. data/examples/pong3d_winner1.tga +0 -0
  17. data/examples/pong3d_winner2.tga +0 -0
  18. data/examples/splitview.rb +432 -0
  19. data/examples/triangle.rb +89 -0
  20. data/examples/wave.rb +294 -0
  21. data/ext/glfw/glfw.c +1094 -0
  22. data/ext/glfw/mkrf_conf.rb +70 -0
  23. data/glfw-src/Makefile +220 -0
  24. data/glfw-src/compile.ami +61 -0
  25. data/glfw-src/compile.bat +217 -0
  26. data/glfw-src/compile.sh +607 -0
  27. data/glfw-src/docs/Makefile +57 -0
  28. data/glfw-src/docs/Reference.pdf +0 -0
  29. data/glfw-src/docs/UsersGuide.pdf +0 -0
  30. data/glfw-src/docs/cleanup.bat +22 -0
  31. data/glfw-src/docs/glfwdoc.sty +80 -0
  32. data/glfw-src/docs/glfwrm.tex +3034 -0
  33. data/glfw-src/docs/glfwug.tex +2024 -0
  34. data/glfw-src/docs/readme.txt +80 -0
  35. data/glfw-src/examples/Makefile.amigaos.gcc +70 -0
  36. data/glfw-src/examples/Makefile.amigaos.vbcc +70 -0
  37. data/glfw-src/examples/Makefile.dos.djgpp +71 -0
  38. data/glfw-src/examples/Makefile.macosx.gcc +96 -0
  39. data/glfw-src/examples/Makefile.win32.bcc +75 -0
  40. data/glfw-src/examples/Makefile.win32.cross-mgw +79 -0
  41. data/glfw-src/examples/Makefile.win32.cygwin +79 -0
  42. data/glfw-src/examples/Makefile.win32.lcc +74 -0
  43. data/glfw-src/examples/Makefile.win32.mgw +75 -0
  44. data/glfw-src/examples/Makefile.win32.msvc +74 -0
  45. data/glfw-src/examples/Makefile.win32.ow +74 -0
  46. data/glfw-src/examples/Makefile.win32.pellesc +74 -0
  47. data/glfw-src/examples/Makefile.x11.in +54 -0
  48. data/glfw-src/examples/boing.c +606 -0
  49. data/glfw-src/examples/bundle.sh +46 -0
  50. data/glfw-src/examples/gears.c +382 -0
  51. data/glfw-src/examples/keytest.c +264 -0
  52. data/glfw-src/examples/listmodes.c +48 -0
  53. data/glfw-src/examples/mipmaps.c +126 -0
  54. data/glfw-src/examples/mipmaps.tga +0 -0
  55. data/glfw-src/examples/mtbench.c +301 -0
  56. data/glfw-src/examples/mthello.c +48 -0
  57. data/glfw-src/examples/particles.c +1148 -0
  58. data/glfw-src/examples/pong3d.c +839 -0
  59. data/glfw-src/examples/pong3d_field.tga +0 -0
  60. data/glfw-src/examples/pong3d_instr.tga +0 -0
  61. data/glfw-src/examples/pong3d_menu.tga +0 -0
  62. data/glfw-src/examples/pong3d_title.tga +0 -0
  63. data/glfw-src/examples/pong3d_winner1.tga +0 -0
  64. data/glfw-src/examples/pong3d_winner2.tga +0 -0
  65. data/glfw-src/examples/splitview.c +506 -0
  66. data/glfw-src/examples/triangle.c +108 -0
  67. data/glfw-src/examples/wave.c +397 -0
  68. data/glfw-src/images/opengl.gif +0 -0
  69. data/glfw-src/images/osicert.gif +0 -0
  70. data/glfw-src/include/GL/glfw.h +486 -0
  71. data/glfw-src/lib/amigaos/Makefile.amigaos.gcc +128 -0
  72. data/glfw-src/lib/amigaos/Makefile.amigaos.vbcc +128 -0
  73. data/glfw-src/lib/amigaos/SDI_compiler.h +94 -0
  74. data/glfw-src/lib/amigaos/amigaos_enable.c +51 -0
  75. data/glfw-src/lib/amigaos/amigaos_fullscreen.c +319 -0
  76. data/glfw-src/lib/amigaos/amigaos_glext.c +61 -0
  77. data/glfw-src/lib/amigaos/amigaos_init.c +284 -0
  78. data/glfw-src/lib/amigaos/amigaos_joystick.c +359 -0
  79. data/glfw-src/lib/amigaos/amigaos_thread.c +494 -0
  80. data/glfw-src/lib/amigaos/amigaos_time.c +206 -0
  81. data/glfw-src/lib/amigaos/amigaos_window.c +830 -0
  82. data/glfw-src/lib/amigaos/platform.h +337 -0
  83. data/glfw-src/lib/dos/Makefile.dos.djgpp +146 -0
  84. data/glfw-src/lib/dos/dos_enable.c +51 -0
  85. data/glfw-src/lib/dos/dos_events.c +173 -0
  86. data/glfw-src/lib/dos/dos_fullscreen.c +101 -0
  87. data/glfw-src/lib/dos/dos_glext.c +59 -0
  88. data/glfw-src/lib/dos/dos_init.c +105 -0
  89. data/glfw-src/lib/dos/dos_irq.s +246 -0
  90. data/glfw-src/lib/dos/dos_joystick.c +94 -0
  91. data/glfw-src/lib/dos/dos_keyboard.c +694 -0
  92. data/glfw-src/lib/dos/dos_mouse.c +337 -0
  93. data/glfw-src/lib/dos/dos_thread.c +267 -0
  94. data/glfw-src/lib/dos/dos_time.c +309 -0
  95. data/glfw-src/lib/dos/dos_window.c +563 -0
  96. data/glfw-src/lib/dos/platform.h +341 -0
  97. data/glfw-src/lib/enable.c +295 -0
  98. data/glfw-src/lib/fullscreen.c +95 -0
  99. data/glfw-src/lib/glext.c +201 -0
  100. data/glfw-src/lib/image.c +629 -0
  101. data/glfw-src/lib/init.c +108 -0
  102. data/glfw-src/lib/input.c +280 -0
  103. data/glfw-src/lib/internal.h +210 -0
  104. data/glfw-src/lib/joystick.c +101 -0
  105. data/glfw-src/lib/macosx/Makefile.macosx.gcc +172 -0
  106. data/glfw-src/lib/macosx/Makefile.macosx.gcc.universal +166 -0
  107. data/glfw-src/lib/macosx/libglfw.pc.in +11 -0
  108. data/glfw-src/lib/macosx/macosx_enable.c +42 -0
  109. data/glfw-src/lib/macosx/macosx_fullscreen.c +126 -0
  110. data/glfw-src/lib/macosx/macosx_glext.c +52 -0
  111. data/glfw-src/lib/macosx/macosx_init.c +194 -0
  112. data/glfw-src/lib/macosx/macosx_joystick.c +50 -0
  113. data/glfw-src/lib/macosx/macosx_thread.c +414 -0
  114. data/glfw-src/lib/macosx/macosx_time.c +112 -0
  115. data/glfw-src/lib/macosx/macosx_window.c +1279 -0
  116. data/glfw-src/lib/macosx/platform.h +349 -0
  117. data/glfw-src/lib/stream.c +194 -0
  118. data/glfw-src/lib/tga.c +405 -0
  119. data/glfw-src/lib/thread.c +340 -0
  120. data/glfw-src/lib/time.c +83 -0
  121. data/glfw-src/lib/win32/Makefile.win32.bcc +265 -0
  122. data/glfw-src/lib/win32/Makefile.win32.cross-mgw +274 -0
  123. data/glfw-src/lib/win32/Makefile.win32.cygwin +279 -0
  124. data/glfw-src/lib/win32/Makefile.win32.lcc +246 -0
  125. data/glfw-src/lib/win32/Makefile.win32.mgw +243 -0
  126. data/glfw-src/lib/win32/Makefile.win32.msvc +242 -0
  127. data/glfw-src/lib/win32/Makefile.win32.ow +242 -0
  128. data/glfw-src/lib/win32/Makefile.win32.pellesc +242 -0
  129. data/glfw-src/lib/win32/glfwdll.def +67 -0
  130. data/glfw-src/lib/win32/glfwdll_mgw1.def +67 -0
  131. data/glfw-src/lib/win32/glfwdll_mgw2.def +67 -0
  132. data/glfw-src/lib/win32/glfwdll_pellesc.def +65 -0
  133. data/glfw-src/lib/win32/libglfw.pc.in +11 -0
  134. data/glfw-src/lib/win32/platform.h +474 -0
  135. data/glfw-src/lib/win32/win32_dllmain.c +60 -0
  136. data/glfw-src/lib/win32/win32_enable.c +155 -0
  137. data/glfw-src/lib/win32/win32_fullscreen.c +317 -0
  138. data/glfw-src/lib/win32/win32_glext.c +85 -0
  139. data/glfw-src/lib/win32/win32_init.c +356 -0
  140. data/glfw-src/lib/win32/win32_joystick.c +234 -0
  141. data/glfw-src/lib/win32/win32_thread.c +511 -0
  142. data/glfw-src/lib/win32/win32_time.c +146 -0
  143. data/glfw-src/lib/win32/win32_window.c +1714 -0
  144. data/glfw-src/lib/window.c +727 -0
  145. data/glfw-src/lib/x11/Makefile.x11.in +243 -0
  146. data/glfw-src/lib/x11/platform.h +415 -0
  147. data/glfw-src/lib/x11/x11_enable.c +51 -0
  148. data/glfw-src/lib/x11/x11_fullscreen.c +524 -0
  149. data/glfw-src/lib/x11/x11_glext.c +69 -0
  150. data/glfw-src/lib/x11/x11_init.c +275 -0
  151. data/glfw-src/lib/x11/x11_joystick.c +371 -0
  152. data/glfw-src/lib/x11/x11_keysym2unicode.c +902 -0
  153. data/glfw-src/lib/x11/x11_thread.c +507 -0
  154. data/glfw-src/lib/x11/x11_time.c +154 -0
  155. data/glfw-src/lib/x11/x11_window.c +1746 -0
  156. data/glfw-src/license.txt +21 -0
  157. data/glfw-src/readme.html +927 -0
  158. data/glfw-src/support/d/examples/Makefile +59 -0
  159. data/glfw-src/support/d/examples/boing.d +610 -0
  160. data/glfw-src/support/d/examples/gears.d +379 -0
  161. data/glfw-src/support/d/examples/keytest.d +272 -0
  162. data/glfw-src/support/d/examples/listmodes.d +48 -0
  163. data/glfw-src/support/d/examples/mipmaps.d +126 -0
  164. data/glfw-src/support/d/examples/mtbench.d +304 -0
  165. data/glfw-src/support/d/examples/mthello.d +54 -0
  166. data/glfw-src/support/d/examples/particles.d +1150 -0
  167. data/glfw-src/support/d/examples/pong3d.d +840 -0
  168. data/glfw-src/support/d/examples/splitview.d +486 -0
  169. data/glfw-src/support/d/examples/triangle.d +108 -0
  170. data/glfw-src/support/d/examples/wave.d +400 -0
  171. data/glfw-src/support/d/imports/gl.d +4539 -0
  172. data/glfw-src/support/d/imports/glfw.d +349 -0
  173. data/glfw-src/support/d/imports/glu.d +328 -0
  174. data/glfw-src/support/d/lib/glfwdll.def +64 -0
  175. data/glfw-src/support/d/lib/glu32.def +56 -0
  176. data/glfw-src/support/d/lib/makefile +12 -0
  177. data/glfw-src/support/d/lib/opengl32.def +372 -0
  178. data/glfw-src/support/d/readme.html +83 -0
  179. data/glfw-src/support/delphi/examples/Triangle.dpr +105 -0
  180. data/glfw-src/support/delphi/lib/glfw.pas +437 -0
  181. data/glfw-src/support/delphi/readme.html +97 -0
  182. data/glfw-src/support/lua/examples/gears.lua +383 -0
  183. data/glfw-src/support/lua/examples/test1.lua +68 -0
  184. data/glfw-src/support/lua/readme.html +128 -0
  185. data/glfw-src/support/lua/src/luaglfw.c +1179 -0
  186. data/glfw-src/support/lua/src/luaglfw.h +48 -0
  187. data/glfw-src/support/lua/src/runlua.c +82 -0
  188. data/glfw-src/support/masm/examples/fpc.mac +47 -0
  189. data/glfw-src/support/masm/examples/makeit.bat +66 -0
  190. data/glfw-src/support/masm/examples/triangle.asm +232 -0
  191. data/glfw-src/support/masm/include/glfw.inc +326 -0
  192. data/glfw-src/support/masm/include/glu32.inc +55 -0
  193. data/glfw-src/support/masm/include/opengl32.inc +372 -0
  194. data/glfw-src/support/masm/lib/glfwdll.lib +0 -0
  195. data/glfw-src/support/masm/readme.html +170 -0
  196. data/glfw-src/support/msvc80/GLFW.sln +26 -0
  197. data/glfw-src/support/msvc80/GLFW.vcproj +257 -0
  198. data/glfw-src/support/msvc80/GLFWDLL.vcproj +287 -0
  199. data/glfw-src/support/visualbasic/bindings/glfw.bas +320 -0
  200. data/glfw-src/support/visualbasic/bindings/glu32.bas +284 -0
  201. data/glfw-src/support/visualbasic/bindings/opengl32.bas +999 -0
  202. data/glfw-src/support/visualbasic/examples/Triangle.bas +101 -0
  203. data/glfw-src/support/visualbasic/readme.html +164 -0
  204. data/website/index.html +84 -0
  205. data/website/style.css +110 -0
  206. 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
+