struct tm *localtime(const time_t *timer) { static struct tm tmDate; DateTimeType dt; UInt32 secs = *timer; // get ROM version UInt32 romVersion; Err e = FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); // form 1/1/1904 12AM to 1/1/1970 12AM DateTimeType Epoch = {0, 0, 0, 1, 1, 1970, 0}; // timer supposed to be based on Epoch secs += TimDateTimeToSeconds(&Epoch); // DST really supported from OS v4.0 if (romVersion >= sysMakeROMVersion(4,0,0,sysROMStageRelease,0)) secs += (PrefGetPreference(prefTimeZone) + PrefGetPreference(prefDaylightSavingAdjustment)) * 60; else secs += (PrefGetPreference(prefMinutesWestOfGMT) - 720) * 60; // no sure about this one TimSecondsToDateTime (secs, &dt); tmDate.tm_sec = dt.second; tmDate.tm_min = dt.minute; tmDate.tm_hour = dt.hour; tmDate.tm_mday = dt.day; tmDate.tm_mon = dt.month - 1; tmDate.tm_year = dt.year - 1900; tmDate.tm_wday = dt.weekDay; return &tmDate; }
static Boolean fIsTreo() { UInt32 rom = 0, hal = 0, company = 0, device = 0, hsFtrVersion; UInt32 requiredVersion = sysMakeROMVersion(5,0,0,sysROMStageRelease,0); if (FtrGet (hsFtrCreator, hsFtrIDVersion, &hsFtrVersion) != 0) return false; FtrGet (sysFtrCreator, sysFtrNumOEMHALID, &hal); FtrGet (sysFtrCreator, sysFtrNumOEMCompanyID, &company); FtrGet (sysFtrCreator, sysFtrNumOEMDeviceID, &device); FtrGet (sysFtrCreator, sysFtrNumROMVersion, &rom); if (device == hsDeviceIDOs5Device1Sim) { // doesn't work on simulator return false; } if ( rom >= requiredVersion && company == hwrOEMCompanyIDHandspring && device == hsDeviceIDOs5Device1 && ( hal == hsHALIDHandspringOs5Rev1 || hal == hsHALIDHandspringOs5Rev1Sim) ) { return true; } return false; }
static Err RomVersionCheck(UInt16 launchFlags) { UInt32 Version; FtrGet(sysFtrCreator, sysFtrNumROMVersion, &Version); if (Version < sysMakeROMVersion(5,0,0,sysROMStageDevelopment,0)) { if ((launchFlags & sysAppLaunchFlagNewGlobals) != 0 && (launchFlags & sysAppLaunchFlagUIApp) != 0) { FrmCustomAlert(WarningOKAlert, "System version 5.0 or greater is required to run this application!", " ", " "); // Palm OS 1.0 requires you to explicitly launch another app if (Version < sysMakeROMVersion(1,0,0,sysROMStageRelease,0)) { AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); } } return sysErrRomIncompatible; } return errNone; }
time_t time(time_t *tloc) { // get ROM version UInt32 romVersion; Err e = FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); // since 1/1/1904 12AM. UInt32 secs = TimGetSeconds(); // form 1/1/1904 12AM to 1/1/1970 12AM DateTimeType Epoch = {0, 0, 0, 1, 1, 1970, 0}; secs -= TimDateTimeToSeconds(&Epoch); // DST really supported from OS v4.0 if (romVersion >= sysMakeROMVersion(4,0,0,sysROMStageRelease,0)) secs -= (PrefGetPreference(prefTimeZone) + PrefGetPreference(prefDaylightSavingAdjustment)) * 60; else secs -= (PrefGetPreference(prefMinutesWestOfGMT) - 720) * 60; if (tloc) *tloc = secs; return (secs); }
FieldType * MyFrmGetActiveField() { Err err; UInt16 focus; FormType * activeForm; if ( (activeForm = FrmGetActiveForm()) == 0 || (focus = FrmGetFocus(activeForm)) == noFocus) { return 0; } FieldType * activeField = 0; switch (FrmGetObjectType(activeForm, focus)) { case frmFieldObj: UInt32 romVersion = 0; err = FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); activeField = (romVersion >= sysMakeROMVersion(4, 0, 0, sysROMStageRelease, 0)) ? FrmGetActiveField(0) : (FieldType *)FrmGetObjectPtr(activeForm, focus); break; case frmTableObj: TableType * activeTable = (TableType *)FrmGetObjectPtr(activeForm, focus); activeField = TblGetCurrentField(activeTable); break; default: break; } /* this might not work, eg., expense. perhaps if the field is new, it has no text handle. if (activeField) { if (FldGetTextHandle(activeField) == 0) { return 0; } FieldAttrType a; FldGetAttributes(activeField, &a); if (!(a.usable && a.editable)) { return 0; } } */ return activeField; }
bool handleProcessSoftKeyStroke(PointType * start, PointType * end) { Err err; UInt32 romVersion; RexxletHackPrefs * prefs = 0; // For romVersion-specific behavior. FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); if (romVersion < sysMakeROMVersion(3, 0, 0, sysROMStageRelease, 0)) { goto passthru; } // Avoid re-entering, only because there's typically not enough // stack space to handle this. If we did our own stack, then maybe... UInt32 isRexxletRunning = 0; err = FtrGet(CREATORID, FEATURE_ISREXXLETRUNNING, &isRexxletRunning); if (err == errNone && isRexxletRunning == 1) { goto passthru; } // Set prefs and check to see if this is our custom penstroke. // If not, pass it thru. prefs = RexxletHackPrefs__ctor(); Int16 strokeIndex = myStroke(start, end, prefs); if (strokeIndex == -1) { goto passthru; } StrokeDescriptor * stroke = RexxletHackPrefs__strokeDescriptor(prefs, strokeIndex); // Set up the Rexxlet launch code's param type. struct RexxAppLaunchRexxletParamType r; MemSet((void *)&r, sizeof(struct RexxAppLaunchRexxletParamType), 0); r.iflags.pauseWhenDone = stroke->flags.pauseWhenDone; r.iflags.copyAndPaste = stroke->flags.copyAndPaste; r.iflags.defaultInput = stroke->flags.defaultInput; r.iflags.defaultOutput = stroke->flags.defaultOutput; r.iflags.defaultError = stroke->flags.defaultError; r.script = RexxletHackPrefs__url(prefs, strokeIndex + 1); // allow a null script...it will pop up the url dialog to prompt for one // if (r.script == 0 || StrLen(r.script) == 0) { // goto passthru; // } r.iflags.args = stroke->flags.args; if (stroke->flags.args == RexxAppLaunchRexxletParamType::ARGS_SELECTION) { FieldType * activeField = MyFrmGetActiveField(); if (activeField) { UInt16 startPosition, endPosition; FldGetSelection(activeField, &startPosition, &endPosition); Int32 len = endPosition - startPosition; if (len > 0) { char * p = FldGetTextPtr(activeField); if (p) { r.args = (char *)MemPtrNew(len + 1); if (r.args) { MemMove(r.args, &p[startPosition], len); r.args[len] = '\0'; } } } } } // no more literal scripts...could be done if we really wanted, e.g., // not in the configuration (we don't want to store scripts in prefs), // but instead to allow the user to use the current selection as the script, // much in the same way we allow the clipboard, e.g., selection: // r.script = "say \"This is the identity Rexxlet! Enter something to return, and press Enter when done:\"; parse pull x; return x"; // r.script = "say \"Please enter numbers to add and press Enter when done:\"; parse pull n; r=0; do i=1 to words(n); if datatype(word(n,i))=\"NUM\" then r=r+word(n,i); end; return r"; // r.script = "parse arg s; say s; return s"; // PGR idea: use currently selected text! if (romVersion < sysMakeROMVersion(5, 0, 0, sysROMStageRelease, 0)) { EvtFlushNextPenStroke(); } // Remember that a rexxlet is active because we're not // going to allow then to be "stacked" for now...not enough stack space! FtrSet(CREATORID, FEATURE_ISREXXLETRUNNING, 1); Rexxlet(r); FtrSet(CREATORID, FEATURE_ISREXXLETRUNNING, 0); if (r.args && stroke->flags.args == RexxAppLaunchRexxletParamType::ARGS_SELECTION) { MemPtrFree(r.args); } if (prefs) { RexxletHackPrefs__dtor(prefs); } return true; passthru: if (prefs) { RexxletHackPrefs__dtor(prefs); } return false; }
UInt32 PilotMain(UInt16 launchCode, MemPtr launchParameters, UInt16 launchFlags) { UInt32 Value; UInt32 Result = errNone; UInt32 CPU; launch Launch; Launch.launchParameters = launchParameters; Launch.launchCode = launchCode; Launch.launchFlags = launchFlags; if ((launchCode == sysAppLaunchCmdNormalLaunch || launchCode == sysAppLaunchCmdOpenDB || launchCode == sysAppLaunchCmdCustomBase) && !RomVersionCheck(launchFlags)) { FtrGet(sysFileCSystem, sysFtrNumProcessorID, &CPU); if (CPU == sysFtrNumProcessorx86) { Module = PealLoadFromResources('armc', 1000, NULL, PROJECT_FOURCC,32,0,0,0); // just for testing Launch.FreeModule = PealUnload; Launch.LoadModule = LoadModule; Launch.GetSymbol = LookupSymbol86; Launch.PealCall = PealCall86; Launch.Module = Module; PceNativeCall(PALMOS_IX86_FUNC(PROJECT_OUTPUT,PaceMain86),&Launch); if (Module) PealUnload(Module); } else if (sysFtrNumProcessorIsARM(CPU)) { UInt32 Version; Boolean MemSema; FtrGet(sysFtrCreator, sysFtrNumROMVersion, &Version); MemSema = Version < sysMakeROMVersion(6,0,0,sysROMStageDevelopment,0); Module = PealLoadFromResources('armc', 1000, NULL, PROJECT_FOURCC,32,0,0,MemSema); if (Module) { PaceMain = PealLookupSymbol(Module, "PaceMain"); if (PaceMain) { Launch.FreeModule = PealUnload; Launch.LoadModule = LoadModule; Launch.GetSymbol = PealLookupSymbol; Launch.PealCall = PealCall; Launch.Module = Module; Result = PealCall(Module,PaceMain,&Launch); } PealUnload(Module); MemHeapCompact(GetHeapId()); } } else FrmCustomAlert(WarningOKAlert, "ARM processor is required to run this application!", " ", " "); if (FtrGet(PROJECT_FOURCC,20,&Value)==errNone) FtrPtrFree(PROJECT_FOURCC,20); } else if (launchCode == sysAppLaunchCmdNotify && (launchFlags & sysAppLaunchFlagSubCall)!=0) { FtrGet(sysFileCSystem, sysFtrNumProcessorID, &CPU); if (CPU == sysFtrNumProcessorx86) Result = PceNativeCall(PALMOS_IX86_FUNC(PROJECT_OUTPUT,PaceMain86),&Launch); else if (sysFtrNumProcessorIsARM(CPU) && Module && PaceMain) Result = PealCall(Module,PaceMain,&Launch); } return Result; }
/*********************************************************************** * * Internal Constants * ***********************************************************************/ #ifndef sysFtrNumDmAutoBackup # define sysFtrNumDmAutoBackup 31 #endif #define HIGH_DENSITY_FEATURE_SET_VERSION 4 #define MAX_CHARACTER_LENGTH 32 /* multi-byte characters cannot be longer than this */ static const UInt32 RomVersion20 = sysMakeROMVersion( 2, 0, 0, sysROMStageRelease, 0 ); static const UInt32 RomVersion30 = sysMakeROMVersion( 3, 0, 0, sysROMStageRelease, 0 ); static const UInt32 RomVersion31 = sysMakeROMVersion( 3, 1, 0, sysROMStageRelease, 0 ); static const UInt32 RomVersion33 = sysMakeROMVersion( 3, 3, 0, sysROMStageRelease, 0 ); static const UInt32 RomVersion35 = sysMakeROMVersion( 3, 5, 0, sysROMStageRelease, 0 ); static const UInt32 RomVersion40 = sysMakeROMVersion( 4, 0, 0, sysROMStageRelease, 0 ); /* The Tungsten T was actually released in the development stage?!? */ static const UInt32 RomVersion50 = sysMakeROMVersion( 5, 0, 0, sysROMStageDevelopment, 0 );
/*------------------------------------------------------CIRexxApp::FindLaunch-+ | | +----------------------------------------------------------------------------*/ Err CIRexxApp::FindLaunch(FindParamsPtr pFindParams) { //<<<JAL TODO: This is currently dependent on the Rexx category. // I'm not sure if we'll ever need to change/add-to this, // but if we do, then this code will have to be changed // along with the GoTo command. Err err; LocalID dbID; UInt16 cardNo = 0; DmOpenRef dbP; DmSearchStateType searchState; UInt16 recordNum; MemHandle hRecord; UInt32 pos; UInt16 matchLength; Boolean match, full; RectangleType r; UInt32 type; UInt32 creator; // Open our database (should we search MemoPad and pedit, too?) // and do our Find. We define the semantics of Find, so // instead of searching the whole records for the search string, // let's just search for scripts with the search string as their "name." if (FindDrawHeader(pFindParams, "Rexx Scripts")) { goto m_return; } if ((err = DmGetNextDatabaseByTypeCreator( true, &searchState, 'data', CREATORID, true, &cardNo, &dbID)) != errNone) { pFindParams->more = false; return errNone; } if ((err = DmDatabaseInfo(0, dbID, 0, 0, 0, 0, 0, 0, 0, 0, 0, &type, &creator)) != errNone || (type != 'data' && creator != CREATORID)) { pFindParams->more = false; return errNone; } if ((dbP = DmOpenDatabase(cardNo, dbID, pFindParams->dbAccesMode)) == 0 || DmGetAppInfoID(dbP) == 0) { /* if categories not initialized then CategoryGetName throws fatal error */ pFindParams->more = false; return errNone; } UInt16 category; char categoryName[dmCategoryLength]; for (category = 0; category < dmRecNumCategories; ++category) { CategoryGetName(dbP, category, categoryName); if (!StrCaselessCompare(categoryName, "REXX")) { break; } } if (category == dmRecNumCategories) { goto m_return; } // set it to dmAllCategories? UInt32 romVersion; FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); full = false; recordNum = pFindParams->recordNum; while (true) { // Because applications can take a long time to finish a Find when // the result may already be on the screen, or for other reasons, // users like to be able to stop the Find. So, stop it if any event // is pending, i.e., if the user does something with the device. // Because actually checking if an event is pending slows the // search itself, just check it every so many records. if ((recordNum & 0x000f) == 0 && EvtSysEventAvail(true)) { pFindParams->more = true; break; } if (!(hRecord = DmQueryNextInCategory(dbP, &recordNum, category))) { pFindParams->more = false; break; } Char * p = (char *)MemHandleLock(hRecord); UInt32 isInternational; err = FtrGet(sysFtrCreator, sysFtrNumIntlMgr, &isInternational); if (err == errNone && isInternational) { match = TxtFindString(p, pFindParams->strToFind, &pos, &matchLength); } else { match = TxtGlueFindString(p, pFindParams->strToFind, &pos, &matchLength); } if (match) { // Add the match to the find paramter block. // If there is no room to display the match // then the following function will return true. full = FindSaveMatch(pFindParams, recordNum, (UInt16)pos, 0, 0, cardNo, dbID); if (!full) { // Get the bounds of the region where we will draw the results, and // display the title of the description neatly in that area. FindGetLineBounds(pFindParams, &r); Int16 x = r.topLeft.x + 1; Int16 y = r.topLeft.y; Int16 w = r.extent.x - 2; Char * cr = StrChr(p, linefeedChr); UInt16 titleLen = (cr == 0)? StrLen(p) : cr - p; Int16 fntWidthToOffset; if (romVersion >= sysMakeROMVersion(3, 1, 0, sysROMStageRelease, 0)) { fntWidthToOffset = FntWidthToOffset(p, titleLen, w, 0, 0); } else { fntWidthToOffset = FntGlueWidthToOffset(p, titleLen, w, 0, 0); } if (fntWidthToOffset == titleLen) { WinDrawChars(p, titleLen, x, y); } else { Int16 titleWidth; titleLen = FntWidthToOffset(p, titleLen, w - FntCharWidth(chrEllipsis), 0, &titleWidth); WinDrawChars(p, titleLen, x, y); WinDrawChar (chrEllipsis, x + titleWidth, y); } ++pFindParams->lineNumber; } } MemHandleUnlock(hRecord); if (full) { break; } ++recordNum; } m_return: DmCloseDatabase(dbP); return errNone; }
/*----------------------------------------------------CIRexxApp::InitInstance-+ | Called when application is invoked | +----------------------------------------------------------------------------*/ Err CIRexxApp::InitInstance() { // true instance vars //none // really global vars // if we didn't get a new global segment for this instance, // then don't re-initialize the existing ones! if (m_wLaunchFlags & sysAppLaunchFlagNewGlobals) { m_rexx = 0; m_memoDB = 0; m_pedit32DB = 0; m_rexxDB = 0; m_scriptIndexDB = 0; m_memoCategory = dmRecNumCategories; m_pedit32Category = dmRecNumCategories; m_rexxCategory = dmRecNumCategories; m_script = 0; m_args = 0; m_isScriptDirty = false; m_scriptInsertPosition = m_scriptSrcollPosition = m_scriptSelect1Position = m_scriptSelect2Position = 0; m_fromForm = EditForm; m_loadRow = 0; m_isRexxRunning = false; m_isScriptIndexDBInitialized = false; g_pBeamerStreamBuf = 0; } // If Rexx is running, then this implies that we were launched // without a new set of globals and with sysAppLaunchFlagSubCall. // So, there are certain things we're not going to be able to do, // like a GoTo command because we cannot re-enter Rexx // while it's running unless we kill the running Rexx. // I'm not sure exactly why we cannot re-enter it, // but I do know it doesn't work and can look into // this later--I think it's a console issue. if (m_isRexxRunning) { // handled below for individual commands // but left here just for comments } // NOTE: LOOK OUT BELOW...do not do anything that will cause a // cross-segment call in non-global launches. Hopefully, // CW9 will allow cross-segment calls under non-normal launches. // It's kind of a ridiculuous issue. I.e., CW will allow you // to set up globals (a5) for expanded mode, but there doesn't // seem to be a way to initialize what else the app needs, // e.g., the cross-segment jump table. UInt32 romVersion; switch(m_wCommand) { case sysAppLaunchCmdNormalLaunch: // irexx ide // enable this for easier testing of notify/rexxets on palm os 5 // the reason this is easier is that the way to cause this to // happen on os 5 is to reset the device, which is a pain // when testing (see call to RegisterForNotifications below) // STATUS: NOT YET WORKING. NEED TO SEE PALM OS 5 STARTUP CODE // TO SEE WHY REXX CANNOT FIND IT'S RESOURCES WHEN SELF-LAUNCHED // UNDER THE NOTIFICATION HANDLER. PERHAPS, CW_SETUP IS // NOT DOING THE RIGHT THING SINCE IT'S A SUBCALL? // LAUNCH CODES INFO I DISCOVERED FOR FUTURE REF: // // 32 when stroke is made (32 is undocumented) // 32 = 0x20 = UNDOCUMENTED // 166 when self-launched // 166 = a6 // x6 = 0x04|0x02 = sysAppLaunchFlagNewStack|sysAppLaunchFlagNewGlobals // Ax = 0x80|0x20 = sysAppLaunchFlagDataRelocated|UNDOCUMENTED // // SO, STILL USING SEPARATE NOHACK VERSON OF REXXLET LAUNCHER. //RegisterForNotifications(); return CPalmStApp<CIRexxApp>::InitInstance(); case rexxAppNoop: // noop return errNone; case rexxAppLaunchRexxlet: // rexxlet (sublaunch) return RexxletLaunch(); case rexxAppLaunchRexxapp: // rexxapp (uiappswitch) return RexxappLaunch(); case sysAppLaunchCmdFind: return FindLaunch((FindParamsPtr)m_pCommandPBP); case sysAppLaunchCmdGoTo: // We cannot yet use Find when a rexxlet is running, // so considering that here is moot for now, // but if we could then we should not allow it. //<<<JAL Does this handle a waiting-on-return rexxlet console? if (m_isRexxRunning) { FrmCustomAlert(ErrorAlert, getRexxAppMessage(msgRexxIsRunning), 0, 0); return errNone; } // If we have new globals, then we weren't running (!sysAppLaunchFlagSubCall), // so start up as if in a normal launch and automatically run the script. // I know it's not obvious, but InitInstance will handle this // launch code as well and end up invoking GotoLaunch(). // I could have placed GotoLaunch() here directly, // but might as well stick with POL. if (m_wLaunchFlags & sysAppLaunchFlagNewGlobals) { return CPalmStApp<CIRexxApp>::InitInstance(); } // Finally, if we were running (sysAppLaunchFlagSubCall), // and the Rexx interpreter wasn't (!m_isRexxRunning), // then just load the script the user wanted and BALR. copyScriptFromFindResult((GoToParamsPtr)m_pCommandPBP); BALR(EditForm, ConsoleForm); return errNone; // The following is for Palm OS 5, and is not working correctly. // // http://www.palmos.com/dev/support/docs/recipes/notifications.html /* Be very careful when registering for notifications on system resets. If you have a bug in how you handle resets (like accessing global variables), you may crash the Palm OS and force another reset, creating an infinite loop. Many users won't know to do a no-notify reset so that they can delete your application. There is a special 'no-notify' reset (also referred to as a warm reset) which you invoke by holding the UP button on the device and poking the reset (i.e. it's like doing a hard reset except that you hold the UP button instead of the power button). This type of reset will NOT send the reset message out to loaded applications and it will NOT cause the loss of any data. At that point, you can do a HotSync to make sure that all your current data is saved before you proceed. When it comes back up, start removing applications--in an attempt to find the culprit (i.e. remove say two applications, do a soft reset and see if loops out again--if so, do another no-notify reset and try removing more apps till you find it surviving a soft reset). */ case sysAppLaunchCmdSystemReset: case sysAppLaunchCmdSyncNotify: // sent when our app is installed FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); if (romVersion >= sysMakeROMVersion(5, 0, 0, sysROMStageRelease, 0)) { // RegisterForNotifications(); } //<<<JAL TODO: why do we register now? // don't we only want to register if rexx is running? // we cannot receive data if rexx isn't. //Cannot make cross-segment calls and possibly calls that require globals //during non-normal launch codes. //BeamerStreamBuf::registerData(); //we know we're at least palm os 3.0, so no need to check again ExgRegisterData(CREATORID, exgRegExtensionID, "REX"); break; case sysAppLaunchCmdNotify: FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); if (romVersion >= sysMakeROMVersion(5, 0, 0, sysROMStageRelease, 0)) { HandleNotification((SysNotifyParamType *)m_pCommandPBP); } break; // Exchange Manager case sysAppLaunchCmdExgAskUser: ((ExgAskParamPtr)m_pCommandPBP)->result = (g_pBeamerStreamBuf && g_pBeamerStreamBuf->isReceiving())? exgAskOk : exgAskCancel; break; case sysAppLaunchCmdExgReceiveData: if (g_pBeamerStreamBuf && g_pBeamerStreamBuf->isReceiving()) { return g_pBeamerStreamBuf->receiveData((ExgSocketPtr)m_pCommandPBP); } break; default: return errNone; } return errNone; }