1 /*
2  * AGL_DSp.cpp
3  * Copyright (C) 2007 by Bryan Duff <duff0097@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  */
20 
21 #include "AGL_DSp.h"
22 #include "Alerts.h"
23 
24 DSpContextAttributes gDSpContextAttributes;     // Global DrawSprocket context attributes
25 DSpContextReference gDSpContext;        // The global DrawSprocket context
26 AGLContext gOpenGLContext;      // The global OpenGL (AGL) context
27 
28 /********************> ToolboxInit() <*****/
ToolboxInit(void)29 void ToolboxInit(void)
30 {
31   MaxApplZone();
32 
33   InitGraf(&qd.thePort);
34   InitFonts();
35   InitWindows();
36   InitMenus();
37   TEInit();
38   InitDialogs(0L);
39   InitCursor();
40 
41 }
42 
43 /********************> HasAppearance() <*****/
HasAppearance(void)44 Boolean HasAppearance(void)
45 {
46 
47   OSErr error;
48   SInt32 response;
49   Boolean appearancePresent = false;
50   Boolean appearance101present = false;
51   Boolean appearance110present = false;
52   Boolean inCompatibilityMode = false;
53 
54   error = Gestalt(gestaltAppearanceAttr, &response);
55 
56   // If Gestalt returns no error and the bit in response represented by the constant
57   // gestaltAppearanceExists is set, proceed, otherwise exit with an error message.
58 
59   if(error == noErr && (BitTst(&response, 31 - gestaltAppearanceExists))) {
60     // At least Version 1.0 is present.  Set a flag.
61     appearancePresent = true;
62 
63     // If the bit in response represented by the constant gestaltAppearanceCompatMode
64     // is set, system-wide Appearance is off.  The result of this check will be
65     // relevant only where Versions 1.0 through 1.0.3 are present.
66     if(BitTst(&response, 31 - gestaltAppearanceCompatMode))
67       inCompatibilityMode = true;
68 
69     // Call Gestalt again with the gestaltAppearanceVersion selector.
70     Gestalt(gestaltAppearanceVersion, &response);
71 
72     // If the low order word in response is 0x0101, Version 1.0.1, 1.0.2, or 1.0.3 is
73     // present. If the low order word in response is 0x0110, Version 1.1 is available.
74     if(response == 0x00000101)
75       appearance101present = true;
76     else if(response == 0x00000110)
77       appearance110present = true;
78   }
79   /*else
80      {
81      StopAlert( kNoAppearanceAlert, nil );
82      ExitToShell();
83      } */
84 
85   // Register this app as an Appearance Client
86   //RegisterAppearanceClient();
87 
88   return appearancePresent;
89 
90 }
91 
92 /********************> SetupScreen() <*****/
SetupScreen(int width,int height)93 CGrafPtr SetupScreen(int width, int height)
94 {
95 
96   OSStatus theError;
97   CGrafPtr theFrontBuffer;
98 
99   // Start DrawSprocket
100   theError = DSpStartup();
101   if(theError)
102     FatalErrorAlert(kErr_DSpStartupFailed, theError);
103 
104   // Set the Context Attributes
105   gDSpContextAttributes.displayWidth = width;
106   gDSpContextAttributes.displayHeight = height;
107   gDSpContextAttributes.colorNeeds = kDSpColorNeeds_Require;
108   gDSpContextAttributes.displayDepthMask = kDSpDepthMask_32;
109   gDSpContextAttributes.backBufferDepthMask = kDSpDepthMask_32;
110   gDSpContextAttributes.displayBestDepth = 32;
111   gDSpContextAttributes.backBufferBestDepth = 32;
112   gDSpContextAttributes.pageCount = 1;
113 
114   // Find the best context for our attributes
115   theError = DSpFindBestContext(&gDSpContextAttributes, &gDSpContext);
116   if(theError != noErr)
117     FatalErrorAlert(kErr_DSpFindBestContextFailed, theError);   // This function is in my Alerts.cpp
118 
119   // Reserve that context
120   theError = DSpContext_Reserve(gDSpContext, &gDSpContextAttributes);
121   if(theError != noErr)
122     FatalErrorAlert(kErr_DSpContext_ReserveFailed, theError);
123 
124   // Fade out
125   theError = DSpContext_FadeGammaOut(NULL, NULL);
126   if(theError != noErr)
127     FatalErrorAlert(kErr_DSpFadeFailed, theError);
128 
129   // Activate the context
130   theError = DSpContext_SetState(gDSpContext, kDSpContextState_Active);
131   if(theError != noErr) {
132     // Fade back in the display before dying
133     theError = DSpContext_FadeGammaIn(NULL, NULL);
134 
135     // Now do the fatal error alert
136     FatalErrorAlert(kErr_ActivateContextFailed, theError);
137   }
138   // Fade in
139   theError = DSpContext_FadeGammaIn(NULL, NULL);
140   if(theError != noErr)
141     FatalErrorAlert(kErr_DSpFadeFailed, theError);
142 
143   // Create a window to draw in
144   CreateWindow(theFrontBuffer, width, height);
145 
146   return theFrontBuffer;
147 
148 }
149 
150 /********************> CreateWindow() <*****/
CreateWindow(CGrafPtr & theFrontBuffer,int width,int height)151 void CreateWindow(CGrafPtr & theFrontBuffer, int width, int height)
152 {
153 
154   Rect rect;
155   AuxWinHandle awh;
156   CTabHandle theColorTable;
157   OSErr error;
158   RGBColor backColor = { 0xFFFF, 0xFFFF, 0xFFFF };
159   RGBColor foreColor = { 0x0000, 0x0000, 0x0000 };
160 
161   // Set the window rect
162   rect.top = rect.left = 0;
163   DSpContext_LocalToGlobal(gDSpContext, (Point *) & rect);
164   rect.right = rect.left + width;
165   rect.bottom = rect.top + height;
166 
167   // Create a new color window
168   theFrontBuffer =
169       (CGrafPtr) NewCWindow(NULL, &rect, "\p", 0, plainDBox, kMoveToFront, 0,
170                             0);
171 
172   // set the content color of the window to black to avoid a white flash when the window appears.
173   if(GetAuxWin((WindowPtr) theFrontBuffer, &awh)) {
174     theColorTable = (**awh).awCTable;
175     error = HandToHand((Handle *) & theColorTable);
176     if(error)
177       DebugStr("\pOut of memory!");
178 
179     (**theColorTable).ctTable[wContentColor].rgb.red = 0;
180     (**theColorTable).ctTable[wContentColor].rgb.green = 0;
181     (**theColorTable).ctTable[wContentColor].rgb.blue = 0;
182 
183     CTabChanged(theColorTable);
184 
185     // the color table will be disposed by the window manager when the window is disposed
186     SetWinColor((WindowPtr) theFrontBuffer, (WCTabHandle) theColorTable);
187   }
188   // Show the window
189   ShowWindow((GrafPtr) theFrontBuffer);
190   SetPort((GrafPtr) theFrontBuffer);
191 
192   // Set current pen colors
193   RGBForeColor(&foreColor);
194   RGBBackColor(&backColor);
195 
196 }
197 
198 /********************> ShutdownScreen() <*****/
ShutdownScreen(CGrafPtr theFrontBuffer)199 void ShutdownScreen(CGrafPtr theFrontBuffer)
200 {
201 
202   DSpContext_FadeGammaOut(NULL, NULL);
203   DisposeWindow((WindowPtr) theFrontBuffer);
204   DSpContext_SetState(gDSpContext, kDSpContextState_Inactive);
205   DSpContext_FadeGammaIn(NULL, NULL);
206   DSpContext_Release(gDSpContext);
207   DSpShutdown();
208 
209 }
210 
211 /********************> SetupAGL() <*****/
SetupAGL(AGLDrawable window)212 AGLContext SetupAGL(AGLDrawable window)
213 {
214   GLint attrib[] = { AGL_RGBA, AGL_DEPTH_SIZE, 24, AGL_DOUBLEBUFFER, AGL_NONE };
215   AGLPixelFormat format;
216   AGLContext context;
217   GLboolean ok;
218 
219   // Choose an rgb pixel format
220   format = aglChoosePixelFormat(NULL, 0, attrib);
221   if(format == NULL)
222     return NULL;
223 
224   // Create an AGL context
225   context = aglCreateContext(format, NULL);
226   if(context == NULL)
227     return NULL;
228 
229   // Attach the window to the context
230   ok = aglSetDrawable(context, window);
231   if(!ok)
232     return NULL;
233 
234   // Make the context the current context
235   ok = aglSetCurrentContext(context);
236   if(!ok)
237     return NULL;
238 
239   // The pixel format is no longer needed so get rid of it
240   aglDestroyPixelFormat(format);
241 
242   return context;
243 
244 }
245 
246 /********************> CleanupAGL() <*****/
CleanupAGL(AGLContext context)247 void CleanupAGL(AGLContext context)
248 {
249 
250   aglSetCurrentContext(NULL);
251   aglSetDrawable(context, NULL);
252   aglDestroyContext(context);
253 
254 }
255