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