Arrrgh, this thing is driving me nuts. :-(((

OK, so I disable the automatic execution of start.prc and set an alarm one 
second later. OK, so when I get the alarm, I display my form and enter an event 
loop. OK, whent he event loop ends, I try to run start.prc manually.

Works almost fine - if there *is* a start.prc, that is. If there isn't, I'm 
just shown a blank screen - until the card is removed, when everything is 
restored. I even tried to enque a keypress to launch the Launcher - it still 
doesn't work. :-((

Debugging the application shows that everything works as it should - the proper 
notifications are received and the program does the right thing. But when it 
terminates, if there wasn't a start.prc to run - blank screen. :-((( It seems 
that somehow the Launcher gets screwed up again...

Can't anybody help me, folks? What am I doing wrong? Below is the current 
source of the illustrative application.

Regards,
Vesselin

#include <PalmOS.h>
#include <VfsMgr.h>
#include "CardRsc.h"

#define appCreatorID            'CrMn'
#define appVersionNum            0x01
#define appPrefID                0x00
#define appPrefVersionNum        0x01

#define version40 (sysMakeROMVersion (4, 0, 0, sysROMStageRelease, 0))
#define version41 (sysMakeROMVersion (4, 1, 0, sysROMStageRelease, 0))
#define version60 (sysMakeROMVersion (6, 0, 0, sysROMStageRelease, 0))

typedef struct
{
    UInt8 cmd;
    UInt16 volRef;
    UInt32 dbType, dbCreatorID;
} AlarmInfoType, *AlarmInfoPtr;

UInt32 GetCreatorID (void)
{
    UInt32 nCreatorID;
    UInt16 nCard;
    LocalID LocalDB;
    Err err;

    err = SysCurAppDatabase (&nCard, &LocalDB);
    ErrFatalDisplayIf (err, "Could not get current app database.");
    err = DmDatabaseInfo (nCard, LocalDB, NULL, NULL, NULL, NULL, NULL, NULL, 
NULL, NULL, NULL, NULL, &nCreatorID);
    ErrFatalDisplayIf (err, "Could not get app database info, looking for 
creator ID");
    return nCreatorID;
}

Boolean MainFormHandleEvent (EventPtr pEvent)
{
    Boolean handled;
    FormPtr pForm;
    UInt32 Monitor, romVersion;
    Err err;
    UInt16 cardNo;
    LocalID dbID;

    handled = false;
    switch (pEvent->eType)
    {
        case frmOpenEvent:
            pForm = FrmGetActiveForm ();
            FrmDrawForm (pForm);
            if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
                Monitor = false;
            FrmSetControlValue (pForm, FrmGetObjectIndex (pForm, 
kMainFormMonitorVolumeMountingCheckbox), Monitor);
            handled = true;
            break;
        case ctlSelectEvent:
            switch (pEvent->data.ctlSelect.controlID)
            {
                case kMainFormMonitorVolumeMountingCheckbox:
                    pForm = FrmGetActiveForm ();
                    FtrGet (sysFtrCreator, sysFtrNumROMVersion, &romVersion);
                    if (romVersion < version40)
                    {
                        FrmSetControlValue (pForm, FrmGetObjectIndex (pForm, 
kMainFormMonitorVolumeMountingCheckbox), false);
                        handled = true;
                        break;
                    }
                    SysCurAppDatabase (&cardNo, &dbID);
                    if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
                        Monitor = false;
                    if (FrmGetControlValue (pForm, FrmGetObjectIndex (pForm, 
kMainFormMonitorVolumeMountingCheckbox)))
                    {
                        if (! Monitor)
                        {
                            Monitor = true;
                            err = SysNotifyRegister (cardNo, dbID, 
sysNotifyVolumeMountedEvent,   NULL, sysNotifyNormalPriority, NULL);
                            err = SysNotifyRegister (cardNo, dbID, 
sysNotifyVolumeUnmountedEvent, NULL, sysNotifyNormalPriority, NULL);
                        }
                    }
                    else
                    {
                        if (Monitor)
                        {
                            Monitor = false;
                            err = SysNotifyUnregister (cardNo, dbID, 
sysNotifyVolumeMountedEvent,   sysNotifyNormalPriority);
                            err = SysNotifyUnregister (cardNo, dbID, 
sysNotifyVolumeUnmountedEvent, sysNotifyNormalPriority);
                        }
                    }
                    FrmSetControlValue (pForm, FrmGetObjectIndex (pForm, 
kMainFormMonitorVolumeMountingCheckbox), Monitor);
                    FtrSet (GetCreatorID (), 1000, Monitor);
                    handled = true;
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
    return handled;
}

Boolean InfoFormHandleEvent (EventPtr pEvent)
{
    Boolean handled;
    FormPtr pForm;

    handled = false;
    switch (pEvent->eType)
    {
        case frmOpenEvent:
            pForm = FrmGetActiveForm ();
            FrmDrawForm (pForm);
            handled = true;
            break;
        default:
            break;
    }
    return handled;
}

void AppStop (void)
{
    FrmCloseAllForms ();
}

Boolean AppHandleEvent (EventPtr pEvent)
{
    UInt16     formId;
    FormPtr    pForm;
    Boolean    handled;

    handled = false;
    if (pEvent->eType == frmLoadEvent)
    {
        formId = pEvent->data.frmLoad.formID;
        pForm = FrmInitForm (formId);
        FrmSetActiveForm (pForm);
        switch (formId)
        {
            case kMainForm:
                FrmSetEventHandler (pForm, MainFormHandleEvent);
                break;
            case kInfoForm:
                FrmSetEventHandler (pForm, InfoFormHandleEvent);
                break;
            default:
                break;
        }
        handled = true;
    }
    return handled;
}

void AppEventLoop (void)
{
    Err       error;
    EventType event;

    do
    {
        EvtGetEvent (&event, evtWaitForever);
        if (SysHandleEvent (&event))
            continue;
        if (MenuHandleEvent (0, &event, &error))
            continue;
        if (AppHandleEvent (&event))
            continue;
        FrmDispatchEvent (&event);
    }
    while (event.eType != appStopEvent);
}

void RegisterForNotifications (void)
{
    UInt16 cardNo;
    LocalID dbID;
    UInt32 romVersion;
    UInt32 Monitor;
    Err err;

    FtrGet (sysFtrCreator, sysFtrNumROMVersion, &romVersion);
    if (romVersion >= version40)
    {
        if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
            Monitor = false;
        if (Monitor)
        {
            SysCurAppDatabase (&cardNo, &dbID);
            err = SysNotifyRegister (cardNo, dbID, sysNotifyVolumeMountedEvent, 
  NULL, sysNotifyNormalPriority, NULL);
            err = SysNotifyRegister (cardNo, dbID, 
sysNotifyVolumeUnmountedEvent, NULL, sysNotifyNormalPriority, NULL);
        }
    }
}

void HandleNotification (SysNotifyParamType *np)
{
    UInt32 Monitor;
    UInt16 cardNo;
    LocalID dbID;
    AlarmInfoPtr alarmInfo;
    DmSearchStateType stateInfo;
    Err err;

    switch (np->notifyType)
    {
        case sysNotifyVolumeMountedEvent:
            if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
                Monitor = false;
            if (Monitor)
            {
                np->handled |= vfsHandledStartPrc;
                SysCurAppDatabase (&cardNo, &dbID);
                alarmInfo = (AlarmInfoPtr) MemPtrNew (sizeof (AlarmInfoType));
                alarmInfo->cmd = 1;
                alarmInfo->volRef = ((VFSSlotMountParamType *) 
np->notifyDetailsP)->vfsMountParam.volRefNum;
                MemPtrSetOwner (alarmInfo, 0);
                AlmSetAlarm (cardNo, dbID, (UInt32) alarmInfo, TimGetSeconds () 
+ 1, true);
            }
            break;
        case sysNotifyVolumeUnmountedEvent:
            if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
                Monitor = false;
            if (Monitor)
            {
                SysCurAppDatabase (&cardNo, &dbID);
                err = FtrGet (GetCreatorID (), 2000, (UInt32 *) &alarmInfo);
                alarmInfo->cmd = 2;
                AlmSetAlarm (cardNo, dbID, (UInt32) alarmInfo, TimGetSeconds () 
+ 1, true);
            }
            break;
        case sysNotifyAppQuittingEvent:
            err = FtrGet (GetCreatorID (), 2000, (UInt32 *) &alarmInfo);
            err = DmGetNextDatabaseByTypeCreator (true, &stateInfo, 
alarmInfo->dbType, alarmInfo->dbCreatorID, true, &cardNo, &dbID);
            err = DmDeleteDatabase (cardNo, dbID);
            SysCurAppDatabase (&cardNo, &dbID);
            err = SysNotifyUnregister (cardNo, dbID, sysNotifyAppQuittingEvent, 
sysNotifyNormalPriority);
            break;
        default:
            break;
    }
}

UInt32 PilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
    Err err;
    UInt16 cardNo;
    UInt32 dbType, dbCreatorID, romVersion;
    LocalID dbID;
    AlarmInfoPtr alarmInfo;
    DmSearchStateType stateInfo;
    FileRef fileRef;

    switch (cmd)
    {
        case sysAppLaunchCmdNormalLaunch:
            FrmGotoForm (kMainForm);
            AppEventLoop ();
            AppStop ();
            break;
        case sysAppLaunchCmdSystemReset:
        case sysAppLaunchCmdSyncNotify:
            RegisterForNotifications ();
            break;
        case sysAppLaunchCmdNotify:
            HandleNotification ((SysNotifyParamType *) cmdPBP);
            break;
        case sysAppLaunchCmdDisplayAlarm:
            alarmInfo = (AlarmInfoPtr) ((SysDisplayAlarmParamType *) 
cmdPBP)->ref;
            switch (alarmInfo->cmd)
            {
                case 1:
                    // Volume mounted alarm - do your thing
                    FrmGotoForm (kInfoForm);
                    AppEventLoop ();
                    AppStop ();
                    // Start start.prc
                    alarmInfo->dbCreatorID = 0;
                    FtrSet (GetCreatorID (), 2000, (UInt32) alarmInfo);
                    err = VFSFileOpen (alarmInfo->volRef, "/PALM/start.prc", 
vfsModeRead, &fileRef);
                    if (err == errNone)
                    {
                        err = VFSFileDBInfo (fileRef, NULL, NULL, NULL, NULL, 
NULL, NULL, NULL, NULL, NULL, &dbType, &dbCreatorID, NULL);
                        if (err == errNone)
                        {
                            err = VFSFileClose (fileRef);
                            err = DmGetNextDatabaseByTypeCreator (true, 
&stateInfo, dbType, dbCreatorID, true, &cardNo, &dbID);
                            if (err != errNone)
                            {
                                err = VFSImportDatabaseFromFile 
(alarmInfo->volRef, "/PALM/start.prc", &cardNo, &dbID);
                                alarmInfo->dbType = dbType;
                                alarmInfo->dbCreatorID = dbCreatorID;
                            }
                            SysUIAppSwitch (cardNo, dbID, 
sysAppLaunchCmdNormalLaunch, NULL);
                        }
                    }
                    break;
                case 2:
                    // Volume unmounted alarm - delete start.prc
                    if (alarmInfo->dbCreatorID == 0)
                        break;
                    err = DmGetNextDatabaseByTypeCreator (true, &stateInfo, 
alarmInfo->dbType, alarmInfo->dbCreatorID, true, &cardNo, &dbID);
                    if (err == errNone)
                    {
                        err = DmDeleteDatabase (cardNo, dbID);
                        if (err != errNone)
                        {
                            SysCurAppDatabase (&cardNo, &dbID);
                            FtrGet (sysFtrCreator, sysFtrNumROMVersion, 
&romVersion);
                            if (romVersion > version41 && romVersion < 
version60)
                                err = SysNotifyRegister (cardNo, dbID, 
sysNotifyAppQuittingEvent,   NULL, sysNotifyNormalPriority, NULL);
                            else
                                AlmSetAlarm (cardNo, dbID, (UInt32) alarmInfo, 
TimGetSeconds () + 1, true);
                        }
                        else
                        {
                            MemPtrFree (alarmInfo);
                            FtrUnregister (GetCreatorID (), 2000);
                        }
                    }
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
    return errNone;
}

-- 
For information on using the Palm Developer Forums, or to unsubscribe, please 
see http://www.palmos.com/dev/support/forums/

Reply via email to