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
;
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
);
157 __glutInitTime(struct timeval
*beginning
)
159 static int beenhere
= 0;
160 static struct timeval genesis
;
163 GETTIMEOFDAY(&genesis
);
166 *beginning
= genesis
;
170 removeArgs(int *argcp
, char **argv
, int numToRemove
)
174 for (i
= 0, j
= numToRemove
; argv
[j
]; i
++, j
++) {
178 *argcp
-= numToRemove
;
182 glutInit(int *argcp
, char **argv
)
184 char *display
= NULL
;
185 char *str
, *geometry
= NULL
;
186 struct timeval unused
;
190 __glutWarning("glutInit being called a second time.");
193 /* Determine temporary program name. */
194 str
= strrchr(argv
[0], '/');
196 __glutProgramName
= argv
[0];
198 __glutProgramName
= str
+ 1;
201 /* Make private copy of command line arguments. */
203 __glutArgv
= (char **) malloc(__glutArgc
* sizeof(char *));
205 __glutFatalError("out of memory.");
206 for (i
= 0; i
< __glutArgc
; i
++) {
207 __glutArgv
[i
] = __glutStrdup(argv
[i
]);
209 __glutFatalError("out of memory.");
212 /* determine permanent program name */
213 str
= strrchr(__glutArgv
[0], '/');
215 __glutProgramName
= __glutArgv
[0];
217 __glutProgramName
= str
+ 1;
220 /* parse arguments for standard options */
221 for (i
= 1; i
< __glutArgc
; i
++) {
222 if (!strcmp(__glutArgv
[i
], "-display")) {
224 __glutWarning("-display option not supported by Win32 GLUT.");
226 if (++i
>= __glutArgc
) {
228 "follow -display option with X display name.");
230 display
= __glutArgv
[i
];
231 removeArgs(argcp
, &argv
[1], 2);
232 } else if (!strcmp(__glutArgv
[i
], "-geometry")) {
233 if (++i
>= __glutArgc
) {
235 "follow -geometry option with geometry parameter.");
237 geometry
= __glutArgv
[i
];
238 removeArgs(argcp
, &argv
[1], 2);
239 } else if (!strcmp(__glutArgv
[i
], "-direct")) {
241 __glutWarning("-direct option not supported by Win32 GLUT.");
243 if (!__glutTryDirect
)
245 "cannot force both direct and indirect rendering.");
246 __glutForceDirect
= GL_TRUE
;
247 removeArgs(argcp
, &argv
[1], 1);
248 } else if (!strcmp(__glutArgv
[i
], "-indirect")) {
250 __glutWarning("-indirect option not supported by Win32 GLUT.");
252 if (__glutForceDirect
)
254 "cannot force both direct and indirect rendering.");
255 __glutTryDirect
= GL_FALSE
;
256 removeArgs(argcp
, &argv
[1], 1);
257 } else if (!strcmp(__glutArgv
[i
], "-iconic")) {
258 __glutIconic
= GL_TRUE
;
259 removeArgs(argcp
, &argv
[1], 1);
260 } else if (!strcmp(__glutArgv
[i
], "-gldebug")) {
261 __glutDebug
= GL_TRUE
;
262 removeArgs(argcp
, &argv
[1], 1);
263 } else if (!strcmp(__glutArgv
[i
], "-sync")) {
265 __glutWarning("-sync option not supported by Win32 GLUT.");
267 synchronize
= GL_TRUE
;
268 removeArgs(argcp
, &argv
[1], 1);
270 /* Once unknown option encountered, stop command line
276 __glutOpenWin32Connection(display
);
278 __glutOpenXConnection(display
);
281 int flags
, x
, y
, width
, height
;
283 /* Fix bogus "{width|height} may be used before set"
288 flags
= XParseGeometry(geometry
, &x
, &y
,
289 (unsigned int *) &width
, (unsigned int *) &height
);
290 if (WidthValue
& flags
) {
291 /* Careful because X does not allow zero or negative
294 __glutInitWidth
= width
;
296 if (HeightValue
& flags
) {
297 /* Careful because X does not allow zero or negative
300 __glutInitHeight
= height
;
302 glutInitWindowSize(__glutInitWidth
, __glutInitHeight
);
303 if (XValue
& flags
) {
304 if (XNegative
& flags
)
305 x
= DisplayWidth(__glutDisplay
, __glutScreen
) +
306 x
- __glutSizeHints
.width
;
307 /* Play safe: reject negative X locations */
311 if (YValue
& flags
) {
312 if (YNegative
& flags
)
313 y
= DisplayHeight(__glutDisplay
, __glutScreen
) +
314 y
- __glutSizeHints
.height
;
315 /* Play safe: reject negative Y locations */
319 glutInitWindowPosition(__glutInitX
, __glutInitY
);
321 __glutInitTime(&unused
);
326 __glutInitWithExit(int *argcp
, char **argv
, void (__cdecl
*exitfunc
)(int))
328 __glutExitFunc
= exitfunc
;
329 glutInit(argcp
, argv
);
335 glutInitWindowPosition(int x
, int y
)
339 if (x
>= 0 && y
>= 0) {
340 __glutSizeHints
.x
= x
;
341 __glutSizeHints
.y
= y
;
342 __glutSizeHints
.flags
|= USPosition
;
344 __glutSizeHints
.flags
&= ~USPosition
;
349 glutInitWindowSize(int width
, int height
)
351 __glutInitWidth
= width
;
352 __glutInitHeight
= height
;
353 if (width
> 0 && height
> 0) {
354 __glutSizeHints
.width
= width
;
355 __glutSizeHints
.height
= height
;
356 __glutSizeHints
.flags
|= USSize
;
358 __glutSizeHints
.flags
&= ~USSize
;
363 glutInitDisplayMode(unsigned int mask
)
365 __glutDisplayMode
= mask
;