home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / mesa-glut.lha / src-glut.aos / glutstuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-24  |  11.8 KB  |  445 lines

  1. /*
  2.  * Amiga GLUT graphics library toolkit
  3.  * Version:  1.1
  4.  * Copyright (C) 1998 Jarno van der Linden
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Library General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Library General Public
  17.  * License along with this library; if not, write to the Free
  18.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * glutstuff.c
  23.  *
  24.  * Version 1.0  27 Jun 1998
  25.  * by Jarno van der Linden
  26.  * jarno@kcbbs.gen.nz
  27.  *
  28.  * Version 1.1  02 Aug 1998
  29.  * by Jarno van der Linden
  30.  * jarno@kcbbs.gen.nz
  31.  *
  32.  * - Quantizer plugin support added
  33.  *
  34.  */
  35.  
  36. #include <signal.h>
  37. #include <stdlib.h>
  38. #include <inline/dos.h>
  39. #include <inline/exec.h>
  40. #include <inline/graphics.h>
  41. #include <inline/layers.h>
  42. #include <inline/intuition.h>
  43. #include <exec/memory.h>
  44. #include "glutstuff.h"
  45.  
  46. /**********************************************************************/
  47.  
  48. /* TODO: maybe we share GfxBase, IntuitionBase and amesaPool with aMesa */
  49. struct Library *GadToolsBase = NULL;
  50. struct Library *GfxBase = NULL;
  51. struct Library *DOSBase = NULL;
  52. struct Library *IntuitionBase = NULL;
  53. struct Library *LayersBase = NULL;
  54. APTR glutPool = NULL;
  55. #if !defined(NDEBUG) && !defined(NODEBUG)
  56. LONG debugOutputGLUT = 0;
  57. #endif
  58.  
  59. struct GlutStuff glutstuff;
  60.  
  61. void glutShutDown(int code)
  62. {
  63.   exit(0);
  64. }
  65.  
  66. void glutConstructor(void)
  67. {
  68.   char Flag[256];
  69.   short int FlagLen;
  70.  
  71.   if (!(DOSBase = OpenLibrary("dos.library", 39))) {
  72.     if ((DOSBase = OpenLibrary("dos.library", 0))) {
  73.       Printf("Can't open dos.library version 39\n");
  74.       CloseLibrary(DOSBase);
  75.     }
  76.     exit(10);
  77.   }
  78.   if (!(IntuitionBase = OpenLibrary("intuition.library", 39))) {
  79.     Printf("Can't open intuition.library version 39\n");
  80.     exit(10);
  81.   }
  82.   if (!(GadToolsBase = OpenLibrary("gadtools.library", 39))) {
  83.     Printf("Can't open gadtools.library version 39\n");
  84.     exit(10);
  85.   }
  86.   if (!(GfxBase = OpenLibrary("graphics.library", 39))) {
  87.     Printf("Can't open graphics.library version 39\n");
  88.     exit(10);
  89.   }
  90.   if(!(LayersBase = OpenLibrary("layers.library", 39))) {
  91.     Printf("Can't open layers.library version 39\n");
  92.     exit(10);
  93.   }
  94.   if (!(glutPool = CreatePool(MEMF_ANY | MEMF_CLEAR, 65536, 32768))) {
  95.     Printf("Can't create mempools for glut\n");
  96.     exit(10);
  97.   }
  98.  
  99.   signal(SIGINT, glutShutDown);
  100.   signal(SIGTERM, glutShutDown);
  101.  
  102.   bzero(&glutstuff, sizeof(glutstuff));
  103.  
  104. #if !defined(NDEBUG) && !defined(NODEBUG)
  105.   if((FlagLen = GetVar("GLUT_DEBUG", Flag, 255, 0)) > 0) {
  106.     Flag[(FlagLen < 256 ? FlagLen : 255)] = '\0';
  107.     if(!strncasecmp(Flag, "ON", 2)) {
  108.       debugOutputGLUT = 1;
  109.       if ((Flag[2] == ' ') &&
  110.           (Flag[3] >= '0') &&
  111.           (Flag[3] <= '9'))
  112.         debugOutputGLUT = Flag[3] - '0';
  113.       DEBUGOUT(1, "enable debugging stage %ld\n", debugOutputGLUT);
  114.     }
  115.     else {
  116.       debugOutputGLUT = 0;
  117.       DEBUGOUT(1, "disable debugging\n");
  118.     }
  119.   }
  120. #endif
  121.  
  122.   if((FlagLen = GetVar("MESA_GLUTOVERWRITE", Flag, 255, 0)) > 0) {
  123.     char *FFlow = Flag;
  124.  
  125.     Flag[(FlagLen < 256 ? FlagLen : 255)] = '\0';
  126.  
  127.     while(*FFlow != '\0') {
  128.       if(!strncasecmp(FFlow, "DOUBLE_OFF", 10)) {
  129.         glutstuff.doublemode = -1;
  130.         DEBUGOUT(1, "force doublebuffering off\n");
  131.       }
  132.       else if(!strncasecmp(FFlow, "DOUBLE_ON", 9)) {
  133.         glutstuff.doublemode = 1;
  134.         DEBUGOUT(1, "force doublebuffering on\n");
  135.       }
  136.       else if(!strncasecmp(FFlow, "RGBA_OFF", 8)) {
  137.         glutstuff.rgbamode = -1;
  138.         DEBUGOUT(1, "force RGBA off\n");
  139.       }
  140.       else if(!strncasecmp(FFlow, "RGBA_ON", 7)) {
  141.         glutstuff.rgbamode = 1;
  142.         DEBUGOUT(1, "force RGBA on\n");
  143.       }
  144.       else if(!strncasecmp(FFlow, "STEREO_OFF", 8)) {
  145.         glutstuff.stereomode = -1;
  146.         DEBUGOUT(1, "force stereo off\n");
  147.       }
  148.       else if(!strncasecmp(FFlow, "STEREO_ON", 7)) {
  149.         glutstuff.stereomode = 1;
  150.         DEBUGOUT(1, "force stereo on\n");
  151.       }
  152.       while(*FFlow != '\0')
  153.         if(*FFlow++ == ' ')
  154.           break;
  155.     }
  156.   }
  157.  
  158.   if(!(glutstuff.msgport = CreateMsgPort()))
  159.     exit (10);
  160.  
  161.   dNewList(&glutstuff.Windows);
  162.   glutstuff.nextwinid = 1;
  163.  
  164.   dNewList(&glutstuff.Menues);
  165.   glutstuff.nextmenuid = 1;
  166.  
  167.   glutstuff.initposx = -1;
  168.   glutstuff.initposy = -1;
  169.   glutstuff.initwidth = 300;
  170.   glutstuff.initheight = 300;
  171.  
  172.   glutstuff.pubscreenname = "Mesa";
  173.  
  174.   glutstuff.rgba = GL_TRUE;
  175.   glutstuff.depth = GL_TRUE;                            /* depth isn't the default! */
  176.  
  177.   glutstuff.initdisplaymode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
  178.  
  179.   glutstuff.palmode = AMESA_WEIGHTED_MATCH;
  180. }
  181.  
  182. void glutDestructor(void)
  183. {
  184.   struct nnode *act;
  185.  
  186.   while ((act = nGetTail(&glutstuff.Windows)))
  187.     glutDestroyWindow(((struct GlutWindow *)act)->WinID);            /* remove something out of the list, so we can't use nGetNext() safely */
  188.  
  189.   while ((act = nGetTail(&glutstuff.Menues)))
  190.     glutDestroyMenu(((struct GlutMenu *)act)->MenuID);                /* remove something out of the list, so we can't use nGetNext() safely */
  191.  
  192.   if (glutstuff.msgport)
  193.     DeleteMsgPort(glutstuff.msgport);
  194.  
  195.   if(LayersBase) {
  196.     CloseLibrary(LayersBase);
  197.     LayersBase = 0;
  198.   }
  199.   if (GfxBase) {
  200.     CloseLibrary(GfxBase);
  201.     GfxBase = 0;
  202.   }
  203.   if (GadToolsBase) {
  204.     CloseLibrary(GadToolsBase);
  205.     GadToolsBase = 0;
  206.   }
  207.   if (IntuitionBase) {
  208.     CloseLibrary(IntuitionBase);
  209.     IntuitionBase = 0;
  210.   }
  211.   if (DOSBase) {
  212.     CloseLibrary(DOSBase);
  213.     DOSBase = 0;
  214.   }
  215.   if (glutPool) {
  216.     DeletePool(glutPool);
  217.     glutPool = 0;
  218.   }
  219. }
  220.  
  221. #if 0
  222. asm("    .text;     .stabs \"___CTOR_LIST__\",22,0,0,_constructor");
  223. asm("    .text;     .stabs \"___DTOR_LIST__\",22,0,0,_destructor");
  224. #endif
  225.  
  226. /******************************************************************************/
  227.  
  228. void stuffMakeCurrent(struct GlutWindow *gw)
  229. {
  230.   if (gw && (glutstuff.curwin != gw)) {
  231.     glutstuff.curwin = gw;
  232.   //ActivateWindow(gw->window);                /* message-loop calls this, so don't use it here */
  233.   //glutstuff.activeWindow = gw;
  234.  
  235.     if (gw->context) {
  236.       amigaMesaBuffer buffer = NULL;
  237.  
  238.       amigaMesaGetContextTags(gw->context, AMA_Buffer, &buffer, TAG_DONE, 0);
  239.       if (buffer)
  240.         amigaMesaMakeCurrent(gw->context, buffer);
  241.     }
  242.   }
  243.  
  244.   DEBUGOUT(4, "stuffMakeCurrent(0x%08x (%d))\n", gw, gw->WinID);
  245. }
  246.  
  247. int stuffGetNewWinID(void)
  248. {
  249.   return glutstuff.nextwinid++;
  250. }
  251.  
  252. struct GlutWindow *stuffGetWin(int winid)
  253. {
  254.   struct GlutWindow *act = NULL;
  255.   
  256.   if (glutstuff.Windows.nodes) {
  257.     act = (struct GlutWindow *)&glutstuff.Windows;
  258.     while((act = (struct GlutWindow *)nGetNext(&act->WindowNode))) {
  259.       DEBUGOUT(4, "%d != %d\n", ((struct GlutWindow *)act)->WinID, winid);
  260.       if (((struct GlutWindow *)act)->WinID == winid)
  261.     break;
  262.     }
  263.     if (act && ((struct GlutWindow *)act)->WinID != winid)
  264.       act = NULL;
  265.   }
  266.  
  267.   DEBUGOUT(4, "0x%08x = stuffGetWindow(%d)\n", act, winid);
  268.   return act;
  269. }
  270.  
  271. void stuffLinkInWin(struct GlutWindow *gw)
  272. {
  273.   if (gw) {
  274.     gw->WinID = stuffGetNewWinID();
  275.   //dEnqueue(&glutstuff.Windows, &gw->WindowNode);
  276.     dAddTail(&glutstuff.Windows, &gw->WindowNode);    /* ever growing list */
  277.     stuffMakeCurrent(gw);
  278.   }
  279.  
  280.   DEBUGOUT(4, "%d (of %d) = stuffLinkInWin(0x%08x)\n", gw->WinID, glutstuff.Windows.nodes, gw);
  281. }
  282.  
  283. void stuffLinkInSubWin(struct GlutWindow *gw, struct GlutWindow *gwn)
  284. {
  285.   if (gw && gwn) {
  286.     gwn->SubWindowParent = gw;
  287.   //dEnqueue(&gw->SubWindows, &gwn->SubWindowNode);
  288.     dAddTail(&gw->SubWindows, &gwn->SubWindowNode);    /* ever growing list */
  289.   }
  290.  
  291.   DEBUGOUT(4, "%d (of %d) = stuffLinkInSubWin(0x%08x, 0x%08x)\n", gwn->WinID, gw->SubWindows.nodes, gw, gwn);
  292. }
  293.  
  294. void stuffLinkOutWin(struct GlutWindow *gw)
  295. {
  296.   if (gw) {
  297.     dRemove(&glutstuff.Windows, &gw->WindowNode);
  298.     if (gw->SubWindowParent)                /* remove window from subwindow-list */
  299.       dRemove(&gw->SubWindowParent->SubWindows, &gw->SubWindowNode);
  300.  
  301.     if (glutstuff.curwin == gw)
  302.       glutstuff.curwin = glutstuff.activeWindow;
  303.     if (glutstuff.curwin == gw)
  304.       glutstuff.curwin = NULL;
  305.   }
  306.  
  307.   DEBUGOUT(4, "stuffLinkOutWindow(0x%08x)\n", gw);
  308. }
  309.  
  310. int stuffGetNewMenuID(void)
  311. {
  312.   return glutstuff.nextmenuid++;
  313. }
  314.  
  315. struct GlutMenu *stuffGetMenu(int menuid)
  316. {
  317.   struct GlutMenu *act = NULL;
  318.   
  319.   if (glutstuff.Menues.nodes) {
  320.     act = (struct GlutMenu *)&glutstuff.Menues;
  321.     while((act = (struct GlutMenu *)nGetNext(&act->MenuNode))) {
  322.       DEBUGOUT(4, "%d != %d\n", ((struct GlutMenu *)act)->MenuID, menuid);
  323.       if (((struct GlutMenu *)act)->MenuID == menuid)
  324.     break;
  325.     }
  326.     if (act && ((struct GlutMenu *)act)->MenuID != menuid)
  327.       act = NULL;
  328.   }
  329.  
  330.   DEBUGOUT(4, "0x%08x = stuffGetMenu(%d)\n", act, menuid);
  331.   return act;
  332. }
  333.  
  334. void stuffLinkInMenu(struct GlutMenu *gm)
  335. {
  336.   if (gm) {
  337.     gm->MenuID = stuffGetNewMenuID();
  338.   //dEnqueue(&glutstuff.Menues, &gm->MenuNode);
  339.     dAddTail(&glutstuff.Menues, &gm->MenuNode);        /* ever growing list */
  340.     stuffMakeCurrentMenu(gm);
  341.   }
  342.  
  343.   DEBUGOUT(4, "%d (of %d) = stuffLinkInMenu(0x%08x)\n", gm->MenuID, glutstuff.Menues.nodes, gm);
  344. }
  345.  
  346. void stuffLinkOutMenu(struct GlutMenu *gm)
  347. {
  348.   if (gm) {
  349.     nRemove(&glutstuff.Menues, &gm->MenuNode);
  350.  
  351.     if (glutstuff.curmenu == gm)
  352.       glutstuff.curmenu = glutstuff.activeMenu;
  353.     if (glutstuff.curmenu == gm)
  354.       glutstuff.curmenu = NULL;
  355.   }
  356.  
  357.   DEBUGOUT(4, "stuffLinkOutMenu(0x%08x)\n", gm);
  358. }
  359.  
  360. void stuffMakeCurrentMenu(struct GlutMenu *gm)
  361. {
  362.   glutstuff.curmenu = gm;
  363. //glutstuff.activeMenu = gm;
  364. }
  365.  
  366. struct GlutMenuEntry *stuffGetMenuEntry(int entry, struct GlutMenu *gm)    /* is 0 == first or 1? */
  367. {
  368.   struct GlutMenuEntry *gme = NULL;
  369.   short int e = entry;
  370.  
  371.   if (gm && (gm->MenuEntries.nodes)) {
  372.     gme = (struct GlutMenuEntry *)&gm->MenuEntries;
  373.     while (--e >= 0)
  374.       gme = (struct GlutMenuEntry *)dGetNext(&gme->EntryNode);
  375.   }
  376.  
  377.   DEBUGOUT(4, "0x%08x = stuffGetMenuEntry(%d, 0x%08x)\n", gme, entry, gm);
  378.   return gme;
  379. }
  380.  
  381. void stuffLinkInMenuEntry(struct GlutMenuEntry *gme, struct GlutMenu *gm)
  382. {
  383.   if (gm && gme) {
  384.     dAddTail(&gm->MenuEntries, &gme->EntryNode);
  385.     gme->EntryMenu = gm;
  386.   }
  387.  
  388.   DEBUGOUT(4, "%d = stuffLinkInMenuEntry(0x%08x, 0x%08x)\n", gm->MenuEntries.nodes, gme, gm);
  389. }
  390.  
  391. void stuffLinkOutMenuEntry(struct GlutMenuEntry *gme, struct GlutMenu *gm)
  392. {
  393.   if (gm && gme) {
  394.     dRemove(&gm->MenuEntries, &gme->EntryNode);
  395.     gme->EntryMenu = NULL;
  396.   }
  397.  
  398.   DEBUGOUT(4, "stuffLinkOutMenuEntry(0x%08x, 0x%08x)\n", gme, gm);
  399. }
  400.  
  401. #ifdef USE_CLIP_LAYER_
  402. /*
  403.  * clipWindow()
  404.  * Clip a window to a specified rectangle (given by upper left and
  405.  * lower right corner.)  the removed region is returned so that it
  406.  * may be re-installed later.
  407.  */
  408. static struct Region *clipWindow(struct Window *win, LONG minX, LONG minY, LONG maxX, LONG maxY)
  409. {
  410.   struct Region *new_region;
  411.   struct Rectangle my_rectangle;
  412.  
  413.   /* set up the limits for the clip */
  414.   my_rectangle.MinX = minX;
  415.   my_rectangle.MinY = minY;
  416.   my_rectangle.MaxX = maxX;
  417.   my_rectangle.MaxY = maxY;
  418.  
  419.   /* get a new region and OR in the limits. */
  420.   if ((new_region = NewRegion())) {
  421.     if (!OrRectRegion(new_region, &my_rectangle)) {
  422.       DisposeRegion(new_region);
  423.       new_region = NULL;
  424.     }
  425.   }
  426.  
  427.   /*
  428.    * Install the new region, and return any existing region.
  429.    * If the above allocation and region processing failed, then
  430.    * new_region will be NULL and no clip region will be installed.
  431.    */
  432.   return (InstallClipRegion(win->WLayer, new_region));
  433. }
  434.  
  435. /*
  436.  * clipWindowToBorders()
  437.  * clip a window to its borders.
  438.  * The removed region is returned so that it may be re-installed later.
  439.  */
  440. struct Region *clipWindowToBorders(struct Window *win)
  441. {
  442.   return (clipWindow(win, win->BorderLeft, win->BorderTop, win->Width - win->BorderRight - 1, win->Height - win->BorderBottom - 1));
  443. }
  444. #endif
  445.