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