home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / MesaDLL / glut_init.cpp < prev    next >
C/C++ Source or Header  |  2002-12-14  |  13KB  |  438 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994, 1997. */
  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. #ifdef __VMS
  9. #include <GL/vms_x_fix.h>
  10. #endif
  11.  
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15.  
  16. #if !defined(_WIN32) && !defined(__OS2__)
  17.    #include <X11/Xlib.h>
  18.    #include <X11/Xatom.h>
  19. #endif
  20.  
  21. /* SGI optimization introduced in IRIX 6.3 to avoid X server
  22.    round trips for interning common X atoms. */
  23. #if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
  24. #include <X11/SGIFastAtom.h>
  25. #else
  26. #define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
  27. #endif
  28.  
  29. #include "glutint.h"
  30.  
  31. /* GLUT inter-file variables */
  32. /* *INDENT-OFF* */
  33. char *__glutProgramName = NULL;
  34. int __glutArgc = 0;
  35. char **__glutArgv = NULL;
  36. char *__glutGeometry = NULL;
  37. Display *__glutDisplay = NULL;
  38. int __glutScreen;
  39. Window __glutRoot;
  40. int __glutScreenHeight;
  41. int __glutScreenWidth;
  42. GLboolean __glutIconic = GL_FALSE;
  43. GLboolean __glutDebug = GL_FALSE;
  44. unsigned int __glutDisplayMode =
  45.   GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
  46. char *__glutDisplayString = NULL;
  47. int __glutConnectionFD;
  48. XSizeHints __glutSizeHints = {0};
  49. int __glutInitWidth = 300, __glutInitHeight = 300;
  50. int __glutInitX = -1, __glutInitY = -1;
  51. GLboolean __glutForceDirect = GL_FALSE,
  52.   __glutTryDirect = GL_TRUE;
  53. Atom __glutWMDeleteWindow;
  54. /* *INDENT-ON* */
  55.  
  56. #ifdef _WIN32
  57. void (__cdecl *__glutExitFunc)(int retval) = NULL;
  58. #endif
  59.  
  60. static Bool synchronize = False;
  61.  
  62. #if defined(__OS2__)
  63.  
  64. MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  65.  
  66.  
  67. void __glutOpenOS2Connection(char* display)
  68. {
  69.   static char *classname=NULL;
  70. extern HAB   hab;      /* PM anchor block handle         */
  71. ERRORID  erridErrorCode;/* last error id code */
  72. int ii;
  73.  
  74.   /* Make sure we register the window only once. */
  75.   if(classname)
  76.     return;
  77.  
  78.   classname = "GLUT";
  79.  
  80.     if ( !WinRegisterClass( hab, /* PM anchor block handle     */
  81.              classname,/* window class name          */
  82.              GlutWindowProc,/* address of window procedure*/
  83.              CS_SIZEREDRAW, /* size changes cause redrawing */
  84.              0UL ) )        /* window data                  */
  85.     {   erridErrorCode = WinGetLastError(hab);
  86.         ii = erridErrorCode;
  87.           return;
  88.     }
  89.   __glutScreenWidth     = GetSystemMetrics(SM_CXSCREEN);
  90.   __glutScreenHeight    = GetSystemMetrics(SM_CYSCREEN);
  91.  
  92.   /* Set the root window to NULL because windows creates a top-level
  93.      window when the parent is NULL.  X creates a top-level window
  94.      when the parent is the root window. */
  95.   __glutRoot            = NULLHANDLE;
  96.  
  97.   /* Set the display to 1 -- we shouldn't be using this anywhere
  98.      (except as an argument to X calls). */
  99.   __glutDisplay         = (Display*)1;
  100.  
  101.   /* There isn't any concept of multiple screens in Win32, therefore,
  102.      we don't need to keep track of the screen we're on... it's always
  103.      the same one. */
  104.   __glutScreen          = 0;
  105. }
  106.  
  107. #elif defined(_WIN32)
  108.  
  109. #ifdef __BORLANDC__
  110. #include <float.h>  /* For masking floating point exceptions. */
  111. #endif
  112.  
  113. void
  114. __glutOpenWin32Connection(char* display)
  115. {
  116.   static char *classname;
  117.   WNDCLASS  wc;
  118.   HINSTANCE hInstance = GetModuleHandle(NULL);
  119.  
  120.   /* Make sure we register the window only once. */
  121.   if(classname)
  122.     return;
  123.  
  124. #ifdef __BORLANDC__
  125.   /* Under certain conditions (e.g. while rendering solid surfaces with
  126.      lighting enabled) Microsoft OpenGL libraries cause some illegal
  127.      operations like floating point overflow or division by zero. The
  128.      default behaviour of Microsoft compilers is to mask (ignore)
  129.      floating point exceptions, while Borland compilers do not.  The
  130.      following function of Borland RTL allows to mask exceptions.
  131.      Advice from Pier Giorgio Esposito (mc2172@mclink.it). */
  132.   _control87(MCW_EM,MCW_EM);
  133. #endif
  134.  
  135.   classname = "GLUT";
  136.  
  137.   /* Clear (important!) and then fill in the window class structure. */
  138.   memset(&wc, 0, sizeof(WNDCLASS));
  139.   wc.style         = CS_OWNDC;
  140.   wc.lpfnWndProc   = (WNDPROC)__glutWindowProc;
  141.   wc.hInstance     = hInstance;
  142.   wc.hIcon         = LoadIcon(hInstance, "GLUT_ICON");
  143.   wc.hCursor       = LoadCursor(hInstance, IDC_ARROW);
  144.   wc.hbrBackground = NULL;
  145.   wc.lpszMenuName  = NULL;
  146.   wc.lpszClassName = classname;
  147.  
  148.   /* Fill in a default icon if one isn't specified as a resource. */
  149.   if(!wc.hIcon)
  150.     wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
  151.  
  152.   if(!RegisterClass(&wc)) {
  153.     __glutFatalError("RegisterClass() failed:"
  154.                     "Cannot register GLUT window class.");
  155.   }
  156.  
  157.   __glutScreenWidth     = GetSystemMetrics(SM_CXSCREEN);
  158.   __glutScreenHeight    = GetSystemMetrics(SM_CYSCREEN);
  159.  
  160.   /* Set the root window to NULL because windows creates a top-level
  161.      window when the parent is NULL.  X creates a top-level window
  162.      when the parent is the root window. */
  163.   __glutRoot            = NULL;
  164.  
  165.   /* Set the display to 1 -- we shouldn't be using this anywhere
  166.      (except as an argument to X calls). */
  167.   __glutDisplay         = (Display*)1;
  168.  
  169.   /* There isn't any concept of multiple screens in Win32, therefore,
  170.      we don't need to keep track of the screen we're on... it's always
  171.      the same one. */
  172.   __glutScreen          = 0;
  173. }
  174. #else /* !_WIN32 */
  175. void
  176. __glutOpenXConnection(char *display)
  177. {
  178.   int errorBase, eventBase;
  179.  
  180.   __glutDisplay = XOpenDisplay(display);
  181.   if (!__glutDisplay)
  182.     __glutFatalError("could not open display: %s",
  183.       XDisplayName(display));
  184.   if (synchronize)
  185.     XSynchronize(__glutDisplay, True);
  186.   if (!glXQueryExtension(__glutDisplay, &errorBase, &eventBase))
  187.     __glutFatalError(
  188.       "OpenGL GLX extension not supported by display: %s",
  189.       XDisplayName(display));
  190.   __glutScreen = DefaultScreen(__glutDisplay);
  191.   __glutRoot = RootWindow(__glutDisplay, __glutScreen);
  192.   __glutScreenWidth = DisplayWidth(__glutDisplay, __glutScreen);
  193.   __glutScreenHeight = DisplayHeight(__glutDisplay,
  194.     __glutScreen);
  195.   __glutConnectionFD = ConnectionNumber(__glutDisplay);
  196.   __glutWMDeleteWindow = XSGIFastInternAtom(__glutDisplay,
  197.     "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW, False);
  198. }
  199. #endif /* _WIN32 */
  200.  
  201. void
  202. #ifdef OLD_VMS
  203.   __glutInitTime(struct timeval6 *beginning)
  204. #else
  205.   __glutInitTime(struct timeval *beginning)
  206. #endif
  207. {
  208.   static int beenhere = 0;
  209. #ifdef OLD_VMS
  210.    static struct timeval6 genesis;
  211. #else
  212.    static struct timeval genesis;
  213. #endif
  214.  
  215.   if (!beenhere) {
  216.     GETTIMEOFDAY(&genesis);
  217.     beenhere = 1;
  218.   }
  219.   *beginning = genesis;
  220. }
  221.  
  222. static void
  223. removeArgs(int *argcp, char **argv, int numToRemove)
  224. {
  225.   int i, j;
  226.  
  227.   for (i = 0, j = numToRemove; argv[j]; i++, j++) {
  228.     argv[i] = argv[j];
  229.   }
  230.   argv[i] = NULL;
  231.   *argcp -= numToRemove;
  232. }
  233.  
  234. void GLUTAPIENTRY
  235. glutInit(int *argcp, char **argv)
  236. {
  237.   char *display = NULL;
  238.   char *str, *geometry = NULL;
  239. #ifdef OLD_VMS
  240.    struct timeval6 unused;
  241. #else
  242.    struct timeval unused;
  243. #endif
  244.   int i;
  245.  
  246.   if (__glutDisplay) {
  247.     __glutWarning("glutInit being called a second time.");
  248.     return;
  249.   }
  250.   /* Determine temporary program name. */
  251.   str = strrchr(argv[0], '/');
  252.   if (str == NULL) {
  253.     __glutProgramName = argv[0];
  254.   } else {
  255.     __glutProgramName = str + 1;
  256.   }
  257.  
  258.   /* Make private copy of command line arguments. */
  259.   __glutArgc = *argcp;
  260.   __glutArgv = (char **) malloc(__glutArgc * sizeof(char *));
  261.   if (!__glutArgv)
  262.     __glutFatalError("out of memory.");
  263.   for (i = 0; i < __glutArgc; i++) {
  264.     __glutArgv[i] = __glutStrdup(argv[i]);
  265.     if (!__glutArgv[i])
  266.       __glutFatalError("out of memory.");
  267.   }
  268.  
  269.   /* determine permanent program name */
  270.   str = strrchr(__glutArgv[0], '/');
  271.   if (str == NULL) {
  272.     __glutProgramName = __glutArgv[0];
  273.   } else {
  274.     __glutProgramName = str + 1;
  275.   }
  276.  
  277.   /* parse arguments for standard options */
  278.   for (i = 1; i < __glutArgc; i++) {
  279.     if (!strcmp(__glutArgv[i], "-display")) {
  280. #if defined(_WIN32)
  281.       __glutWarning("-display option not supported by Win32 GLUT.");
  282. #endif
  283.       if (++i >= __glutArgc) {
  284.         __glutFatalError(
  285.           "follow -display option with X display name.");
  286.       }
  287.       display = __glutArgv[i];
  288.       removeArgs(argcp, &argv[1], 2);
  289.     } else if (!strcmp(__glutArgv[i], "-geometry")) {
  290.       if (++i >= __glutArgc) {
  291.         __glutFatalError(
  292.           "follow -geometry option with geometry parameter.");
  293.       }
  294.       geometry = __glutArgv[i];
  295.       removeArgs(argcp, &argv[1], 2);
  296.     } else if (!strcmp(__glutArgv[i], "-direct")) {
  297. #if defined(_WIN32)
  298.       __glutWarning("-direct option not supported by Win32 GLUT.");
  299. #endif
  300.       if (!__glutTryDirect)
  301.         __glutFatalError(
  302.           "cannot force both direct and indirect rendering.");
  303.       __glutForceDirect = GL_TRUE;
  304.       removeArgs(argcp, &argv[1], 1);
  305.     } else if (!strcmp(__glutArgv[i], "-indirect")) {
  306. #if defined(_WIN32)
  307.       __glutWarning("-indirect option not supported by Win32 GLUT.");
  308. #endif
  309.       if (__glutForceDirect)
  310.         __glutFatalError(
  311.           "cannot force both direct and indirect rendering.");
  312.       __glutTryDirect = GL_FALSE;
  313.       removeArgs(argcp, &argv[1], 1);
  314.     } else if (!strcmp(__glutArgv[i], "-iconic")) {
  315.       __glutIconic = GL_TRUE;
  316.       removeArgs(argcp, &argv[1], 1);
  317.     } else if (!strcmp(__glutArgv[i], "-gldebug")) {
  318.       __glutDebug = GL_TRUE;
  319.       removeArgs(argcp, &argv[1], 1);
  320.     } else if (!strcmp(__glutArgv[i], "-sync")) {
  321. #if defined(_WIN32)
  322.       __glutWarning("-sync option not supported by Win32 GLUT.");
  323. #endif
  324.       synchronize = GL_TRUE;
  325.       removeArgs(argcp, &argv[1], 1);
  326.     } else {
  327.       /* Once unknown option encountered, stop command line
  328.          processing. */
  329.       break;
  330.     }
  331.   }
  332. #if defined(__OS2__)
  333.   __glutOpenOS2Connection(display);
  334. #elif defined(_WIN32)
  335.   __glutOpenWin32Connection(display);
  336. #else
  337.   __glutOpenXConnection(display);
  338. #endif
  339.   if (geometry) {
  340.     int flags, x, y, width, height;
  341.  
  342.     /* Fix bogus "{width|height} may be used before set"
  343.        warning */
  344.     width = 0;
  345.     height = 0;
  346.  
  347.     flags = XParseGeometry(geometry, &x, &y,
  348.       (unsigned int *) &width, (unsigned int *) &height);
  349.     if (WidthValue & flags) {
  350.       /* Careful because X does not allow zero or negative
  351.          width windows */
  352.       if (width > 0)
  353.         __glutInitWidth = width;
  354.     }
  355.     if (HeightValue & flags) {
  356.       /* Careful because X does not allow zero or negative
  357.          height windows */
  358.       if (height > 0)
  359.         __glutInitHeight = height;
  360.     }
  361.     glutInitWindowSize(__glutInitWidth, __glutInitHeight);
  362.     if (XValue & flags) {
  363.       if (XNegative & flags)
  364.         x = DisplayWidth(__glutDisplay, __glutScreen) +
  365.           x - __glutSizeHints.width;
  366.       /* Play safe: reject negative X locations */
  367.       if (x >= 0)
  368.         __glutInitX = x;
  369.     }
  370.     if (YValue & flags) {
  371.       if (YNegative & flags)
  372.         y = DisplayHeight(__glutDisplay, __glutScreen) +
  373.           y - __glutSizeHints.height;
  374.       /* Play safe: reject negative Y locations */
  375.       if (y >= 0)
  376.         __glutInitY = y;
  377.     }
  378.     glutInitWindowPosition(__glutInitX, __glutInitY);
  379.   }
  380.   __glutInitTime(&unused);
  381.  
  382.   /* check if GLUT_FPS env var is set */
  383.   {
  384.      const char *fps = getenv("GLUT_FPS");
  385.      if (fps) {
  386.         sscanf(fps, "%d", &__glutFPS);
  387.         if (__glutFPS <= 0)
  388.            __glutFPS = 5000;  /* 5000 milliseconds */
  389.      }
  390.   }
  391. }
  392.  
  393. #ifdef _WIN32
  394. void APIENTRY
  395. __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int))
  396. {
  397.   __glutExitFunc = exitfunc;
  398.   glutInit(argcp, argv);
  399. }
  400. #endif
  401.  
  402. /* CENTRY */
  403. void GLUTAPIENTRY
  404. glutInitWindowPosition(int x, int y)
  405. {
  406.   __glutInitX = x;
  407.   __glutInitY = y;
  408.   if (x >= 0 && y >= 0) {
  409.     __glutSizeHints.x = x;
  410.     __glutSizeHints.y = y;
  411.     __glutSizeHints.flags |= USPosition;
  412.   } else {
  413.     __glutSizeHints.flags &= ~USPosition;
  414.   }
  415. }
  416.  
  417. void GLUTAPIENTRY
  418. glutInitWindowSize(int width, int height)
  419. {
  420.   __glutInitWidth = width;
  421.   __glutInitHeight = height;
  422.   if (width > 0 && height > 0) {
  423.     __glutSizeHints.width = width;
  424.     __glutSizeHints.height = height;
  425.     __glutSizeHints.flags |= USSize;
  426.   } else {
  427.     __glutSizeHints.flags &= ~USSize;
  428.   }
  429. }
  430.  
  431. void GLUTAPIENTRY
  432. glutInitDisplayMode(unsigned int mask)
  433. {
  434.   __glutDisplayMode = mask;
  435. }
  436.  
  437. /* ENDCENTRY */
  438.