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,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
+