Source/MyPACK_4096.c

#include <Types.h>
#include <Lists.h>
#include <Devices.h>
#include <Controls.h>
#include <TextUtils.h>
#include <Resources.h>
#include <Printing.h>
#include <Files.h>
 
#include "SettingsUtils.h"
#include "driverTypes.h"
 
typedef struct {
    short           size;
    ControlHandle   leftButton;
    ControlHandle   rightButton;
    ControlHandle   onButton;
    ControlHandle   offButton;
} controlsList, *controlsListPtr, **controlsListHandle;
 
typedef enum {
    leftButtonID = 1,
    rightButtonID,
    onButtonID,
    offButtonID,
    byteMask = 0xff
} buttonID;
 
/* control utilities */
static void MySetControlVal(ControlHandle theControl,short value);
static void SaveControls(controlsListPtr theControls);
static controlsListHandle RetrieveControls(void);
static void DisposeControls(void);
 
/* other util functions */
static void ShowAbout(void);
 
/* chooser message handlers */
static OSErr DoInit(controlsListPtr theControls,StringPtr zoneName);
static OSErr DoAddSelection(StringPtr zoneName, ListHandle theList);
static OSErr DoFillList(StringPtr zoneName, ListHandle theList);
static OSErr DoGetSelection(StringPtr zoneName, StringPtr objName,
    ListHandle theList);
static OSErr DoSelect(StringPtr zoneName, StringPtr objName, ListHandle theList,
    long rowNum);
static OSErr DoDeselect(StringPtr zoneName, StringPtr objName, ListHandle theList,
    long rowNum);
static OSErr DoCleanup(StringPtr zoneName, ListHandle theList);
static OSErr DoLeftButton(StringPtr zoneName, StringPtr objName,
    ListHandle theList, short modifiers);
static OSErr DoButtons(StringPtr zoneName, StringPtr objName, ListHandle theList,
    buttonID whichButton, short modifiers);
 
pascal OSErr ChooserMain(short msg, short caller, StringPtr objName,
        StringPtr zoneName, ListHandle theList, long data);
 
#if defined(__MWERKS__)
asm void __Startup__ (void);
asm void __Startup__ (void)
{
    BRA.S   @1
    DC.W    0x5346
    DC.L    0x5041434B
    DC.W    0xF000
    DC.W    0x0201
    DC.L    0x0C13F800
@1:
    JMP ChooserMain
}
#endif /* __MWERKS */
 
 
/*********************************************************************************/
/* control utilities */
static void MySetControlVal(ControlHandle theControl, short value)
{
    if (theControl) {
        SetControlValue(theControl,value);
    } else {
        DebugStr("\pBogus control handle in MySetControlVal");
    }
}
 
static void SaveControls(controlsListPtr theControls)
{
    Str255  foo;
    Handle  savedControls = NewHandleClear(sizeof(controlsList));
    
    foo[0] = 0;
    BlockMove((void *)theControls,(void *)(*savedControls),sizeof(controlsList));
    AddResource(savedControls,'CtLs',-4080,foo);
}
 
static controlsListHandle RetrieveControls(void)
{
    return((controlsListHandle)GetResource('CtLs',-4080));
}
 
static void DisposeControls(void)
{
    Handle  theControls = (Handle)RetrieveControls();
    if (theControls) {
        RemoveResource(theControls);
        DisposeHandle(theControls);
        UpdateResFile(CurResFile());
    } else {
        DebugStr("\pD'Ohh! We lost the controls!");
    }
}
 
/*********************************************************************************/
/* other util functions */
static void ShowAbout(void)
{
    Alert(-4080, nil);
}
 
/*********************************************************************************/
/* chooser message handlers */
static OSErr DoInit(controlsListPtr theControls,StringPtr zoneName)
{
    short   state = GetSavedRadioOption();
    if (!theControls) {
        DebugStr("\pBad controls in DoInit");
        return(nilHandleErr);
    }
    ShowControl(theControls->onButton);
    ShowControl(theControls->offButton);
    MySetControlVal(theControls->onButton,!!state);
    MySetControlVal(theControls->offButton,!state);
    SaveControls(theControls);
    return(noErr);
}
 
static OSErr DoAddSelection(StringPtr zoneName, ListHandle theList)
{
    DebugStr("\pGot Add selection message");
    return(noErr);
}
 
static OSErr DoFillList(StringPtr zoneName, ListHandle theList)
{
    int i,total;
    Str255  theString;
    total = countChooserStrings;
    for(i=0;i<total;i++) {
        Cell    theCell;
 
        GetIndString(theString,chooserStrings,i+1);
        LAddRow(1,i+1,theList);
        SetPt(&theCell,0,i);
        LSetCell(&(theString[1]),(short)(theString[0]),theCell,theList);
    }
    return(noErr);
}
 
static OSErr DoGetSelection(StringPtr zoneName, StringPtr objName,
    ListHandle theList)
{
    // This is called when our driver is first chosen in the chooser to
    // select the zone and object name that we want selected. Since I'm
    // not saving that information, I can't very well set it to anything
    // so I just return noErr.
    
    // given that for non-appletalk devices, zoneName and objName aren't
    // very useful, the API for this function doesn't seem optimal.
 
    //  DebugStr("\pGot get selection message");
    return(noErr);
}
 
static OSErr DoSelect(StringPtr zoneName, StringPtr objName, ListHandle theList,
    long rowNum)
{
    // note: if we don't accept the fillListMsg, the last param to this is
    // undefined. If we do accept it, the objName param is undefined, and
    // the last param is the row # of the list item that was chosen.
    // If we're an appletalk device, the last param is a pointer to the
    // AddrBlock for the device. Isn't that simple?
 
    // DebugStr("\pGot select message");
    return(noErr);
}
 
static OSErr DoDeselect(StringPtr zoneName, StringPtr objName, ListHandle theList,
    long rowNum)
{
    // note: if we don't accept the fillListMsg, the last param to this is
    // undefined. If we do accept it, the objName param is undefined, and
    // the last param is the row # of the list item that was chosen.
    // If we're an appletalk device, the last param is a pointer to the
    // AddrBlock for the device. Isn't that simple?
 
    // DebugStr("\pGot deselect message");
    return(noErr);
}
 
static OSErr DoCleanup(StringPtr zoneName, ListHandle theList)
{
    controlsListHandle  theControls = RetrieveControls();
 
    // notice that I only save the setting when I get the terminate
    // this is to save the pounding on the ResFile if I had a LOT
    // more stuff to save
    if (!theControls) {
        DebugStr("\pBad controls in DoCleanup");
        return(nilHandleErr);
    }
    SaveRadioOption(GetControlValue((**theControls).onButton));
    DisposeControls();
    return(noErr);
}
 
static OSErr DoLeftButton(StringPtr zoneName, StringPtr objName,
    ListHandle theList, short modifiers)
{
    Str255  theString;
    short   whichItem;
    Cell    theCell;
 
    theCell.h = theCell.v = 0;
 
    // figure out which is selected -- for an appletalk device, the
    // zoneName and objName would be what you'd probably want to
    // look at.
 
    // I could also save this away when I get the select message
    // and then read it back here, but the settings already
    // display how to handle global data.
 
    if (LGetSelect(true,&theCell,theList)) whichItem = theCell.v;
    else return(noErr);
 
    GetIndString(theString,longerStrings,whichItem+1);
    ParamText(theString,nil,nil,nil);
    Alert(-4081, nil);
    return(noErr);
}
 
static OSErr DoButtons(StringPtr zoneName, StringPtr objName, ListHandle theList,
    buttonID whichButton, short modifiers)
{
    controlsListHandle  theControls = RetrieveControls();
    
    if (!theControls) {
        DebugStr("\pEEK! Can't retrieve the control handles");
        return(ResError());
    }
 
    switch(whichButton) {
        case leftButtonID:  // we've got a selection, do something with it
            return(DoLeftButton(zoneName,objName,theList,modifiers));
            break;
        case rightButtonID:
            ShowAbout();
            break;
        case onButtonID:
            // notice that I don't save the setting every time it changes
            SetControlValue((**theControls).onButton,1);
            SetControlValue((**theControls).offButton,0);
            break;
        case offButtonID:
            SetControlValue((**theControls).onButton,0);
            SetControlValue((**theControls).offButton,1);
            break;
        default:
            DebugStr("\pWhat the heck kind of button is that?");
            break;
    }
    return(noErr);
}
 
pascal OSErr ChooserMain(short msg, short caller, StringPtr objName,
        StringPtr zoneName, ListHandle theList, long data)
{
    OSErr   error = noErr;
    if (caller != chooserID) {
        DebugStr("\pHmm. We got called by someone that isn't the chooser");
    }
    switch(msg) {
        case chooserInitMsg:
            error = DoInit((controlsListPtr)objName,zoneName);
            break;
        case newSelMsg:
            error = DoAddSelection(zoneName,theList);
            break;
        case fillListMsg:
            error = DoFillList(zoneName, theList);
            break;
        case getSelMsg:
            error = DoGetSelection(zoneName, objName, theList);
            break;
        case selectMsg:
            error = DoSelect(zoneName, objName, theList, data);
            break;
        case deselectMsg:
            error = DoDeselect(zoneName, objName, theList, data);
            break;
        case terminateMsg:
            error = DoCleanup(zoneName, theList);
            break;
        case buttonMsg:
            error = DoButtons(zoneName, objName, theList, (data & byteMask),
                                (short)(data >> 16));
            break;
        default:
            DebugStr("\pWhat the heck message was that?");
            break;
    }
    return(error);
}