2 /* Copyright (c) Mark J. Kilgard, 1994, 1997. */
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. */
9 #include <GL/vms_x_fix.h>
18 #include <X11/Xatom.h>
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>
26 #define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
31 /* GLUT inter-file variables */
33 char *__glutProgramName
= NULL
;
35 char **__glutArgv
= NULL
;
36 char *__glutGeometry
= NULL
;
37 Display
*__glutDisplay
= NULL
;
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 char *__glutPPMFile
= NULL
;
58 void (__cdecl
*__glutExitFunc
)(int retval
) = NULL
;
61 static Bool synchronize
= False
;
66 #include <float.h> /* For masking floating point exceptions. */
70 __glutOpenWin32Connection(char* display
)
72 static char *classname
;
74 HINSTANCE hInstance
= GetModuleHandle(NULL
);
76 /* Make sure we register the window only once. */
81 /* Under certain conditions (e.g. while rendering solid surfaces with
82 lighting enabled) Microsoft OpenGL libraries cause some illegal
83 operations like floating point overflow or division by zero. The
84 default behaviour of Microsoft compilers is to mask (ignore)
85 floating point exceptions, while Borland compilers do not. The
86 following function of Borland RTL allows to mask exceptions.
87 Advice from Pier Giorgio Esposito (mc2172@mclink.it). */
88 _control87(MCW_EM
,MCW_EM
);
93 /* Clear (important!) and then fill in the window class structure. */
94 memset(&wc
, 0, sizeof(WNDCLASS
));
96 wc
.lpfnWndProc
= (WNDPROC
)__glutWindowProc
;
97 wc
.hInstance
= hInstance
;
98 wc
.hIcon
= LoadIcon(hInstance
, "GLUT_ICON");
99 wc
.hCursor
= LoadCursor(hInstance
, IDC_ARROW
);
100 wc
.hbrBackground
= NULL
;
101 wc
.lpszMenuName
= NULL
;
102 wc
.lpszClassName
= classname
;
104 /* Fill in a default icon if one isn't specified as a resource. */
106 wc
.hIcon
= LoadIcon(NULL
, IDI_WINLOGO
);
108 if(!RegisterClass(&wc
)) {
109 __glutFatalError("RegisterClass() failed:"
110 "Cannot register GLUT window class.");
113 __glutScreenWidth
= GetSystemMetrics(SM_CXSCREEN
);
114 __glutScreenHeight
= GetSystemMetrics(SM_CYSCREEN
);
116 /* Set the root window to NULL because windows creates a top-level
117 window when the parent is NULL. X creates a top-level window
118 when the parent is the root window. */
121 /* Set the display to 1 -- we shouldn't be using this anywhere
122 (except as an argument to X calls). */
123 __glutDisplay
= (Display
*)1;
125 /* There isn't any concept of multiple screens in Win32, therefore,
126 we don't need to keep track of the screen we're on... it's always
132 __glutOpenXConnection(char *display
)
134 int errorBase
, eventBase
;
136 __glutDisplay
= XOpenDisplay(display
);
138 __glutFatalError("could not open display: %s",
139 XDisplayName(display
));
141 XSynchronize(__glutDisplay
, True
);
142 if (!glXQueryExtension(__glutDisplay
, &errorBase
, &eventBase
))
144 "OpenGL GLX extension not supported by display: %s",
145 XDisplayName(display
));
146 __glutScreen
= DefaultScreen(__glutDisplay
);
147 __glutRoot
= RootWindow(__glutDisplay
, __glutScreen
);
148 __glutScreenWidth
= DisplayWidth(__glutDisplay
, __glutScreen
);
149 __glutScreenHeight
= DisplayHeight(__glutDisplay
,
151 __glutConnectionFD
= ConnectionNumber(__glutDisplay
);
152 __glutWMDeleteWindow
= XSGIFastInternAtom(__glutDisplay
,
153 "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW
, False
);
159 __glutInitTime(struct timeval6
*beginning
)
161 __glutInitTime(struct timeval
*beginning
)
164 static int beenhere
= 0;
166 static struct timeval6 genesis
;
168 static struct timeval genesis
;
172 GETTIMEOFDAY(&genesis
);
175 *beginning
= genesis
;
179 removeArgs(int *argcp
, char **argv
, int numToRemove
)
183 for (i
= 0, j
= numToRemove
; argv
[j
]; i
++, j
++) {
187 *argcp
-= numToRemove
;
191 glutInit(int *argcp
, char **argv
)
193 char *display
= NULL
;
194 char *str
, *geometry
= NULL
;
196 struct timeval6 unused
;
198 struct timeval unused
;
203 __glutWarning("glutInit being called a second time.");
206 /* Determine temporary program name. */
207 str
= strrchr(argv
[0], '/');
209 __glutProgramName
= argv
[0];
211 __glutProgramName
= str
+ 1;
214 /* Make private copy of command line arguments. */
216 __glutArgv
= (char **) malloc(__glutArgc
* sizeof(char *));
218 __glutFatalError("out of memory.");
219 for (i
= 0; i
< __glutArgc
; i
++) {
220 __glutArgv
[i
] = __glutStrdup(argv
[i
]);
222 __glutFatalError("out of memory.");
225 /* determine permanent program name */
226 str
= strrchr(__glutArgv
[0], '/');
228 __glutProgramName
= __glutArgv
[0];
230 __glutProgramName
= str
+ 1;
233 /* parse arguments for standard options */
234 for (i
= 1; i
< __glutArgc
; i
++) {
235 if (!strcmp(__glutArgv
[i
], "-display")) {
237 __glutWarning("-display option not supported by Win32 GLUT.");
239 if (++i
>= __glutArgc
) {
241 "follow -display option with X display name.");
243 display
= __glutArgv
[i
];
244 removeArgs(argcp
, &argv
[1], 2);
245 } else if (!strcmp(__glutArgv
[i
], "-geometry")) {
246 if (++i
>= __glutArgc
) {
248 "follow -geometry option with geometry parameter.");
250 geometry
= __glutArgv
[i
];
251 removeArgs(argcp
, &argv
[1], 2);
252 } else if (!strcmp(__glutArgv
[i
], "-direct")) {
254 __glutWarning("-direct option not supported by Win32 GLUT.");
256 if (!__glutTryDirect
)
258 "cannot force both direct and indirect rendering.");
259 __glutForceDirect
= GL_TRUE
;
260 removeArgs(argcp
, &argv
[1], 1);
261 } else if (!strcmp(__glutArgv
[i
], "-indirect")) {
263 __glutWarning("-indirect option not supported by Win32 GLUT.");
265 if (__glutForceDirect
)
267 "cannot force both direct and indirect rendering.");
268 __glutTryDirect
= GL_FALSE
;
269 removeArgs(argcp
, &argv
[1], 1);
270 } else if (!strcmp(__glutArgv
[i
], "-iconic")) {
271 __glutIconic
= GL_TRUE
;
272 removeArgs(argcp
, &argv
[1], 1);
273 } else if (!strcmp(__glutArgv
[i
], "-gldebug")) {
274 __glutDebug
= GL_TRUE
;
275 removeArgs(argcp
, &argv
[1], 1);
276 } else if (!strcmp(__glutArgv
[i
], "-sync")) {
278 __glutWarning("-sync option not supported by Win32 GLUT.");
280 synchronize
= GL_TRUE
;
281 removeArgs(argcp
, &argv
[1], 1);
283 /* Once unknown option encountered, stop command line
289 __glutOpenWin32Connection(display
);
291 __glutOpenXConnection(display
);
294 int flags
, x
, y
, width
, height
;
296 /* Fix bogus "{width|height} may be used before set"
301 flags
= XParseGeometry(geometry
, &x
, &y
,
302 (unsigned int *) &width
, (unsigned int *) &height
);
303 if (WidthValue
& flags
) {
304 /* Careful because X does not allow zero or negative
307 __glutInitWidth
= width
;
309 if (HeightValue
& flags
) {
310 /* Careful because X does not allow zero or negative
313 __glutInitHeight
= height
;
315 glutInitWindowSize(__glutInitWidth
, __glutInitHeight
);
316 if (XValue
& flags
) {
317 if (XNegative
& flags
)
318 x
= DisplayWidth(__glutDisplay
, __glutScreen
) +
319 x
- __glutSizeHints
.width
;
320 /* Play safe: reject negative X locations */
324 if (YValue
& flags
) {
325 if (YNegative
& flags
)
326 y
= DisplayHeight(__glutDisplay
, __glutScreen
) +
327 y
- __glutSizeHints
.height
;
328 /* Play safe: reject negative Y locations */
332 glutInitWindowPosition(__glutInitX
, __glutInitY
);
334 __glutInitTime(&unused
);
336 /* check if GLUT_FPS env var is set */
338 const char *fps
= getenv("GLUT_FPS");
340 sscanf(fps
, "%d", &__glutFPS
);
342 __glutFPS
= 5000; /* 5000 milliseconds */
346 /* check if GLUT_PPM_FILE env var is set */
347 __glutPPMFile
= getenv("GLUT_PPM_FILE");
352 __glutInitWithExit(int *argcp
, char **argv
, void (__cdecl
*exitfunc
)(int))
354 __glutExitFunc
= exitfunc
;
355 glutInit(argcp
, argv
);
361 glutInitWindowPosition(int x
, int y
)
365 if (x
>= 0 && y
>= 0) {
366 __glutSizeHints
.x
= x
;
367 __glutSizeHints
.y
= y
;
368 __glutSizeHints
.flags
|= USPosition
;
370 __glutSizeHints
.flags
&= ~USPosition
;
375 glutInitWindowSize(int width
, int height
)
377 __glutInitWidth
= width
;
378 __glutInitHeight
= height
;
379 if (width
> 0 && height
> 0) {
380 __glutSizeHints
.width
= width
;
381 __glutSizeHints
.height
= height
;
382 __glutSizeHints
.flags
|= USSize
;
384 __glutSizeHints
.flags
&= ~USSize
;
389 glutInitDisplayMode(unsigned int mask
)
391 __glutDisplayMode
= mask
;