|  |  |  |  | 
 8
 Palm System Features
  
8
 Palm System Featuresstatic void SetTimeOfNextAlarm (UInt32 alarmTime, UInt32 ref){    UInt16 cardNo;    LocalID dbID;    DmSearchStateType searchInfo;    DmGetNextDatabaseByTypeCreator (true, &searchInfo,     	 sysFileTApplication, sysFileCDatebook, true, &cardNo, &dbID);    AlmSetAlarm (cardNo, dbID, ref, alarmTime, true);}PilotMain function respond to the launch codes sysAppLaunchCmdAlarmTriggered launch code. After each application has processed this launch code, the alarm manager sends each application sysAppLaunchCmdDisplayAlarm so that the application can display the alarm. The section "Alarm Scenario" gives more information about when these launch codes are received and what actions your application might take. For a specific example of responding to these launch codes, see the Datebook sample code. 
 
AlmSetAlarm and then call it again before the first alarm has triggered, the alarm manager replaces the first alarm with the second alarm. You can use the AlmGetAlarm function to find out if the application has any alarms pending. AlmSetAlarm takes a UInt32 parameter that you can use to pass a specific value so that you have access to it when the alarm triggers. (This is the ref parameter shown in Listing 8.1.) The parameter blocks for both launch codes provide access to this reference parameter. If the reference parameter isn't sufficient, you can define an application feature. See the section "Features" in this chapter. AlmSetAlarm is the local ID of the application (the prc file), not of the record database that the application accesses. You use record database's local ID more frequently than you do the application's local ID, so this is a common mistake to make. AlmSetAlarm, the alarm time is given as the number of seconds since 1/1/1904. If you need to convert a conventional date and time value to the number of seconds since 1/1/1904, use AlmSetAlarm with 0 specified for the alarm seconds parameter. sysAppLaunchCmdAlarmTriggered because doing so will delay other applications from receiving alarms that are set to trigger at the same time. 
   If this alarm requires no further processing, the application should set the purgeAlarm field in the launch code's parameter block to true before returning. Doing so removes the alarm from the queue, which means it won't receive the sysAppLaunchCmdDisplayAlarm launch code.
   The alarm manager finds in the alarm queue the next application that set an alarm and repeats steps 2 and 3. 
   This process is repeated until no more applications are found with this alarm time.
   The alarm manager then finds once again the first application in the alarm queue who set an alarm for this alarm time and sends this application the launch code sysAppLaunchCmdAlarmTriggered launch code, but the display cycle for the second set of alarms is postponed until all earlier alarms have finished displaying.
 
AlmSetAlarm. (Similarly, you use the AlmGetAlarm to see if any alarms are pending for this procedure.) 
 
AlmSetProcAlarm is currently implemented as a macro that calls AlmSetAlarm using a special value for the card number parameter to notify the alarm manager that this is a procedure alarm. Instead of specifying the application's local ID and card number, you specify a function pointer. The other rules for AlmSetAlarm still apply. Notably, a given function can only have one alarm pending at a time, and you can clear any pending alarm by passing 0 for the alarm time. 
 
void myAlarmFunc (UInt16 almProcCmd, SysAlarmTriggeredParamType *paramP)
IMPORTANT: The function pointer must remain valid from the timeAlmSetProcAlarmis called to the time the alarm is triggered. If the procedure is in a shared library, you must keep the library open. If the procedure is in a separately loaded code resource, the resource must remain locked until the alarm fires. When you close a library or unlock a resource, you must remove any pending alarms. If you don't, the system will crash when the alarm is triggered.
purgeAlarm field, which specifies if the alarm should be removed from the queue. In the case of procedure alarms, the alarm should always be removed from the queue. The system sets the purgeAlarm value to true after calling your function. 
sysFtrCreator and a feature number of sysFtrNumROMVersion). Currently, the different versions of the system software have the following numbers:
| 0x01003001 | Palm OS 1.0 | 
| 0x02003000 | Palm OS 2.0 | 
| 0x03003000 | Palm OS 3.0 | 
| 0x03103000 | Palm OS 3.1 | 
| 0x03103000 | Palm OS 3.1 | 
| 0x03103000 | Palm OS 3.1 | 
| 0x03203000 | Palm OS 3.2 | 
| 0x03503000 | Palm OS 3.5 | 
// See if we're on ROM version 2.0 or later.FtrGet(sysFtrCreator, sysFtrNumROMVersion,     	 &romVersion);if (romVersion >= 0x02000000) {    ....}SystemMgr.h. System features are stored in a feature table in the ROM. (In Palm OS 3.1 and higher, the contents of this table are copied into the RAM feature table at system startup.) Checking for the presence of system features allows an application to be compatible with multiple versions of the system by refining its behavior depending on which capabilities are present or not. Future hardware platforms may lack some capabilities present in the first platform, so checking the system version feature is important. 
 
IMPORTANT: For best results, we recommend that you check for specific features rather than relying on the system version number to determine if a specific API is available. For more details on checking for features, see the appendix Compatibility Guide in Palm OS SDK Reference.
FtrGet returns the 32-bit value of the feature. If the feature doesn't exist, an error code is returned.
 
FtrUnregister to remove features that were created by calling FtrSet.
 
FtrGetByIndex and incrementing repeatedly by 1 eventually returns all available features. FtrGetByIndex accepts a parameter that specifies whether to search the ROM feature table or RAM feature table. Note that in Palm OS version 3.1 and higher, the contents of the ROM table are copied into the RAM table at system startup; thus the RAM table serves the entire system. 
FtrPtrNew(appCreator, 
	 	 myFtrMemFtr, 32, &ftrMem);
NOTE:  Starting with Palm OS 3.5FtrPtrNewallows allocating chunks larger than 64k. Do keep in mind standard issues with allocating large chunks of memory: there might not be enough contiguous space, and it can impact system performance.
MyAppPreferencesType prefs; if (FtrGet(appCreator, myPrefFtr, (UInt32*)&prefs) != 0) {    // Feature memory doesn't exist, so allocate it.    FtrPtrNew(appCreator, myPrefFtr, 32, &thePref);    // Load the preferences database.     PrefGetAppPreferences (appCreator, prefID, &prefs,     	 sizeof(prefs), true);    // Write it to feature memory.     DmWrite(thePref, 0, &prefs, sizeof(prefs));}// Now prefs is guaranteed to be defined.FtrPtrNew to allocate a feature memory chunk and store an icon representing the current state in that location. Applications can then use FtrGet to access the icon and pass the result to WinDrawBitmap to display the connection state on the screen. 
handled flag. Clients can set this flag to communicate to other clients that the event has been handled, while still allowing them to receive the notification. An example of this is the sysNotifyAntennaRaisedEvent for Palm VII series devices. A client might decide to handle the antenna key down event and in this case, sets handled to true to inform other clients that the event has been handled. 
sysNotifyMenuCmdBarOpenEvent is similar to this style of notification. 
SysNotifyRegister(myCardNo, appDBID,     sysNotifySyncStartEvent, NULL,     sysNotifyNormalPriority, myDataP);SysNotifyRegister looks slightly different. See Listing 8.4.
SysNotifyRegister(myCardNo, shlibDBID,    sysNotifySyncStartEvent, SyncNotifyHandler,    sysNotifyNormalPriority, myDataP);SysNotifyRegister function specify the following:
prc file. Be sure you're not passing the local ID of the record database that your application accesses. You use the record database's local ID more frequently than you do the application's local ID, so this is a common mistake to make. sysNotifySyncStartEvent specifies that you want to be informed when a HotSync operation is about to start. There is also a sysNotifySyncFinishEvent that specifies that a HotSync operation has ended. NULL for this parameter to specify that they should be notified through the application launch code PilotMain function. 
 
PilotMain function and therefore no way to receive a launch code, so it passes a pointer to a callback routine. Only use a callback routine if your code doesn't have a PilotMain. 
 
prc file even if you specify a callback routine. 
sysNotifyNormalPriority means that you don't want your code to receive any special consideration when receiving the notification. Notifications are broadcast synchronously in priority order. The lower the number you specify here, the earlier you receive the notification in the list. sysNotifyNormalPriority. If you absolutely must ensure that your code is notified in a certain order (either before most notifications or after most notifications), use a value between -15 and +15 for the priority. Using a value in this range ensures that your code won't collide with the system's handling of notifications. 
myDataP is a pointer to any data you need to access in your notification handler routine. As with most launch codes, sysAppLaunchCmdNotify does not provide access to global variables, so you should use this pointer to pass yourself any needed data. sysNotifySyncStartEvent notification to both clients. 
 
sysAppLaunchCmdNotify launch code. This launch code's parameter block is a myDataP in the example above). Some notifications contain extra information in a notifyDetailsP field in this structure. The HotSync notifications do not use the notifyDetailsP field. 
 
SyncNotifyHandler function. This function is passed the same SysNotifyParamType structure that is passed through the launch code mechanism. 
 
IMPORTANT: Because the callback pointer is used to directly call the function, the pointer must remain valid from the timeSysNotifyRegisteris called to the time the notification is broadcast. If the function is in a shared library, you must keep the library open. If the function is in a separately loaded code resource, the resource must remain locked while registered for the notification. When you close a library or unlock a resource, you must first unregister for any notifications. If you don't, the system will crash when the notification is broadcast.
sysAppLaunchCmdNotify and the shared library's callback function are called notification handlers. A notification handler may perform any processing necessary, including displaying a user interface or broadcasting other notifications. 
 
sysNotifyTimeChangeEvent notification that performs no work other than setting up a deferred notification (myDeferredNotifyEvent) and scheduling it for broadcast. When the application receives the myDeferredNotifyEvent, it calls the MyNotifyHandler function, which is where the application really handles the time change event.
case sysAppLaunchCmdNotify :     if (cmdPBP->notify->notifyType == sysNotifyTimeChangeEvent) {    	 SysNotifyParamType notifyParm;    	 MyGlobalsToAccess myData;    	 /* initialize myData here */    	 /* Create the notification block. */    	 notifyParam.notifyType = myDeferredNotifyEvent;    	 notifyParam.broadcaster = myCreatorID;    	 notifyParam.notifyDetailsP= NULL;    	 notifyParam.handled = false;    	 /* Register for my notification */    	 SysNotifyRegister(myCardNo, appDBID, myDeferredNotifyEvent, 
	 	 	 NULL, sysNotifyNormalPriority, &myData);    	 /* Broadcast the notification */    	 SysNotifyBroadcastDeferred(¬ifyParam, NULL);    } else if (cmdPBP->notify->notifyType == myDeferredNotifyEvent)    	 MyNotifyHandler(cmdPBP->notify);break;SysNotifyBroadcastDeferred, which waits until the next time SysNotifyBroadcastDeferred to avoid the possibility of overflowing the notification stack. 
 
sysNotifySleepRequestEvent sysNotifySleepNotifyEvent sysNotifyEarlyWakeupEvent sysNotifyLateWakeupEvent sysNotifySleepNotifyEvent. 
 
sysNotifySleepRequestEvent instead. This notification informs all clients that the system might go to sleep. If necessary, your handler can delay the sleep request by doing the following:
notify->notifyDetailsP->deferSleep++;deferSleep value when each notification handler returns. If it is nonzero, it cancels the sleep event. 
 
resumeSleepChr and the command key bit set (to signal that the character is virtual) and add it to the event queue. When the system receives this event, it will again broadcast the sysNotifySleepRequestEvent to all clients. If deferSleep is 0 after all clients return, then the system knows it is safe to go to sleep, and it broadcasts the sysNotifySleepNotifyEvent to all of its clients. 
 
sysNotifySleepRequestEvent many times before the system actually goes to sleep, but you receive the sysNotifySleepNotifyEvent exactly once. 
 
sysNotifyEarlyWakeupEvent is broadcast very early on in the wakeup process, generally before the screen has turned on. At this stage, it is not guaranteed that the system will fully wake up. It may simply handle an alarm or a battery charger event and go back to sleep. Most applications that need notification of a wakeup event will probably want to register for sysNotifyLateWakeupEvent instead. At this stage, the screen has been turned on and the system is guaranteed to fully wake up. 
http://www.midi.org Web site. 
 
sysFileTMidi file type and sysFileCSystem creator to open this database.
 
keyDown, keyUp and tempo events in a single track; other commands which might be in the SMF are ignored. For more information, see the following:
MakeSMF.c file, can be helpful to see how to create an SMF programmatically.
 
FtrGet function returns a system version of less than 0x03000000. Doing so will crash your application. See the section "The System Version Feature" for more information.
sndCmdNoteOn and sndCmdFrqOn operations execute asynchronously; that is, they are non-blocking and can be interrupted by another sound command. In contrast, the sndCmdFreqDurationAmp operation is synchronous and blocking (it cannot be interrupted). 
 
 function play the SMF to completion without being interrupted by user events.
prefSysSoundVolume, prefGameSoundVolume, or prefAlarmSoundVolume selectors to the 
NOTE:  See "Sound Preferences Compatibility Information" for important information regarding the correct use of sound preferences in various versions of Palm OS.
 parameter block. Alternatively, you can pass amplitude information to the SndDoCmd function as an element of a SndCommandType parameter block. 
 
NULL is supported and maps to the shared channel), a pointer to a structure of SndCommandType, and a flag indicating whether the command should be performed asynchronously. 
 
SndPlaySMF function. This function, which is new in Palm OS 3.0, is used by the built in Date Book application to play alarm sounds. 
 
SndPlaySMF or SndDoCmd functions. Of course, you can use the SndPlaySMF function to play a single MIDI note from an SMF. You can also use the SndDoCmd function to play a single MIDI note by passing the sndCmdNoteOn command selector to this function. To specify by frequency the note to be played, pass the sndCmdFrqOn command selector to the SndDoCmd function.You can pass the sndCmdQuiet selector to this function to stop playback of the current note.
 
prefGameSoundVolume setting, as described in the section "Sound Preferences Compatibility Information."
 
SoundMgr.h file provided by the Palm OS SDK.
AddSmfToDatabase example function shown in the following code listing. This function returns 0 if successful, and returns a non-zero value otherwise. To use a different database, pass different creator and type values to the // Useful structure field offset macro#define prvFieldOffset(type, field) ((UInt32)(&((type*)0)->field))// returns 0 for success, nonzero for errorInt16 AddSmfToDatabase(MemHandle smfH, Char* trackName){    Err	 	 	 	 	 err = 0;    DmOpenRef	 	 	 	 	 dbP;    UInt16*	 	 	 	 	 recIndex;    MemHandle	 	 	 	 	 recH;    UInt8*	 	 	 	 	 recP;    UInt8*	 	 	 	 	 smfP;    UInt32	 	 	 	 	 bMidiOffset;    UInt32	 	 	 	 	 dwSmfSize;    SndMidiRecHdrType	 	 	 	 	 	 	 	 	 recHdr;        bMidiOffset = sizeof(SndMidiRecHdrType) + 
	 	 	 	 	 	 	 	 StrLen(trackName) + 1;    dwSmfSize = MemHandleSize(smfH);        recHdr.signature = sndMidiRecSignature;    recHdr.reserved = 0;    recHdr.bDataOffset = bMidiOffset;    dbP = DmOpenDatabaseByTypeCreator(sysFileTMidi, sysFileCSystem,
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dmModeReadWrite | dmModeExclusive);    if (!dbP)    	 return 1;    // Allocate a new record for the midi resource    recIndex = dmMaxRecordIndex;    recH = DmNewRecord(dbP, &recIndex, dwSmfSize + bMidiOffset);    if ( !recH )    	 return 2;        // Lock down the source SMF and target record and copy the data    smfP = MemHandleLock(smfH);    recP = MemHandleLock(recH);        err = DmWrite(recP, 0, &recHdr, sizeof(recHdr));    if (!err) err = DmStrCopy(recP, prvFieldOffset(SndMidiRecType,
	 	 	 name), trackName);    if (!err) err = DmWrite(recP, bMidiOffset, smfP, dwSmfSize);        // Unlock the pointers    MemHandleUnlock(smfH);    MemHandleUnlock(recH);        //Because DmNewRecord marks the new record as busy, 
	 // we must call DmReleaseRecord before closing the database    DmReleaseRecord(dbP, recIndex, 1);
	 DmCloseDatabase(dbP);    return err;}sysFileTMidi for MIDI record databases. The system MIDI database, with type sysFileTMidi and creator sysFileCSystem, holds multiple system alarm sounds. In addition, your applications can create their own private MIDI databases of type sysFileTMidi and your own creator.
 
SndCreateMidiList utility function retrieves information about Standard Midi Files from one or more MIDI databases. This information is returned as a table of entries. Each entry contains the name of an SMF; its unique record ID; and the database ID and card number of the record database in which it resides.
 
sysFileTMidi type and an appropriate creator value to the DmOpenDatabaseByTypeCreator function. For example, to retrieve a SMF from the system MIDI database, pass type sysFileTMidi and creator sysFileCSystem. The DmOpenDatabaseByTypeCreator function returns a reference to the open database. 
 
DmGetRecord function--it marks the record as busy. When you intend to use the record in read-only fashion, use the DmQueryRecord function --it does not mark the record as busy. You must lock the handle returned by either of these functions before making further use of it. 
 
smfP parameter to play the MIDI file. 
 
DmGetRecord to open the record for editing, you must call DmReleaseRecord to make the record available once again to other callers. If you used DmQueryRecord to open the record for read-only use, you need not call DmReleaseRecord. 
 
SndSetDefaultVolume function updates cached values but not stored preferences. Applications should avoid modifying stored preferences or cached values in favor of respecting the user's choices for preferences.
SystemPreferencesTypeV10 structure holds the current values of all system-wide preferences. You must extract from this structure the values of the sysSoundLevel and alarmSoundLevel fields. These values are the only sound preference information that Palm OS version 1.0 provides. 
 
slOn (on) or slOff (off). Your code must interpret the values read from these fields as an indication of whether those volumes should be on or off, then map them to appropriate amplitude values to pass to Sound Manager functions: map the slOn selector to the sndMaxAmp constant (defined in SoundMgr.h) and map the slOff selector to the value 0 (zero). 
typedef struct {    UInt16 version;	 	 	 	 	 	 	 // Version of preference info        // International preferences    CountryType country;	 	 	 	 	 // Country the device is in    DateFormatType dateFormat;	 	 	 // Format to display date in    DateFormatType longDateFormat;	 // Format to display date in    UInt8 weekStartDay;	 	 	 	 	 // Sunday or Monday    TimeFormatType timeFormat;	 	 	 // Format to display time in    NumberFormatType numberFormat;	 // Format to display numbers in        // system preferences    UInt8 autoOffDuration;	 	 	 	 // Time period before shutting off    SoundLevelTypeV20 sysSoundLevel;	 	 //	 error beeps    SoundLevelTypeV20 alarmSoundLevel;	 //	 alarm only    Boolean hideSecretRecords;	 	 	 // True to not display records with    	 	 	 	 	 	 	 	 	 	 	 	 // their secret bit attribute set    Boolean deviceLocked;	 	 	 	 	 	 	 	 	 	 	 // Device locked until the system    	 	 	 	 	 	 	 	 	 	 	 // password is entered    UInt16	 	 sysPrefFlags;	 	 	 	 // Miscellaneous system pref flags copied into
	 	 	 	 	 	 	 	 	  // the global GSysPrefFlags at boot time.    SysBatteryKind sysBatteryKind;	 
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 // The type of batteries installed.
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 // This is copied into the globals
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 // GSysbatteryKind at boot time.        } SystemPreferencesTypeV10;prefSysSoundLevelV20, prefGameSoundLevelV20, or prefAlarmSoundLevelV20 to the PrefGetPreference function to retrieve individual amplitude preference values for alarm sounds, game sounds, or for overall (system) sound amplitude. As in Palm OS 1.0, each of these settings holds values of either slOn (on) or slOff (off), as defined in the Preferences.h file. Your code must interpret the values read from these fields as an indication of whether those volumes should be on or off, then map them to appropriate amplitude values to pass to Sound Manager functions: map the slOn selector to the sndMaxAmp constant (defined in SoundMgr.h file) and map the slOff selector to the value 0 (zero). 
 
PrefGetPreference function, see the Preferences.h file. 
prefSysSoundVolume, prefGameSoundVolume, and prefAlarmSoundVolume for use with the PrefGetPreference function. The values this function returns for these selectors are actual amplitude settings that may be passed directly to Sound Manager functions. 
 
NOTE:  The amplitude selectors used in previous versions of Palm OS (all ending with theLevelsuffix, such asprefGameSoundLevel) are obsoleted in version 3.0 of Palm OS and replaced by new selectors. The old selectors remain available in Palm OS 3.X to ensure backward compatibility and are suffixedV20(for example,prefGameSoundLevelV20).
sndCmdFreqDurationAmp to the SndDoCmd function on versions of Palm OS prior to 3.0. sysAppLaunchCmdSystemReset launch code is not sent to applications. This is useful if there is an application on the device that crashes upon receiving this launch code (not uncommon) and therefore prevents the system from booting. sysAppLaunchCmdSystemReset launch code is sent to the applications at this time. If the user selected the "Delete all data" option, the digitizer calibration screen comes up first. The default databases for the four main applications is copied out of the ROM. 
 
SysReset is used, for example, by the Sync application. When the user copies an extension onto the Palm OS device, the Sync application automatically resets the device after the sync is completed to allow the extension to install itself. 
 
SysColdBoot call is similar, but even more dangerous. It performs a hard reset that clears all user storage RAM on the device, destroying all user data. 
EvtGetEvent, power management occurs automatically. If there has been no user input for the amount of time determined by the current setting of the auto-off preference, the system automatically enters sleep mode without intervention from the application.
 
EvtGetEvent; this forces the unit to wake up out of doze mode and to return to the application when the time out expires, even if there is no event to process. Using these mechanisms provides the longest possible battery life.
SysSleep to put itself immediately into low-power sleep mode. Normally, the system puts itself to sleep when there has been no user activity for the minimum auto-off time or when the user presses the power key. 
 
SysSetAutoOffTime with a time-out of 0, doing this depletes the battery. 
 
NOTE:  Only system software can launch a separate task. The multi-tasking API is not available to developer applications.
sysROMTokenSnum selector to the SysGetROMToken function. If the SysGetROMToken function returns an error, or if the returned pointer to the buffer is NULL, or if the first byte of the text buffer is 0xFF, then no serial number is available.
 
DrawSerialNumOrMessage function shown in Listing 8.8 retrieves the ROM serial number, calculates the checksum, and draws both on the screen at a specified location. If the device has no serial number, this function draws a message you specify. This function accepts as its input a pair of coordinates at which it draws output, and a pointer to the message it draws when a serial number is not available. 
 
static void DrawSerialNumOrMessage(Int16 x, Int16 y, Char* noNumberMessage){    Char* bufP;    UInt16* bufLen;    Err retval;    Int16   count;    UInt8    checkSum;    Char    checksumStr[2];        
	 	 // holds the dash and the checksum digit    retval = SysGetROMToken (0, sysROMTokenSnum, 
	 	 	 	 	 	 	 	 	 	 	 	 	 	 (UInt8**) &bufP, &bufLen);    if ((!retval) && (bufP) && ((UInt8) *bufP != 0xFF)) {  
	 	 // there's a valid serial number!    	 // Calculate the checksum:  Start with zero, add each digit,
	 	 // then rotate the result one bit to the left and repeat.        checkSum = 0;        for (count=0; count<bufLen; count++) {            checkSum += bufP[count];            checkSum = (checkSum<<1) | ((checkSum & 0x80) >> 7);            }    	 // Add the two hex digits (nibbles) together, +2 
	 	 // (range: 2 - 31 ==> 2-9, A-W)    	 // By adding 2 to the result before converting to ascii,
	 	 // we eliminate the numbers 0 and 1, which can be
	 	 // difficult to distinguish from the letters O and I.
	 	 checkSum = ((checkSum>>4) & 0x0F) + (checkSum & 0x0F) + 2;    	 // draw the serial number and find out how wide it was
	 	 WinDrawChars(bufP, bufLen, x, y);
	 	 x += FntCharsWidth(bufP, bufLen);    	 // draw the dash and the checksum digit right after it
	 	 checksumStr[0] = '-';
	 	 checksumStr[1] = 
	 	 	 	 ((checkSum < 10) ? (checkSum +'0'):(checkSum -10 +'A'));
	 	 WinDrawChars (checksumStr, 2, x, y);
	 	 }    else // there's no serial number
	 	 // draw a status message if the caller provided one
	 	 if (noNumberMessage)
	 	 	 WinDrawChars(noNumberMessage, StrLen(noNumberMessage),x, y);}TimGetTicks function could be used in a loop to implement a delay, it is recommended that applications use the SysTaskDelay function automatically puts the unit into low-power mode during the delay. Using TimGetTicks in a loop consumes much more current.
FplAdd, FplSub, and so on. 
 
FplAdd, FplSub, etc.
 
Fpl functions provided only 16-bit floating-point arithmetic. Linking in the library explicitly won't cause problems when you compile for a 2.0 or later device.
Fpl calls (documented in the chapter "Float Manager" in the Palm OS SDK Reference) are still available. They may be useful for applications that don't need high precision, don't want to incur the size penalty of the float library, and want to run on 1.0 devices only. To get 1.0 behavior, use the 1.0 calls (FplAdd, etc.) and don't link in the library. 
| Alarm Manager Functions | |
|---|---|
| AlmSetAlarm AlmSetProcAlarm | AlmGetAlarm AlmGetProcAlarm | 
| Feature Manager Functions | |
|---|---|
| FtrGet FtrSet FtrPtrNew FtrPtrResize | FtrGetByIndex FtrUnregister FtrPtrFree | 
| Notification Manager Functions | |
|---|---|
| SysNotifyRegister SysNotifyBroadcast | SysNotifyUnregister SysNotifyBroadcastDeferred | 
| Sound Manager Functions | |
|---|---|
| SndCreateMidiList SndGetDefaultVolume SndPlaySystemSound | SndDoCmd SndPlaySmf SndPlaySmfResource | 
| System Manager Functions | |
|---|---|
| Launching Applications | |
| SysAppLaunch SysBroadcastActionCode | SysUIAppSwitch | 
| System Dialogs | |
| SysGraffitiReferenceDialog SysKeyboardDialogV10 | SysKeyboardDialog | 
| Power Management | |
| SysBatteryInfo SysSetAutoOffTime | SysBatteryInfoV20 SysTaskDelay | 
| System Management | |
| SysLibFind SysRandom SysGremlins | SysLibLoad SysReset | 
| Working With Strings and Resources | |
| SysBinarySearch SysQSort SysCreatePanelList SysFormPointerArrayToStrings | SysInsertionSort SysCopyStringResource SysStringByIndex | 
| Database Support | |
| SysCreateDataBaseList | SysCurAppDatabase | 
| Error Handling | |
| SysErrString | |
| Event Handling | |
| SysHandleEvent | |
| System Information | |
| SysGetOSVersionString SysGetROMToken | SysGetStackInfo SysTicksPerSecond | 
| Time Manager Functions | |
|---|---|
| Allowing User to Change Date and Time | |
| DayHandleEvent SelectDay | SelectTimeV33 SelectDayV10 | 
| Changing the Date | |
| DateAdjust TimSetSeconds | TimAdjust | 
| Converting to Date Format | |
| DateDaysToDate TimSecondsToDateTime | DateSecondsToDate | 
| Converting Dates to Other Formats | |
| DateToAscii DateToDays TimGetSeconds TimGetTicks | TimeToAscii DateToDOWDMFormat TimDateTimeToSeconds | 
| Date Information | |
| DayOfMonth DaysInMonth | DayOfWeek | 
| Float Manager Functions | |
|---|---|
| FplAdd FplBase10Info FplFloatToLong FplFree FplInit FplMul | FplAToF FplDiv FplFloatToULong FplFToA FplLongToFloat FplSub | 
|   |  |  |  |  |   |