xref: /haiku/src/libs/glut/glutInit.cpp (revision 25a7b01d15612846f332751841da3579db313082)
1*da465207SAlexander von Gluck IV /***********************************************************
2*da465207SAlexander von Gluck IV  *      Copyright (C) 1997, Be Inc.  Copyright (C) 1999, Jake Hamby.
3*da465207SAlexander von Gluck IV  *
4*da465207SAlexander von Gluck IV  * This program is freely distributable without licensing fees
5*da465207SAlexander von Gluck IV  * and is provided without guarantee or warrantee expressed or
6*da465207SAlexander von Gluck IV  * implied. This program is -not- in the public domain.
7*da465207SAlexander von Gluck IV  *
8*da465207SAlexander von Gluck IV  *
9*da465207SAlexander von Gluck IV  *  FILE:	glutInit.cpp
10*da465207SAlexander von Gluck IV  *
11*da465207SAlexander von Gluck IV  *	DESCRIPTION:	initialize GLUT state
12*da465207SAlexander von Gluck IV  ***********************************************************/
13*da465207SAlexander von Gluck IV 
14*da465207SAlexander von Gluck IV /***********************************************************
15*da465207SAlexander von Gluck IV  *	Headers
16*da465207SAlexander von Gluck IV  ***********************************************************/
17*da465207SAlexander von Gluck IV #include <GL/glut.h>
18*da465207SAlexander von Gluck IV #include <string.h>
19*da465207SAlexander von Gluck IV #include <stdlib.h>
20*da465207SAlexander von Gluck IV #include <signal.h>
21*da465207SAlexander von Gluck IV #include "glutint.h"
22*da465207SAlexander von Gluck IV #include "glutState.h"
23*da465207SAlexander von Gluck IV #include "glutBlocker.h"
24*da465207SAlexander von Gluck IV #include "beos_x11.h"
25*da465207SAlexander von Gluck IV 
26*da465207SAlexander von Gluck IV /***********************************************************
27*da465207SAlexander von Gluck IV  *	Global variables
28*da465207SAlexander von Gluck IV  ***********************************************************/
29*da465207SAlexander von Gluck IV GlutState gState;
30*da465207SAlexander von Gluck IV char *__glutProgramName = NULL;
31*da465207SAlexander von Gluck IV 
32*da465207SAlexander von Gluck IV /***********************************************************
33*da465207SAlexander von Gluck IV  *	Private variables
34*da465207SAlexander von Gluck IV  ***********************************************************/
35*da465207SAlexander von Gluck IV static int __glutArgc;
36*da465207SAlexander von Gluck IV static char **__glutArgv;
37*da465207SAlexander von Gluck IV 
38*da465207SAlexander von Gluck IV /***********************************************************
39*da465207SAlexander von Gluck IV  *	FUNCTION:	__glutInitTime
40*da465207SAlexander von Gluck IV  *
41*da465207SAlexander von Gluck IV  *	DESCRIPTION:  set up start time variable
42*da465207SAlexander von Gluck IV  ***********************************************************/
__glutInitTime(bigtime_t * beginning)43*da465207SAlexander von Gluck IV void __glutInitTime(bigtime_t *beginning)
44*da465207SAlexander von Gluck IV {
45*da465207SAlexander von Gluck IV   static int beenhere = 0;
46*da465207SAlexander von Gluck IV   static bigtime_t genesis;
47*da465207SAlexander von Gluck IV 
48*da465207SAlexander von Gluck IV   if (!beenhere) {
49*da465207SAlexander von Gluck IV     genesis = system_time();
50*da465207SAlexander von Gluck IV     beenhere = 1;
51*da465207SAlexander von Gluck IV   }
52*da465207SAlexander von Gluck IV   *beginning = genesis;
53*da465207SAlexander von Gluck IV }
54*da465207SAlexander von Gluck IV 
55*da465207SAlexander von Gluck IV /***********************************************************
56*da465207SAlexander von Gluck IV  *	FUNCTION:	removeArgs
57*da465207SAlexander von Gluck IV  *
58*da465207SAlexander von Gluck IV  *	DESCRIPTION:  helper function for glutInit to remove args
59*da465207SAlexander von Gluck IV  *		from argv variable passed in
60*da465207SAlexander von Gluck IV  ***********************************************************/
61*da465207SAlexander von Gluck IV static void
removeArgs(int * argcp,char ** argv,int numToRemove)62*da465207SAlexander von Gluck IV removeArgs(int *argcp, char **argv, int numToRemove)
63*da465207SAlexander von Gluck IV {
64*da465207SAlexander von Gluck IV   int i, j;
65*da465207SAlexander von Gluck IV 
66*da465207SAlexander von Gluck IV   for (i = 0, j = numToRemove; argv[j]; i++, j++) {
67*da465207SAlexander von Gluck IV     argv[i] = argv[j];
68*da465207SAlexander von Gluck IV   }
69*da465207SAlexander von Gluck IV   argv[i] = NULL;
70*da465207SAlexander von Gluck IV   *argcp -= numToRemove;
71*da465207SAlexander von Gluck IV }
72*da465207SAlexander von Gluck IV 
73*da465207SAlexander von Gluck IV /***********************************************************
74*da465207SAlexander von Gluck IV  *	FUNCTION:	bAppThread
75*da465207SAlexander von Gluck IV  *
76*da465207SAlexander von Gluck IV  *	DESCRIPTION:  starts the BApplication message loop running
77*da465207SAlexander von Gluck IV  ***********************************************************/
bAppThread(void * arg)78*da465207SAlexander von Gluck IV static int32 bAppThread(void *arg) {
79*da465207SAlexander von Gluck IV 	be_app->Lock();
80*da465207SAlexander von Gluck IV 	return be_app->Run();
81*da465207SAlexander von Gluck IV }
82*da465207SAlexander von Gluck IV 
83*da465207SAlexander von Gluck IV /***********************************************************
84*da465207SAlexander von Gluck IV  *	FUNCTION:	sigHandler
85*da465207SAlexander von Gluck IV  *
86*da465207SAlexander von Gluck IV  *	DESCRIPTION:  shuts down the app on CTRL-C
87*da465207SAlexander von Gluck IV  ***********************************************************/
sigHandler(int)88*da465207SAlexander von Gluck IV static void sigHandler(int) {
89*da465207SAlexander von Gluck IV   gState.quitAll = true;
90*da465207SAlexander von Gluck IV   gBlock.NewEvent();
91*da465207SAlexander von Gluck IV }
92*da465207SAlexander von Gluck IV 
93*da465207SAlexander von Gluck IV /***********************************************************
94*da465207SAlexander von Gluck IV  *	FUNCTION:	glutInit (2.1)
95*da465207SAlexander von Gluck IV  *
96*da465207SAlexander von Gluck IV  *	DESCRIPTION:  create BApplication, parse cmd-line arguments,
97*da465207SAlexander von Gluck IV  *		and set up gState structure.
98*da465207SAlexander von Gluck IV  ***********************************************************/
glutInit(int * argcp,char ** argv)99*da465207SAlexander von Gluck IV void glutInit(int *argcp, char **argv) {
100*da465207SAlexander von Gluck IV   char *str, *geometry = NULL;
101*da465207SAlexander von Gluck IV   int i;
102*da465207SAlexander von Gluck IV 
103*da465207SAlexander von Gluck IV   if (gState.display) {
104*da465207SAlexander von Gluck IV     __glutWarning("glutInit being called a second time.");
105*da465207SAlexander von Gluck IV     return;
106*da465207SAlexander von Gluck IV   }
107*da465207SAlexander von Gluck IV   /* Determine temporary program name. */
108*da465207SAlexander von Gluck IV   str = strrchr(argv[0], '/');
109*da465207SAlexander von Gluck IV   if (str == NULL) {
110*da465207SAlexander von Gluck IV     __glutProgramName = argv[0];
111*da465207SAlexander von Gluck IV   } else {
112*da465207SAlexander von Gluck IV     __glutProgramName = str + 1;
113*da465207SAlexander von Gluck IV   }
114*da465207SAlexander von Gluck IV 
115*da465207SAlexander von Gluck IV   /* Make private copy of command line arguments. */
116*da465207SAlexander von Gluck IV   __glutArgc = *argcp;
117*da465207SAlexander von Gluck IV   __glutArgv = (char **) malloc(__glutArgc * sizeof(char *));
118*da465207SAlexander von Gluck IV   if (!__glutArgv)
119*da465207SAlexander von Gluck IV     __glutFatalError("out of memory.");
120*da465207SAlexander von Gluck IV   for (i = 0; i < __glutArgc; i++) {
121*da465207SAlexander von Gluck IV     __glutArgv[i] = strdup(argv[i]);
122*da465207SAlexander von Gluck IV     if (!__glutArgv[i])
123*da465207SAlexander von Gluck IV       __glutFatalError("out of memory.");
124*da465207SAlexander von Gluck IV   }
125*da465207SAlexander von Gluck IV 
126*da465207SAlexander von Gluck IV   /* determine permanent program name */
127*da465207SAlexander von Gluck IV   str = strrchr(__glutArgv[0], '/');
128*da465207SAlexander von Gluck IV   if (str == NULL) {
129*da465207SAlexander von Gluck IV     __glutProgramName = __glutArgv[0];
130*da465207SAlexander von Gluck IV   } else {
131*da465207SAlexander von Gluck IV     __glutProgramName = str + 1;
132*da465207SAlexander von Gluck IV   }
133*da465207SAlexander von Gluck IV 
134*da465207SAlexander von Gluck IV   /* parse arguments for standard options */
135*da465207SAlexander von Gluck IV   for (i = 1; i < __glutArgc; i++) {
136*da465207SAlexander von Gluck IV     if (!strcmp(__glutArgv[i], "-display")) {
137*da465207SAlexander von Gluck IV       __glutWarning("-display option only valid for X glut.");
138*da465207SAlexander von Gluck IV       if (++i >= __glutArgc) {
139*da465207SAlexander von Gluck IV         __glutFatalError(
140*da465207SAlexander von Gluck IV           "follow -display option with X display name.");
141*da465207SAlexander von Gluck IV       }
142*da465207SAlexander von Gluck IV       removeArgs(argcp, &argv[1], 2);
143*da465207SAlexander von Gluck IV     } else if (!strcmp(__glutArgv[i], "-geometry")) {
144*da465207SAlexander von Gluck IV       if (++i >= __glutArgc) {
145*da465207SAlexander von Gluck IV         __glutFatalError(
146*da465207SAlexander von Gluck IV           "follow -geometry option with geometry parameter.");
147*da465207SAlexander von Gluck IV       }
148*da465207SAlexander von Gluck IV       geometry = __glutArgv[i];
149*da465207SAlexander von Gluck IV       removeArgs(argcp, &argv[1], 2);
150*da465207SAlexander von Gluck IV     } else if (!strcmp(__glutArgv[i], "-direct")) {
151*da465207SAlexander von Gluck IV       __glutWarning("-direct option only valid for X glut.");
152*da465207SAlexander von Gluck IV       removeArgs(argcp, &argv[1], 1);
153*da465207SAlexander von Gluck IV     } else if (!strcmp(__glutArgv[i], "-indirect")) {
154*da465207SAlexander von Gluck IV       __glutWarning("-indirect option only valid for X glut.");
155*da465207SAlexander von Gluck IV       removeArgs(argcp, &argv[1], 1);
156*da465207SAlexander von Gluck IV     } else if (!strcmp(__glutArgv[i], "-iconic")) {
157*da465207SAlexander von Gluck IV       __glutWarning("-iconic option doesn't make sense in BeOS.");
158*da465207SAlexander von Gluck IV       removeArgs(argcp, &argv[1], 1);
159*da465207SAlexander von Gluck IV     } else if (!strcmp(__glutArgv[i], "-gldebug")) {
160*da465207SAlexander von Gluck IV       gState.debug = true;
161*da465207SAlexander von Gluck IV       removeArgs(argcp, &argv[1], 1);
162*da465207SAlexander von Gluck IV     } else if (!strcmp(__glutArgv[i], "-sync")) {
163*da465207SAlexander von Gluck IV       __glutWarning("-sync option only valid for X glut.");
164*da465207SAlexander von Gluck IV       removeArgs(argcp, &argv[1], 1);
165*da465207SAlexander von Gluck IV     } else {
166*da465207SAlexander von Gluck IV       /* Once unknown option encountered, stop command line
167*da465207SAlexander von Gluck IV          processing. */
168*da465207SAlexander von Gluck IV       break;
169*da465207SAlexander von Gluck IV     }
170*da465207SAlexander von Gluck IV   }
171*da465207SAlexander von Gluck IV 
172*da465207SAlexander von Gluck IV   __glutInit();  /* Create BApplication first so DisplayWidth() works */
173*da465207SAlexander von Gluck IV   if (geometry) {
174*da465207SAlexander von Gluck IV     int flags, x, y, width, height;
175*da465207SAlexander von Gluck IV 
176*da465207SAlexander von Gluck IV     /* Fix bogus "{width|height} may be used before set"
177*da465207SAlexander von Gluck IV        warning */
178*da465207SAlexander von Gluck IV     width = 0;
179*da465207SAlexander von Gluck IV     height = 0;
180*da465207SAlexander von Gluck IV 
181*da465207SAlexander von Gluck IV     flags = XParseGeometry(geometry, &x, &y,
182*da465207SAlexander von Gluck IV       (unsigned int *) &width, (unsigned int *) &height);
183*da465207SAlexander von Gluck IV     if (WidthValue & flags) {
184*da465207SAlexander von Gluck IV       /* Careful because X does not allow zero or negative
185*da465207SAlexander von Gluck IV          width windows */
186*da465207SAlexander von Gluck IV       if (width > 0)
187*da465207SAlexander von Gluck IV         gState.initWidth = width;
188*da465207SAlexander von Gluck IV     }
189*da465207SAlexander von Gluck IV     if (HeightValue & flags) {
190*da465207SAlexander von Gluck IV       /* Careful because X does not allow zero or negative
191*da465207SAlexander von Gluck IV          height windows */
192*da465207SAlexander von Gluck IV       if (height > 0)
193*da465207SAlexander von Gluck IV         gState.initHeight = height;
194*da465207SAlexander von Gluck IV     }
195*da465207SAlexander von Gluck IV     if (XValue & flags) {
196*da465207SAlexander von Gluck IV       if (XNegative & flags)
197*da465207SAlexander von Gluck IV         x = DisplayWidth() + x - gState.initWidth;
198*da465207SAlexander von Gluck IV       /* Play safe: reject negative X locations */
199*da465207SAlexander von Gluck IV       if (x >= 0)
200*da465207SAlexander von Gluck IV         gState.initX = x;
201*da465207SAlexander von Gluck IV     }
202*da465207SAlexander von Gluck IV     if (YValue & flags) {
203*da465207SAlexander von Gluck IV       if (YNegative & flags)
204*da465207SAlexander von Gluck IV         y = DisplayHeight() + y - gState.initHeight;
205*da465207SAlexander von Gluck IV       /* Play safe: reject negative Y locations */
206*da465207SAlexander von Gluck IV       if (y >= 0)
207*da465207SAlexander von Gluck IV         gState.initY = y;
208*da465207SAlexander von Gluck IV     }
209*da465207SAlexander von Gluck IV   }
210*da465207SAlexander von Gluck IV }
211*da465207SAlexander von Gluck IV 
212*da465207SAlexander von Gluck IV /***********************************************************
213*da465207SAlexander von Gluck IV  *	FUNCTION:	__glutInit
214*da465207SAlexander von Gluck IV  *
215*da465207SAlexander von Gluck IV  *	DESCRIPTION:  create BApplication, parse cmd-line arguments,
216*da465207SAlexander von Gluck IV  *		and set up gState structure.
217*da465207SAlexander von Gluck IV  ***********************************************************/
__glutInit()218*da465207SAlexander von Gluck IV void __glutInit() {
219*da465207SAlexander von Gluck IV   // open BApplication
220*da465207SAlexander von Gluck IV   gState.display = new BApplication("application/x-glut-demo");
221*da465207SAlexander von Gluck IV   be_app->Unlock();
222*da465207SAlexander von Gluck IV   gState.appthread = spawn_thread(bAppThread, "BApplication", B_NORMAL_PRIORITY, 0);
223*da465207SAlexander von Gluck IV   resume_thread(gState.appthread);
224*da465207SAlexander von Gluck IV 
225*da465207SAlexander von Gluck IV   bigtime_t unused;
226*da465207SAlexander von Gluck IV   __glutInitTime(&unused);
227*da465207SAlexander von Gluck IV 
228*da465207SAlexander von Gluck IV   /* set atexit() function to cleanup before exiting */
229*da465207SAlexander von Gluck IV   if(atexit(__glutExitCleanup))
230*da465207SAlexander von Gluck IV   	__glutFatalError("can't set exit handler");
231*da465207SAlexander von Gluck IV 
232*da465207SAlexander von Gluck IV   /* similarly, destroy all windows on CTRL-C */
233*da465207SAlexander von Gluck IV   signal(SIGINT, sigHandler);
234*da465207SAlexander von Gluck IV }
235*da465207SAlexander von Gluck IV 
236*da465207SAlexander von Gluck IV 
237*da465207SAlexander von Gluck IV void
__glutExitCleanup()238*da465207SAlexander von Gluck IV __glutExitCleanup()
239*da465207SAlexander von Gluck IV {
240*da465207SAlexander von Gluck IV 	if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE) > 0)
241*da465207SAlexander von Gluck IV 		// Try to restore initial screen mode...
242*da465207SAlexander von Gluck IV 		glutLeaveGameMode();
243*da465207SAlexander von Gluck IV 
244*da465207SAlexander von Gluck IV 	__glutDestroyAllWindows();
245*da465207SAlexander von Gluck IV }
246*da465207SAlexander von Gluck IV 
247*da465207SAlexander von Gluck IV /***********************************************************
248*da465207SAlexander von Gluck IV  *	FUNCTION:	glutInitWindowPosition (2.2)
249*da465207SAlexander von Gluck IV  *
250*da465207SAlexander von Gluck IV  *	DESCRIPTION:  set initial window position
251*da465207SAlexander von Gluck IV  ***********************************************************/
glutInitWindowPosition(int x,int y)252*da465207SAlexander von Gluck IV void glutInitWindowPosition(int x, int y) {
253*da465207SAlexander von Gluck IV 	gState.initX = x;
254*da465207SAlexander von Gluck IV 	gState.initY = y;
255*da465207SAlexander von Gluck IV }
256*da465207SAlexander von Gluck IV 
257*da465207SAlexander von Gluck IV /***********************************************************
258*da465207SAlexander von Gluck IV  *	FUNCTION:	glutInitWindowSize (2.2)
259*da465207SAlexander von Gluck IV  *
260*da465207SAlexander von Gluck IV  *	DESCRIPTION:  set initial window size
261*da465207SAlexander von Gluck IV  ***********************************************************/
glutInitWindowSize(int width,int height)262*da465207SAlexander von Gluck IV void glutInitWindowSize(int width, int height) {
263*da465207SAlexander von Gluck IV 	gState.initWidth = width;
264*da465207SAlexander von Gluck IV 	gState.initHeight = height;
265*da465207SAlexander von Gluck IV }
266*da465207SAlexander von Gluck IV 
267*da465207SAlexander von Gluck IV /***********************************************************
268*da465207SAlexander von Gluck IV  *	FUNCTION:	glutInitDisplayMode (2.3)
269*da465207SAlexander von Gluck IV  *
270*da465207SAlexander von Gluck IV  *	DESCRIPTION:  set initial display mode
271*da465207SAlexander von Gluck IV  ***********************************************************/
glutInitDisplayMode(unsigned int mode)272*da465207SAlexander von Gluck IV void glutInitDisplayMode(unsigned int mode) {
273*da465207SAlexander von Gluck IV 	gState.displayMode = mode;
274*da465207SAlexander von Gluck IV }
275