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>
16 #if !defined(_WIN32) && !defined(__OS2__)
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
;
57 void (__cdecl
*__glutExitFunc
)(int retval
) = NULL
;
60 static Bool synchronize
= False
;
64 MRESULT EXPENTRY
GlutWindowProc( HWND hwnd
, ULONG msg
, MPARAM mp1
, MPARAM mp2
);
65 MRESULT EXPENTRY
GlutWindowChildProc( HWND hwnd
, ULONG msg
, MPARAM mp1
, MPARAM mp2
);
68 void __glutOpenOS2Connection(char* display
)
70 static char *classname
=NULL
;
71 extern HAB hab
; /* PM anchor block handle */
72 ERRORID erridErrorCode
;/* last error id code */
75 /* Make sure we register the window only once. */
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
);
91 classname
= "GLUTCHILD";
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
);
103 __glutScreenWidth
= GetSystemMetrics(SM_CXSCREEN
);
104 __glutScreenHeight
= GetSystemMetrics(SM_CYSCREEN
);
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
;
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;
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
121 #elif defined(_WIN32)
124 #include <float.h> /* For masking floating point exceptions. */
128 __glutOpenWin32Connection(char* display
)
130 static char *classname
;
132 HINSTANCE hInstance
= GetModuleHandle(NULL
);
134 /* Make sure we register the window only once. */
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
);
151 /* Clear (important!) and then fill in the window class structure. */
152 memset(&wc
, 0, sizeof(WNDCLASS
));
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
;
162 /* Fill in a default icon if one isn't specified as a resource. */
164 wc
.hIcon
= LoadIcon(NULL
, IDI_WINLOGO
);
166 if(!RegisterClass(&wc
)) {
167 __glutFatalError("RegisterClass() failed:"
168 "Cannot register GLUT window class.");
171 __glutScreenWidth
= GetSystemMetrics(SM_CXSCREEN
);
172 __glutScreenHeight
= GetSystemMetrics(SM_CYSCREEN
);
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. */
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;
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
190 __glutOpenXConnection(char *display
)
192 int errorBase
, eventBase
;
194 __glutDisplay
= XOpenDisplay(display
);
196 __glutFatalError("could not open display: %s",
197 XDisplayName(display
));
199 XSynchronize(__glutDisplay
, True
);
200 if (!glXQueryExtension(__glutDisplay
, &errorBase
, &eventBase
))
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
,
209 __glutConnectionFD
= ConnectionNumber(__glutDisplay
);
210 __glutWMDeleteWindow
= XSGIFastInternAtom(__glutDisplay
,
211 "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW
, False
);
217 __glutInitTime(struct timeval6
*beginning
)
219 __glutInitTime(struct timeval
*beginning
)
222 static int beenhere
= 0;
224 static struct timeval6 genesis
;
226 static struct timeval genesis
;
230 GETTIMEOFDAY(&genesis
);
233 *beginning
= genesis
;
237 removeArgs(int *argcp
, char **argv
, int numToRemove
)
241 for (i
= 0, j
= numToRemove
; argv
[j
]; i
++, j
++) {
245 *argcp
-= numToRemove
;
249 glutInit(int *argcp
, char **argv
)
251 char *display
= NULL
;
252 char *str
, *geometry
= NULL
;
254 struct timeval6 unused
;
256 struct timeval unused
;
261 __glutWarning("glutInit being called a second time.");
264 /* Determine temporary program name. */
265 str
= strrchr(argv
[0], '/');
267 __glutProgramName
= argv
[0];
269 __glutProgramName
= str
+ 1;
272 /* Make private copy of command line arguments. */
274 __glutArgv
= (char **) malloc(__glutArgc
* sizeof(char *));
276 __glutFatalError("out of memory.");
277 for (i
= 0; i
< __glutArgc
; i
++) {
278 __glutArgv
[i
] = __glutStrdup(argv
[i
]);
280 __glutFatalError("out of memory.");
283 /* determine permanent program name */
284 str
= strrchr(__glutArgv
[0], '/');
286 __glutProgramName
= __glutArgv
[0];
288 __glutProgramName
= str
+ 1;
291 /* parse arguments for standard options */
292 for (i
= 1; i
< __glutArgc
; i
++) {
293 if (!strcmp(__glutArgv
[i
], "-display")) {
295 __glutWarning("-display option not supported by Win32 GLUT.");
297 if (++i
>= __glutArgc
) {
299 "follow -display option with X display name.");
301 display
= __glutArgv
[i
];
302 removeArgs(argcp
, &argv
[1], 2);
303 } else if (!strcmp(__glutArgv
[i
], "-geometry")) {
304 if (++i
>= __glutArgc
) {
306 "follow -geometry option with geometry parameter.");
308 geometry
= __glutArgv
[i
];
309 removeArgs(argcp
, &argv
[1], 2);
310 } else if (!strcmp(__glutArgv
[i
], "-direct")) {
312 __glutWarning("-direct option not supported by Win32 GLUT.");
314 if (!__glutTryDirect
)
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")) {
321 __glutWarning("-indirect option not supported by Win32 GLUT.");
323 if (__glutForceDirect
)
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")) {
336 __glutWarning("-sync option not supported by Win32 GLUT.");
338 synchronize
= GL_TRUE
;
339 removeArgs(argcp
, &argv
[1], 1);
341 /* Once unknown option encountered, stop command line
347 __glutOpenOS2Connection(display
);
348 #elif defined(_WIN32)
349 __glutOpenWin32Connection(display
);
351 __glutOpenXConnection(display
);
354 int flags
, x
, y
, width
, height
;
356 /* Fix bogus "{width|height} may be used before set"
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
367 __glutInitWidth
= width
;
369 if (HeightValue
& flags
) {
370 /* Careful because X does not allow zero or negative
373 __glutInitHeight
= height
;
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 */
384 if (YValue
& flags
) {
385 if (YNegative
& flags
)
386 y
= DisplayHeight(__glutDisplay
, __glutScreen
) +
387 y
- __glutSizeHints
.height
;
388 /* Play safe: reject negative Y locations */
392 glutInitWindowPosition(__glutInitX
, __glutInitY
);
394 __glutInitTime(&unused
);
396 /* check if GLUT_FPS env var is set */
398 const char *fps
= getenv("GLUT_FPS");
400 sscanf(fps
, "%d", &__glutFPS
);
402 __glutFPS
= 5000; /* 5000 milliseconds */
409 __glutInitWithExit(int *argcp
, char **argv
, void (__cdecl
*exitfunc
)(int))
411 __glutExitFunc
= exitfunc
;
412 glutInit(argcp
, argv
);
418 glutInitWindowPosition(int x
, int y
)
422 if (x
>= 0 && y
>= 0) {
423 __glutSizeHints
.x
= x
;
424 __glutSizeHints
.y
= y
;
425 __glutSizeHints
.flags
|= USPosition
;
427 __glutSizeHints
.flags
&= ~USPosition
;
432 glutInitWindowSize(int width
, int height
)
434 __glutInitWidth
= width
;
435 __glutInitHeight
= height
;
436 if (width
> 0 && height
> 0) {
437 __glutSizeHints
.width
= width
;
438 __glutSizeHints
.height
= height
;
439 __glutSizeHints
.flags
|= USSize
;
441 __glutSizeHints
.flags
&= ~USSize
;
446 glutInitDisplayMode(unsigned int mask
)
448 __glutDisplayMode
= mask
;