Simple DrawSprocket Main.c

/*
    File:       Simple DrawSprocket Main.c
 
    Contains:   Template for standard Macintosh Application using DrawSprocket
                Cmd-Q to exit.
 
    Written by: Geoff Stahl (ggs)
 
    Copyright:  Copyright (c) 1999 Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
*/
 
// Building with DrawSprocket 1.7
//#define kDSp17 1
 
// system includes ----------------------------------------------------------
 
#include <MacMemory.h>
#include <Events.h>
#include <Fonts.h>
#include <Windows.h>
#include <TextEdit.h>
#include <Dialogs.h>
#include <Sound.h>
#include <SoundInput.h>
#include <ToolUtils.h>
#include <OSUtils.h>
#include <Devices.h>
#include <Resources.h>
#include <Folders.h>
 
#include <DrawSprocket.h>
 
#include <stdio.h>
 
// project includes ---------------------------------------------------------
 
 
// function declarations ----------------------------------------------------
 
void InitToolbox(void);
void GraphicsInitAttributes(DSpContextAttributes *inAttributes);
Boolean SetUp (void);
void DoMenu (SInt32 menuResult);
void DoKey (SInt8 theKey, SInt8 theCode);
void DoUpdate (void);
void CToPStr (register const char *inString, Str255 * outString );
void DoEvent (void);
void CleanUp (void);
 
// statics/globals (internal only) ------------------------------------------
 
// Menu defs
enum 
{
    kMenuApple = 128,
    kMenuFile = 129,
    
    kAppleAbout = 1,
    kFileDoNothing = 1,
    kFileQuit,
    
    kActiveSleep = 0,
    
    kInActiveSleep = 32767
};
 
NumVersion gVersionDSp;
 
Boolean gDone = false;
SInt32 gSleepTime = kActiveSleep;
 
RGBColor grgbColor = {0x4000,0x6000,0x6000};
 
DSpContextReference gTheContext;
GDHandle ghGD;
 
 
// functions (internal/private) ---------------------------------------------
 
void InitToolbox (void)
{
    MenuHandle menu;
    SInt16 modifiers = 0;
    EventRecord event;
    short x;
 
    for (x = 0; x < 3; x++)
        MoreMasters (); 
    MaxApplZone ();
 
    InitGraf((Ptr) &qd.thePort);
    InitFonts();
    InitWindows();
    InitMenus();
    TEInit();
    InitDialogs(nil);
    InitCursor();
    
    qd.randSeed =  TickCount();
 
    // init events
    EventAvail(everyEvent, &event);
    modifiers |= event.modifiers;
    EventAvail(everyEvent, &event);
    modifiers |= event.modifiers;
    EventAvail(everyEvent, &event);
    modifiers |= event.modifiers;
 
    // Init Menus
    menu = NewMenu (kMenuApple, "\p\024");          // new  apple menu
    InsertMenu (menu, 0);                           // add menu to end
    AppendResMenu(menu, 'DRVR');
    
    menu = NewMenu (kMenuFile, "\pFile");           // new menu
    InsertMenu (menu, 0);                           // add menu to end
    AppendMenu (menu, "\pDo Nothing;Quit/Q"); // add items
    
    DrawMenuBar();
} 
 
// --------------------------------------------------------------------------
 
void GraphicsInitAttributes(DSpContextAttributes *inAttributes)
{
    BlockZero (inAttributes, sizeof (DSpContextAttributes));
}
 
// --------------------------------------------------------------------------
 
Boolean SetUp (void)
{
    OSErr err = noErr;
    DSpContextAttributes theAttributes;
    DisplayIDType displayID;
    
    InitToolbox ();
    
    // Do DrawSprocket Setup
    
    if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpStartup)
    {
        DebugStr("\pDSp extension not loaded\n");
        return false;
    }
    if (noErr != DSpStartup ())
    {
        DebugStr("\pUnable to startup DSp\n");
        return false;
    }
        
    // Find DSp version (just to show how)
#ifdef kDSp17
    if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpGetVersion) 
#endif
    {
        // must be 1.1.4 or earlier so look at extension
        short resFileSave, resFileDSp;
        short vRefDSp;
        long dirIDDSp;
        FSSpec fsSpecDSp;
        OSErr err;
        Handle hVersion;
        
        // assume 1.0 version to start with (worst case)
        gVersionDSp.majorRev = 1;
        gVersionDSp.minorAndBugRev = 0;
        gVersionDSp.stage = 0x80;
        gVersionDSp.nonRelRev = 0;
 
        resFileSave = CurResFile();
        SetResLoad (false);
        // search application directory for debug lib
        resFileDSp = OpenResFile ("\pDrawSprocketDebugLib");
        err = ResError ();
        if (fnfErr == err)
        {
            // search application directory for lib
            resFileDSp = OpenResFile ("\pDrawSprocketLib");
            err = ResError ();
            if (fnfErr == err)
            {
                // search extensions folder for debug lib
                FindFolder (kOnSystemDisk, kExtensionFolderType, kDontCreateFolder, &vRefDSp, &dirIDDSp);
                FSMakeFSSpec (vRefDSp, dirIDDSp, "\pDrawSprocketLib", &fsSpecDSp);
                resFileDSp = FSpOpenResFile (&fsSpecDSp, fsRdPerm);
                err = ResError ();
                if (fnfErr == err)
                {
                    // search extensions folder directory for lib
                    FSMakeFSSpec (vRefDSp, dirIDDSp, "\pDrawSprocketDebugLib", &fsSpecDSp);
                    resFileDSp = FSpOpenResFile (&fsSpecDSp, fsRdPerm);
                    err = ResError ();
                }
            }
        }
        // if we have an open resource file and no error
        if ((noErr == err) && (-1 != resFileDSp))
        {
            SetResLoad (true);
            hVersion = GetResource ('vers', 1); 
            err = ResError ();
            if ((noErr == err) && (NULL != hVersion))
            {
                gVersionDSp.majorRev = *(((unsigned char *)*hVersion) + 0);
                gVersionDSp.minorAndBugRev = *(((unsigned char *)*hVersion) + 1);
                gVersionDSp.stage = *(((unsigned char *)*hVersion) + 2);
                gVersionDSp.nonRelRev = *(((unsigned char *)*hVersion) + 3);
                ReleaseResource (hVersion);
            }
            UseResFile(resFileSave);
            CloseResFile(resFileDSp);
        }   
    }
#ifdef kDSp17
    else
        gVersionDSp = DSpGetVersion ();
#endif
 
    GraphicsInitAttributes (&theAttributes);
    
    theAttributes.displayWidth          = 640;
    theAttributes.displayHeight         = 480;
    theAttributes.colorNeeds            = kDSpColorNeeds_Require;
    theAttributes.displayDepthMask      = kDSpDepthMask_8;
    theAttributes.displayBestDepth      = 8;
    theAttributes.backBufferDepthMask   = kDSpDepthMask_All;            // must be specified even if only fornt buffer is needed
    theAttributes.backBufferBestDepth   = 8;
    theAttributes.pageCount             = 1;                            // only the front buffer is needed
    // use two above if you want to swap buffers to animate
    
    // will display user dialog if context selection is required otherwise as find best context
    err = DSpUserSelectContext(&theAttributes, 0L, nil, &gTheContext);
    if (noErr != err)
    {
        DebugStr("\pA suitable display context could not be found.");
        return false;
    }
 
    DSpSetBlankingColor(&grgbColor);
    
    // get our device for future use
    err =  DSpContext_GetDisplayID (gTheContext, &displayID);
    if (noErr != err)
    {
        DebugStr("\pDSpContext_GetDisplayID () had an error.");
        return false;
    }
 
    // get GDHandle for ID'd device
    err = DMGetGDeviceByDisplayID (displayID, &ghGD, false);
    if (noErr != err)
    {
        DebugStr("\pDMGetGDeviceByDisplayID() had an error.");
        return false;
    }
    
    // reserve our context
    err = DSpContext_Reserve (gTheContext, &theAttributes);
    if (noErr != err)
    {
        DebugStr("\pUnable to create the display!");
        return false;
    }
 
    HideCursor();
 
    err = DSpContext_FadeGammaOut (NULL, NULL);                 // remove for debug
    if (noErr != err)
        DebugStr("\pUnable to fade the display!");
 
    // activate our context
    err = DSpContext_SetState (gTheContext, kDSpContextState_Active);
    if (noErr != err)
    {
        DSpContext_FadeGammaIn (NULL, NULL);    
        DebugStr("\pUnable to set the display!");
        return false;
    }
        
    err = DSpContext_FadeGammaIn (NULL, NULL);  
    if(noErr != err)
        DebugStr("\pUnable to fade the display!");
 
    return true;
}
 
// --------------------------------------------------------------------------
 
void DoMenu (SInt32 menuResult)
{
    SInt16 theMenu;
    SInt16 theItem;
    Str255 daName;
    MenuRef theMenuHandle;
        
    theMenu = HiWord(menuResult);
    theItem = LoWord(menuResult);
    theMenuHandle = GetMenuHandle(theMenu);
 
    switch (theMenu)
    {
        case kMenuApple:
            switch (theItem)
            {
                case kAppleAbout:
                    break;
                default:
                    OpenDeskAcc(daName);
                    break;
            }
            break;
        case kMenuFile:
            switch (theItem)
            {
                case kFileDoNothing:
                    break;
                case kFileQuit:
                    gDone = true;
                    break;
            }
            break;
    }
    HiliteMenu(0);
    DrawMenuBar();
}
 
// --------------------------------------------------------------------------
 
void DoKey (SInt8 theKey, SInt8 theCode)
{
    #pragma unused (theKey, theCode)
}
 
//---------------------------------------------------------------------------
 
// Copy C string to Pascal string
 
void CToPStr (register const char *inString, Str255 * outString )       // copies in to out
{   
    register unsigned char x = 0;
    do
    {
        *(((char*)outString) + 1 + x) = *(inString + x);
        x++;
    }
    while ((*(inString + x) != 0)  && (x < 256));
    *((char*)outString) = (char) x;                                 
}
 
// --------------------------------------------------------------------------
 
void DoUpdate (void)
{
    OSStatus err;
    CGrafPtr pCGrafFrontBuffer, pCGrafSave = NULL;
    GDHandle hGDSave;
    RGBColor rgbSave, rgbRed = {0x7FFF, 0x0000, 0x0000}, rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF};
    short fNum, len;
    Str255 aStr = "\p";
    char aChar[256];
 
    err = DSpContext_GetFrontBuffer (gTheContext, &pCGrafFrontBuffer);  
    if (err != noErr)
    {
        DebugStr("\pUnable to get front buffer");
        return;
    }
        
    GetGWorld (&pCGrafSave, &hGDSave);
    SetGWorld (pCGrafFrontBuffer, ghGD);
    GetForeColor (&rgbSave);
    
    // draw here
    RGBForeColor (&rgbRed);
    PaintRect (&pCGrafFrontBuffer->portRect);
 
    RGBForeColor (&rgbWhite);
 
    // set text
    GetFNum("\pGeneva", &fNum);
    TextFont(fNum);
    TextSize(12);
    
    // draw centered to screen
    sprintf (aChar, "%d x %d", pCGrafFrontBuffer->portRect.right - pCGrafFrontBuffer->portRect.left, pCGrafFrontBuffer->portRect.bottom - pCGrafFrontBuffer->portRect.top);
    CToPStr (aChar, &aStr);
    len = StringWidth (aStr);
    MoveTo ((short) (pCGrafFrontBuffer->portRect.left + (pCGrafFrontBuffer->portRect.right - pCGrafFrontBuffer->portRect.left) / 2 - (len / 2)), 18);
    DrawString(aStr);
    
    RGBForeColor (&rgbSave);
    SetGWorld (pCGrafSave, hGDSave);
 
/*  
    OSErr err;
    CGrafPtr pCGrafFrontBuffer, pCGrafSave = NULL;
    GDHandle hGD = NULL;
    RGBColor rgbRed = {0x7FFF, 0x0000, 0x0000};
 
    err = DSpContext_GetFrontBuffer (gTheContext, &pCGrafFrontBuffer);  
    if (noErr != err)
        DebugStr("\pUnable to get front buffer");
        
        
    GetGWorld (&pCGrafSave, &hGD);
    SetGWorld (pCGrafFrontBuffer, ghGD);
    
    // draw here
    RGBForeColor (&rgbRed);
    MoveTo (0, 0);
    LineTo (640, 480);
    MoveTo (640, 0);
    LineTo (0, 480);
    
    SetGWorld (pCGrafSave, hGD);
*/
}
 
// --------------------------------------------------------------------------
 
void DoEvent (void)
{
    OSErr err = noErr;
    EventRecord theEvent;
    SInt16 whatPart;
    SInt32 menuResult;
    WindowRef whichWindow;
    SInt8 theKey;
    SInt8 theCode;
    Boolean fProcessed = false;
    
    if (WaitNextEvent(everyEvent, &theEvent, gSleepTime, NULL))
    {
        DSpProcessEvent(&theEvent, &fProcessed);
        if (false == fProcessed)
        {
            switch (theEvent.what)
            {
                case mouseDown:
                    whatPart = FindWindow(theEvent.where, &whichWindow);
                    switch (whatPart)
                    {
                        case inGoAway:
                            break;
                        case inMenuBar:
                            DrawMenuBar();
                            menuResult = MenuSelect(theEvent.where);
                            if (HiWord(menuResult) != 0)
                                DoMenu(menuResult);
                            break;
                        case inSysWindow:
                            SystemClick(&theEvent, whichWindow);
                            break;
                    }
                    break;
                case keyDown:
                case autoKey:
                    theKey = theEvent.message & charCodeMask;
                    theCode = (theEvent.message & keyCodeMask) >> 8;
                    if ((theEvent.modifiers & cmdKey) != 0)
                    {
                        menuResult = MenuKey(theKey);
                        if (HiWord(menuResult) != 0)
                            DoMenu (menuResult);
                    }
                    else
                        DoKey (theKey, theCode);
                    break;
                case updateEvt:
                    BeginUpdate((WindowRef) theEvent.message);
                    DoUpdate();
                    EndUpdate((WindowRef) theEvent.message);
                    break;
                case diskEvt:
                    break;
                case osEvt:
                    if (0x01000000 & theEvent.message)      //  Suspend/resume event
                    {
                        // need to handle DSp suspend resume events here
                        if (0x00000001 & theEvent.message)  //  Resume
                        {
                            err = DSpContext_FadeGammaOut (NULL, NULL);                 // remove for debug
                            if (noErr != err)
                                DebugStr("\pUnable to fade the display!");
 
                            // activate our context
                            err = DSpContext_SetState (gTheContext, kDSpContextState_Active);
                            if (noErr != err)
                                DebugStr("\pUnable to set the display!");
                                
                            err = DSpContext_FadeGammaIn (NULL, NULL);  
                            if(noErr != err)
                                DebugStr("\pUnable to fade the display!");
                                
                            HideCursor ();
                            gSleepTime = kActiveSleep;
                        }
                        else    // suspend
                        {   
                            err = DSpContext_FadeGammaOut (NULL, NULL);                 // remove for debug
                            if (noErr != err)
                                DebugStr("\pUnable to fade the display!");
 
                            // pause our context
                            err = DSpContext_SetState (gTheContext, kDSpContextState_Paused);
                            if (noErr != err)
                                DebugStr("\pUnable to set the display!");
                                
                            err = DSpContext_FadeGammaIn (NULL, NULL);  
                            if(noErr != err)
                                DebugStr("\pUnable to fade the display!");
                            
                            ShowCursor ();
                            gSleepTime = kInActiveSleep;
                        }
                    }
                    break;
 
                case kHighLevelEvent:
                    AEProcessAppleEvent(&theEvent);
                    break;
            }
        } // if DSp
    }
    else
    {
        // idle tasks
    }
}
 
// --------------------------------------------------------------------------
 
void CleanUp (void)
{
    OSErr err = noErr;
 
    err = DSpContext_FadeGammaOut (NULL, NULL);                 // remove for debug
    if (noErr != err)
        DebugStr("\pUnable to fade the display!");
 
    err = DSpContext_SetState (gTheContext, kDSpContextState_Inactive);
    if (noErr != err)
        DebugStr("\pUnable to set the display!");
        
    err = DSpContext_FadeGammaIn (NULL, NULL);  
    if(noErr != err)
        DebugStr("\pUnable to fade the display!");
        
    ShowCursor ();
 
    err = DSpContext_Release (gTheContext);
    if (noErr != err) 
        DebugStr ("\pDSpContext_Release error");
        
    err = DSpShutdown ();
    if (noErr != err) 
        DebugStr ("\pDSpShutdown error");
}
 
// --------------------------------------------------------------------------
 
int main (void)
{
    if (SetUp ())
    {
        DoUpdate ();
        while (!gDone) 
        {
            DoEvent ();
        }
    }
    CleanUp ();
    return 0;
}