source: trunk/src/opengl/glut/glut_init.c

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 10.1 KB
Line 
1/* $Id: glut_init.c,v 1.5 2000-05-20 13:48:23 jeroen Exp $ */
2/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
3
4/* This program is freely distributable without licensing fees
5 and is provided without guarantee or warrantee expressed or
6 implied. This program is -not- in the public domain. */
7
8#include <stdlib.h>
9#include <string.h>
10#include <stdio.h>
11
12#if !defined(_WIN32) && !defined(__WIN32OS2__)
13#include <X11/Xlib.h>
14#include <X11/Xatom.h>
15#endif
16
17#if defined(__WIN32OS2__)
18#include <windows.h>
19#include "GL/gl.h"
20#undef WH_NB_HOOKS /* Get rid of copiler warning... */
21#endif
22
23/* SGI optimization introduced in IRIX 6.3 to avoid X server
24 round trips for interning common X atoms. */
25#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
26#include <X11/SGIFastAtom.h>
27#else
28#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
29#endif
30
31#include "glutint.h"
32
33/* GLUT inter-file variables */
34/* *INDENT-OFF* */
35char *__glutProgramName = NULL;
36int __glutArgc = 0;
37char **__glutArgv = NULL;
38char *__glutGeometry = NULL;
39Display *__glutDisplay = NULL;
40int __glutScreen;
41Window __glutRoot;
42int __glutScreenHeight;
43int __glutScreenWidth;
44GLboolean __glutIconic = GL_FALSE;
45GLboolean __glutDebug = GL_FALSE;
46unsigned int __glutDisplayMode =
47 GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
48char *__glutDisplayString = NULL;
49int __glutConnectionFD;
50XSizeHints __glutSizeHints = {0};
51int __glutInitWidth = 300, __glutInitHeight = 300;
52int __glutInitX = -1, __glutInitY = -1;
53GLboolean __glutForceDirect = GL_FALSE,
54 __glutTryDirect = GL_TRUE;
55Atom __glutWMDeleteWindow;
56/* *INDENT-ON* */
57
58static Bool synchronize = False;
59
60#if defined(_WIN32) || defined(__WIN32OS2__)
61
62#if defined(__BORLANDC__) || defined(__WIN32OS2__)
63#include <float.h> /* For masking floating point exceptions. */
64#endif
65
66void
67__glutOpenWin32Connection(char* display)
68{
69 static char *classname;
70 WNDCLASS wc;
71 HINSTANCE hInstance = GetModuleHandle(NULL);
72
73 /* Make sure we register the window only once. */
74 if(classname)
75 return;
76
77#if defined(__BORLANDC__) || defined(__WIN32OS2__)
78 /* Under certain conditions (e.g. while rendering solid surfaces with
79 lighting enabled) Microsoft OpenGL libraries cause some illegal
80 operations like floating point overflow or division by zero. The
81 default behaviour of Microsoft compilers is to mask (ignore)
82 floating point exceptions, while Borland compilers do not. The
83 following function of Borland RTL allows to mask exceptions.
84 Advice from Pier Giorgio Esposito (mc2172@mclink.it). */
85 _control87(MCW_EM,MCW_EM);
86#endif
87
88 classname = "GLUT";
89
90 /* Clear (important!) and then fill in the window class structure. */
91 memset(&wc, 0, sizeof(WNDCLASS));
92 wc.hIcon = LoadIcon(hInstance, "GLUT_ICON");
93 wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
94
95 wc.lpfnWndProc = (WNDPROC)__glutWindowProc;
96 wc.style = CS_OWNDC;
97 wc.hInstance = hInstance;
98 wc.hbrBackground = NULL;
99 wc.lpszMenuName = NULL;
100 wc.lpszClassName = classname;
101
102 /* Fill in a default icon if one isn't specified as a resource. */
103 if(!wc.hIcon)
104 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
105
106 if(!RegisterClass(&wc)) {
107 __glutFatalError("RegisterClass() failed:"
108 "Cannot register GLUT window class.");
109 }
110
111 __glutScreenWidth = GetSystemMetrics(SM_CXSCREEN);
112 __glutScreenHeight = GetSystemMetrics(SM_CYSCREEN);
113
114 /* Set the root window to NULL because windows creates a top-level
115 window when the parent is NULL. X creates a top-level window
116 when the parent is the root window. */
117 __glutRoot = NULL;
118
119 /* Set the display to 1 -- we shouldn't be using this anywhere
120 (except as an argument to X calls). */
121 __glutDisplay = (Display*)1;
122
123 /* There isn't any concept of multiple screens in Win32, therefore,
124 we don't need to keep track of the screen we're on... it's always
125 the same one. */
126 __glutScreen = 0;
127}
128#else /* !_WIN32 */
129void
130__glutOpenXConnection(char *display)
131{
132 int errorBase, eventBase;
133
134 __glutDisplay = XOpenDisplay(display);
135 if (!__glutDisplay)
136 __glutFatalError("could not open display: %s",
137 XDisplayName(display));
138 if (synchronize)
139 XSynchronize(__glutDisplay, True);
140 if (!glXQueryExtension(__glutDisplay, &errorBase, &eventBase))
141 __glutFatalError(
142 "OpenGL GLX extension not supported by display: %s",
143 XDisplayName(display));
144 __glutScreen = DefaultScreen(__glutDisplay);
145 __glutRoot = RootWindow(__glutDisplay, __glutScreen);
146 __glutScreenWidth = DisplayWidth(__glutDisplay, __glutScreen);
147 __glutScreenHeight = DisplayHeight(__glutDisplay,
148 __glutScreen);
149 __glutConnectionFD = ConnectionNumber(__glutDisplay);
150 __glutWMDeleteWindow = XSGIFastInternAtom(__glutDisplay,
151 "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW, False);
152}
153#endif /* _WIN32 */
154
155void
156__glutInitTime(struct timeval *beginning)
157{
158 static int beenhere = 0;
159 static struct timeval genesis;
160
161 if (!beenhere) {
162 GETTIMEOFDAY(&genesis);
163 beenhere = 1;
164 }
165 *beginning = genesis;
166}
167
168static void
169removeArgs(int *argcp, char **argv, int numToRemove)
170{
171 int i, j;
172
173 for (i = 0, j = numToRemove; argv[j]; i++, j++) {
174 argv[i] = argv[j];
175 }
176 argv[i] = NULL;
177 *argcp -= numToRemove;
178}
179
180void GLAPIENTRY
181glutInit(int *argcp, char **argv)
182{
183 char *display = NULL;
184 char *str, *geometry = NULL;
185 struct timeval unused;
186 int i;
187
188 if (__glutDisplay) {
189 __glutWarning("glutInit being called a second time.");
190 return;
191 }
192 /* Determine temporary program name. */
193 str = strrchr(argv[0], '/');
194 if (str == NULL) {
195 __glutProgramName = argv[0];
196 } else {
197 __glutProgramName = str + 1;
198 }
199
200 /* Make private copy of command line arguments. */
201 __glutArgc = *argcp;
202 __glutArgv = (char **) malloc(__glutArgc * sizeof(char *));
203 if (!__glutArgv)
204 __glutFatalError("out of memory.");
205 for (i = 0; i < __glutArgc; i++) {
206 __glutArgv[i] = __glutStrdup(argv[i]);
207 if (!__glutArgv[i])
208 __glutFatalError("out of memory.");
209 }
210
211 /* determine permanent program name */
212 str = strrchr(__glutArgv[0], '/');
213 if (str == NULL) {
214 __glutProgramName = __glutArgv[0];
215 } else {
216 __glutProgramName = str + 1;
217 }
218
219 /* parse arguments for standard options */
220 for (i = 1; i < __glutArgc; i++) {
221 if (!strcmp(__glutArgv[i], "-display")) {
222#if defined(_WIN32) || defined(__WIN32OS2__)
223 __glutWarning("-display option invalid for win32 glut.");
224#endif
225 if (++i >= __glutArgc) {
226 __glutFatalError(
227 "follow -display option with X display name.");
228 }
229 display = __glutArgv[i];
230 removeArgs(argcp, &argv[1], 2);
231 } else if (!strcmp(__glutArgv[i], "-geometry")) {
232 if (++i >= __glutArgc) {
233 __glutFatalError(
234 "follow -geometry option with geometry parameter.");
235 }
236 geometry = __glutArgv[i];
237 removeArgs(argcp, &argv[1], 2);
238 } else if (!strcmp(__glutArgv[i], "-direct")) {
239#if defined(_WIN32) || defined(__WIN32OS2__)
240 __glutWarning("-direct option invalid for win32 glut.");
241#endif
242 if (!__glutTryDirect)
243 __glutFatalError(
244 "cannot force both direct and indirect rendering.");
245 __glutForceDirect = GL_TRUE;
246 removeArgs(argcp, &argv[1], 1);
247 } else if (!strcmp(__glutArgv[i], "-indirect")) {
248#if defined(_WIN32) || defined(__WIN32OS2__)
249 __glutWarning("-indirect option invalid for win32 glut.");
250#endif
251 if (__glutForceDirect)
252 __glutFatalError(
253 "cannot force both direct and indirect rendering.");
254 __glutTryDirect = GL_FALSE;
255 removeArgs(argcp, &argv[1], 1);
256 } else if (!strcmp(__glutArgv[i], "-iconic")) {
257 __glutIconic = GL_TRUE;
258 removeArgs(argcp, &argv[1], 1);
259 } else if (!strcmp(__glutArgv[i], "-gldebug")) {
260 __glutDebug = GL_TRUE;
261 removeArgs(argcp, &argv[1], 1);
262 } else if (!strcmp(__glutArgv[i], "-sync")) {
263#if defined(_WIN32) || defined(__WIN32OS2__)
264 __glutWarning("-indirect option invalid for win32 glut.");
265#endif
266 synchronize = GL_TRUE;
267 removeArgs(argcp, &argv[1], 1);
268 } else {
269 /* Once unknown option encountered, stop command line
270 processing. */
271 break;
272 }
273 }
274
275
276#if defined(_WIN32) || defined(__WIN32OS2__)
277 __glutOpenWin32Connection(display);
278#else
279 __glutOpenXConnection(display);
280#endif
281 if (geometry) {
282 int flags, x, y, width, height;
283
284 /* Fix bogus "{width|height} may be used before set"
285 warning */
286 width = 0;
287 height = 0;
288
289 flags = XParseGeometry(geometry, &x, &y,
290 (unsigned int *) &width, (unsigned int *) &height);
291 if (WidthValue & flags) {
292 /* Careful because X does not allow zero or negative
293 width windows */
294 if (width > 0)
295 __glutInitWidth = width;
296 }
297 if (HeightValue & flags) {
298 /* Careful because X does not allow zero or negative
299 height windows */
300 if (height > 0)
301 __glutInitHeight = height;
302 }
303 glutInitWindowSize(__glutInitWidth, __glutInitHeight);
304 if (XValue & flags) {
305 if (XNegative & flags)
306 x = DisplayWidth(__glutDisplay, __glutScreen) +
307 x - __glutSizeHints.width;
308 /* Play safe: reject negative X locations */
309 if (x >= 0)
310 __glutInitX = x;
311 }
312 if (YValue & flags) {
313 if (YNegative & flags)
314 y = DisplayHeight(__glutDisplay, __glutScreen) +
315 y - __glutSizeHints.height;
316 /* Play safe: reject negative Y locations */
317 if (y >= 0)
318 __glutInitY = y;
319 }
320 glutInitWindowPosition(__glutInitX, __glutInitY);
321 }
322 __glutInitTime(&unused);
323}
324
325/* CENTRY */
326void GLAPIENTRY
327glutInitWindowPosition(int x, int y)
328{
329 __glutInitX = x;
330 __glutInitY = y;
331 if (x >= 0 && y >= 0) {
332 __glutSizeHints.x = x;
333 __glutSizeHints.y = y;
334 __glutSizeHints.flags |= USPosition;
335 } else {
336 __glutSizeHints.flags &= ~USPosition;
337 }
338}
339
340void GLAPIENTRY
341glutInitWindowSize(int width, int height)
342{
343 __glutInitWidth = width;
344 __glutInitHeight = height;
345 if (width > 0 && height > 0) {
346 __glutSizeHints.width = width;
347 __glutSizeHints.height = height;
348 __glutSizeHints.flags |= USSize;
349 } else {
350 __glutSizeHints.flags &= ~USSize;
351 }
352}
353
354void GLAPIENTRY
355glutInitDisplayMode(unsigned int mask)
356{
357 __glutDisplayMode = mask;
358}
359
360/* ENDCENTRY */
Note: See TracBrowser for help on using the repository browser.