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>
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>
25 #define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
30 /* GLUT inter-file variables */
32 char *__glutProgramName
= NULL
;
34 char **__glutArgv
= NULL
;
35 char *__glutGeometry
= NULL
;
36 Display
*__glutDisplay
= NULL
;
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
= {0};
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
;
57 void (__cdecl
*__glutExitFunc
)(int retval
) = NULL
;
60 static Bool synchronize
= False
;
65 #include <float.h> /* For masking floating point exceptions. */
69 __glutOpenWin32Connection(char* display
)
71 static char *classname
;
73 HINSTANCE hInstance
= GetModuleHandle(NULL
);
75 /* Make sure we register the window only once. */
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
);
92 /* Clear (important!) and then fill in the window class structure. */
93 memset(&wc
, 0, sizeof(WNDCLASS
));
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
;
103 /* Fill in a default icon if one isn't specified as a resource. */
105 wc
.hIcon
= LoadIcon(NULL
, IDI_WINLOGO
);
107 if(!RegisterClass(&wc
)) {
108 __glutFatalError("RegisterClass() failed:"
109 "Cannot register GLUT window class.");
112 __glutScreenWidth
= GetSystemMetrics(SM_CXSCREEN
);
113 __glutScreenHeight
= GetSystemMetrics(SM_CYSCREEN
);
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. */
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;
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
131 __glutOpenXConnection(char *display
)
133 int errorBase
, eventBase
;
135 __glutDisplay
= XOpenDisplay(display
);
137 __glutFatalError("could not open display: %s",
138 XDisplayName(display
));
140 XSynchronize(__glutDisplay
, True
);
141 if (!glXQueryExtension(__glutDisplay
, &errorBase
, &eventBase
))
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
,
150 __glutConnectionFD
= ConnectionNumber(__glutDisplay
);
151 __glutWMDeleteWindow
= XSGIFastInternAtom(__glutDisplay
,
152 "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW
, False
);
158 __glutInitTime(struct timeval6
*beginning
)
160 __glutInitTime(struct timeval
*beginning
)
163 static int beenhere
= 0;
165 static struct timeval6 genesis
;
167 static struct timeval genesis
;
171 GETTIMEOFDAY(&genesis
);
174 *beginning
= genesis
;
178 removeArgs(int *argcp
, char **argv
, int numToRemove
)
182 for (i
= 0, j
= numToRemove
; argv
[j
]; i
++, j
++) {
186 *argcp
-= numToRemove
;
190 glutInit(int *argcp
, char **argv
)
192 char *display
= NULL
;
193 char *str
, *geometry
= NULL
;
195 struct timeval6 unused
;
197 struct timeval unused
;
202 __glutWarning("glutInit being called a second time.");
205 /* Determine temporary program name. */
206 str
= strrchr(argv
[0], '/');
208 __glutProgramName
= argv
[0];
210 __glutProgramName
= str
+ 1;
213 /* Make private copy of command line arguments. */
215 __glutArgv
= (char **) malloc(__glutArgc
* sizeof(char *));
217 __glutFatalError("out of memory.");
218 for (i
= 0; i
< __glutArgc
; i
++) {
219 __glutArgv
[i
] = __glutStrdup(argv
[i
]);
221 __glutFatalError("out of memory.");
224 /* determine permanent program name */
225 str
= strrchr(__glutArgv
[0], '/');
227 __glutProgramName
= __glutArgv
[0];
229 __glutProgramName
= str
+ 1;
232 /* parse arguments for standard options */
233 for (i
= 1; i
< __glutArgc
; i
++) {
234 if (!strcmp(__glutArgv
[i
], "-display")) {
236 __glutWarning("-display option not supported by Win32 GLUT.");
238 if (++i
>= __glutArgc
) {
240 "follow -display option with X display name.");
242 display
= __glutArgv
[i
];
243 removeArgs(argcp
, &argv
[1], 2);
244 } else if (!strcmp(__glutArgv
[i
], "-geometry")) {
245 if (++i
>= __glutArgc
) {
247 "follow -geometry option with geometry parameter.");
249 geometry
= __glutArgv
[i
];
250 removeArgs(argcp
, &argv
[1], 2);
251 } else if (!strcmp(__glutArgv
[i
], "-direct")) {
253 __glutWarning("-direct option not supported by Win32 GLUT.");
255 if (!__glutTryDirect
)
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")) {
262 __glutWarning("-indirect option not supported by Win32 GLUT.");
264 if (__glutForceDirect
)
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")) {
277 __glutWarning("-sync option not supported by Win32 GLUT.");
279 synchronize
= GL_TRUE
;
280 removeArgs(argcp
, &argv
[1], 1);
282 /* Once unknown option encountered, stop command line
288 __glutOpenWin32Connection(display
);
290 __glutOpenXConnection(display
);
293 int flags
, x
, y
, width
, height
;
295 /* Fix bogus "{width|height} may be used before set"
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
306 __glutInitWidth
= width
;
308 if (HeightValue
& flags
) {
309 /* Careful because X does not allow zero or negative
312 __glutInitHeight
= height
;
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 */
323 if (YValue
& flags
) {
324 if (YNegative
& flags
)
325 y
= DisplayHeight(__glutDisplay
, __glutScreen
) +
326 y
- __glutSizeHints
.height
;
327 /* Play safe: reject negative Y locations */
331 glutInitWindowPosition(__glutInitX
, __glutInitY
);
333 __glutInitTime(&unused
);
335 /* check if GLUT_FPS env var is set */
337 const char *fps
= getenv("GLUT_FPS");
339 sscanf(fps
, "%d", &__glutFPS
);
341 __glutFPS
= 5000; /* 5000 milliseconds */
345 /* check if GLUT_PPM_FILE env var is set */
346 __glutPPMFile
= getenv("GLUT_PPM_FILE");
351 __glutInitWithExit(int *argcp
, char **argv
, void (__cdecl
*exitfunc
)(int))
353 __glutExitFunc
= exitfunc
;
354 glutInit(argcp
, argv
);
360 glutInitWindowPosition(int x
, int y
)
364 if (x
>= 0 && y
>= 0) {
365 __glutSizeHints
.x
= x
;
366 __glutSizeHints
.y
= y
;
367 __glutSizeHints
.flags
|= USPosition
;
369 __glutSizeHints
.flags
&= ~USPosition
;
374 glutInitWindowSize(int width
, int height
)
376 __glutInitWidth
= width
;
377 __glutInitHeight
= height
;
378 if (width
> 0 && height
> 0) {
379 __glutSizeHints
.width
= width
;
380 __glutSizeHints
.height
= height
;
381 __glutSizeHints
.flags
|= USSize
;
383 __glutSizeHints
.flags
&= ~USSize
;
388 glutInitDisplayMode(unsigned int mask
)
390 __glutDisplayMode
= mask
;