home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / OpenGL 1.0 SDK / Source / Libraries / glut / glut_win.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-18  |  13.7 KB  |  694 lines  |  [TEXT/CWIE]

  1. /* Copyright (c) Mark J. Kilgard, 1994. */
  2.  
  3. /* This program is freely distributable without licensing fees 
  4.    and is provided without guarantee or warrantee expressed or 
  5.    implied. This program is -not- in the public domain. */
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <assert.h>
  11.  
  12. #include "gl.h"
  13. #include "agl.h"
  14. #include "glut.h"
  15. #include "glut_const.h"
  16. #include "glutint.h"
  17.  
  18. GLUTwindow *__glutCurrentWindow = NULL;
  19. GLUTwindow **__glutWindowList = NULL;
  20. int __glutWindowListSize = 0;
  21.  
  22. static GLUTwindow *__glutWindowCache = NULL;
  23.  
  24. GLUTwindow * __glutGetWindow(CWindowPtr win)
  25. {
  26.     int i;
  27.  
  28.     /* Does win belong to the last window ID looked up? */
  29.     if(__glutWindowCache && (win == __glutWindowCache->win))
  30.     {
  31.         return __glutWindowCache;
  32.     }
  33.     
  34.     /* Otherwise scan the window list looking for the window ID. */
  35.     for(i = 0; i < __glutWindowListSize; i++)
  36.     {
  37.         if(__glutWindowList[i])
  38.         {
  39.             if(win == __glutWindowList[i]->win)
  40.             {
  41.                 __glutWindowCache = __glutWindowList[i];
  42.                 return __glutWindowCache;
  43.             }
  44.         }
  45.     }
  46.  
  47.     return NULL;
  48. }
  49.  
  50. int glutGetWindow(void)
  51. {
  52.     if(__glutCurrentWindow)
  53.         return __glutCurrentWindow->num + 1;
  54.     else
  55.         return 0;
  56. }
  57.  
  58. int __glutSetCurrentWindow(GLUTwindow *window)
  59. {
  60.     __glutCurrentWindow = window;
  61.  
  62.     if(__glutCurrentWindow)
  63.     {
  64.         if(!window->fullscreen)
  65.             aglSetDrawable(__glutCurrentWindow->ctx, __glutCurrentWindow->win);
  66.         else
  67.             aglSetFullScreen(__glutCurrentWindow->ctx, __glutCurrentWindow->width, __glutCurrentWindow->height, 60, 0);
  68.             
  69.         aglSetCurrentContext(__glutCurrentWindow->ctx);
  70.     }
  71.     else
  72.     {
  73.         AGLContext ctx = aglGetCurrentContext();
  74.         
  75.         if(ctx)
  76.         {
  77.             aglSetCurrentContext(NULL);
  78.             aglSetDrawable(ctx, NULL);
  79.         }
  80.     }
  81.     
  82.     return (__glutCurrentWindow ? true : false);
  83. }
  84.  
  85. void glutSetWindow(int win)
  86. {
  87.     GLUTwindow *window;
  88.  
  89.     if(win < 1 || win > __glutWindowListSize)
  90.     {
  91.         __glutWarning("glutWindowSet attempted on bogus window.");
  92.         return;
  93.     }
  94.  
  95.     window = __glutWindowList[win - 1];
  96.     if(!window)
  97.     {
  98.         __glutWarning("glutWindowSet attempted on bogus window.");
  99.         return;
  100.     }
  101.  
  102.     __glutSetCurrentWindow(window);
  103. }
  104.  
  105. static int getUnusedWindowSlot(void)
  106. {
  107.     int i;
  108.  
  109.     /* Look for allocated, unused slot. */
  110.     for(i = 0; i < __glutWindowListSize; i++)
  111.     {
  112.         if(!__glutWindowList[i])
  113.         {
  114.             return i;
  115.         }
  116.     }
  117.     
  118.     /* Allocate a new slot. */
  119.     __glutWindowListSize++;
  120.     
  121.     if(__glutWindowList)
  122.     {
  123.         __glutWindowList = (GLUTwindow **) realloc(__glutWindowList,
  124.                         __glutWindowListSize * sizeof(GLUTwindow *));
  125.     }
  126.     else
  127.     {
  128.         __glutWindowList = (GLUTwindow **) malloc(sizeof(GLUTwindow *));
  129.     }
  130.     
  131.     if(!__glutWindowList) __glutFatalError("out of memory.");
  132.     
  133.     __glutWindowList[__glutWindowListSize - 1] = NULL;
  134.     
  135.     return __glutWindowListSize - 1;
  136. }
  137.  
  138. static AGLPixelFormat getVisualInfoCI(unsigned int mode)
  139. {
  140.     static GLint bufSizeList[] = { 16, 12, 8, 4, 2, 1, 0 };
  141.     AGLPixelFormat vi = NULL;
  142.     GLint list[32];
  143.     GLint i, n = 0;
  144.  
  145.     list[n++] = AGL_BUFFER_SIZE;
  146.     list[n++] = 1;
  147.     
  148.     if (GLUT_WIND_IS_DOUBLE(mode))
  149.     {
  150.         list[n++] = AGL_DOUBLEBUFFER;
  151.     }
  152.     
  153.     if (GLUT_WIND_IS_STEREO(mode))
  154.     {
  155.         list[n++] = AGL_STEREO;
  156.     }
  157.     
  158.     if (GLUT_WIND_HAS_DEPTH(mode))
  159.     {
  160.         list[n++] = AGL_DEPTH_SIZE;
  161.         list[n++] = 1;
  162.     }
  163.     
  164.     if (GLUT_WIND_HAS_STENCIL(mode))
  165.     {
  166.         list[n++] = AGL_STENCIL_SIZE;
  167.         list[n++] = 1;
  168.     }
  169.     
  170.     if(GLUT_WIND_IS_FULLSCREEN(mode))
  171.     {
  172.         list[n++] = AGL_FULLSCREEN;
  173.     }
  174.     
  175.     list[n] = AGL_NONE;
  176.  
  177.     aglConfigure(AGL_RETAIN_RENDERERS, GL_TRUE);    /* beretta */
  178.     for(i = 0; bufSizeList[i]; i++)
  179.     {
  180.         list[1] = bufSizeList[i];
  181.         vi = aglChoosePixelFormat(NULL, 0, list);
  182.     }
  183.     aglConfigure(AGL_RETAIN_RENDERERS, GL_FALSE);    /* beretta */
  184.     
  185.     return vi;
  186. }
  187.  
  188. static AGLPixelFormat getVisualInfoRGB(unsigned int mode)
  189. {
  190.     GLint list[40];
  191.     GLint n = 0;
  192.  
  193.     list[n++] = AGL_RGBA;
  194.     
  195. /*
  196.     list[n++] = AGL_RED_SIZE;
  197.     list[n++] = 1;
  198.     list[n++] = AGL_GREEN_SIZE;
  199.     list[n++] = 1;
  200.     list[n++] = AGL_BLUE_SIZE;
  201.     list[n++] = 1;
  202. */
  203.  
  204.     if(GLUT_WIND_HAS_ALPHA(mode))
  205.     {
  206.         list[n++] = AGL_ALPHA_SIZE;
  207.         list[n++] = 1;
  208.     }
  209.     
  210.     if(GLUT_WIND_IS_DOUBLE(mode))
  211.     {
  212.         list[n++] = AGL_DOUBLEBUFFER;
  213.     }
  214.     
  215.     if(GLUT_WIND_IS_STEREO(mode))
  216.     {
  217.         list[n++] = AGL_STEREO;
  218.     }
  219.     
  220.     if(GLUT_WIND_HAS_DEPTH(mode))
  221.     {
  222.         list[n++] = AGL_DEPTH_SIZE;
  223.         list[n++] = 24;
  224.     }
  225.     
  226.     if(GLUT_WIND_HAS_STENCIL(mode))
  227.     {
  228.         list[n++] = AGL_STENCIL_SIZE;
  229.         list[n++] = 1;
  230.     }
  231.     
  232.     if(GLUT_WIND_HAS_ACCUM(mode))
  233.     {
  234.         list[n++] = AGL_ACCUM_RED_SIZE;
  235.         list[n++] = 16;
  236.         list[n++] = AGL_ACCUM_GREEN_SIZE;
  237.         list[n++] = 16;
  238.         list[n++] = AGL_ACCUM_BLUE_SIZE;
  239.         list[n++] = 16;
  240.         
  241.         if(GLUT_WIND_HAS_ALPHA(mode))
  242.         {
  243.             list[n++] = AGL_ACCUM_ALPHA_SIZE;
  244.             list[n++] = 16;
  245.         }
  246.     }
  247.     
  248.     if(GLUT_WIND_IS_FULLSCREEN(mode))
  249.     {
  250.         list[n++] = AGL_FULLSCREEN;
  251.     }
  252.     
  253.     list[n++] = AGL_ALL_RENDERERS;
  254.     
  255.     #if defined(AGL_VERSION_1_1) && defined(AGL_SGIS_multisample)
  256.         if(GLUT_WIND_IS_MULTISAMPLE(mode))
  257.         {
  258.             if(!__glutIsSupportedByAGL("AGL_SGIS_multisample"))
  259.                 return NULL;
  260.             list[n++] = AGL_SAMPLES_SGIS;
  261.             list[n++] = 4;
  262.         }
  263.     #endif
  264.     
  265.     list[n] = (int) AGL_NONE; /* terminate list */
  266.  
  267.     return aglChoosePixelFormat(NULL, 0, list);
  268. }
  269.  
  270. AGLPixelFormat __glutGetVisualInfo(unsigned int mode)
  271. {
  272.     if (GLUT_WIND_IS_LUMINANCE(mode)) return NULL;
  273.  
  274.     if (GLUT_WIND_IS_RGB(mode))
  275.         return getVisualInfoRGB(mode);
  276.     else
  277.         return getVisualInfoCI(mode);
  278. }
  279.  
  280. AGLPixelFormat __glutDetermineVisual(unsigned int displayMode, Bool *treatAsSingle,
  281.                                       AGLPixelFormat (getVisualInfo) (unsigned int))
  282. {
  283.     AGLPixelFormat vis;
  284.  
  285.     *treatAsSingle = GLUT_WIND_IS_SINGLE(displayMode);
  286.     vis = getVisualInfo(displayMode);
  287.     
  288.     if (!vis)
  289.     {
  290.         if(GLUT_WIND_IS_SINGLE(displayMode))
  291.         {
  292.             displayMode |= GLUT_DOUBLE;
  293.             vis = getVisualInfo(displayMode);
  294.             *treatAsSingle = true;
  295.         }
  296.         
  297.         if (!vis && GLUT_WIND_IS_MULTISAMPLE(displayMode))
  298.         {
  299.             displayMode &= ~GLUT_MULTISAMPLE;
  300.             vis = getVisualInfo(displayMode);
  301.         }
  302.     }
  303.     
  304.     return vis;
  305. }
  306.  
  307. static AGLPixelFormat __glutDetermineWindowVisual(Bool *treatAsSingle)
  308. {
  309.     if(__glutDisplayString)
  310.     {
  311.         return __glutVisualInfoFromString(__glutDisplayString);
  312.     }
  313.     else
  314.     {
  315.         return __glutDetermineVisual(__glutDisplayMode, treatAsSingle, __glutGetVisualInfo);
  316.     }
  317. }
  318.  
  319.  
  320. void __glutSetupColormap(AGLPixelFormat vi, GLUTcolormap ** colormap, CSpecArray * cmap)
  321. {
  322. }
  323.  
  324. void __glutDefaultDisplay(void)
  325. {
  326.     __glutWarning("The following is a new check for GLUT 3.0; update your code.");
  327.     
  328.     if(__glutCurrentWindow)
  329.         __glutFatalError( "redisplay needed for window %d, but no display callback.", __glutCurrentWindow->num + 1);
  330.     else
  331.         __glutFatalError( "redisplay needed for window ?, but no display callback.");
  332. }
  333.  
  334. void __glutDefaultReshape(int width, int height)
  335. {
  336. }
  337.  
  338. GLUTwindow *__glutCreateWindow(GLUTwindow *parent, const char *title, int x, int y, int width, int height, int win_type)
  339. {
  340.     Str255 ps;
  341.     GLUTwindow *window;
  342.     GLint value;
  343.     int winnum;
  344.     int i, arc = 0;
  345.     
  346.     __glutInitApp();
  347.  
  348.     winnum = getUnusedWindowSlot();
  349.     
  350.     window = (GLUTwindow *) malloc(sizeof(GLUTwindow));
  351.     if(!window)
  352.     {
  353.         __glutFatalError("out of memory.");
  354.     }
  355.     
  356.     window->num = winnum;
  357.  
  358.     window->vis = __glutDetermineWindowVisual(&window->treatAsSingle);
  359.     if(!window->vis)
  360.     {
  361.         __glutFatalError("visual with necessary capabilities not found.");
  362.     }
  363.     
  364.     window->ctx = aglCreateContext(window->vis, NULL);
  365.     if(!window->ctx)
  366.     {
  367.         __glutFatalError("context could not be created.");
  368.     }
  369.     
  370.     window->renderCtx = window->ctx;
  371.     
  372.     aglDescribePixelFormat(window->vis, AGL_FULLSCREEN, &value);
  373.     window->fullscreen = value;
  374.     
  375.     aglDescribePixelFormat(window->vis, AGL_RGBA, &value);
  376.     if(!value) aglDisable(window->ctx, AGL_COLORMAP_TRACKING);
  377.  
  378.     if(!window->fullscreen)
  379.     {
  380.         window->win = (CWindowPtr) GetNewCWindow(win_type,nil,(WindowPtr)-1L);
  381.         if(!window->win)
  382.         {
  383.             __glutFatalError("window could not be created.");
  384.         }
  385.         
  386.         if(title)
  387.         {
  388.             strcpy(window->title, title);
  389.             __glutCToStr255(window->title, ps);
  390.             SetWTitle((GrafPort *) window->win, ps);
  391.         }
  392.         else
  393.         {
  394.             strcpy(window->title, "GLUT Window");
  395.             __glutCToStr255("GLUT Window", ps);
  396.             SetWTitle((GrafPort *) window->win, ps);
  397.         }
  398.  
  399.         MoveWindow((GrafPort *) window->win, x, y, GL_FALSE);
  400.         SizeWindow((GrafPort *) window->win, width, height,GL_FALSE);
  401.         ShowWindow((GrafPort *) window->win);
  402.         HiliteWindow((GrafPort *) window->win, TRUE);
  403.         SetPort((GrafPort *) window->win);
  404.     }
  405.     else
  406.     {
  407.         window->win = NULL;
  408.         strcpy(window->title, "");
  409.     }
  410.     
  411.     window->renderWin = window->win;
  412.     
  413.     window->width = width;
  414.     window->height = height;
  415.     window->forceReshape = true;
  416.     window->button_press = 0;
  417.     
  418.     window->parent = parent;
  419.     if(parent)
  420.     {
  421.         window->siblings = parent->children;
  422.         parent->children = window;
  423.     }
  424.     else
  425.     {
  426.         window->siblings = NULL;
  427.     }
  428.  
  429.     window->children = NULL;
  430.     window->prevWorkWin = NULL;
  431.  
  432.     window->display = __glutDefaultDisplay;
  433.     window->reshape = __glutDefaultReshape;
  434.     window->visibility = NULL;
  435.     window->workMask = GLUT_NO_WORK;
  436.     window->mouse = NULL;
  437.     window->special = NULL;
  438.     window->motion = NULL;
  439.     window->passive = NULL;
  440.     window->keyboard = NULL;
  441.     window->entry = NULL;
  442.     window->menu_state = NULL;
  443.     window->menu_status = NULL;
  444.     window->window_status = NULL;
  445.     window->entry_mode = 0;
  446.     window->cursor = GLUT_CURSOR_INHERIT;
  447.     
  448.     for(i = 0; i < MAX_MENUS; i++) window->menus[i] = 0;
  449.  
  450.     __glutWindowList[winnum] = window;
  451.     __glutSetCurrentWindow(window);
  452.     
  453.     return window;
  454. }
  455.  
  456. int glutCreateWindow(const char *title)
  457. {
  458.     GLUTwindow *window;
  459.  
  460.     window = __glutCreateWindow(NULL, title,
  461.         __glutInitX, __glutInitY,
  462.         __glutInitWidth, __glutInitHeight, kMainWindow);
  463.  
  464.     return window->num + 1;
  465. }
  466.  
  467. int glutCreatePlainWindow(const char *title)
  468. {
  469.     GLUTwindow *window;
  470.  
  471.     window = __glutCreateWindow(NULL, title,
  472.         __glutInitX, __glutInitY,
  473.         __glutInitWidth, __glutInitHeight, kPlainWindow);
  474.  
  475.     return window->num + 1;
  476. }
  477.  
  478. int glutCreateSubWindow(int win, int x, int y, int width, int height)
  479. {
  480.   GLUTwindow *window;
  481.  
  482.   if(__glutWindowList[win - 1])
  483.   {
  484.       window = __glutCreateWindow(__glutWindowList[win - 1], "GLUT Window",
  485.         x, y, width, height, kMainWindow);
  486.   }
  487.   else
  488.   {
  489.       window = __glutCreateWindow(__glutWindowList[win - 1], __glutWindowList[win - 1]->title,
  490.         x, y, width, height, kMainWindow);
  491.   }
  492.  
  493.   return window->num + 1;
  494. }
  495.  
  496. void __glutDestroyWindow(GLUTwindow * window, GLUTwindow * initialWindow)
  497. {
  498.     GLUTwindow **prev, *cur, *parent, *siblings;
  499.  
  500.     if(!window) return;
  501.     
  502.     __glutRemoveFromWorkList(window);
  503.  
  504.     /* Recursively destroy any children. */
  505.     cur = window->children;
  506.     while(cur)
  507.     {
  508.         siblings = cur->siblings;
  509.         __glutDestroyWindow(cur, initialWindow);
  510.         cur = siblings;
  511.     }
  512.     
  513.     /* Remove from parent's children list (only necessary for
  514.     non-initial windows and subwindows!). */
  515.     parent = window->parent;
  516.     if(parent && parent == initialWindow->parent)
  517.     {
  518.         prev = &parent->children;
  519.         cur = parent->children;
  520.         
  521.         while(cur)
  522.         {
  523.             if(cur == window)
  524.             {
  525.                 *prev = cur->siblings;
  526.                 break;
  527.             }
  528.             
  529.             prev = &(cur->siblings);
  530.             cur = cur->siblings;
  531.         }
  532.     }
  533.     
  534.     aglDestroyContext(window->ctx);
  535.  
  536.     /* Unbind if bound to this window. */
  537.     if(window == __glutCurrentWindow)
  538.         __glutSetCurrentWindow(NULL);
  539.     
  540.     if(!window->fullscreen)
  541.         DisposeWindow((GrafPort *) window->win);
  542.  
  543.     /* NULLing the __glutWindowList helps detect is a window
  544.     instance has been destroyed, given a window number. */
  545.     __glutWindowList[window->num] = NULL;
  546.  
  547.     /* Remove window from the "get window cache" if it is there. */
  548.     if(__glutWindowCache == window)
  549.         __glutWindowCache = NULL;
  550.  
  551.     aglDestroyPixelFormat(window->vis);
  552.     free(window);
  553. }
  554.  
  555. void glutDestroyWindow(int win)
  556. {
  557.   GLUTwindow *window = __glutWindowList[win - 1];
  558.  
  559.   __glutDestroyWindow(window, window);
  560. }
  561.  
  562. void glutSwapBuffers(void)
  563. {
  564.     aglSwapBuffers(aglGetCurrentContext());
  565. }
  566.  
  567. void glutDisplayFunc(GLUTdisplayCB displayFunc)
  568. {
  569.     if(!__glutCurrentWindow)
  570.     {
  571.         __glutWarning("glutDisplayFunc: no active window");
  572.         return;
  573.     }
  574.  
  575.     if (!displayFunc) __glutFatalError("NULL display callback not allowed in GLUT 3.0; update your code.");
  576.  
  577.     __glutCurrentWindow->display = displayFunc;
  578. }
  579.  
  580. void glutKeyboardFunc(GLUTkeyboardCB keyboardFunc)
  581. {
  582.     if(!__glutCurrentWindow)
  583.     {
  584.         __glutWarning("glutKeyboardFunc: no active window");
  585.         return;
  586.     }
  587.     
  588.   __glutCurrentWindow->keyboard = keyboardFunc;
  589. }
  590.  
  591. void glutSpecialFunc(GLUTspecialCB specialFunc)
  592. {
  593.     if(!__glutCurrentWindow)
  594.     {
  595.         __glutWarning("glutSpecialFunc: no active window");
  596.         return;
  597.     }
  598.     
  599.   __glutCurrentWindow->special = specialFunc;
  600. }
  601.  
  602. void glutMouseFunc(GLUTmouseCB mouseFunc)
  603. {
  604.     if(!__glutCurrentWindow)
  605.     {
  606.         __glutWarning("glutMouseFunc: no active window");
  607.         return;
  608.     }
  609.     
  610.   __glutCurrentWindow->mouse = mouseFunc;
  611. }
  612.  
  613. void glutMotionFunc(GLUTmotionCB motionFunc)
  614. {
  615.     if(!__glutCurrentWindow)
  616.     {
  617.         __glutWarning("glutMotionFunc: no active window");
  618.         return;
  619.     }
  620.     
  621.   __glutCurrentWindow->motion = motionFunc;
  622.   
  623.   if(motionFunc) __glutPutOnWorkList(__glutCurrentWindow, GLUT_BUTTON_WORK);
  624. }
  625.  
  626. void glutPassiveMotionFunc(GLUTpassiveCB passiveMotionFunc)
  627. {
  628.     if(!__glutCurrentWindow)
  629.     {
  630.         __glutWarning("glutPassiveMotionFunc: no active window");
  631.         return;
  632.     }
  633.     
  634.   __glutCurrentWindow->passive = passiveMotionFunc;
  635.   
  636.   if(passiveMotionFunc) __glutPutOnWorkList(__glutCurrentWindow, GLUT_PASSIVE_WORK);
  637. }
  638.  
  639. void glutEntryFunc(GLUTentryCB entryFunc)
  640. {
  641.     if(!__glutCurrentWindow)
  642.     {
  643.         __glutWarning("glutEntryFunc: no active window");
  644.         return;
  645.     }
  646.     
  647.     __glutCurrentWindow->entry = entryFunc;
  648.     __glutCurrentWindow->entry_mode = GLUT_ENTERED;
  649.         
  650.     if(entryFunc) __glutPutOnWorkList(__glutCurrentWindow, GLUT_ENTRY_WORK);
  651. }
  652.  
  653. void glutWindowStatusFunc(GLUTwindowStatusCB windowStatusFunc)
  654. {
  655.     if(!__glutCurrentWindow)
  656.     {
  657.         __glutWarning("glutWindowStatusFunc: no active window");
  658.         return;
  659.     }
  660.     
  661.     __glutCurrentWindow->window_status = windowStatusFunc;
  662. }
  663.  
  664. void glutVisibilityFunc(GLUTvisibilityCB visibilityFunc)
  665. {
  666.     if(!__glutCurrentWindow)
  667.     {
  668.         __glutWarning("glutVisibilityFunc: no active window");
  669.         return;
  670.     }
  671.     
  672.     __glutCurrentWindow->visibility = visibilityFunc;
  673.     
  674.     if(visibilityFunc) visibilityFunc(GLUT_VISIBLE);
  675. }
  676.  
  677. void glutReshapeFunc(GLUTreshapeCB reshapeFunc)
  678. {
  679.     if(!__glutCurrentWindow)
  680.     {
  681.         __glutWarning("glutReshapeFunc: no active window");
  682.         return;
  683.     }
  684.     
  685.   if(reshapeFunc)
  686.   {
  687.         __glutCurrentWindow->reshape = reshapeFunc;
  688.   }
  689.   else
  690.   {
  691.         __glutCurrentWindow->reshape = __glutDefaultReshape;
  692.   }
  693. }
  694.