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 ***********************************************************/ 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 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 ***********************************************************/ 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 ***********************************************************/ 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 ***********************************************************/ 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 ***********************************************************/ 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 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 ***********************************************************/ 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 ***********************************************************/ 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 ***********************************************************/ 272 void glutInitDisplayMode(unsigned int mode) { 273 gState.displayMode = mode; 274 } 275