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