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