ruby-glfw 0.9

Sign up to get free protection for your applications and to get access to all the features.
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,154 @@
1
+ //========================================================================
2
+ // GLFW - An OpenGL framework
3
+ // File: x11_time.c
4
+ // Platform: X11 (Unix)
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
+ // Initialise timer
36
+ //========================================================================
37
+
38
+ void _glfwInitTimer( void )
39
+ {
40
+ struct timeval tv;
41
+
42
+ // "Resolution" is 1 us
43
+ _glfwLibrary.Timer.Resolution = 1e-6;
44
+
45
+ // Set start-time for timer
46
+ gettimeofday( &tv, NULL );
47
+ _glfwLibrary.Timer.t0 = (long long) tv.tv_sec * (long long) 1000000 +
48
+ (long long) tv.tv_usec;
49
+ }
50
+
51
+
52
+ //************************************************************************
53
+ //**** Platform implementation functions ****
54
+ //************************************************************************
55
+
56
+ //========================================================================
57
+ // Return timer value in seconds
58
+ //========================================================================
59
+
60
+ double _glfwPlatformGetTime( void )
61
+ {
62
+ long long t;
63
+ struct timeval tv;
64
+
65
+ gettimeofday( &tv, NULL );
66
+ t = (long long) tv.tv_sec * (long long) 1000000 +
67
+ (long long) tv.tv_usec;
68
+
69
+ return (double)(t - _glfwLibrary.Timer.t0) * _glfwLibrary.Timer.Resolution;
70
+ }
71
+
72
+
73
+ //========================================================================
74
+ // Set timer value in seconds
75
+ //========================================================================
76
+
77
+ void _glfwPlatformSetTime( double t )
78
+ {
79
+ long long t0;
80
+ struct timeval tv;
81
+
82
+ gettimeofday( &tv, NULL );
83
+ t0 = (long long) tv.tv_sec * (long long) 1000000 +
84
+ (long long) tv.tv_usec;
85
+
86
+ // Calulate new starting time
87
+ _glfwLibrary.Timer.t0 = t0 - (long long)(t/_glfwLibrary.Timer.Resolution);
88
+ }
89
+
90
+
91
+ //========================================================================
92
+ // Put a thread to sleep for a specified amount of time
93
+ //========================================================================
94
+
95
+ void _glfwPlatformSleep( double time )
96
+ {
97
+ #ifdef _GLFW_HAS_PTHREAD
98
+
99
+ if( time == 0.0 )
100
+ {
101
+ #ifdef _GLFW_HAS_SCHED_YIELD
102
+ sched_yield();
103
+ #endif
104
+ return;
105
+ }
106
+
107
+ struct timeval currenttime;
108
+ struct timespec wait;
109
+ pthread_mutex_t mutex;
110
+ pthread_cond_t cond;
111
+ long dt_sec, dt_usec;
112
+
113
+ // Not all pthread implementations have a pthread_sleep() function. We
114
+ // do it the portable way, using a timed wait for a condition that we
115
+ // will never signal. NOTE: The unistd functions sleep/usleep suspends
116
+ // the entire PROCESS, not a signle thread, which is why we can not
117
+ // use them to implement glfwSleep.
118
+
119
+ // Set timeout time, relatvie to current time
120
+ gettimeofday( &currenttime, NULL );
121
+ dt_sec = (long) time;
122
+ dt_usec = (long) ((time - (double)dt_sec) * 1000000.0);
123
+ wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;
124
+ if( wait.tv_nsec > 1000000000L )
125
+ {
126
+ wait.tv_nsec -= 1000000000L;
127
+ dt_sec++;
128
+ }
129
+ wait.tv_sec = currenttime.tv_sec + dt_sec;
130
+
131
+ // Initialize condition and mutex objects
132
+ pthread_mutex_init( &mutex, NULL );
133
+ pthread_cond_init( &cond, NULL );
134
+
135
+ // Do a timed wait
136
+ pthread_mutex_lock( &mutex );
137
+ pthread_cond_timedwait( &cond, &mutex, &wait );
138
+ pthread_mutex_unlock( &mutex );
139
+
140
+ // Destroy condition and mutex objects
141
+ pthread_mutex_destroy( &mutex );
142
+ pthread_cond_destroy( &cond );
143
+
144
+ #else
145
+
146
+ // For systems without PTHREAD, use unistd usleep
147
+ if( time > 0 )
148
+ {
149
+ usleep( (unsigned int) (time*1000000) );
150
+ }
151
+
152
+ #endif // _GLFW_HAS_PTHREAD
153
+ }
154
+
@@ -0,0 +1,1746 @@
1
+ //========================================================================
2
+ // GLFW - An OpenGL framework
3
+ // File: x11_window.c
4
+ // Platform: X11 (Unix)
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
+ /* Defines some GLX FSAA tokens if not yet defined */
35
+ #ifndef GLX_SAMPLE_BUFFERS
36
+ # define GLX_SAMPLE_BUFFERS 100000
37
+ #endif
38
+ #ifndef GLX_SAMPLES
39
+ # define GLX_SAMPLES 100001
40
+ #endif
41
+
42
+
43
+ /* KDE decoration values */
44
+ enum {
45
+ KDE_noDecoration = 0,
46
+ KDE_normalDecoration = 1,
47
+ KDE_tinyDecoration = 2,
48
+ KDE_noFocus = 256,
49
+ KDE_standaloneMenuBar = 512,
50
+ KDE_desktopIcon = 1024 ,
51
+ KDE_staysOnTop = 2048
52
+ };
53
+
54
+
55
+ //************************************************************************
56
+ //**** GLFW internal functions ****
57
+ //************************************************************************
58
+
59
+ //========================================================================
60
+ // _glfwWaitForMapNotify()
61
+ //========================================================================
62
+
63
+ Bool _glfwWaitForMapNotify( Display *d, XEvent *e, char *arg )
64
+ {
65
+ return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
66
+ }
67
+
68
+
69
+ //========================================================================
70
+ // _glfwWaitForUnmapNotify()
71
+ //========================================================================
72
+
73
+ Bool _glfwWaitForUnmapNotify( Display *d, XEvent *e, char *arg )
74
+ {
75
+ return (e->type == UnmapNotify) && (e->xmap.window == (Window)arg);
76
+ }
77
+
78
+
79
+ //========================================================================
80
+ // _glfwDisableDecorations() - Turn off window decorations
81
+ // Based on xawdecode: src/wmhooks.c
82
+ //========================================================================
83
+
84
+ #define MWM_HINTS_DECORATIONS (1L << 1)
85
+
86
+ static void _glfwDisableDecorations( void )
87
+ {
88
+ int RemovedDecorations;
89
+ Atom HintAtom;
90
+ XSetWindowAttributes attributes;
91
+
92
+ RemovedDecorations = 0;
93
+
94
+ // First try to set MWM hints
95
+ HintAtom = XInternAtom( _glfwLibrary.Dpy, "_MOTIF_WM_HINTS", True );
96
+ if ( HintAtom != None )
97
+ {
98
+ struct {
99
+ unsigned long flags;
100
+ unsigned long functions;
101
+ unsigned long decorations;
102
+ long input_mode;
103
+ unsigned long status;
104
+ } MWMHints = { MWM_HINTS_DECORATIONS, 0, 0, 0, 0 };
105
+
106
+ XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom,
107
+ 32, PropModeReplace, (unsigned char *)&MWMHints,
108
+ sizeof(MWMHints)/4 );
109
+ RemovedDecorations = 1;
110
+ }
111
+
112
+ // Now try to set KWM hints
113
+ HintAtom = XInternAtom( _glfwLibrary.Dpy, "KWM_WIN_DECORATION", True );
114
+ if ( HintAtom != None )
115
+ {
116
+ long KWMHints = KDE_tinyDecoration;
117
+
118
+ XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom,
119
+ 32, PropModeReplace, (unsigned char *)&KWMHints,
120
+ sizeof(KWMHints)/4 );
121
+ RemovedDecorations = 1;
122
+ }
123
+
124
+ // Now try to set GNOME hints
125
+ HintAtom = XInternAtom(_glfwLibrary.Dpy, "_WIN_HINTS", True );
126
+ if ( HintAtom != None )
127
+ {
128
+ long GNOMEHints = 0;
129
+
130
+ XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom,
131
+ 32, PropModeReplace, (unsigned char *)&GNOMEHints,
132
+ sizeof(GNOMEHints)/4 );
133
+ RemovedDecorations = 1;
134
+ }
135
+
136
+ // Now try to set KDE NET_WM hints
137
+ HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE", True );
138
+ if ( HintAtom != None )
139
+ {
140
+ Atom NET_WMHints[2];
141
+
142
+ NET_WMHints[0] = XInternAtom( _glfwLibrary.Dpy, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", True );
143
+ /* define a fallback... */
144
+ NET_WMHints[1] = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE_NORMAL", True );
145
+
146
+ XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, XA_ATOM,
147
+ 32, PropModeReplace, (unsigned char *)&NET_WMHints,
148
+ 2 );
149
+ RemovedDecorations = 1;
150
+ }
151
+
152
+ // Set ICCCM fullscreen WM hint
153
+ HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_STATE", True );
154
+ if ( HintAtom != None )
155
+ {
156
+ Atom NET_WMHints[1];
157
+
158
+ NET_WMHints[0] = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_STATE_FULLSCREEN", True );
159
+
160
+ XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, XA_ATOM,
161
+ 32, PropModeReplace, (unsigned char *)&NET_WMHints, 1 );
162
+ }
163
+
164
+
165
+ // Did we sucessfully remove the window decorations?
166
+ if( RemovedDecorations )
167
+ {
168
+ // Finally set the transient hints
169
+ XSetTransientForHint( _glfwLibrary.Dpy, _glfwWin.Win, RootWindow(_glfwLibrary.Dpy, _glfwWin.Scrn) );
170
+ XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
171
+ XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
172
+ }
173
+ else
174
+ {
175
+ // The Butcher way of removing window decorations
176
+ attributes.override_redirect = True;
177
+ XChangeWindowAttributes( _glfwLibrary.Dpy, _glfwWin.Win,
178
+ CWOverrideRedirect, &attributes );
179
+ _glfwWin.OverrideRedirect = GL_TRUE;
180
+ }
181
+ }
182
+
183
+
184
+ //========================================================================
185
+ // _glfwEnableDecorations() - Turn on window decorations
186
+ //========================================================================
187
+
188
+ static void _glfwEnableDecorations( void )
189
+ {
190
+ int ActivatedDecorations;
191
+ Atom HintAtom;
192
+
193
+ // If this is an override redirect window, skip it...
194
+ if( _glfwWin.OverrideRedirect )
195
+ {
196
+ return;
197
+ }
198
+
199
+ ActivatedDecorations = 0;
200
+
201
+ // First try to unset MWM hints
202
+ HintAtom = XInternAtom( _glfwLibrary.Dpy, "_MOTIF_WM_HINTS", True );
203
+ if ( HintAtom != None )
204
+ {
205
+ XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom );
206
+ ActivatedDecorations = 1;
207
+ }
208
+
209
+ // Now try to unset KWM hints
210
+ HintAtom = XInternAtom( _glfwLibrary.Dpy, "KWM_WIN_DECORATION", True );
211
+ if ( HintAtom != None )
212
+ {
213
+ XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom );
214
+ ActivatedDecorations = 1;
215
+ }
216
+
217
+ // Now try to unset GNOME hints
218
+ HintAtom = XInternAtom( _glfwLibrary.Dpy, "_WIN_HINTS", True );
219
+ if ( HintAtom != None )
220
+ {
221
+ XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom );
222
+ ActivatedDecorations = 1;
223
+ }
224
+
225
+ // Now try to unset NET_WM hints
226
+ HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE", True );
227
+ if ( HintAtom != None )
228
+ {
229
+ Atom NET_WMHints = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE_NORMAL", True);
230
+ if( NET_WMHints != None )
231
+ {
232
+ XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win,
233
+ HintAtom, XA_ATOM, 32, PropModeReplace,
234
+ (unsigned char *)&NET_WMHints, 1 );
235
+ ActivatedDecorations = 1;
236
+ }
237
+ }
238
+
239
+ // Finally unset the transient hints if necessary
240
+ if( ActivatedDecorations )
241
+ {
242
+ // NOTE: Does this work?
243
+ XSetTransientForHint( _glfwLibrary.Dpy, _glfwWin.Win, None);
244
+ XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
245
+ XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
246
+ }
247
+ }
248
+
249
+
250
+ //========================================================================
251
+ // _glfwChooseVisual() - We do our own function here, since
252
+ // glXChooseVisual does not behave as we want it to (not according to the
253
+ // GLFW specs)
254
+ //========================================================================
255
+
256
+ XVisualInfo * _glfwChooseVisual( Display *Dpy, int Screen, int r, int g,
257
+ int b, int a, int d, int s, int ar, int ag, int ab, int aa, int aux,
258
+ int fsaa, int stereo)
259
+ {
260
+ XVisualInfo *VI, *VI_list, VI_tmp;
261
+ int nitems_return, i;
262
+ int vi_gl, vi_rgba, vi_double, vi_stereo;
263
+ int vi_r, vi_g, vi_b, vi_a, vi_d, vi_s, vi_ar, vi_ag, vi_ab, vi_aa;
264
+ int vi_aux;
265
+ int color, accum, vi_accum;
266
+ int missing, color_diff, extra_diff;
267
+ int best_vis, best_missing, best_color_diff, best_extra_diff;
268
+ int samples, samplebuffers, vi_samples, vi_samplebuffers;
269
+
270
+ // Get list of visuals for this screen & display
271
+ VI_tmp.screen = Screen;
272
+ VI_list = XGetVisualInfo( Dpy, VisualScreenMask, &VI_tmp,
273
+ &nitems_return );
274
+ if( VI_list == NULL )
275
+ {
276
+ return NULL;
277
+ }
278
+
279
+ // Pick some prefered color depth if the user did not request a
280
+ // specific depth (note: if the user did not request a specific color
281
+ // depth, this will not be a driving demand, it's only here to avoid
282
+ // selection randomness)
283
+ color = (r > 0 || g > 0 || b > 0);
284
+ if( !color )
285
+ {
286
+ r = g = b = 8;
287
+ }
288
+
289
+ // Make sure that stereo is 1 or 0
290
+ stereo = stereo ? 1 : 0;
291
+
292
+ // Convenience pre-calculation
293
+ accum = (ar > 0 || ag > 0 || ab > 0 || aa > 0);
294
+
295
+ samples = fsaa;
296
+ samplebuffers = (fsaa > 0) ? 1 : 0;
297
+
298
+
299
+
300
+ // Loop through list of visuals to find best match
301
+ best_vis = -1;
302
+ best_missing = 0x7fffffff;
303
+ best_color_diff = 0x7fffffff;
304
+ best_extra_diff = 0x7fffffff;
305
+ for( i = 0; i < nitems_return; i ++ )
306
+ {
307
+ // We want GL, RGBA & DOUBLEBUFFER, and NOT STEREO / STEREO
308
+ glXGetConfig( Dpy, &VI_list[i], GLX_USE_GL, &vi_gl );
309
+ glXGetConfig( Dpy, &VI_list[i], GLX_RGBA, &vi_rgba );
310
+ glXGetConfig( Dpy, &VI_list[i], GLX_DOUBLEBUFFER, &vi_double );
311
+ glXGetConfig( Dpy, &VI_list[i], GLX_STEREO, &vi_stereo );
312
+ vi_stereo = vi_stereo ? 1 : 0;
313
+ if( vi_gl && vi_rgba && vi_double && (vi_stereo == stereo) )
314
+ {
315
+ // Get visual color parameters
316
+ glXGetConfig( Dpy, &VI_list[i], GLX_RED_SIZE, &vi_r );
317
+ glXGetConfig( Dpy, &VI_list[i], GLX_GREEN_SIZE, &vi_g );
318
+ glXGetConfig( Dpy, &VI_list[i], GLX_BLUE_SIZE, &vi_b );
319
+
320
+ // Get visual "extra" parameters
321
+ glXGetConfig( Dpy, &VI_list[i], GLX_ALPHA_SIZE, &vi_a );
322
+ glXGetConfig( Dpy, &VI_list[i], GLX_DEPTH_SIZE, &vi_d );
323
+ glXGetConfig( Dpy, &VI_list[i], GLX_STENCIL_SIZE, &vi_s );
324
+ glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_RED_SIZE, &vi_ar );
325
+ glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_GREEN_SIZE, &vi_ag );
326
+ glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_BLUE_SIZE, &vi_ab );
327
+ glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_ALPHA_SIZE, &vi_aa );
328
+ glXGetConfig( Dpy, &VI_list[i], GLX_AUX_BUFFERS, &vi_aux );
329
+ glXGetConfig( Dpy, &VI_list[i], GLX_SAMPLE_BUFFERS, &vi_samplebuffers );
330
+ glXGetConfig( Dpy, &VI_list[i], GLX_SAMPLES, &vi_samples );
331
+
332
+ vi_accum = (vi_ar > 0 || vi_ag > 0 || vi_ab > 0 || vi_aa > 0);
333
+
334
+ // Check how many buffers are missing
335
+ missing = 0;
336
+ if( a > 0 && vi_a == 0 ) missing ++;
337
+ if( d > 0 && vi_d == 0 ) missing ++;
338
+ if( s > 0 && vi_s == 0 ) missing ++;
339
+ if( accum && !vi_accum ) missing ++;
340
+ if( aux > 0 && vi_aux == 0 ) missing ++;
341
+ if( samplebuffers > 0 && vi_samplebuffers == 0 ) missing ++;
342
+
343
+
344
+ // Calculate color diff
345
+ color_diff = (r - vi_r) * (r - vi_r) +
346
+ (g - vi_g) * (g - vi_g) +
347
+ (b - vi_b) * (b - vi_b);
348
+
349
+ // Calculate "extra" diff
350
+ extra_diff = 0;
351
+ if( a > 0 )
352
+ {
353
+ extra_diff += (a - vi_a) * (a - vi_a);
354
+ }
355
+ if( d > 0 )
356
+ {
357
+ extra_diff += (d - vi_d) * (d - vi_d);
358
+ }
359
+ if( s > 0 )
360
+ {
361
+ extra_diff += (s - vi_s) * (s - vi_s);
362
+ }
363
+ if( accum )
364
+ {
365
+ extra_diff += (ar - vi_ar) * (ar - vi_ar) +
366
+ (ag - vi_ag) * (ag - vi_ag) +
367
+ (ab - vi_ab) * (ab - vi_ab) +
368
+ (aa - vi_aa) * (aa - vi_aa);
369
+ }
370
+ if( aux > 0 )
371
+ {
372
+ extra_diff += (aux - vi_aux) * (aux - vi_aux);
373
+ }
374
+ if( samples > 0 )
375
+ {
376
+ extra_diff += (samples - vi_samples) * (samples - vi_samples);
377
+
378
+ }
379
+ // Check if this is a better match. We implement some
380
+ // complicated rules, by prioritizing in this order:
381
+ // 1) Visuals with the least number of missing buffers always
382
+ // have priority
383
+ // 2a) If (r,g,b)!=(0,0,0), color depth has priority over
384
+ // other buffers
385
+ // 2b) If (r,g,b)==(0,0,0), other buffers have priority over
386
+ // color depth
387
+ if( missing < best_missing )
388
+ {
389
+ best_vis = i;
390
+ }
391
+ else if( missing == best_missing )
392
+ {
393
+ if( color )
394
+ {
395
+ if( (color_diff < best_color_diff) ||
396
+ (color_diff == best_color_diff &&
397
+ extra_diff < best_extra_diff) )
398
+ {
399
+ best_vis = i;
400
+ }
401
+ }
402
+ else
403
+ {
404
+ if( (extra_diff < best_extra_diff) ||
405
+ (extra_diff == best_extra_diff &&
406
+ color_diff < best_color_diff) )
407
+ {
408
+ best_vis = i;
409
+ }
410
+ }
411
+ }
412
+ if( best_vis == i )
413
+ {
414
+ best_missing = missing;
415
+ best_color_diff = color_diff;
416
+ best_extra_diff = extra_diff;
417
+ }
418
+ }
419
+ }
420
+
421
+ // Copy best visual to a visual to return
422
+ if( best_vis >= 0 )
423
+ {
424
+ VI = XGetVisualInfo( Dpy, VisualIDMask, &VI_list[ best_vis ],
425
+ &nitems_return );
426
+ }
427
+ else
428
+ {
429
+ VI = NULL;
430
+ }
431
+
432
+ // Free visuals list
433
+ XFree( VI_list );
434
+
435
+ return VI;
436
+ }
437
+
438
+
439
+ //========================================================================
440
+ // _glfwTranslateKey() - Translates an X Window key to internal coding
441
+ //========================================================================
442
+
443
+ static int _glfwTranslateKey( int keycode )
444
+ {
445
+ KeySym key, key_lc, key_uc;
446
+
447
+ // Try secondary keysym, for numeric keypad keys
448
+ // Note: This way we always force "NumLock = ON", which at least
449
+ // enables GLFW users to detect numeric keypad keys
450
+ key = XKeycodeToKeysym( _glfwLibrary.Dpy, keycode, 1 );
451
+ switch( key )
452
+ {
453
+ // Numeric keypad
454
+ case XK_KP_0: return GLFW_KEY_KP_0;
455
+ case XK_KP_1: return GLFW_KEY_KP_1;
456
+ case XK_KP_2: return GLFW_KEY_KP_2;
457
+ case XK_KP_3: return GLFW_KEY_KP_3;
458
+ case XK_KP_4: return GLFW_KEY_KP_4;
459
+ case XK_KP_5: return GLFW_KEY_KP_5;
460
+ case XK_KP_6: return GLFW_KEY_KP_6;
461
+ case XK_KP_7: return GLFW_KEY_KP_7;
462
+ case XK_KP_8: return GLFW_KEY_KP_8;
463
+ case XK_KP_9: return GLFW_KEY_KP_9;
464
+ case XK_KP_Separator:
465
+ case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL;
466
+ case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;
467
+ case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
468
+ default: break;
469
+ }
470
+
471
+ // Now try pimary keysym
472
+ key = XKeycodeToKeysym( _glfwLibrary.Dpy, keycode, 0 );
473
+ switch( key )
474
+ {
475
+ // Special keys (non character keys)
476
+ case XK_Escape: return GLFW_KEY_ESC;
477
+ case XK_Tab: return GLFW_KEY_TAB;
478
+ case XK_Shift_L: return GLFW_KEY_LSHIFT;
479
+ case XK_Shift_R: return GLFW_KEY_RSHIFT;
480
+ case XK_Control_L: return GLFW_KEY_LCTRL;
481
+ case XK_Control_R: return GLFW_KEY_RCTRL;
482
+ case XK_Meta_L:
483
+ case XK_Alt_L: return GLFW_KEY_LALT;
484
+ case XK_Mode_switch: // Mapped to Alt_R on many keyboards
485
+ case XK_Meta_R:
486
+ case XK_Alt_R: return GLFW_KEY_RALT;
487
+ case XK_KP_Delete:
488
+ case XK_Delete: return GLFW_KEY_DEL;
489
+ case XK_BackSpace: return GLFW_KEY_BACKSPACE;
490
+ case XK_Return: return GLFW_KEY_ENTER;
491
+ case XK_KP_Home:
492
+ case XK_Home: return GLFW_KEY_HOME;
493
+ case XK_KP_End:
494
+ case XK_End: return GLFW_KEY_END;
495
+ case XK_KP_Page_Up:
496
+ case XK_Page_Up: return GLFW_KEY_PAGEUP;
497
+ case XK_KP_Page_Down:
498
+ case XK_Page_Down: return GLFW_KEY_PAGEDOWN;
499
+ case XK_KP_Insert:
500
+ case XK_Insert: return GLFW_KEY_INSERT;
501
+ case XK_KP_Left:
502
+ case XK_Left: return GLFW_KEY_LEFT;
503
+ case XK_KP_Right:
504
+ case XK_Right: return GLFW_KEY_RIGHT;
505
+ case XK_KP_Down:
506
+ case XK_Down: return GLFW_KEY_DOWN;
507
+ case XK_KP_Up:
508
+ case XK_Up: return GLFW_KEY_UP;
509
+ case XK_F1: return GLFW_KEY_F1;
510
+ case XK_F2: return GLFW_KEY_F2;
511
+ case XK_F3: return GLFW_KEY_F3;
512
+ case XK_F4: return GLFW_KEY_F4;
513
+ case XK_F5: return GLFW_KEY_F5;
514
+ case XK_F6: return GLFW_KEY_F6;
515
+ case XK_F7: return GLFW_KEY_F7;
516
+ case XK_F8: return GLFW_KEY_F8;
517
+ case XK_F9: return GLFW_KEY_F9;
518
+ case XK_F10: return GLFW_KEY_F10;
519
+ case XK_F11: return GLFW_KEY_F11;
520
+ case XK_F12: return GLFW_KEY_F12;
521
+ case XK_F13: return GLFW_KEY_F13;
522
+ case XK_F14: return GLFW_KEY_F14;
523
+ case XK_F15: return GLFW_KEY_F15;
524
+ case XK_F16: return GLFW_KEY_F16;
525
+ case XK_F17: return GLFW_KEY_F17;
526
+ case XK_F18: return GLFW_KEY_F18;
527
+ case XK_F19: return GLFW_KEY_F19;
528
+ case XK_F20: return GLFW_KEY_F20;
529
+ case XK_F21: return GLFW_KEY_F21;
530
+ case XK_F22: return GLFW_KEY_F22;
531
+ case XK_F23: return GLFW_KEY_F23;
532
+ case XK_F24: return GLFW_KEY_F24;
533
+ case XK_F25: return GLFW_KEY_F25;
534
+
535
+ // Numeric keypad (should have been detected in secondary keysym!)
536
+ case XK_KP_Divide: return GLFW_KEY_KP_DIVIDE;
537
+ case XK_KP_Multiply: return GLFW_KEY_KP_MULTIPLY;
538
+ case XK_KP_Subtract: return GLFW_KEY_KP_SUBTRACT;
539
+ case XK_KP_Add: return GLFW_KEY_KP_ADD;
540
+ case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;
541
+ case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
542
+
543
+ // The rest (should be printable keys)
544
+ default:
545
+ // Make uppercase
546
+ XConvertCase( key, &key_lc, &key_uc );
547
+ key = key_uc;
548
+
549
+ // Valid ISO 8859-1 character?
550
+ if( (key >= 32 && key <= 126) ||
551
+ (key >= 160 && key <= 255) )
552
+ {
553
+ return (int) key;
554
+ }
555
+ return GLFW_KEY_UNKNOWN;
556
+ }
557
+ }
558
+
559
+
560
+ //========================================================================
561
+ // _glfwTranslateChar() - Translates an X Window event to Unicode
562
+ //========================================================================
563
+
564
+ static int _glfwTranslateChar( XKeyEvent *event )
565
+ {
566
+ KeySym keysym;
567
+
568
+ // Get X11 keysym
569
+ XLookupString( event, NULL, 0, &keysym, NULL );
570
+
571
+ // Convert to Unicode (see x11_keysym2unicode.c)
572
+ return (int) _glfwKeySym2Unicode( keysym );
573
+ }
574
+
575
+
576
+
577
+ //========================================================================
578
+ // Get next X event (called by glfwPollEvents)
579
+ //========================================================================
580
+
581
+ static int _glfwGetNextEvent( void )
582
+ {
583
+ XEvent event, next_event;
584
+
585
+ // Pull next event from event queue
586
+ XNextEvent( _glfwLibrary.Dpy, &event );
587
+
588
+ // Handle certain window messages
589
+ switch( event.type )
590
+ {
591
+ // Is a key being pressed?
592
+ case KeyPress:
593
+ {
594
+ // Translate and report key press
595
+ _glfwInputKey( _glfwTranslateKey( event.xkey.keycode ), GLFW_PRESS );
596
+
597
+ // Translate and report character input
598
+ if( _glfwWin.CharCallback )
599
+ {
600
+ _glfwInputChar( _glfwTranslateChar( &event.xkey ), GLFW_PRESS );
601
+ }
602
+ break;
603
+ }
604
+
605
+ // Is a key being released?
606
+ case KeyRelease:
607
+ {
608
+ // Do not report key releases for key repeats. For key repeats
609
+ // we will get KeyRelease/KeyPress pairs with identical time
610
+ // stamps. User selected key repeat filtering is handled in
611
+ // _glfwInputKey()/_glfwInputChar().
612
+ if( XEventsQueued( _glfwLibrary.Dpy, QueuedAfterReading ) )
613
+ {
614
+ XPeekEvent( _glfwLibrary.Dpy, &next_event );
615
+ if( next_event.type == KeyPress &&
616
+ next_event.xkey.window == event.xkey.window &&
617
+ next_event.xkey.keycode == event.xkey.keycode &&
618
+ next_event.xkey.time == event.xkey.time )
619
+ {
620
+ // Do not report anything for this event
621
+ break;
622
+ }
623
+ }
624
+
625
+ // Translate and report key release
626
+ _glfwInputKey( _glfwTranslateKey( event.xkey.keycode ), GLFW_RELEASE );
627
+
628
+ // Translate and report character input
629
+ if( _glfwWin.CharCallback )
630
+ {
631
+ _glfwInputChar( _glfwTranslateChar( &event.xkey ), GLFW_RELEASE );
632
+ }
633
+ break;
634
+ }
635
+
636
+ // Were any of the mouse-buttons pressed?
637
+ case ButtonPress:
638
+ {
639
+ if( event.xbutton.button == Button1 )
640
+ {
641
+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );
642
+ }
643
+ else if( event.xbutton.button == Button2 )
644
+ {
645
+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS );
646
+ }
647
+ else if( event.xbutton.button == Button3 )
648
+ {
649
+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );
650
+ }
651
+
652
+ // XFree86 3.3.2 and later translates mouse wheel up/down into
653
+ // mouse button 4 & 5 presses
654
+ else if( event.xbutton.button == Button4 )
655
+ {
656
+ _glfwInput.WheelPos++; // To verify: is this up or down?
657
+ if( _glfwWin.MouseWheelCallback )
658
+ {
659
+ _glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
660
+ }
661
+ }
662
+ else if( event.xbutton.button == Button5 )
663
+ {
664
+ _glfwInput.WheelPos--;
665
+ if( _glfwWin.MouseWheelCallback )
666
+ {
667
+ _glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
668
+ }
669
+ }
670
+ break;
671
+ }
672
+
673
+ // Were any of the mouse-buttons released?
674
+ case ButtonRelease:
675
+ {
676
+ if( event.xbutton.button == Button1 )
677
+ {
678
+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT,
679
+ GLFW_RELEASE );
680
+ }
681
+ else if( event.xbutton.button == Button2 )
682
+ {
683
+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE,
684
+ GLFW_RELEASE );
685
+ }
686
+ else if( event.xbutton.button == Button3 )
687
+ {
688
+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT,
689
+ GLFW_RELEASE );
690
+ }
691
+ break;
692
+ }
693
+
694
+ // Was the mouse moved?
695
+ case MotionNotify:
696
+ {
697
+ if( event.xmotion.x != _glfwInput.CursorPosX ||
698
+ event.xmotion.y != _glfwInput.CursorPosY )
699
+ {
700
+ if( _glfwWin.MouseLock )
701
+ {
702
+ _glfwInput.MousePosX += event.xmotion.x -
703
+ _glfwInput.CursorPosX;
704
+ _glfwInput.MousePosY += event.xmotion.y -
705
+ _glfwInput.CursorPosY;
706
+ }
707
+ else
708
+ {
709
+ _glfwInput.MousePosX = event.xmotion.x;
710
+ _glfwInput.MousePosY = event.xmotion.y;
711
+ }
712
+ _glfwInput.CursorPosX = event.xmotion.x;
713
+ _glfwInput.CursorPosY = event.xmotion.y;
714
+ _glfwInput.MouseMoved = GL_TRUE;
715
+
716
+ // Call user callback function
717
+ if( _glfwWin.MousePosCallback )
718
+ {
719
+ _glfwWin.MousePosCallback( _glfwInput.MousePosX,
720
+ _glfwInput.MousePosY );
721
+ }
722
+ }
723
+ break;
724
+ }
725
+
726
+ // Was the window resized?
727
+ case ConfigureNotify:
728
+ {
729
+ if( event.xconfigure.width != _glfwWin.Width ||
730
+ event.xconfigure.height != _glfwWin.Height )
731
+ {
732
+ _glfwWin.Width = event.xconfigure.width;
733
+ _glfwWin.Height = event.xconfigure.height;
734
+ if( _glfwWin.WindowSizeCallback )
735
+ {
736
+ _glfwWin.WindowSizeCallback( _glfwWin.Width,
737
+ _glfwWin.Height );
738
+ }
739
+ }
740
+ break;
741
+ }
742
+
743
+ // Was the window closed by the window manager?
744
+ case ClientMessage:
745
+ {
746
+ if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.WMDeleteWindow )
747
+ {
748
+ return GL_TRUE;
749
+ }
750
+
751
+ if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.WMPing )
752
+ {
753
+ XSendEvent( _glfwLibrary.Dpy,
754
+ RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ),
755
+ False, SubstructureNotifyMask | SubstructureRedirectMask, &event );
756
+ }
757
+ break;
758
+ }
759
+
760
+ // Was the window mapped (un-iconified)?
761
+ case MapNotify:
762
+ _glfwWin.MapNotifyCount++;
763
+ break;
764
+
765
+ // Was the window unmapped (iconified)?
766
+ case UnmapNotify:
767
+ _glfwWin.MapNotifyCount--;
768
+ break;
769
+
770
+ // Was the window activated?
771
+ case FocusIn:
772
+ _glfwWin.FocusInCount++;
773
+ break;
774
+
775
+ // Was the window de-activated?
776
+ case FocusOut:
777
+ _glfwWin.FocusInCount--;
778
+ break;
779
+
780
+ // Was the window contents damaged?
781
+ case Expose:
782
+ {
783
+ // Call user callback function
784
+ if( _glfwWin.WindowRefreshCallback )
785
+ {
786
+ _glfwWin.WindowRefreshCallback();
787
+ }
788
+ break;
789
+ }
790
+
791
+ // Was the window destroyed?
792
+ case DestroyNotify:
793
+ return GL_TRUE;
794
+
795
+ default:
796
+ {
797
+ #if defined( _GLFW_HAS_XRANDR )
798
+ switch( event.type - _glfwLibrary.XRandR.EventBase )
799
+ {
800
+ case RRScreenChangeNotify:
801
+ {
802
+ // Show XRandR that we really care
803
+ XRRUpdateConfiguration( &event );
804
+ break;
805
+ }
806
+ }
807
+ #endif
808
+ break;
809
+ }
810
+ }
811
+
812
+ // The window was not destroyed
813
+ return GL_FALSE;
814
+ }
815
+
816
+
817
+ //========================================================================
818
+ // _glfwCreateNULLCursor() - Create a blank cursor (for locked mouse mode)
819
+ //========================================================================
820
+
821
+ Cursor _glfwCreateNULLCursor( Display *display, Window root )
822
+ {
823
+ Pixmap cursormask;
824
+ XGCValues xgc;
825
+ GC gc;
826
+ XColor col;
827
+ Cursor cursor;
828
+
829
+ cursormask = XCreatePixmap( display, root, 1, 1, 1 );
830
+ xgc.function = GXclear;
831
+ gc = XCreateGC( display, cursormask, GCFunction, &xgc );
832
+ XFillRectangle( display, cursormask, gc, 0, 0, 1, 1 );
833
+ col.pixel = 0;
834
+ col.red = 0;
835
+ col.flags = 4;
836
+ cursor = XCreatePixmapCursor( display, cursormask, cursormask,
837
+ &col,&col, 0,0 );
838
+ XFreePixmap( display, cursormask );
839
+ XFreeGC( display, gc );
840
+
841
+ return cursor;
842
+ }
843
+
844
+
845
+ //========================================================================
846
+ // _glfwInitGLXExtensions() - Initialize GLX-specific extensions
847
+ //========================================================================
848
+
849
+ static void _glfwInitGLXExtensions( void )
850
+ {
851
+ int has_swap_control;
852
+
853
+ // Initialize OpenGL extension: GLX_SGI_swap_control
854
+ has_swap_control = _glfwPlatformExtensionSupported(
855
+ "GLX_SGI_swap_control"
856
+ );
857
+
858
+ if( has_swap_control )
859
+ {
860
+ _glfwWin.SwapInterval = (GLXSWAPINTERVALSGI_T)
861
+ _glfw_glXGetProcAddress( (GLubyte*) "glXSwapIntervalSGI" );
862
+ }
863
+ else
864
+ {
865
+ _glfwWin.SwapInterval = NULL;
866
+ }
867
+ }
868
+
869
+
870
+
871
+ //************************************************************************
872
+ //**** Platform implementation functions ****
873
+ //************************************************************************
874
+
875
+ //========================================================================
876
+ // _glfwPlatformOpenWindow() - Here is where the window is created, and
877
+ // the OpenGL rendering context is created
878
+ //========================================================================
879
+
880
+ int _glfwPlatformOpenWindow( int width, int height, int redbits,
881
+ int greenbits, int bluebits, int alphabits, int depthbits,
882
+ int stencilbits, int mode, _GLFWhints* hints )
883
+ {
884
+ Colormap cmap;
885
+ XSetWindowAttributes wa;
886
+ XEvent event;
887
+ Atom protocols[2];
888
+
889
+ // Clear platform specific GLFW window state
890
+ _glfwWin.VI = NULL;
891
+ _glfwWin.CX = (GLXContext)0;
892
+ _glfwWin.Win = (Window)0;
893
+ _glfwWin.Hints = NULL;
894
+ _glfwWin.PointerGrabbed = GL_FALSE;
895
+ _glfwWin.KeyboardGrabbed = GL_FALSE;
896
+ _glfwWin.OverrideRedirect = GL_FALSE;
897
+ _glfwWin.FS.ModeChanged = GL_FALSE;
898
+ _glfwWin.Saver.Changed = GL_FALSE;
899
+ _glfwWin.RefreshRate = hints->RefreshRate;
900
+
901
+ // Fullscreen & screen saver settings
902
+ // Check if GLX is supported on this display
903
+ if( !glXQueryExtension( _glfwLibrary.Dpy, NULL, NULL ) )
904
+ {
905
+ _glfwPlatformCloseWindow();
906
+ return GL_FALSE;
907
+ }
908
+
909
+ // Get screen ID for this window
910
+ _glfwWin.Scrn = _glfwLibrary.DefaultScreen;
911
+
912
+ // Get an appropriate visual
913
+ _glfwWin.VI = _glfwChooseVisual( _glfwLibrary.Dpy,
914
+ _glfwWin.Scrn,
915
+ redbits, greenbits, bluebits,
916
+ alphabits, depthbits, stencilbits,
917
+ hints->AccumRedBits, hints->AccumGreenBits,
918
+ hints->AccumBlueBits, hints->AccumAlphaBits,
919
+ hints->AuxBuffers, hints->Samples, hints->Stereo );
920
+ if( _glfwWin.VI == NULL )
921
+ {
922
+ _glfwPlatformCloseWindow();
923
+ return GL_FALSE;
924
+ }
925
+
926
+ // Create a GLX context
927
+ _glfwWin.CX = glXCreateContext( _glfwLibrary.Dpy, _glfwWin.VI, 0, GL_TRUE );
928
+ if( _glfwWin.CX == NULL )
929
+ {
930
+ _glfwPlatformCloseWindow();
931
+ return GL_FALSE;
932
+ }
933
+
934
+ // Create a colormap
935
+ cmap = XCreateColormap( _glfwLibrary.Dpy, RootWindow( _glfwLibrary.Dpy,
936
+ _glfwWin.VI->screen), _glfwWin.VI->visual, AllocNone );
937
+
938
+ // Do we want fullscreen?
939
+ if( mode == GLFW_FULLSCREEN )
940
+ {
941
+ // Change video mode
942
+ _glfwSetVideoMode( _glfwWin.Scrn, &_glfwWin.Width,
943
+ &_glfwWin.Height, &_glfwWin.RefreshRate );
944
+
945
+ // Remember old screen saver settings
946
+ XGetScreenSaver( _glfwLibrary.Dpy, &_glfwWin.Saver.Timeout,
947
+ &_glfwWin.Saver.Interval, &_glfwWin.Saver.Blanking,
948
+ &_glfwWin.Saver.Exposure );
949
+
950
+ // Disable screen saver
951
+ XSetScreenSaver( _glfwLibrary.Dpy, 0, 0, DontPreferBlanking,
952
+ DefaultExposures );
953
+ }
954
+
955
+ // Attributes for window
956
+ wa.colormap = cmap;
957
+ wa.border_pixel = 0;
958
+ wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
959
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
960
+ ExposureMask | FocusChangeMask | VisibilityChangeMask;
961
+
962
+ // Create a window
963
+ _glfwWin.Win = XCreateWindow(
964
+ _glfwLibrary.Dpy,
965
+ RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ),
966
+ 0, 0, // Upper left corner
967
+ _glfwWin.Width, _glfwWin.Height, // Width, height
968
+ 0, // Borderwidth
969
+ _glfwWin.VI->depth, // Depth
970
+ InputOutput,
971
+ _glfwWin.VI->visual,
972
+ CWBorderPixel | CWColormap | CWEventMask,
973
+ &wa
974
+ );
975
+ if( !_glfwWin.Win )
976
+ {
977
+ _glfwPlatformCloseWindow();
978
+ return GL_FALSE;
979
+ }
980
+
981
+ // Get the delete window WM protocol atom
982
+ _glfwWin.WMDeleteWindow = XInternAtom( _glfwLibrary.Dpy,
983
+ "WM_DELETE_WINDOW",
984
+ False );
985
+
986
+ // Get the ping WM protocol atom
987
+ _glfwWin.WMPing = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_PING", False );
988
+
989
+ protocols[0] = _glfwWin.WMDeleteWindow;
990
+ protocols[1] = _glfwWin.WMPing;
991
+
992
+ // Allow us to trap the Window Close protocol
993
+ XSetWMProtocols( _glfwLibrary.Dpy, _glfwWin.Win, protocols,
994
+ sizeof(protocols) / sizeof(Atom) );
995
+
996
+ // Remove window decorations for fullscreen windows
997
+ if( mode == GLFW_FULLSCREEN )
998
+ {
999
+ _glfwDisableDecorations();
1000
+ }
1001
+
1002
+ _glfwWin.Hints = XAllocSizeHints();
1003
+
1004
+ if( hints->WindowNoResize )
1005
+ {
1006
+ _glfwWin.Hints->flags |= (PMinSize | PMaxSize);
1007
+ _glfwWin.Hints->min_width = _glfwWin.Hints->max_width = _glfwWin.Width;
1008
+ _glfwWin.Hints->min_height = _glfwWin.Hints->max_height = _glfwWin.Height;
1009
+ }
1010
+
1011
+ if( mode == GLFW_FULLSCREEN )
1012
+ {
1013
+ _glfwWin.Hints->flags |= PPosition;
1014
+ _glfwWin.Hints->x = 0;
1015
+ _glfwWin.Hints->y = 0;
1016
+ }
1017
+
1018
+ XSetWMNormalHints( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Hints );
1019
+
1020
+ // Map window
1021
+ XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
1022
+
1023
+ // Wait for map notification
1024
+ XIfEvent( _glfwLibrary.Dpy, &event, _glfwWaitForMapNotify,
1025
+ (char*)_glfwWin.Win );
1026
+
1027
+ // Make sure that our window ends up on top of things
1028
+ XRaiseWindow( _glfwLibrary.Dpy, _glfwWin.Win );
1029
+
1030
+ // Fullscreen mode "post processing"
1031
+ if( mode == GLFW_FULLSCREEN )
1032
+ {
1033
+ #if defined( _GLFW_HAS_XRANDR )
1034
+ // Request screen change notifications
1035
+ if( _glfwLibrary.XRandR.Available )
1036
+ {
1037
+ XRRSelectInput( _glfwLibrary.Dpy,
1038
+ _glfwWin.Win,
1039
+ RRScreenChangeNotifyMask );
1040
+ }
1041
+ #endif
1042
+
1043
+ // Force window position/size (some WMs do their own window
1044
+ // geometry, which we want to override)
1045
+ XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 );
1046
+ XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Width,
1047
+ _glfwWin.Height );
1048
+
1049
+ // Grab keyboard
1050
+ if( XGrabKeyboard( _glfwLibrary.Dpy, _glfwWin.Win, True,
1051
+ GrabModeAsync, GrabModeAsync, CurrentTime ) ==
1052
+ GrabSuccess )
1053
+ {
1054
+ _glfwWin.KeyboardGrabbed = GL_TRUE;
1055
+ }
1056
+
1057
+ // Grab mouse cursor
1058
+ if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True,
1059
+ ButtonPressMask | ButtonReleaseMask |
1060
+ PointerMotionMask, GrabModeAsync, GrabModeAsync,
1061
+ _glfwWin.Win, None, CurrentTime ) ==
1062
+ GrabSuccess )
1063
+ {
1064
+ _glfwWin.PointerGrabbed = GL_TRUE;
1065
+ }
1066
+
1067
+ // Try to get window inside viewport (for virtual displays) by
1068
+ // moving the mouse cursor to the upper left corner (and then to
1069
+ // the center) - this works for XFree86
1070
+ XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0, 0,0 );
1071
+ XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0,
1072
+ _glfwWin.Width/2, _glfwWin.Height/2 );
1073
+ }
1074
+
1075
+ // Set window & icon name
1076
+ _glfwPlatformSetWindowTitle( "GLFW Window" );
1077
+
1078
+ // Connect the context to the window
1079
+ glXMakeCurrent( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.CX );
1080
+
1081
+ // Start by clearing the front buffer to black (avoid ugly desktop
1082
+ // remains in our OpenGL window)
1083
+ glClear( GL_COLOR_BUFFER_BIT );
1084
+ glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win );
1085
+
1086
+ // Initialize GLX-specific OpenGL extensions
1087
+ _glfwInitGLXExtensions();
1088
+
1089
+ return GL_TRUE;
1090
+ }
1091
+
1092
+
1093
+ //========================================================================
1094
+ // Properly kill the window/video display
1095
+ //========================================================================
1096
+
1097
+ void _glfwPlatformCloseWindow( void )
1098
+ {
1099
+ #if defined( _GLFW_HAS_XRANDR )
1100
+ XRRScreenConfiguration *sc;
1101
+ Window root;
1102
+ #endif
1103
+
1104
+ // Free WM size hints
1105
+ if( _glfwWin.Hints )
1106
+ {
1107
+ XFree( _glfwWin.Hints );
1108
+ _glfwWin.Hints = NULL;
1109
+ }
1110
+
1111
+ // Do we have a rendering context?
1112
+ if( _glfwWin.CX )
1113
+ {
1114
+ // Release the context
1115
+ glXMakeCurrent( _glfwLibrary.Dpy, None, NULL );
1116
+
1117
+ // Delete the context
1118
+ glXDestroyContext( _glfwLibrary.Dpy, _glfwWin.CX );
1119
+ _glfwWin.CX = NULL;
1120
+ }
1121
+
1122
+ // Ungrab pointer and/or keyboard?
1123
+ if( _glfwWin.KeyboardGrabbed )
1124
+ {
1125
+ XUngrabKeyboard( _glfwLibrary.Dpy, CurrentTime );
1126
+ _glfwWin.KeyboardGrabbed = GL_FALSE;
1127
+ }
1128
+ if( _glfwWin.PointerGrabbed )
1129
+ {
1130
+ XUngrabPointer( _glfwLibrary.Dpy, CurrentTime );
1131
+ _glfwWin.PointerGrabbed = GL_FALSE;
1132
+ }
1133
+
1134
+ // Do we have a window?
1135
+ if( _glfwWin.Win )
1136
+ {
1137
+ // Unmap the window
1138
+ XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
1139
+
1140
+ // Destroy the window
1141
+ XDestroyWindow( _glfwLibrary.Dpy, _glfwWin.Win );
1142
+ _glfwWin.Win = (Window) 0;
1143
+ }
1144
+
1145
+ // Did we change the fullscreen resolution?
1146
+ if( _glfwWin.FS.ModeChanged )
1147
+ {
1148
+ #if defined( _GLFW_HAS_XRANDR )
1149
+ if( _glfwLibrary.XRandR.Available )
1150
+ {
1151
+ root = RootWindow( _glfwLibrary.Dpy, _glfwWin.Scrn );
1152
+ sc = XRRGetScreenInfo( _glfwLibrary.Dpy, root );
1153
+
1154
+ XRRSetScreenConfig( _glfwLibrary.Dpy,
1155
+ sc,
1156
+ root,
1157
+ _glfwWin.FS.OldSizeID,
1158
+ _glfwWin.FS.OldRotation,
1159
+ CurrentTime );
1160
+
1161
+ XRRFreeScreenConfigInfo( sc );
1162
+ }
1163
+ #elif defined( _GLFW_HAS_XF86VIDMODE )
1164
+ if( _glfwLibrary.XF86VidMode.Available )
1165
+ {
1166
+ // Unlock mode switch
1167
+ XF86VidModeLockModeSwitch( _glfwLibrary.Dpy,
1168
+ _glfwWin.Scrn,
1169
+ 0 );
1170
+
1171
+ // Change the video mode back to the old mode
1172
+ XF86VidModeSwitchToMode( _glfwLibrary.Dpy,
1173
+ _glfwWin.Scrn, &_glfwWin.FS.OldMode );
1174
+ }
1175
+ #endif
1176
+ _glfwWin.FS.ModeChanged = GL_FALSE;
1177
+ }
1178
+
1179
+ // Did we change the screen saver setting?
1180
+ if( _glfwWin.Saver.Changed )
1181
+ {
1182
+ // Restore old screen saver settings
1183
+ XSetScreenSaver( _glfwLibrary.Dpy, _glfwWin.Saver.Timeout,
1184
+ _glfwWin.Saver.Interval, _glfwWin.Saver.Blanking,
1185
+ _glfwWin.Saver.Exposure );
1186
+ _glfwWin.Saver.Changed = GL_FALSE;
1187
+ }
1188
+
1189
+ XSync( _glfwLibrary.Dpy, True );
1190
+ }
1191
+
1192
+
1193
+ //========================================================================
1194
+ // _glfwPlatformSetWindowTitle() - Set the window title.
1195
+ //========================================================================
1196
+
1197
+ void _glfwPlatformSetWindowTitle( const char *title )
1198
+ {
1199
+ // Set window & icon title
1200
+ XStoreName( _glfwLibrary.Dpy, _glfwWin.Win, title );
1201
+ XSetIconName( _glfwLibrary.Dpy, _glfwWin.Win, title );
1202
+ }
1203
+
1204
+
1205
+ //========================================================================
1206
+ // _glfwPlatformSetWindowSize() - Set the window size.
1207
+ //========================================================================
1208
+
1209
+ void _glfwPlatformSetWindowSize( int width, int height )
1210
+ {
1211
+ int mode = 0, rate, sizechanged = GL_FALSE;
1212
+ GLint drawbuffer;
1213
+ GLfloat clearcolor[4];
1214
+
1215
+ rate = _glfwWin.RefreshRate;
1216
+
1217
+ // If we are in fullscreen mode, get some info about the current mode
1218
+ if( _glfwWin.Fullscreen )
1219
+ {
1220
+ // Get closest match for target video mode
1221
+ mode = _glfwGetClosestVideoMode( _glfwWin.Scrn, &width, &height, &rate );
1222
+ }
1223
+
1224
+ if( _glfwWin.WindowNoResize )
1225
+ {
1226
+ _glfwWin.Hints->min_width = _glfwWin.Hints->max_width = width;
1227
+ _glfwWin.Hints->min_height = _glfwWin.Hints->max_height = height;
1228
+ }
1229
+
1230
+ XSetWMNormalHints( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Hints );
1231
+
1232
+ // Change window size before changing fullscreen mode?
1233
+ if( _glfwWin.Fullscreen && (width > _glfwWin.Width) )
1234
+ {
1235
+ XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, width, height );
1236
+ sizechanged = GL_TRUE;
1237
+ }
1238
+
1239
+ // Change fullscreen video mode?
1240
+ if( _glfwWin.Fullscreen )
1241
+ {
1242
+ // Change video mode (keeping current rate)
1243
+ _glfwSetVideoModeMODE( _glfwWin.Scrn, mode, _glfwWin.RefreshRate );
1244
+
1245
+ // Clear the front buffer to black (avoid ugly desktop remains in
1246
+ // our OpenGL window)
1247
+ glGetIntegerv( GL_DRAW_BUFFER, &drawbuffer );
1248
+ glGetFloatv( GL_COLOR_CLEAR_VALUE, clearcolor );
1249
+ glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
1250
+ glClear( GL_COLOR_BUFFER_BIT );
1251
+ if( drawbuffer == GL_BACK )
1252
+ {
1253
+ glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win );
1254
+ }
1255
+ glClearColor( clearcolor[0], clearcolor[1], clearcolor[2],
1256
+ clearcolor[3] );
1257
+ }
1258
+
1259
+ // Set window size (if not already changed)
1260
+ if( !sizechanged )
1261
+ {
1262
+ XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, width, height );
1263
+ }
1264
+ }
1265
+
1266
+
1267
+ //========================================================================
1268
+ // _glfwPlatformSetWindowPos() - Set the window position.
1269
+ //========================================================================
1270
+
1271
+ void _glfwPlatformSetWindowPos( int x, int y )
1272
+ {
1273
+ // Set window position
1274
+ XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, x, y );
1275
+ }
1276
+
1277
+
1278
+ //========================================================================
1279
+ // _glfwPlatformIconfyWindow() - Window iconification
1280
+ //========================================================================
1281
+
1282
+ void _glfwPlatformIconifyWindow( void )
1283
+ {
1284
+ // We can't do this for override redirect windows
1285
+ if( _glfwWin.OverrideRedirect )
1286
+ {
1287
+ return;
1288
+ }
1289
+
1290
+ // In fullscreen mode, we need to restore the desktop video mode
1291
+ if( _glfwWin.Fullscreen )
1292
+ {
1293
+ #if defined( _GLFW_HAS_XF86VIDMODE )
1294
+ if( _glfwLibrary.XF86VidMode.Available )
1295
+ {
1296
+ // Unlock mode switch
1297
+ XF86VidModeLockModeSwitch( _glfwLibrary.Dpy,
1298
+ _glfwWin.Scrn,
1299
+ 0 );
1300
+
1301
+ // Change the video mode back to the old mode
1302
+ XF86VidModeSwitchToMode( _glfwLibrary.Dpy,
1303
+ _glfwWin.Scrn, &_glfwWin.FS.OldMode );
1304
+ }
1305
+ #endif
1306
+ _glfwWin.FS.ModeChanged = GL_FALSE;
1307
+ }
1308
+
1309
+ // Show mouse pointer
1310
+ if( _glfwWin.PointerHidden )
1311
+ {
1312
+ XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win );
1313
+ _glfwWin.PointerHidden = GL_FALSE;
1314
+ }
1315
+
1316
+ // Un-grab mouse pointer
1317
+ if( _glfwWin.PointerGrabbed )
1318
+ {
1319
+ XUngrabPointer( _glfwLibrary.Dpy, CurrentTime );
1320
+ _glfwWin.PointerGrabbed = GL_FALSE;
1321
+ }
1322
+
1323
+ // Iconify window
1324
+ XIconifyWindow( _glfwLibrary.Dpy, _glfwWin.Win,
1325
+ _glfwWin.Scrn );
1326
+
1327
+ // Window is now iconified
1328
+ _glfwWin.Iconified = GL_TRUE;
1329
+ }
1330
+
1331
+
1332
+ //========================================================================
1333
+ // Window un-iconification
1334
+ //========================================================================
1335
+
1336
+ void _glfwPlatformRestoreWindow( void )
1337
+ {
1338
+ // We can't do this for override redirect windows
1339
+ if( _glfwWin.OverrideRedirect )
1340
+ {
1341
+ return;
1342
+ }
1343
+
1344
+ // In fullscreen mode, change back video mode to user selected mode
1345
+ if( _glfwWin.Fullscreen )
1346
+ {
1347
+ _glfwSetVideoMode( _glfwWin.Scrn,
1348
+ &_glfwWin.Width, &_glfwWin.Height, &_glfwWin.RefreshRate );
1349
+ }
1350
+
1351
+ // Un-iconify window
1352
+ XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
1353
+
1354
+ // In fullscreen mode...
1355
+ if( _glfwWin.Fullscreen )
1356
+ {
1357
+ // Make sure window is in upper left corner
1358
+ XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 );
1359
+
1360
+ // Get input focus
1361
+ XSetInputFocus( _glfwLibrary.Dpy, _glfwWin.Win, RevertToParent,
1362
+ CurrentTime );
1363
+ }
1364
+
1365
+ // Lock mouse, if necessary
1366
+ if( _glfwWin.MouseLock )
1367
+ {
1368
+ // Hide cursor
1369
+ if( !_glfwWin.PointerHidden )
1370
+ {
1371
+ XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win,
1372
+ _glfwCreateNULLCursor( _glfwLibrary.Dpy,
1373
+ _glfwWin.Win ) );
1374
+ _glfwWin.PointerHidden = GL_TRUE;
1375
+ }
1376
+
1377
+ // Grab cursor
1378
+ if( !_glfwWin.PointerGrabbed )
1379
+ {
1380
+ if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True,
1381
+ ButtonPressMask | ButtonReleaseMask |
1382
+ PointerMotionMask, GrabModeAsync,
1383
+ GrabModeAsync, _glfwWin.Win, None,
1384
+ CurrentTime ) == GrabSuccess )
1385
+ {
1386
+ _glfwWin.PointerGrabbed = GL_TRUE;
1387
+ }
1388
+ }
1389
+ }
1390
+
1391
+ // Window is no longer iconified
1392
+ _glfwWin.Iconified = GL_FALSE;
1393
+ }
1394
+
1395
+
1396
+ //========================================================================
1397
+ // _glfwPlatformSwapBuffers() - Swap buffers (double-buffering) and poll
1398
+ // any new events.
1399
+ //========================================================================
1400
+
1401
+ void _glfwPlatformSwapBuffers( void )
1402
+ {
1403
+ // Update display-buffer
1404
+ glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win );
1405
+ }
1406
+
1407
+
1408
+ //========================================================================
1409
+ // _glfwPlatformSwapInterval() - Set double buffering swap interval
1410
+ //========================================================================
1411
+
1412
+ void _glfwPlatformSwapInterval( int interval )
1413
+ {
1414
+ if( _glfwWin.SwapInterval )
1415
+ {
1416
+ _glfwWin.SwapInterval( interval );
1417
+ }
1418
+ }
1419
+
1420
+
1421
+ //========================================================================
1422
+ // _glfwPlatformRefreshWindowParams()
1423
+ //========================================================================
1424
+
1425
+ void _glfwPlatformRefreshWindowParams( void )
1426
+ {
1427
+ #if defined( _GLFW_HAS_XRANDR )
1428
+ XRRScreenConfiguration *sc;
1429
+ #elif defined( _GLFW_HAS_XF86VIDMODE )
1430
+ XF86VidModeModeLine modeline;
1431
+ int dotclock;
1432
+ float pixels_per_second, pixels_per_frame;
1433
+ #endif
1434
+ int sample_buffers;
1435
+
1436
+ // AFAIK, there is no easy/sure way of knowing if OpenGL is hardware
1437
+ // accelerated
1438
+ _glfwWin.Accelerated = GL_TRUE;
1439
+
1440
+ // "Standard" window parameters
1441
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_RED_SIZE,
1442
+ &_glfwWin.RedBits );
1443
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_GREEN_SIZE,
1444
+ &_glfwWin.GreenBits );
1445
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_BLUE_SIZE,
1446
+ &_glfwWin.BlueBits );
1447
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ALPHA_SIZE,
1448
+ &_glfwWin.AlphaBits );
1449
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_DEPTH_SIZE,
1450
+ &_glfwWin.DepthBits );
1451
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_STENCIL_SIZE,
1452
+ &_glfwWin.StencilBits );
1453
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_RED_SIZE,
1454
+ &_glfwWin.AccumRedBits );
1455
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_GREEN_SIZE,
1456
+ &_glfwWin.AccumGreenBits );
1457
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_BLUE_SIZE,
1458
+ &_glfwWin.AccumBlueBits );
1459
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_ALPHA_SIZE,
1460
+ &_glfwWin.AccumAlphaBits );
1461
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_AUX_BUFFERS,
1462
+ &_glfwWin.AuxBuffers );
1463
+
1464
+ // Get stereo rendering setting
1465
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_STEREO,
1466
+ &_glfwWin.Stereo );
1467
+ _glfwWin.Stereo = _glfwWin.Stereo ? 1 : 0;
1468
+
1469
+ // Get multisample buffer samples
1470
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_SAMPLES,
1471
+ &_glfwWin.Samples );
1472
+ glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_SAMPLE_BUFFERS,
1473
+ &sample_buffers );
1474
+ if( sample_buffers == 0 )
1475
+ _glfwWin.Samples = 0;
1476
+
1477
+ // Default to refresh rate unknown (=0 according to GLFW spec)
1478
+ _glfwWin.RefreshRate = 0;
1479
+
1480
+ // Retrieve refresh rate, if possible
1481
+ #if defined( _GLFW_HAS_XRANDR )
1482
+ if( _glfwLibrary.XRandR.Available )
1483
+ {
1484
+ sc = XRRGetScreenInfo( _glfwLibrary.Dpy,
1485
+ RootWindow( _glfwLibrary.Dpy, _glfwWin.Scrn ) );
1486
+ _glfwWin.RefreshRate = XRRConfigCurrentRate( sc );
1487
+ XRRFreeScreenConfigInfo( sc );
1488
+ }
1489
+ #elif defined( _GLFW_HAS_XF86VIDMODE )
1490
+ if( _glfwLibrary.XF86VidMode.Available )
1491
+ {
1492
+ // Use the XF86VidMode extension to get current video mode
1493
+ XF86VidModeGetModeLine( _glfwLibrary.Dpy, _glfwWin.Scrn,
1494
+ &dotclock, &modeline );
1495
+ pixels_per_second = 1000.0f * (float) dotclock;
1496
+ pixels_per_frame = (float) modeline.htotal * modeline.vtotal;
1497
+ _glfwWin.RefreshRate = (int)(pixels_per_second/pixels_per_frame+0.5);
1498
+ }
1499
+ #endif
1500
+ }
1501
+
1502
+
1503
+ //========================================================================
1504
+ // _glfwPlatformPollEvents() - Poll for new window and input events
1505
+ //========================================================================
1506
+
1507
+ void _glfwPlatformPollEvents( void )
1508
+ {
1509
+ int winclosed = GL_FALSE;
1510
+
1511
+ // Flag that the cursor has not moved
1512
+ _glfwInput.MouseMoved = GL_FALSE;
1513
+
1514
+ // Clear MapNotify and FocusIn counts
1515
+ _glfwWin.MapNotifyCount = 0;
1516
+ _glfwWin.FocusInCount = 0;
1517
+
1518
+ // Use XSync to synchronise events to the X display.
1519
+ // I don't know if this can have a serious performance impact. My
1520
+ // benchmarks with a GeForce card under Linux shows no difference with
1521
+ // or without XSync, but when the GL window is rendered over a slow
1522
+ // network I have noticed bad event syncronisation problems when XSync
1523
+ // is not used, so I decided to use it.
1524
+ XSync( _glfwLibrary.Dpy, False );
1525
+
1526
+ // Empty the window event queue
1527
+ while( XPending( _glfwLibrary.Dpy ) )
1528
+ {
1529
+ if( _glfwGetNextEvent() )
1530
+ {
1531
+ winclosed = GL_TRUE;
1532
+ }
1533
+ }
1534
+
1535
+ // Did we get mouse movement in locked cursor mode?
1536
+ if( _glfwInput.MouseMoved && _glfwWin.MouseLock )
1537
+ {
1538
+ int maxx, minx, maxy, miny;
1539
+
1540
+ // Calculate movement threshold
1541
+ minx = _glfwWin.Width / 4;
1542
+ maxx = (_glfwWin.Width * 3) / 4;
1543
+ miny = _glfwWin.Height / 4;
1544
+ maxy = (_glfwWin.Height * 3) / 4;
1545
+
1546
+ // Did the mouse cursor move beyond our movement threshold
1547
+ if(_glfwInput.CursorPosX < minx || _glfwInput.CursorPosX > maxx ||
1548
+ _glfwInput.CursorPosY < miny || _glfwInput.CursorPosY > maxy)
1549
+ {
1550
+ // Move the mouse pointer back to the window center so that it
1551
+ // does not wander off...
1552
+ _glfwPlatformSetMouseCursorPos( _glfwWin.Width/2,
1553
+ _glfwWin.Height/2 );
1554
+ XSync( _glfwLibrary.Dpy, False );
1555
+ }
1556
+ }
1557
+
1558
+ // Was the window (un)iconified?
1559
+ if( _glfwWin.MapNotifyCount < 0 && !_glfwWin.Iconified )
1560
+ {
1561
+ // Show mouse pointer
1562
+ if( _glfwWin.PointerHidden )
1563
+ {
1564
+ XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win );
1565
+ _glfwWin.PointerHidden = GL_FALSE;
1566
+ }
1567
+
1568
+ // Un-grab mouse pointer
1569
+ if( _glfwWin.PointerGrabbed )
1570
+ {
1571
+ XUngrabPointer( _glfwLibrary.Dpy, CurrentTime );
1572
+ _glfwWin.PointerGrabbed = GL_FALSE;
1573
+ }
1574
+
1575
+ _glfwWin.Iconified = GL_TRUE;
1576
+ }
1577
+ else if( _glfwWin.MapNotifyCount > 0 && _glfwWin.Iconified )
1578
+ {
1579
+ // Restore fullscreen mode properties
1580
+ if( _glfwWin.Fullscreen )
1581
+ {
1582
+ // Change back video mode to user selected mode
1583
+ _glfwSetVideoMode( _glfwWin.Scrn, &_glfwWin.Width,
1584
+ &_glfwWin.Height, &_glfwWin.RefreshRate );
1585
+
1586
+ // Disable window manager decorations
1587
+ _glfwEnableDecorations();
1588
+
1589
+ // Make sure window is in upper left corner
1590
+ XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 );
1591
+
1592
+ // Get input focus
1593
+ XSetInputFocus( _glfwLibrary.Dpy, _glfwWin.Win,
1594
+ RevertToParent, CurrentTime );
1595
+ }
1596
+
1597
+ // Hide cursor if necessary
1598
+ if( _glfwWin.MouseLock && !_glfwWin.PointerHidden )
1599
+ {
1600
+ if( !_glfwWin.PointerHidden )
1601
+ {
1602
+ XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win,
1603
+ _glfwCreateNULLCursor( _glfwLibrary.Dpy,
1604
+ _glfwWin.Win ) );
1605
+ _glfwWin.PointerHidden = GL_TRUE;
1606
+ }
1607
+ }
1608
+
1609
+ // Grab cursor if necessary
1610
+ if( (_glfwWin.MouseLock || _glfwWin.Fullscreen) &&
1611
+ !_glfwWin.PointerGrabbed )
1612
+ {
1613
+ if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True,
1614
+ ButtonPressMask | ButtonReleaseMask |
1615
+ PointerMotionMask, GrabModeAsync,
1616
+ GrabModeAsync, _glfwWin.Win, None,
1617
+ CurrentTime ) == GrabSuccess )
1618
+ {
1619
+ _glfwWin.PointerGrabbed = GL_TRUE;
1620
+ }
1621
+ }
1622
+
1623
+ _glfwWin.Iconified = GL_FALSE;
1624
+ }
1625
+
1626
+ // Did the window get/lose focus
1627
+ if( _glfwWin.FocusInCount > 0 && !_glfwWin.Active )
1628
+ {
1629
+ // If we are in fullscreen mode, restore window
1630
+ if( _glfwWin.Fullscreen && _glfwWin.Iconified )
1631
+ {
1632
+ _glfwPlatformRestoreWindow();
1633
+ }
1634
+
1635
+ // Window is now active
1636
+ _glfwWin.Active = GL_TRUE;
1637
+ }
1638
+ else if( _glfwWin.FocusInCount < 0 && _glfwWin.Active )
1639
+ {
1640
+ // If we are in fullscreen mode, iconfify window
1641
+ if( _glfwWin.Fullscreen )
1642
+ {
1643
+ _glfwPlatformIconifyWindow();
1644
+ }
1645
+
1646
+ // Window is not active
1647
+ _glfwWin.Active = GL_FALSE;
1648
+ _glfwInputDeactivation();
1649
+ }
1650
+
1651
+ // Was there a window close request?
1652
+ if( winclosed && _glfwWin.WindowCloseCallback )
1653
+ {
1654
+ // Check if the program wants us to close the window
1655
+ winclosed = _glfwWin.WindowCloseCallback();
1656
+ }
1657
+ if( winclosed )
1658
+ {
1659
+ glfwCloseWindow();
1660
+ }
1661
+ }
1662
+
1663
+
1664
+ //========================================================================
1665
+ // _glfwPlatformWaitEvents() - Wait for new window and input events
1666
+ //========================================================================
1667
+
1668
+ void _glfwPlatformWaitEvents( void )
1669
+ {
1670
+ XEvent event;
1671
+
1672
+ // Wait for new events (blocking)
1673
+ XNextEvent( _glfwLibrary.Dpy, &event );
1674
+ XPutBackEvent( _glfwLibrary.Dpy, &event );
1675
+
1676
+ // Poll events from queue
1677
+ _glfwPlatformPollEvents();
1678
+ }
1679
+
1680
+
1681
+ //========================================================================
1682
+ // _glfwPlatformHideMouseCursor() - Hide mouse cursor (lock it)
1683
+ //========================================================================
1684
+
1685
+ void _glfwPlatformHideMouseCursor( void )
1686
+ {
1687
+ // Hide cursor
1688
+ if( !_glfwWin.PointerHidden )
1689
+ {
1690
+ XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win,
1691
+ _glfwCreateNULLCursor( _glfwLibrary.Dpy,
1692
+ _glfwWin.Win ) );
1693
+ _glfwWin.PointerHidden = GL_TRUE;
1694
+ }
1695
+
1696
+ // Grab cursor to user window
1697
+ if( !_glfwWin.PointerGrabbed )
1698
+ {
1699
+ if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True,
1700
+ ButtonPressMask | ButtonReleaseMask |
1701
+ PointerMotionMask, GrabModeAsync, GrabModeAsync,
1702
+ _glfwWin.Win, None, CurrentTime ) ==
1703
+ GrabSuccess )
1704
+ {
1705
+ _glfwWin.PointerGrabbed = GL_TRUE;
1706
+ }
1707
+ }
1708
+ }
1709
+
1710
+
1711
+ //========================================================================
1712
+ // _glfwPlatformShowMouseCursor() - Show mouse cursor (unlock it)
1713
+ //========================================================================
1714
+
1715
+ void _glfwPlatformShowMouseCursor( void )
1716
+ {
1717
+ // Un-grab cursor (only in windowed mode: in fullscreen mode we still
1718
+ // want the mouse grabbed in order to confine the cursor to the window
1719
+ // area)
1720
+ if( _glfwWin.PointerGrabbed && !_glfwWin.Fullscreen )
1721
+ {
1722
+ XUngrabPointer( _glfwLibrary.Dpy, CurrentTime );
1723
+ _glfwWin.PointerGrabbed = GL_FALSE;
1724
+ }
1725
+
1726
+ // Show cursor
1727
+ if( _glfwWin.PointerHidden )
1728
+ {
1729
+ XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win );
1730
+ _glfwWin.PointerHidden = GL_FALSE;
1731
+ }
1732
+ }
1733
+
1734
+
1735
+ //========================================================================
1736
+ // _glfwPlatformSetMouseCursorPos() - Set physical mouse cursor position
1737
+ //========================================================================
1738
+
1739
+ void _glfwPlatformSetMouseCursorPos( int x, int y )
1740
+ {
1741
+ // Change cursor position
1742
+ _glfwInput.CursorPosX = x;
1743
+ _glfwInput.CursorPosY = y;
1744
+ XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0, x, y );
1745
+ }
1746
+