Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

glut_init.c

Go to the documentation of this file.
00001 
00002 /* Copyright (c) Mark J. Kilgard, 1994, 1997. */
00003 
00004 /* This program is freely distributable without licensing fees
00005    and is provided without guarantee or warrantee expressed or
00006    implied. This program is -not- in the public domain. */
00007 
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <stdio.h>
00011 
00012 #if !defined(_WIN32)
00013 #include <X11/Xlib.h>
00014 #include <X11/Xatom.h>
00015 #endif
00016 
00017 /* SGI optimization introduced in IRIX 6.3 to avoid X server
00018    round trips for interning common X atoms. */
00019 #if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
00020 #include <X11/SGIFastAtom.h>
00021 #else
00022 #define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
00023 #endif
00024 
00025 #include "glutint.h"
00026 
00027 /* GLUT inter-file variables */
00028 /* *INDENT-OFF* */
00029 char *__glutProgramName = NULL;
00030 int __glutArgc = 0;
00031 char **__glutArgv = NULL;
00032 char *__glutGeometry = NULL;
00033 Display *__glutDisplay = NULL;
00034 int __glutScreen;
00035 Window __glutRoot;
00036 int __glutScreenHeight;
00037 int __glutScreenWidth;
00038 GLboolean __glutIconic = GL_FALSE;
00039 GLboolean __glutDebug = GL_FALSE;
00040 unsigned int __glutDisplayMode =
00041   GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
00042 char *__glutDisplayString = NULL;
00043 int __glutConnectionFD;
00044 XSizeHints __glutSizeHints = {0};
00045 int __glutInitWidth = 300, __glutInitHeight = 300;
00046 int __glutInitX = -1, __glutInitY = -1;
00047 GLboolean __glutForceDirect = GL_FALSE,
00048   __glutTryDirect = GL_TRUE;
00049 Atom __glutWMDeleteWindow;
00050 /* *INDENT-ON* */
00051 
00052 static Bool synchronize = False;
00053 
00054 #if defined(_WIN32)
00055 
00056 #ifdef __BORLANDC__
00057 #include <float.h>  /* For masking floating point exceptions. */
00058 #endif
00059 
00060 void
00061 __glutOpenWin32Connection(char* display)
00062 {
00063   static char *classname;
00064   WNDCLASS  wc;
00065   HINSTANCE hInstance = GetModuleHandle(NULL);
00066   
00067   /* Make sure we register the window only once. */
00068   if(classname)
00069     return;
00070 
00071 #ifdef __BORLANDC__
00072   /* Under certain conditions (e.g. while rendering solid surfaces with
00073      lighting enabled) Microsoft OpenGL libraries cause some illegal
00074      operations like floating point overflow or division by zero. The
00075      default behaviour of Microsoft compilers is to mask (ignore)
00076      floating point exceptions, while Borland compilers do not.  The
00077      following function of Borland RTL allows to mask exceptions.
00078      Advice from Pier Giorgio Esposito (mc2172@mclink.it). */
00079   _control87(MCW_EM,MCW_EM);
00080 #endif
00081 
00082   classname = "GLUT";
00083 
00084   /* Clear (important!) and then fill in the window class structure. */
00085   memset(&wc, 0, sizeof(WNDCLASS));
00086   wc.style         = CS_OWNDC;
00087   wc.lpfnWndProc   = (WNDPROC)__glutWindowProc;
00088   wc.hInstance     = hInstance;
00089   wc.hIcon         = LoadIcon(hInstance, "GLUT_ICON");
00090   wc.hCursor       = LoadCursor(hInstance, IDC_ARROW);
00091   wc.hbrBackground = NULL;
00092   wc.lpszMenuName  = NULL;
00093   wc.lpszClassName = classname;
00094 
00095   /* Fill in a default icon if one isn't specified as a resource. */
00096   if(!wc.hIcon)
00097     wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
00098   
00099   if(!RegisterClass(&wc)) {
00100     __glutFatalError("RegisterClass() failed:"
00101            "Cannot register GLUT window class.");
00102   }
00103  
00104   __glutScreenWidth     = GetSystemMetrics(SM_CXSCREEN);
00105   __glutScreenHeight    = GetSystemMetrics(SM_CYSCREEN);
00106 
00107   /* Set the root window to NULL because windows creates a top-level
00108      window when the parent is NULL.  X creates a top-level window
00109      when the parent is the root window. */
00110   __glutRoot            = NULL;
00111 
00112   /* Set the display to 1 -- we shouldn't be using this anywhere
00113      (except as an argument to X calls). */
00114   __glutDisplay         = (Display*)1;
00115 
00116   /* There isn't any concept of multiple screens in Win32, therefore,
00117      we don't need to keep track of the screen we're on... it's always
00118      the same one. */
00119   __glutScreen          = 0;
00120 }
00121 #else /* !_WIN32 */
00122 void
00123 __glutOpenXConnection(char *display)
00124 {
00125   int errorBase, eventBase;
00126 
00127   __glutDisplay = XOpenDisplay(display);
00128   if (!__glutDisplay)
00129     __glutFatalError("could not open display: %s",
00130       XDisplayName(display));
00131   if (synchronize)
00132     XSynchronize(__glutDisplay, True);
00133   if (!glXQueryExtension(__glutDisplay, &errorBase, &eventBase))
00134     __glutFatalError(
00135       "OpenGL GLX extension not supported by display: %s",
00136       XDisplayName(display));
00137   __glutScreen = DefaultScreen(__glutDisplay);
00138   __glutRoot = RootWindow(__glutDisplay, __glutScreen);
00139   __glutScreenWidth = DisplayWidth(__glutDisplay, __glutScreen);
00140   __glutScreenHeight = DisplayHeight(__glutDisplay,
00141     __glutScreen);
00142   __glutConnectionFD = ConnectionNumber(__glutDisplay);
00143   __glutWMDeleteWindow = XSGIFastInternAtom(__glutDisplay,
00144     "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW, False);
00145 }
00146 #endif /* _WIN32 */
00147 
00148 void
00149 __glutInitTime(struct timeval *beginning)
00150 {
00151   static int beenhere = 0;
00152   static struct timeval genesis;
00153 
00154   if (!beenhere) {
00155     GETTIMEOFDAY(&genesis);
00156     beenhere = 1;
00157   }
00158   *beginning = genesis;
00159 }
00160 
00161 static void
00162 removeArgs(int *argcp, char **argv, int numToRemove)
00163 {
00164   int i, j;
00165 
00166   for (i = 0, j = numToRemove; argv[j]; i++, j++) {
00167     argv[i] = argv[j];
00168   }
00169   argv[i] = NULL;
00170   *argcp -= numToRemove;
00171 }
00172 
00173 void APIENTRY 
00174 glutInit(int *argcp, char **argv)
00175 {
00176   char *display = NULL;
00177   char *str, *geometry = NULL;
00178   struct timeval unused;
00179   int i;
00180 
00181   if (__glutDisplay) {
00182     __glutWarning("glutInit being called a second time.");
00183     return;
00184   }
00185   /* Determine temporary program name. */
00186   str = strrchr(argv[0], '/');
00187   if (str == NULL) {
00188     __glutProgramName = argv[0];
00189   } else {
00190     __glutProgramName = str + 1;
00191   }
00192 
00193   /* Make private copy of command line arguments. */
00194   __glutArgc = *argcp;
00195   __glutArgv = (char **) malloc(__glutArgc * sizeof(char *));
00196   if (!__glutArgv)
00197     __glutFatalError("out of memory.");
00198   for (i = 0; i < __glutArgc; i++) {
00199     __glutArgv[i] = __glutStrdup(argv[i]);
00200     if (!__glutArgv[i])
00201       __glutFatalError("out of memory.");
00202   }
00203 
00204   /* determine permanent program name */
00205   str = strrchr(__glutArgv[0], '/');
00206   if (str == NULL) {
00207     __glutProgramName = __glutArgv[0];
00208   } else {
00209     __glutProgramName = str + 1;
00210   }
00211 
00212   /* parse arguments for standard options */
00213   for (i = 1; i < __glutArgc; i++) {
00214     if (!strcmp(__glutArgv[i], "-display")) {
00215 #if defined(_WIN32)
00216       __glutWarning("-display option invalid for win32 glut.");
00217 #endif
00218       if (++i >= __glutArgc) {
00219         __glutFatalError(
00220           "follow -display option with X display name.");
00221       }
00222       display = __glutArgv[i];
00223       removeArgs(argcp, &argv[1], 2);
00224     } else if (!strcmp(__glutArgv[i], "-geometry")) {
00225       if (++i >= __glutArgc) {
00226         __glutFatalError(
00227           "follow -geometry option with geometry parameter.");
00228       }
00229       geometry = __glutArgv[i];
00230       removeArgs(argcp, &argv[1], 2);
00231     } else if (!strcmp(__glutArgv[i], "-direct")) {
00232 #if defined(_WIN32)
00233       __glutWarning("-direct option invalid for win32 glut.");
00234 #endif
00235       if (!__glutTryDirect)
00236         __glutFatalError(
00237           "cannot force both direct and indirect rendering.");
00238       __glutForceDirect = GL_TRUE;
00239       removeArgs(argcp, &argv[1], 1);
00240     } else if (!strcmp(__glutArgv[i], "-indirect")) {
00241 #if defined(_WIN32)
00242       __glutWarning("-indirect option invalid for win32 glut.");
00243 #endif
00244       if (__glutForceDirect)
00245         __glutFatalError(
00246           "cannot force both direct and indirect rendering.");
00247       __glutTryDirect = GL_FALSE;
00248       removeArgs(argcp, &argv[1], 1);
00249     } else if (!strcmp(__glutArgv[i], "-iconic")) {
00250       __glutIconic = GL_TRUE;
00251       removeArgs(argcp, &argv[1], 1);
00252     } else if (!strcmp(__glutArgv[i], "-gldebug")) {
00253       __glutDebug = GL_TRUE;
00254       removeArgs(argcp, &argv[1], 1);
00255     } else if (!strcmp(__glutArgv[i], "-sync")) {
00256 #if defined(_WIN32)
00257       __glutWarning("-indirect option invalid for win32 glut.");
00258 #endif
00259       synchronize = GL_TRUE;
00260       removeArgs(argcp, &argv[1], 1);
00261     } else {
00262       /* Once unknown option encountered, stop command line
00263          processing. */
00264       break;
00265     }
00266   }
00267 #if defined(_WIN32)
00268   __glutOpenWin32Connection(display);
00269 #else
00270   __glutOpenXConnection(display);
00271 #endif
00272   if (geometry) {
00273     int flags, x, y, width, height;
00274 
00275     /* Fix bogus "{width|height} may be used before set"
00276        warning */
00277     width = 0;
00278     height = 0;
00279 
00280     flags = XParseGeometry(geometry, &x, &y,
00281       (unsigned int *) &width, (unsigned int *) &height);
00282     if (WidthValue & flags) {
00283       /* Careful because X does not allow zero or negative
00284          width windows */
00285       if (width > 0)
00286         __glutInitWidth = width;
00287     }
00288     if (HeightValue & flags) {
00289       /* Careful because X does not allow zero or negative
00290          height windows */
00291       if (height > 0)
00292         __glutInitHeight = height;
00293     }
00294     glutInitWindowSize(__glutInitWidth, __glutInitHeight);
00295     if (XValue & flags) {
00296       if (XNegative & flags)
00297         x = DisplayWidth(__glutDisplay, __glutScreen) +
00298           x - __glutSizeHints.width;
00299       /* Play safe: reject negative X locations */
00300       if (x >= 0)
00301         __glutInitX = x;
00302     }
00303     if (YValue & flags) {
00304       if (YNegative & flags)
00305         y = DisplayHeight(__glutDisplay, __glutScreen) +
00306           y - __glutSizeHints.height;
00307       /* Play safe: reject negative Y locations */
00308       if (y >= 0)
00309         __glutInitY = y;
00310     }
00311     glutInitWindowPosition(__glutInitX, __glutInitY);
00312   }
00313   __glutInitTime(&unused);
00314 }
00315 
00316 /* CENTRY */
00317 void APIENTRY 
00318 glutInitWindowPosition(int x, int y)
00319 {
00320   __glutInitX = x;
00321   __glutInitY = y;
00322   if (x >= 0 && y >= 0) {
00323     __glutSizeHints.x = x;
00324     __glutSizeHints.y = y;
00325     __glutSizeHints.flags |= USPosition;
00326   } else {
00327     __glutSizeHints.flags &= ~USPosition;
00328   }
00329 }
00330 
00331 void APIENTRY 
00332 glutInitWindowSize(int width, int height)
00333 {
00334   __glutInitWidth = width;
00335   __glutInitHeight = height;
00336   if (width > 0 && height > 0) {
00337     __glutSizeHints.width = width;
00338     __glutSizeHints.height = height;
00339     __glutSizeHints.flags |= USSize;
00340   } else {
00341     __glutSizeHints.flags &= ~USSize;
00342   }
00343 }
00344 
00345 void APIENTRY 
00346 glutInitDisplayMode(unsigned int mask)
00347 {
00348   __glutDisplayMode = mask;
00349 }
00350 
00351 void APIENTRY 
00352 glutInitWacom(void)
00353 {
00354   __glutWacomCalibrate();
00355   /* FIXME
00356      1. For unknown reasons, Xsgi doesn't always send a ConfigureNotify event
00357      when reshaping window. There is no calibration at start-up, user must
00358      move window to get it done.
00359      2. For unknown reasons, XFree send the wrong x and y values with the first
00360      ConfigureNotify event. As if we had called glutInitWindowPosition(0, 0).
00361 
00362      See also glut_event.c
00363   */
00364 }
00365 
00366 /* ENDCENTRY */

Generated on Mon Sep 18 11:39:31 2006 for jot by  doxygen 1.4.4