OSDN Git Service

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