palm-os-sdk/PalmOne/Samples/_HelperReceiver/Src/HelperReceiver.c

760 lines
18 KiB
C

/***************************************************************
*
* Project:
* HelperReceiver
*
* Copyright info:
* Copyright (c) Handspring 1999 -- All Rights Reserved
*
* FileName:
* HelperReceiver.c
*
* Description:
* A sample test application to demonstrate to to register
* and received SMS, Email, and WEB system helper notifications.
*
* History:
* 18-apr-2000 dia Created
* 24-may-2000 vmk Modified for the semi-final Helpers API
* 20-jul-2000 jem Modified from MailWrapper to simulate phone usage.
* 06-sep-2000 sv Modified to conform to new Helper Services API.
* 14-oct-2003 fhv Modified to build under Palm OS 5 SDK.
* 18-oct-2003 fhv Added Email and WEB processing to release a sample code
* for DTS (developers).
****************************************************************/
#include <PalmOS.h>
#include <68K/Hs.h>
#include <Helper.h>
#include <HelperServiceClass.h>
#include <HsNav.h>
#include "HelperReceiver.h"
/***********************************************************************
*
* Private Equates
*
***********************************************************************/
//Crazy mod to the file to get it to compile - this is actually registered
//in HsCreators.h, but would cause registration trouble with the other phone
//incs directory
#define HelperReceiverCreator 'TRHR'
#define prvMyHelperID HelperReceiverCreator
// Until the new Helper Service Classes are defined, we define them here
// so implementation for the Default Apps panel can continue. Remove these
// service class ID definitions when HelperServiceClass.h has been updated.
#define kHelperServiceClassIDURL 'url_'
/***********************************************************************
*
* Global variables
*
***********************************************************************/
static void
DoRegister (void)
{
UInt16 cardNo;
LocalID dbID;
Err err;
// Get information about this application to send to Notification
// manager calls...
SysCurAppDatabase (&cardNo, &dbID);
err = SysNotifyRegister (cardNo, dbID, sysNotifyHelperEvent,
NULL /*callbackP*/,
sysNotifyNormalPriority,
NULL /*userDataP*/);
// add another scenario: register successfully.
if (err == errNone)
FrmCustomAlert (rscRegisterSuccessAlertID, "YES!", "", "");
if (err == sysNotifyErrDuplicateEntry)
{
FrmCustomAlert (rscRegisterFailedAlertID, "App already registered", "", "");
}
else if (err)
{
Char buffer[32];
StrIToH (buffer, err);
FrmCustomAlert (rscRegisterFailedAlertID, "Err: 0x", buffer, "");
}
}
static void
DoUnregister (void)
{
UInt16 cardNo;
LocalID dbID;
Err err;
// Get information about this application to send to Notification
// manager calls...
SysCurAppDatabase (&cardNo, &dbID);
err = SysNotifyUnregister (cardNo, dbID, sysNotifyHelperEvent,
sysNotifyNormalPriority);
// add another scenario: register successfully.
if (err == errNone)
FrmCustomAlert (rscUnregisterSuccessAlertID, "YES!", "", "");
if (err == sysNotifyErrEntryNotFound)
{
FrmCustomAlert (rscUnregisterFailedAlertID, "App was not registered", "", "");
}
else if (err)
{
Char buffer[32];
StrIToH (buffer, err);
FrmCustomAlert (rscUnregisterFailedAlertID, "Err: 0x", buffer, "");
}
}
/***************************************************************
* Function: MainFrmInit
*
* Summary: This routine initializes the "Main View" of our app
*
* Parameters:
* frmP IN form pointer
*
* Returns:
* void
*
* Called By:
* MainFrmEventHandler()
*
* Notes:
*
* History:
* 18-apr-2000 dia Ceated
*
****************************************************************/
static void
MainFrmInit (FormPtr frmP)
{
;
}
/***************************************************************
* Function: MainFrmDoCommand
*
* Summary: Execute a menu command for our main form
*
* Parameters:
* command IN menu command to execute
*
* Returns:
* true if event was handled
*
* Called By:
* MainFrmEventHandler()
*
* Notes:
*
* History:
* 18-apr-2000 dia Ceated
*
****************************************************************/
static Boolean
MainFrmDoCommand (UInt16 command)
{
Boolean handled = false;
UInt16 cardNo;
LocalID dbID;
DmSearchStateType searchState;
DmGetNextDatabaseByTypeCreator(true, &searchState, sysFileTApplication,
HelperReceiverCreator, true, &cardNo, &dbID);
switch (command)
{
case MainOptionsAbout:
MenuEraseStatus(0);
HsAboutHandspringApp(cardNo, dbID, "2007", "Palm DTS Team");
handled = true;
break;
default:
break;
}
return handled;
}
/***************************************************************
* Function: MainFrmHandleControl
*
* Summary: Handle a control select event
*
* Parameters:
* eventP IN The control select event...
*
* Returns:
* true if event was handled
*
* Called By:
* MainFrmEventHandler()
*
* Notes:
*
* History:
* 18-apr-2000 dia Ceated
*
****************************************************************/
static Boolean
MainFrmHandleControl (EventPtr eventP)
{
Boolean handled = false;
// Figure out which of the two buttons it was...
switch (eventP->data.ctlSelect.controlID)
{
case rscMainViewEnableButtonID:
DoRegister();
handled = true;
break;
case rscMainViewDisableButtonID:
DoUnregister();
handled = true;
break;
default:
// allow other events to be handled by frmhandleevent
handled = false;
break;
}
return handled;
}
/***************************************************************
* Function: MainFrmEventHandler
*
* Summary: Event handler for our main form.
*
* Parameters:
* eventP IN pointer to event to handle
*
* Returns:
* true if event was handled
*
* Called By:
* FrmDispatchEvent() when event is for our main form.
* FrmDispatchEvent() is called by our AppEventLoop()
*
* Notes:
*
* History:
* 18-apr-2000 dia Ceated
*
****************************************************************/
static Boolean
MainFrmEventHandler (EventPtr eventP)
{
FormPtr formP;
Boolean handled = false;
switch (eventP->eType)
{
// -------------------------------------------------------
// Init the form
// -------------------------------------------------------
case frmOpenEvent:
formP = FrmGetActiveForm ();
MainFrmInit (formP);
FrmDrawForm (formP);
FrmNavObjectTakeFocus(formP, rscMainViewEnableButtonID);
handled = true;
break;
// -------------------------------------------------------
// Menu commands
// -------------------------------------------------------
case menuEvent:
handled = MainFrmDoCommand (eventP->data.menu.itemID);
break;
// -------------------------------------------------------
// Buttons
// -------------------------------------------------------
case ctlSelectEvent:
handled = MainFrmHandleControl (eventP);
break;
// -------------------------------------------------------
// Close our form
// -------------------------------------------------------
case frmCloseEvent:
break;
default:
break;
}
return handled;
}
/***************************************************************
* Function: AppStart
*
* Summary: Application initialization when being launched
* as a normal application (i.e. not to execute an action code).
*
* Parameters:
* void
*
* Returns:
* 0 if no error
*
* Called By:
* PilotMain when action code is for a normal launch.
*
* Notes:
*
* History:
* 26-Feb-1999 RM Ceated
*
****************************************************************/
static UInt32
AppStart(void)
{
FrmGotoForm (rscMainViewFormID);
return 0;
}
/***************************************************************
* Function: AppStop
*
* Summary: Application cleanup. This routine cleans up
* all initialization performed by AppStart().
*
* Parameters:
* void
*
* Returns:
* 0 if no error
*
* Called By:
* PilotMain, after EventLoop returns
*
* Notes:
*
* History:
* 26-Feb-1999 RM Ceated
*
****************************************************************/
static void
AppStop (void)
{
FrmCloseAllForms();
}
/***************************************************************
* Function: AppEventLoop
*
* Summary: This routine loads form resources and set the event
* handler for the form loaded.
*
* Parameters:
* eventP IN pointer to event
*
* Returns:
* true if event was handled.
*
* Called By:
* AppEventLoop.
*
* Notes:
*
* History:
* 26-Feb-1999 RM Ceated
*
****************************************************************/
static Boolean
AppHandleEvent (EventPtr eventP)
{
UInt16 formID;
FormPtr frmP;
Boolean handled = false;
if (eventP->eType == frmLoadEvent)
{
// Load the form resource.
formID = eventP->data.frmLoad.formID;
frmP = FrmInitForm (formID);
FrmSetActiveForm (frmP);
// Set the event handler for the form. The handler of the currently
// active form is called by FrmHandleEvent each time is receives an
// event.
switch (formID)
{
case rscMainViewFormID:
FrmSetEventHandler(frmP, MainFrmEventHandler);
handled = true;
break;
default:
break;
}
}
return handled;
}
/***************************************************************
* Function: AppEventLoop
*
* Summary: Main event loop for the application
*
* Parameters:
* void
*
* Returns:
* 0 if no error
*
* Called By:
* PilotMain after initializing.
*
* Notes:
*
* History:
* 26-Feb-1999 RM Ceated
*
****************************************************************/
static void
AppEventLoop(void)
{
UInt16 err;
EventType event;
do
{
EvtGetEvent (&event, evtWaitForever);
if (!SysHandleEvent (&event))
if (!MenuHandleEvent (0, &event, &err))
if (!AppHandleEvent (&event))
FrmDispatchEvent (&event);
} while(event.eType != appStopEvent);
}
// Executes the helperNotifyActionCodeExecute request if it is intended
// for this helper
static Boolean
ProcessExecute (HelperNotifyEventType* helperParamP)
{
HelperNotifyExecuteType* executeP;
Boolean handled = false;
executeP = helperParamP->data.executeP;
// If this is a request for SMS service and it either targets
// this specific helper via its helperID or wildcard (0), then
// handle it.
if ( (executeP->serviceClassID == kHelperServiceClassIDSMS)
&&
((executeP->helperAppID == prvMyHelperID) || (executeP->helperAppID == 0)) )
{
UInt32 buttonNo;
HelperServiceSMSDetailsType * detailsP = executeP->detailsP;
buttonNo = FrmCustomAlert(rscHelperReceiverSMSAlertID, "Send SMS", executeP->displayedName, executeP->dataP);
if (buttonNo)
{
if (detailsP && detailsP->message && StrLen(detailsP->message))
{
FrmCustomAlert(rscHelperReceiverMessageAlertID, NULL, NULL, detailsP->message);
}
else
{
FrmCustomAlert(rscHelperReceiverMessageAlertID, NULL, NULL, "(empty message)");
}
}
executeP->err = 0;
handled = true;
}
else if ( (executeP->serviceClassID == kHelperServiceClassIDEMail)
&&
((executeP->helperAppID == prvMyHelperID) || (executeP->helperAppID == 0)) )
{
UInt32 buttonNo;
HelperServiceEMailDetailsType* detailsP = executeP->detailsP;
buttonNo = FrmCustomAlert(rscHelperReceiverEmailAlertID, "Send Email", executeP->displayedName, executeP->dataP);
if (buttonNo)
{
if (detailsP && detailsP->message && StrLen(detailsP->message))
{
FrmCustomAlert(rscHelperReceiverMessageAlertID, "Subject: ", detailsP->subject, detailsP->message);
}
else
{
FrmCustomAlert(rscHelperReceiverMessageAlertID, NULL, NULL, "(empty message)");
}
}
executeP->err = 0;
handled = true;
}
else if ( (executeP->serviceClassID == kHelperServiceClassIDURL)
&&
((executeP->helperAppID == prvMyHelperID) || (executeP->helperAppID == 0)) )
{
UInt32 buttonNo;
buttonNo = FrmCustomAlert(rscHelperReceiverWebAlertID, "Go To Link", executeP->dataP, NULL);
executeP->err = 0;
handled = true;
}
return (handled);
} // ProcessExecute
// Executes the helperNotifyActionCodeValidate request if it is intended
// for this helper; the purpose of this request is to determine whether
// any helper (or a specific helper) for a specific service class exists,
// without incurring the memory management overhead of
// helperNotifyActionCodeEnumerate.
static Boolean
ProcessValidate (HelperNotifyEventType* helperParamP)
{
HelperNotifyValidateType* validateP;
Boolean handled = false;
validateP = helperParamP->data.validateP;
// If this is a request for Voice or Fax service and it either targets
// this specific helper via its helperID or wildcard (0), then
// handle it.
if ( ((validateP->serviceClassID == kHelperServiceClassIDSMS)
||(validateP->serviceClassID == kHelperServiceClassIDEMail)
||(validateP->serviceClassID == kHelperServiceClassIDURL))
&& (validateP->helperAppID == prvMyHelperID || validateP->helperAppID == 0) )
{
handled = true;
}
return (handled);
} // ProcessValidate
// Executes the helperNotifyActionCodeEnumerate request; the "host" makes
// this request in order to discover which services are available. All
// helpers are required to handle this call
static void
ProcessEnumerate (HelperNotifyEventType* helperParamP, UInt32 classID)
{
HelperNotifyEnumerateListType* nodeP;
// Allocate the enumeration list node
nodeP = MemPtrNew (sizeof(*nodeP));
if (!nodeP)
{
ErrNonFatalDisplay ("Out of memory");
return;
}
// Change owner to "system" so the memory will not be deleted automatically
// when we return from PilotMain
MemPtrSetOwner (nodeP, 0);
// Initialize the node
MemSet (nodeP, sizeof (*nodeP), 0);
// DOLATER; should get names from resources for localization.
// For display in default helper configuration and other UI
StrNCopy (nodeP->helperAppName, "Helper Receiver", sizeof(nodeP->helperAppName));
// For possible display in an action pop-up or similar UI gadget;
// it's a good idea to keep this short.
StrNCopy (nodeP->actionName, "Send Message", sizeof(nodeP->actionName));
nodeP->helperAppID = prvMyHelperID; // our unique helper ID
nodeP->serviceClassID = classID; // class of service we support
// Finally, link in the node into the list
HelperEnumerateEnqueueEntry ((HelperNotifyEnumerateListType*)helperParamP->data.enumerateP, nodeP); // HelperEnumNodeEnqueue is a macro
return;
}
/***************************************************************
* Function: PilotMain
*
* Summary: Entry point
*
* Parameters:
* cmd IN Action code for the app. This is one of the
* action codes sysAppLaunchCmdXXX defined in
* <SystemMgr.h>
* cmdPBP IN Parameter block pointer for action code.
* launchFlags IN Launch flags, one or more of
* sysAppLaunchFlagXXX defined in <SystemMgr.h>
*
* Returns:
* 0 if no error
*
* Called By:
* PalmOS when launching the app or asking it to execute an
* action code like find or goto.
*
* Notes:
*
*
* History:
* 26-Feb-1999 RM Ceated by Ron Marianetti
* 24-May-2000 vmk Modified for the "semi-final" Helpers API
*
****************************************************************/
static UInt32
HelperReceiverPilotMain (UInt16 cmd, void* cmdPBP, UInt16 launchFlags)
{
UInt32 err;
switch (cmd)
{
case sysAppLaunchCmdNormalLaunch:
{
err = AppStart(); // Application start code
if (err) return err;
AppEventLoop(); // Event loop
AppStop (); // Application stop code
}
break;
case sysAppLaunchCmdNotify:
{
SysNotifyParamType* paramP = (SysNotifyParamType*) cmdPBP;
// Look for notifications from the helper manager...
if (paramP->notifyType == sysNotifyHelperEvent)
{
HelperNotifyEventType* helperParamP = (HelperNotifyEventType*) paramP->notifyDetailsP;
// Just to verify that nothing broke...
#if (kHelperNotifyCurrentVersion != 1)
#error "Helper structure changed--are we still OK?"
#endif
// Figure out which type of helper manager event...
if (helperParamP->actionCode == kHelperNotifyActionCodeExecute)
{
// Only one helper is allowed to actually handle this request
if (!paramP->handled)
{
paramP->handled = ProcessExecute (helperParamP);
// Must be careful not to set paramP->handled to false because
// others may have already handled this notification
}
}
else if (helperParamP->actionCode == kHelperNotifyActionCodeValidate)
{
// Only one helper is allowed to actually handle this request
if (!paramP->handled)
{
paramP->handled = ProcessValidate (helperParamP);
}
}
else if (helperParamP->actionCode == kHelperNotifyActionCodeEnumerate)
{
// More than one helper may need to handle this request,
// so we don't check the "handled" flag here
ProcessEnumerate (helperParamP, kHelperServiceClassIDSMS);
ProcessEnumerate (helperParamP, kHelperServiceClassIDEMail);
ProcessEnumerate (helperParamP, kHelperServiceClassIDURL);
paramP->handled = true; // all helpers are required to handle
// the "Enumerate" request.
}
else
{
ErrNonFatalDisplay ("unknown helperNotifyActionCode");
}
}
}
break;
case sysAppLaunchCmdSyncNotify:
case sysAppLaunchCmdSystemReset:
// Want to register upon reset and upon card insertion...
// ...need to set "-resetAfterInstall" to get these notification from a card.
DoRegister();
break;
}
return 0;
}
// Make a call to a more specific functiom
UInt32
PilotMain (UInt16 cmd, void* cmdPBP, UInt16 launchFlags)
{
return HelperReceiverPilotMain (cmd, cmdPBP, launchFlags);
}