1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
//========================================================================
// GLFW - An OpenGL framework
// File: x11_init.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// Initialize GLFW thread package
//========================================================================
static void _glfwInitThreads( void )
{
// Initialize critical section handle
#ifdef _GLFW_HAS_PTHREAD
(void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL );
#endif
// The first thread (the main thread) has ID 0
_glfwThrd.NextID = 0;
// Fill out information about the main thread (this thread)
_glfwThrd.First.ID = _glfwThrd.NextID++;
_glfwThrd.First.Function = NULL;
_glfwThrd.First.Previous = NULL;
_glfwThrd.First.Next = NULL;
#ifdef _GLFW_HAS_PTHREAD
_glfwThrd.First.PosixID = pthread_self();
#endif
}
//========================================================================
// Terminate GLFW thread package
//========================================================================
static void _glfwTerminateThreads( void )
{
#ifdef _GLFW_HAS_PTHREAD
_GLFWthread *t, *t_next;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO
// DIE, _BEFORE_ CALLING glfwTerminate()!!!)
t = _glfwThrd.First.Next;
while( t != NULL )
{
// Get pointer to next thread
t_next = t->Next;
// Simply murder the process, no mercy!
pthread_kill( t->PosixID, SIGKILL );
// Free memory allocated for this thread
free( (void *) t );
// Select next thread in list
t = t_next;
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Delete critical section handle
pthread_mutex_destroy( &_glfwThrd.CriticalSection );
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// Dynamically load libraries
//========================================================================
#ifdef _GLFW_DLOPEN_LIBGL
static char * _glfw_libGL_name[ ] =
{
"libGL.so",
"libGL.so.1",
"/usr/lib/libGL.so",
"/usr/lib/libGL.so.1",
NULL
};
#endif
static void _glfwInitLibraries( void )
{
#ifdef _GLFW_DLOPEN_LIBGL
int i;
_glfwLibrary.Libs.libGL = NULL;
for( i = 0; !_glfw_libGL_name[ i ] != NULL; i ++ )
{
_glfwLibrary.Libs.libGL = dlopen( _glfw_libGL_name[ i ],
RTLD_LAZY | RTLD_GLOBAL );
if( _glfwLibrary.Libs.libGL )
break;
}
#endif
}
//========================================================================
// Terminate GLFW when exiting application
//========================================================================
void _glfwTerminate_atexit( void )
{
glfwTerminate();
}
//========================================================================
// Initialize X11 display
//========================================================================
static int _glfwInitDisplay( void )
{
// Open display
_glfwLibrary.Dpy = XOpenDisplay( 0 );
if( !_glfwLibrary.Dpy )
{
return GL_FALSE;
}
// Check screens
_glfwLibrary.NumScreens = ScreenCount( _glfwLibrary.Dpy );
_glfwLibrary.DefaultScreen = DefaultScreen( _glfwLibrary.Dpy );
// Check for XF86VidMode extension
#ifdef _GLFW_HAS_XF86VIDMODE
_glfwLibrary.XF86VidMode.Available =
XF86VidModeQueryExtension( _glfwLibrary.Dpy,
&_glfwLibrary.XF86VidMode.EventBase,
&_glfwLibrary.XF86VidMode.ErrorBase);
#else
_glfwLibrary.XF86VidMode.Available = 0;
#endif
// Check for XRandR extension
#ifdef _GLFW_HAS_XRANDR
_glfwLibrary.XRandR.Available =
XRRQueryExtension( _glfwLibrary.Dpy,
&_glfwLibrary.XRandR.EventBase,
&_glfwLibrary.XRandR.ErrorBase );
#else
_glfwLibrary.XRandR.Available = 0;
#endif
return GL_TRUE;
}
//========================================================================
// Terminate X11 display
//========================================================================
static void _glfwTerminateDisplay( void )
{
// Open display
if( _glfwLibrary.Dpy )
{
XCloseDisplay( _glfwLibrary.Dpy );
_glfwLibrary.Dpy = NULL;
}
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// Initialize various GLFW state
//========================================================================
int _glfwPlatformInit( void )
{
// Initialize display
if( !_glfwInitDisplay() )
{
return GL_FALSE;
}
// Initialize thread package
_glfwInitThreads();
// Try to load libGL.so if necessary
_glfwInitLibraries();
// Install atexit() routine
atexit( _glfwTerminate_atexit );
// Initialize joysticks
_glfwInitJoysticks();
// Start the timer
_glfwInitTimer();
return GL_TRUE;
}
//========================================================================
// Close window and kill all threads
//========================================================================
int _glfwPlatformTerminate( void )
{
#ifdef _GLFW_HAS_PTHREAD
// Only the main thread is allowed to do this...
if( pthread_self() != _glfwThrd.First.PosixID )
{
return GL_FALSE;
}
#endif // _GLFW_HAS_PTHREAD
// Close OpenGL window
glfwCloseWindow();
// Kill thread package
_glfwTerminateThreads();
// Terminate display
_glfwTerminateDisplay();
// Terminate joysticks
_glfwTerminateJoysticks();
// Unload libGL.so if necessary
#ifdef _GLFW_DLOPEN_LIBGL
if( _glfwLibrary.Libs.libGL != NULL )
{
dlclose( _glfwLibrary.Libs.libGL );
_glfwLibrary.Libs.libGL = NULL;
}
#endif
return GL_TRUE;
}
|