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. */
14 #include <X11/Xatom.h>
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>
22 #define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
27 /* GLUT inter-file variables */
29 char *__glutProgramName
= NULL
;
31 char **__glutArgv
= NULL
;
32 char *__glutGeometry
= NULL
;
33 Display
*__glutDisplay
= NULL
;
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
;
53 void (__cdecl
*__glutExitFunc
)(int retval
) = NULL
;
56 static Bool synchronize
= False
;
61 #include <float.h> /* For masking floating point exceptions. */
65 __glutOpenWin32Connection(char* display
)
67 static char *classname
;
69 HINSTANCE hInstance
= GetModuleHandle(NULL
);
71 /* Make sure we register the window only once. */
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
);
88 /* Clear (important!) and then fill in the window class structure. */
89 memset(&wc
, 0, sizeof(WNDCLASS
));
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
;
99 /* Fill in a default icon if one isn't specified as a resource. */
101 wc
.hIcon
= LoadIcon(NULL
, IDI_WINLOGO
);
103 if(!RegisterClass(&wc
)) {
104 __glutFatalError("RegisterClass() failed:"
105 "Cannot register GLUT window class.");
108 __glutScreenWidth
= GetSystemMetrics(SM_CXSCREEN
);
109 __glutScreenHeight
= GetSystemMetrics(SM_CYSCREEN
);
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. */
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;
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
127 __glutOpenXConnection(char *display
)
129 int errorBase
, eventBase
;
131 __glutDisplay
= XOpenDisplay(display
);
133 __glutFatalError("could not open display: %s",
134 XDisplayName(display
));
136 XSynchronize(__glutDisplay
, True
);
137 if (!glXQueryExtension(__glutDisplay
, &errorBase
, &eventBase
))
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
,
146 __glutConnectionFD
= ConnectionNumber(__glutDisplay
);
147 __glutWMDeleteWindow
= XSGIFastInternAtom(__glutDisplay
,
148 "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW
, False
);
153 __glutInitTime(struct timeval
*beginning
)
155 static int beenhere
= 0;
156 static struct timeval genesis
;
159 GETTIMEOFDAY(&genesis
);
162 *beginning
= genesis
;
166 removeArgs(int *argcp
, char **argv
, int numToRemove
)
170 for (i
= 0, j
= numToRemove
; argv
[j
]; i
++, j
++) {
174 *argcp
-= numToRemove
;
178 glutInit(int *argcp
, char **argv
)
180 char *display
= NULL
;
181 char *str
, *geometry
= NULL
;
182 struct timeval unused
;
186 __glutWarning("glutInit being called a second time.");
189 /* Determine temporary program name. */
190 str
= strrchr(argv
[0], '/');
192 __glutProgramName
= argv
[0];
194 __glutProgramName
= str
+ 1;
197 /* Make private copy of command line arguments. */
199 __glutArgv
= (char **) malloc(__glutArgc
* sizeof(char *));
201 __glutFatalError("out of memory.");
202 for (i
= 0; i
< __glutArgc
; i
++) {
203 __glutArgv
[i
] = __glutStrdup(argv
[i
]);
205 __glutFatalError("out of memory.");
208 /* determine permanent program name */
209 str
= strrchr(__glutArgv
[0], '/');
211 __glutProgramName
= __glutArgv
[0];
213 __glutProgramName
= str
+ 1;
216 /* parse arguments for standard options */
217 for (i
= 1; i
< __glutArgc
; i
++) {
218 if (!strcmp(__glutArgv
[i
], "-display")) {
220 __glutWarning("-display option not supported by Win32 GLUT.");
222 if (++i
>= __glutArgc
) {
224 "follow -display option with X display name.");
226 display
= __glutArgv
[i
];
227 removeArgs(argcp
, &argv
[1], 2);
228 } else if (!strcmp(__glutArgv
[i
], "-geometry")) {
229 if (++i
>= __glutArgc
) {
231 "follow -geometry option with geometry parameter.");
233 geometry
= __glutArgv
[i
];
234 removeArgs(argcp
, &argv
[1], 2);
235 } else if (!strcmp(__glutArgv
[i
], "-direct")) {
237 __glutWarning("-direct option not supported by Win32 GLUT.");
239 if (!__glutTryDirect
)
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")) {
246 __glutWarning("-indirect option not supported by Win32 GLUT.");
248 if (__glutForceDirect
)
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")) {
261 __glutWarning("-sync option not supported by Win32 GLUT.");
263 synchronize
= GL_TRUE
;
264 removeArgs(argcp
, &argv
[1], 1);
266 /* Once unknown option encountered, stop command line
272 __glutOpenWin32Connection(display
);
274 __glutOpenXConnection(display
);
277 int flags
, x
, y
, width
, height
;
279 /* Fix bogus "{width|height} may be used before set"
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
290 __glutInitWidth
= width
;
292 if (HeightValue
& flags
) {
293 /* Careful because X does not allow zero or negative
296 __glutInitHeight
= height
;
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 */
307 if (YValue
& flags
) {
308 if (YNegative
& flags
)
309 y
= DisplayHeight(__glutDisplay
, __glutScreen
) +
310 y
- __glutSizeHints
.height
;
311 /* Play safe: reject negative Y locations */
315 glutInitWindowPosition(__glutInitX
, __glutInitY
);
317 __glutInitTime(&unused
);
322 __glutInitWithExit(int *argcp
, char **argv
, void (__cdecl
*exitfunc
)(int))
324 __glutExitFunc
= exitfunc
;
325 glutInit(argcp
, argv
);
331 glutInitWindowPosition(int x
, int y
)
335 if (x
>= 0 && y
>= 0) {
336 __glutSizeHints
.x
= x
;
337 __glutSizeHints
.y
= y
;
338 __glutSizeHints
.flags
|= USPosition
;
340 __glutSizeHints
.flags
&= ~USPosition
;
345 glutInitWindowSize(int width
, int height
)
347 __glutInitWidth
= width
;
348 __glutInitHeight
= height
;
349 if (width
> 0 && height
> 0) {
350 __glutSizeHints
.width
= width
;
351 __glutSizeHints
.height
= height
;
352 __glutSizeHints
.flags
|= USSize
;
354 __glutSizeHints
.flags
&= ~USSize
;
359 glutInitDisplayMode(unsigned int mask
)
361 __glutDisplayMode
= mask
;