Convert crlf->lf line endings.
[mesa.git] / src / glut / os2 / glut_init.cpp
1
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 #ifdef __VMS
9 #include <GL/vms_x_fix.h>
10 #endif
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15
16 #if !defined(_WIN32) && !defined(__OS2__)
17 #include <X11/Xlib.h>
18 #include <X11/Xatom.h>
19 #endif
20
21 /* SGI optimization introduced in IRIX 6.3 to avoid X server
22 round trips for interning common X atoms. */
23 #if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
24 #include <X11/SGIFastAtom.h>
25 #else
26 #define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
27 #endif
28
29 #include "glutint.h"
30
31 /* GLUT inter-file variables */
32 /* *INDENT-OFF* */
33 char *__glutProgramName = NULL;
34 int __glutArgc = 0;
35 char **__glutArgv = NULL;
36 char *__glutGeometry = NULL;
37 Display *__glutDisplay = NULL;
38 int __glutScreen;
39 Window __glutRoot;
40 int __glutScreenHeight;
41 int __glutScreenWidth;
42 GLboolean __glutIconic = GL_FALSE;
43 GLboolean __glutDebug = GL_FALSE;
44 unsigned int __glutDisplayMode =
45 GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
46 char *__glutDisplayString = NULL;
47 int __glutConnectionFD;
48 XSizeHints __glutSizeHints = {0};
49 int __glutInitWidth = 300, __glutInitHeight = 300;
50 int __glutInitX = -1, __glutInitY = -1;
51 GLboolean __glutForceDirect = GL_FALSE,
52 __glutTryDirect = GL_TRUE;
53 Atom __glutWMDeleteWindow;
54 /* *INDENT-ON* */
55
56 #ifdef _WIN32
57 void (__cdecl *__glutExitFunc)(int retval) = NULL;
58 #endif
59
60 static Bool synchronize = False;
61
62 #if defined(__OS2__)
63
64 MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
65 MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
66
67
68 void __glutOpenOS2Connection(char* display)
69 {
70 static char *classname=NULL;
71 extern HAB hab; /* PM anchor block handle */
72 ERRORID erridErrorCode;/* last error id code */
73 int ii;
74
75 /* Make sure we register the window only once. */
76 if(classname)
77 return;
78
79 classname = "GLUT";
80
81 if ( !WinRegisterClass( hab, /* PM anchor block handle */
82 classname,/* window class name */
83 GlutWindowProc,/* address of window procedure*/
84 CS_SIZEREDRAW, /* |CS_SYNCPAINT size changes cause redrawing */
85 0UL ) ) /* window data */
86 { erridErrorCode = WinGetLastError(hab);
87 ii = erridErrorCode;
88 return;
89 }
90
91 classname = "GLUTCHILD";
92
93 if ( !WinRegisterClass( hab, /* PM anchor block handle */
94 classname,/* window class name */
95 GlutWindowChildProc,/* address of window procedure*/
96 CS_SIZEREDRAW, /* size changes cause redrawing */
97 0UL ) ) /* window data */
98 { erridErrorCode = WinGetLastError(hab);
99 ii = erridErrorCode;
100 return;
101 }
102
103 __glutScreenWidth = GetSystemMetrics(SM_CXSCREEN);
104 __glutScreenHeight = GetSystemMetrics(SM_CYSCREEN);
105
106 /* Set the root window to NULL because windows creates a top-level
107 window when the parent is NULL. X creates a top-level window
108 when the parent is the root window. */
109 __glutRoot = NULLHANDLE;
110
111 /* Set the display to 1 -- we shouldn't be using this anywhere
112 (except as an argument to X calls). */
113 __glutDisplay = (Display*)1;
114
115 /* There isn't any concept of multiple screens in Win32, therefore,
116 we don't need to keep track of the screen we're on... it's always
117 the same one. */
118 __glutScreen = 0;
119 }
120
121 #elif defined(_WIN32)
122
123 #ifdef __BORLANDC__
124 #include <float.h> /* For masking floating point exceptions. */
125 #endif
126
127 void
128 __glutOpenWin32Connection(char* display)
129 {
130 static char *classname;
131 WNDCLASS wc;
132 HINSTANCE hInstance = GetModuleHandle(NULL);
133
134 /* Make sure we register the window only once. */
135 if(classname)
136 return;
137
138 #ifdef __BORLANDC__
139 /* Under certain conditions (e.g. while rendering solid surfaces with
140 lighting enabled) Microsoft OpenGL libraries cause some illegal
141 operations like floating point overflow or division by zero. The
142 default behaviour of Microsoft compilers is to mask (ignore)
143 floating point exceptions, while Borland compilers do not. The
144 following function of Borland RTL allows to mask exceptions.
145 Advice from Pier Giorgio Esposito (mc2172@mclink.it). */
146 _control87(MCW_EM,MCW_EM);
147 #endif
148
149 classname = "GLUT";
150
151 /* Clear (important!) and then fill in the window class structure. */
152 memset(&wc, 0, sizeof(WNDCLASS));
153 wc.style = CS_OWNDC;
154 wc.lpfnWndProc = (WNDPROC)__glutWindowProc;
155 wc.hInstance = hInstance;
156 wc.hIcon = LoadIcon(hInstance, "GLUT_ICON");
157 wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
158 wc.hbrBackground = NULL;
159 wc.lpszMenuName = NULL;
160 wc.lpszClassName = classname;
161
162 /* Fill in a default icon if one isn't specified as a resource. */
163 if(!wc.hIcon)
164 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
165
166 if(!RegisterClass(&wc)) {
167 __glutFatalError("RegisterClass() failed:"
168 "Cannot register GLUT window class.");
169 }
170
171 __glutScreenWidth = GetSystemMetrics(SM_CXSCREEN);
172 __glutScreenHeight = GetSystemMetrics(SM_CYSCREEN);
173
174 /* Set the root window to NULL because windows creates a top-level
175 window when the parent is NULL. X creates a top-level window
176 when the parent is the root window. */
177 __glutRoot = NULL;
178
179 /* Set the display to 1 -- we shouldn't be using this anywhere
180 (except as an argument to X calls). */
181 __glutDisplay = (Display*)1;
182
183 /* There isn't any concept of multiple screens in Win32, therefore,
184 we don't need to keep track of the screen we're on... it's always
185 the same one. */
186 __glutScreen = 0;
187 }
188 #else /* !_WIN32 */
189 void
190 __glutOpenXConnection(char *display)
191 {
192 int errorBase, eventBase;
193
194 __glutDisplay = XOpenDisplay(display);
195 if (!__glutDisplay)
196 __glutFatalError("could not open display: %s",
197 XDisplayName(display));
198 if (synchronize)
199 XSynchronize(__glutDisplay, True);
200 if (!glXQueryExtension(__glutDisplay, &errorBase, &eventBase))
201 __glutFatalError(
202 "OpenGL GLX extension not supported by display: %s",
203 XDisplayName(display));
204 __glutScreen = DefaultScreen(__glutDisplay);
205 __glutRoot = RootWindow(__glutDisplay, __glutScreen);
206 __glutScreenWidth = DisplayWidth(__glutDisplay, __glutScreen);
207 __glutScreenHeight = DisplayHeight(__glutDisplay,
208 __glutScreen);
209 __glutConnectionFD = ConnectionNumber(__glutDisplay);
210 __glutWMDeleteWindow = XSGIFastInternAtom(__glutDisplay,
211 "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW, False);
212 }
213 #endif /* _WIN32 */
214
215 void
216 #ifdef OLD_VMS
217 __glutInitTime(struct timeval6 *beginning)
218 #else
219 __glutInitTime(struct timeval *beginning)
220 #endif
221 {
222 static int beenhere = 0;
223 #ifdef OLD_VMS
224 static struct timeval6 genesis;
225 #else
226 static struct timeval genesis;
227 #endif
228
229 if (!beenhere) {
230 GETTIMEOFDAY(&genesis);
231 beenhere = 1;
232 }
233 *beginning = genesis;
234 }
235
236 static void
237 removeArgs(int *argcp, char **argv, int numToRemove)
238 {
239 int i, j;
240
241 for (i = 0, j = numToRemove; argv[j]; i++, j++) {
242 argv[i] = argv[j];
243 }
244 argv[i] = NULL;
245 *argcp -= numToRemove;
246 }
247
248 void GLUTAPIENTRY
249 glutInit(int *argcp, char **argv)
250 {
251 char *display = NULL;
252 char *str, *geometry = NULL;
253 #ifdef OLD_VMS
254 struct timeval6 unused;
255 #else
256 struct timeval unused;
257 #endif
258 int i;
259
260 if (__glutDisplay) {
261 __glutWarning("glutInit being called a second time.");
262 return;
263 }
264 /* Determine temporary program name. */
265 str = strrchr(argv[0], '/');
266 if (str == NULL) {
267 __glutProgramName = argv[0];
268 } else {
269 __glutProgramName = str + 1;
270 }
271
272 /* Make private copy of command line arguments. */
273 __glutArgc = *argcp;
274 __glutArgv = (char **) malloc(__glutArgc * sizeof(char *));
275 if (!__glutArgv)
276 __glutFatalError("out of memory.");
277 for (i = 0; i < __glutArgc; i++) {
278 __glutArgv[i] = __glutStrdup(argv[i]);
279 if (!__glutArgv[i])
280 __glutFatalError("out of memory.");
281 }
282
283 /* determine permanent program name */
284 str = strrchr(__glutArgv[0], '/');
285 if (str == NULL) {
286 __glutProgramName = __glutArgv[0];
287 } else {
288 __glutProgramName = str + 1;
289 }
290
291 /* parse arguments for standard options */
292 for (i = 1; i < __glutArgc; i++) {
293 if (!strcmp(__glutArgv[i], "-display")) {
294 #if defined(_WIN32)
295 __glutWarning("-display option not supported by Win32 GLUT.");
296 #endif
297 if (++i >= __glutArgc) {
298 __glutFatalError(
299 "follow -display option with X display name.");
300 }
301 display = __glutArgv[i];
302 removeArgs(argcp, &argv[1], 2);
303 } else if (!strcmp(__glutArgv[i], "-geometry")) {
304 if (++i >= __glutArgc) {
305 __glutFatalError(
306 "follow -geometry option with geometry parameter.");
307 }
308 geometry = __glutArgv[i];
309 removeArgs(argcp, &argv[1], 2);
310 } else if (!strcmp(__glutArgv[i], "-direct")) {
311 #if defined(_WIN32)
312 __glutWarning("-direct option not supported by Win32 GLUT.");
313 #endif
314 if (!__glutTryDirect)
315 __glutFatalError(
316 "cannot force both direct and indirect rendering.");
317 __glutForceDirect = GL_TRUE;
318 removeArgs(argcp, &argv[1], 1);
319 } else if (!strcmp(__glutArgv[i], "-indirect")) {
320 #if defined(_WIN32)
321 __glutWarning("-indirect option not supported by Win32 GLUT.");
322 #endif
323 if (__glutForceDirect)
324 __glutFatalError(
325 "cannot force both direct and indirect rendering.");
326 __glutTryDirect = GL_FALSE;
327 removeArgs(argcp, &argv[1], 1);
328 } else if (!strcmp(__glutArgv[i], "-iconic")) {
329 __glutIconic = GL_TRUE;
330 removeArgs(argcp, &argv[1], 1);
331 } else if (!strcmp(__glutArgv[i], "-gldebug")) {
332 __glutDebug = GL_TRUE;
333 removeArgs(argcp, &argv[1], 1);
334 } else if (!strcmp(__glutArgv[i], "-sync")) {
335 #if defined(_WIN32)
336 __glutWarning("-sync option not supported by Win32 GLUT.");
337 #endif
338 synchronize = GL_TRUE;
339 removeArgs(argcp, &argv[1], 1);
340 } else {
341 /* Once unknown option encountered, stop command line
342 processing. */
343 break;
344 }
345 }
346 #if defined(__OS2__)
347 __glutOpenOS2Connection(display);
348 #elif defined(_WIN32)
349 __glutOpenWin32Connection(display);
350 #else
351 __glutOpenXConnection(display);
352 #endif
353 if (geometry) {
354 int flags, x, y, width, height;
355
356 /* Fix bogus "{width|height} may be used before set"
357 warning */
358 width = 0;
359 height = 0;
360
361 flags = XParseGeometry(geometry, &x, &y,
362 (unsigned int *) &width, (unsigned int *) &height);
363 if (WidthValue & flags) {
364 /* Careful because X does not allow zero or negative
365 width windows */
366 if (width > 0)
367 __glutInitWidth = width;
368 }
369 if (HeightValue & flags) {
370 /* Careful because X does not allow zero or negative
371 height windows */
372 if (height > 0)
373 __glutInitHeight = height;
374 }
375 glutInitWindowSize(__glutInitWidth, __glutInitHeight);
376 if (XValue & flags) {
377 if (XNegative & flags)
378 x = DisplayWidth(__glutDisplay, __glutScreen) +
379 x - __glutSizeHints.width;
380 /* Play safe: reject negative X locations */
381 if (x >= 0)
382 __glutInitX = x;
383 }
384 if (YValue & flags) {
385 if (YNegative & flags)
386 y = DisplayHeight(__glutDisplay, __glutScreen) +
387 y - __glutSizeHints.height;
388 /* Play safe: reject negative Y locations */
389 if (y >= 0)
390 __glutInitY = y;
391 }
392 glutInitWindowPosition(__glutInitX, __glutInitY);
393 }
394 __glutInitTime(&unused);
395
396 /* check if GLUT_FPS env var is set */
397 {
398 const char *fps = getenv("GLUT_FPS");
399 if (fps) {
400 sscanf(fps, "%d", &__glutFPS);
401 if (__glutFPS <= 0)
402 __glutFPS = 5000; /* 5000 milliseconds */
403 }
404 }
405 }
406
407 #ifdef _WIN32
408 void APIENTRY
409 __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int))
410 {
411 __glutExitFunc = exitfunc;
412 glutInit(argcp, argv);
413 }
414 #endif
415
416 /* CENTRY */
417 void GLUTAPIENTRY
418 glutInitWindowPosition(int x, int y)
419 {
420 __glutInitX = x;
421 __glutInitY = y;
422 if (x >= 0 && y >= 0) {
423 __glutSizeHints.x = x;
424 __glutSizeHints.y = y;
425 __glutSizeHints.flags |= USPosition;
426 } else {
427 __glutSizeHints.flags &= ~USPosition;
428 }
429 }
430
431 void GLUTAPIENTRY
432 glutInitWindowSize(int width, int height)
433 {
434 __glutInitWidth = width;
435 __glutInitHeight = height;
436 if (width > 0 && height > 0) {
437 __glutSizeHints.width = width;
438 __glutSizeHints.height = height;
439 __glutSizeHints.flags |= USSize;
440 } else {
441 __glutSizeHints.flags &= ~USSize;
442 }
443 }
444
445 void GLUTAPIENTRY
446 glutInitDisplayMode(unsigned int mask)
447 {
448 __glutDisplayMode = mask;
449 }
450
451 /* ENDCENTRY */