AlmSetAlarm
to set the alarm. Specify when the alarm should trigger and which application should be informed at that time.
static 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
and
sysAppLaunchCmdDisplayAlarm
.
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
TimDateTimeToSeconds
. AlmSetAlarm
with 0 specified for the alarm seconds parameter.
AlmSetAlarm
.
The alarm manager adds the new alarm to its alarm queue. The alarm queue contains all alarm requests. Triggered alarms are queued up until the alarm manager can send the launch code to the application that created the alarm. However, if the alarm queue becomes full, the oldest entry that has been both triggered and notified is deleted to make room for a new alarm.
When the alarm time is reached, the alarm manager searches the alarm queue for the first application that set an alarm for this alarm time.
The alarm manager sends this application the
sysAppLaunchCmdAlarmTriggered
launch code.
The application can now:
The application should not perform any lengthy tasks in response to 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
sysAppLaunchCmdDisplayAlarm
.
The application can now:
The alarm manager processes the alarm queue for the next application that set an alarm for the alarm being triggered and step 6 and 7 are repeated.
This process is repeated until no more applications are found with this alarm time.
If a new alarm time is triggered while an older alarm is still being displayed, all applications with alarms scheduled for this second alarm time are sent the sysAppLaunchCmdAlarmTriggered
launch code, but the display cycle for the second set of alarms is postponed until all earlier alarms have finished displaying.
AlmSetProcAlarm
instead of AlmSetAlarm
. (Similarly, you use the
AlmGetProcAlarm
function instead of 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 timeAlmSetProcAlarm
is 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.
sysAppLaunchCmdAlarmTriggered
launch code. It provides access to the reference parameter specified when the alarm was set, the time specified when the alarm was set, and the 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
and pass it the feature creator and feature number. If the feature exists, FtrGet
returns the 32-bit value of the feature. If the feature doesn't exist, an error code is returned.
FtrUnregister
or until the system resets; simply quitting an application doesn't remove a feature published by that application.
FtrUnregister
to remove features that were created by calling FtrSet
.
FtrGetByIndex
repeatedly. Passing an index value starting at 0 to 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.
DmWrite
, which means that writing to feature memory is no faster than writing to a database. However, feature memory can provide more efficient access to that data in certain circumstances.
FtrPtrNew
, specifying a feature creator, a feature number, the number of bytes to allocate, and a location where the feature manager can return a pointer to the newly allocated memory chunk. For example:
FtrPtrNew(appCreator,
myFtrMemFtr, 32, &ftrMem);
FtrGet
.
NOTE:  Starting with Palm OS 3.5FtrPtrNew
allows 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
function. Once you register for a notification, you remain registered until the system is reset or until you explicitly unregister for this notification using
SysNotifyUnregister
.
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
sysAppLaunchCmdNotify
. As with all other launch codes, the system passes this to the application's 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
SysNotifyParamType
structure containing the notification name, the broadcaster, and a pointer to your specific data (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 timeSysNotifyRegister
is 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.
SysHandleEvent
, which means your application event loop may not have progressed to the point where it is possible for you to display a user interface, or you may overflow the stack.
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
function broadcasts the specified notification to all interested parties; however, it waits to do so until the current event has completed processing. Thus, by using a separate deferred notification, you can be sure that all other clients have had a chance to respond to the first notification.
SysNotifyBroadcast
, which immediately broadcasts the notification, and SysNotifyBroadcastDeferred
, which waits until the next time
EvtGetEvent
is called. Notification handlers should use 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.
keyDownEvent
with the 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
PrefGetPreference
function.
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
DmOpenDatabaseByTypeCreator
function.
// Useful structure field offset macro
#define prvFieldOffset(type, field) ((UInt32)(&((type*)0)->field))
// returns 0 for success, nonzero for error
Int16 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 theLevel
suffix, 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.
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
to reset the device. This call does a soft reset and has the same effect as pressing the reset switch on the unit. Normally applications should not use this call.
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);
}
TimGetSeconds
. Real time on the Palm OS device is measured in seconds from midnight, Jan. 1, 1904. Call
TimSecondsToDateTime
and TimDateTimeToSeconds to convert between seconds and a structure specifying year, month, day, hour, minute, and second.
SysTicksPerSecond
, which is conditionally compiled for different platforms. Use the function TimGetTicks to read the current tick count.
TimGetTicks
function could be used in a loop to implement a delay, it is recommended that applications use the
SysTaskDelay
function instead. 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 |
  |   |