/* * OpenIconSet - returns a DmOpenRef to an icon set * * Arguments: * name = Optional name of icon set to open (can be NULL). * canUseDefault = Indicates if it's ok to open a default icon set if * the named icon set isn't available. * * Returns: * NULL = Unable to open an icon set. * non-NULL = DmOpenRef to the icon set database. * * Remarks: If OpenIconSet() returns a valid DmOpenRef, the caller * is required to call DmCloseDatabase() to close it when * the caller is finished with it. */ DmOpenRef OpenIconSet(const Char *name, Boolean canUseDefault) { DmOpenRef pdb = 0; // If 'name' was specified, try to open it. if (name && *name) { const UInt16 card = 0; const LocalID lid = DmFindDatabase(card, name); if (lid) { UInt32 type; UInt32 creator; // Double check the type and creator. DmDatabaseInfo(card, lid, 0, 0, 0, 0, 0, 0, 0, 0, 0, &type, &creator); if ('Rsrc' == type && 'Actn' == creator) pdb = DmOpenDatabase(card, lid, dmModeReadOnly); } } // Fall back to the default icon set if we need to. if (!pdb && canUseDefault) pdb = DmOpenDatabaseByTypeCreator('Rsrc', 'Actn', dmModeReadOnly); // At this point we may or may not have been able to open an icon set. // The return value may be NULL or it may point to an icon set. return pdb; }
/* Create an app info chunk if missing, return result from the database call */ static void InitPlkrAppInfo ( DmOpenRef docRef /* reference to document */ ) /* THROWS */ { UInt16 cardNo; MemHandle handle; LocalID dbID; LocalID appInfoID; PlkrAppInfoType* appInfoP; Err err; err = DmOpenDatabaseInfo( docRef, &dbID, NULL, NULL, &cardNo, NULL ); THROW_IF( err != errNone, err ); err = DmDatabaseInfo( cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &appInfoID, NULL, NULL, NULL ); THROW_IF( err != errNone, err ); if ( appInfoID == 0 ) { handle = DmNewHandle( docRef, sizeof *appInfoP ); THROW_IF( handle == NULL, dmErrMemError ); appInfoID = MemHandleToLocalID( handle ); DmSetDatabaseInfo( cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &appInfoID, NULL, NULL, NULL ); } appInfoP = MemLocalIDToLockedPtr( appInfoID, cardNo ); DmSet( appInfoP, 0, sizeof *appInfoP, 0 ); CategoryInitialize( ( AppInfoPtr ) appInfoP, strCatDefault ); MemPtrUnlock( appInfoP ); }
/********************************************************************** * Function: getDatabase * Description: pass the function the necessare database information, * and it will either open an existing database or create a new one if * neccessary. "created" will be true if a new database was created * *******************************************************************/ Err getDatabaseByTypeCreatorName (DmOpenRef * DBptr, UInt32 type, UInt32 creator, UInt32 mode, char *name) { Err errors; LocalID id; UInt16 cardNum, attr; DmSearchStateType srch; Char db_name[32]; errors = DmGetNextDatabaseByTypeCreator(true, &srch, type, creator, false, &cardNum, &id); while(!errors && id) { *DBptr = DmOpenDatabase (cardNum, id, mode); DmDatabaseInfo (cardNum, id, db_name, &attr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if(StrCompare(name, db_name) == 0) { attr |= dmHdrAttrBackup; DmSetDatabaseInfo (cardNum, id, NULL, &attr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } if(*DBptr) DmCloseDatabase(*DBptr); errors = DmGetNextDatabaseByTypeCreator(false, &srch, type, creator, false, &cardNum, &id); } return 1; }
/* Finds and opens database, * calls plugin specific code to create new item, * then fills in GoTo parameters. */ static UInt16 PickBooger(KleenexPtr kleenexP) { DmOpenRef dbR; UInt32 creatorID; UInt16 cardNo; LocalID dbID; Boolean closedb = false; UInt16 err, index; Char name[dmDBNameLength]; /* Check for the correct version */ if (!((kleenexP->version) & IBVERSION_PICTURE)) return (boogerErrorVersionMismatch); /* Open the database */ cardNo = 0; if (!(dbID = DmFindDatabase(cardNo, "DiddleIDB"))) return 1; if ((dbR = DmOpenDatabase(cardNo, dbID, dmModeReadWrite))) { closedb = true; } else if (DmGetLastErr() == dmErrAlreadyOpenForWrites) { dbR = NULL; while ((dbR = DmNextOpenDatabase(dbR))) { DmOpenDatabaseInfo(dbR, &dbID, NULL, NULL, &cardNo, NULL); DmDatabaseInfo(cardNo, dbID, name, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &creatorID); if (!StrCompare(name, "DiddleIDB") && (creatorID == DB_CREATOR)) break; } if (!dbR) return 1; } /* Call plugin specific routine to create item in database */ err = DoTheBoogie(kleenexP, dbR, &index); /* Close the database */ if (closedb) DmCloseDatabase(dbR); /* Did it work? */ if (err) return (1); /* Load the GoTo parameters */ if (!(kleenexP->booger.cmdPBP = MemPtrNew(sizeof(GoToParamsType)))) return (1); MemSet(kleenexP->booger.cmdPBP, sizeof(GoToParamsType), 0); ((GoToParamsType *)(kleenexP->booger.cmdPBP))->dbCardNo = cardNo; ((GoToParamsType *)(kleenexP->booger.cmdPBP))->dbID = dbID; ((GoToParamsType *)(kleenexP->booger.cmdPBP))->recordNum = index; MemPtrSetOwner(kleenexP->booger.cmdPBP, 0); return (errNone); }
/* Finds and opens database, * calls plugin specific code to create new item, * then fills in GoTo parameters. */ static UInt16 PickBooger(KleenexPtr kleenexP) { DmOpenRef dbR; DmSearchStateType searchstate; UInt32 creatorID, dbtype; UInt16 cardNo; LocalID dbID; Boolean closedb = false; UInt16 err, index; /* Check for the correct version */ if (!((kleenexP->version) & IBVERSION_ORIG)) return (boogerErrorVersionMismatch); /* Open the database */ if (DmGetNextDatabaseByTypeCreator(true, &searchstate, DB_TYPE, DB_CREATOR, true, &cardNo, &dbID)) return (1); if ((dbR = DmOpenDatabase(cardNo, dbID, dmModeReadWrite))) { closedb = true; } else if (DmGetLastErr() == dmErrAlreadyOpenForWrites) { dbR = NULL; while ((dbR = DmNextOpenDatabase(dbR))) { DmOpenDatabaseInfo(dbR, &dbID, NULL, NULL, &cardNo, NULL); DmDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dbtype, &creatorID); if ((dbtype == DB_TYPE) && (creatorID == DB_CREATOR)) break; } if (!dbR) return (1); } /* Call plugin specific routine to create item in database */ err = DoTheBoogie(kleenexP, dbR, &index); /* Close the database */ if (closedb) DmCloseDatabase(dbR); /* Did it work? */ if (err) return (1); /* Load the GoTo parameters */ if (!(kleenexP->booger.cmdPBP = MemPtrNew(sizeof(GoToParamsType)))) return (1); MemSet(kleenexP->booger.cmdPBP, sizeof(GoToParamsType), 0); ((GoToParamsType *)(kleenexP->booger.cmdPBP))->dbCardNo = cardNo; ((GoToParamsType *)(kleenexP->booger.cmdPBP))->dbID = dbID; ((GoToParamsType *)(kleenexP->booger.cmdPBP))->recordNum = index; MemPtrSetOwner(kleenexP->booger.cmdPBP, 0); return (errNone); }
//TODO : use Boolean instead of void to check err static DmOpenRef GlbOpenInternal(const Char *nameP) { LocalID dbID = DmFindDatabase(0, nameP); if (dbID) { UInt32 dbType, dbCreator; Err e = DmDatabaseInfo(0, dbID, 0, 0, 0, 0, 0, 0, 0, 0, 0, &dbType, &dbCreator); if (!e && dbType == 'GLBS' && dbCreator == appFileCreator) return DmOpenDatabase(0, dbID, dmModeReadOnly); } return NULL; }
static Err AppStartLoadSkin() { Err err = errNone; // if skin defined, check if the db still exists if (gPrefs->skin.dbID) { UInt32 type, creator; // check if the DB still exists DmSearchStateType state; UInt16 cardNo; LocalID dbID; Boolean found = false; err = DmGetNextDatabaseByTypeCreator(true, &state, 'skin', appFileCreator, false, &cardNo, &dbID); while (!err && dbID && !found) { found = (cardNo == gPrefs->skin.cardNo && dbID == gPrefs->skin.dbID); err = DmGetNextDatabaseByTypeCreator(false, &state, 'skin', appFileCreator, false, &cardNo, &dbID); } if (found) { // remember to check version for next revision of the skin err = DmDatabaseInfo (gPrefs->skin.cardNo, gPrefs->skin.dbID, gPrefs->skin.nameP, 0, 0, 0, 0, 0, 0, 0,0, &type, &creator); if (!err) if (type != 'skin' || creator != appFileCreator) err = dmErrInvalidParam; } if (!found || err) MemSet(&(gPrefs->skin),sizeof(SkinInfoType),0); } // No skin ? try to get the first one if (!gPrefs->skin.dbID) { DmSearchStateType stateInfo; err = DmGetNextDatabaseByTypeCreator(true, &stateInfo, 'skin', appFileCreator, false, &gPrefs->skin.cardNo, &gPrefs->skin.dbID); if (!err) err = DmDatabaseInfo (gPrefs->skin.cardNo, gPrefs->skin.dbID, gPrefs->skin.nameP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); } return err; }
//! @todo do something with ErrFindDatabaseByNameTypeCreator() static Err ErrFindDatabaseByNameTypeCreator(const char* dbName, UInt32 type, UInt32 creator, LocalID *dbId) { Err err; DmSearchStateType stateInfo; UInt16 cardNo = 0; char dbNameBuf[dmDBNameLength]; Assert(dbName); Assert(StrLen(dbName)<dmDBNameLength); Assert(dbId); err = DmGetNextDatabaseByTypeCreator(true, &stateInfo, type, creator, 0, &cardNo, dbId); while (errNone == err) { MemSet(dbNameBuf, sizeof(dbName), 0); DmDatabaseInfo(cardNo, *dbId, dbNameBuf, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL); if (0==StrCompare(dbName, dbNameBuf)) return errNone; err = DmGetNextDatabaseByTypeCreator(false, &stateInfo, type, creator, 0, &cardNo, dbId); } return dmErrCantFind; }
/* Initialize internal lists of user font prcs */ void InitializeUserFontDBs( void ) { DmSearchStateType stateInfo; UInt16 cardNo; LocalID dbID; Err err; DBEntryType* dbListEntry; userFontDBList = ListCreate(); if ( userFontDBList == NULL ) return; err = DmGetNextDatabaseByTypeCreator( true, &stateInfo, (UInt32) UserFontResourceType, (UInt32) ViewerAppID, false, &cardNo, &dbID ); while ( err == errNone ) { dbListEntry = SafeMemPtrNew( sizeof( DBEntryType ) ); err = DmDatabaseInfo( cardNo, dbID, dbListEntry->name, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); if ( err == errNone ) { dbListEntry->cardNo = cardNo; dbListEntry->dbID = dbID; dbListEntry->onVFS = false; ListAppend( userFontDBList, dbListEntry ); } else { SafeMemPtrFree( dbListEntry ); } err = DmGetNextDatabaseByTypeCreator( false, &stateInfo, (UInt32) UserFontResourceType, (UInt32) ViewerAppID, false, &cardNo, &dbID ); } SortAndMakeUserFontNameList(); }
NCSError NCSFileOpen(const NCSTChar *szFilename, int iFlags, NCS_FILE_HANDLE *phFile) { #ifdef WIN32 DWORD dwMode = GENERIC_READ; DWORD dwCreate = OPEN_EXISTING; if(iFlags & NCS_FILE_READ) dwMode = GENERIC_READ; if(iFlags & NCS_FILE_READ_WRITE) dwMode = GENERIC_READ|GENERIC_WRITE; if(iFlags & NCS_FILE_CREATE) dwCreate = CREATE_ALWAYS; if(iFlags & NCS_FILE_CREATE_UNIQUE) dwCreate = CREATE_NEW; if(iFlags & NCS_FILE_APPEND) dwCreate = OPEN_ALWAYS; *phFile = CreateFile(szFilename, // file name dwMode, // Generic read mode FILE_SHARE_READ, // Let anyone access and share the file NULL, // No security info (so can't be inherited by child process) dwCreate, // File must exist to be opened FILE_FLAG_RANDOM_ACCESS, // Going to be doing lots of random access NULL); // And no template file for attributes if( *phFile == INVALID_HANDLE_VALUE ) { return( NCS_FILE_OPEN_FAILED ); } else { return( NCS_SUCCESS ); } #elif defined MACINTOSH #if __POWERPC__ int i,length, result; Str255 pascalString; FSSpec fileSpec; // We have a C string, we need a PASCAL string. length = strlen(szFilename) + 1; for(i = 1; i < length; ++i) pascalString[i] = szFilename[i - 1]; pascalString[0] = strlen(szFilename); // Create a File Specification Record, then create a File result = FSMakeFSSpec(0,0,pascalString,&fileSpec); // return is meaningless, since the only possible error doesn't effect processing in this case switch(result) { case noErr: // we could dRes pFile here, but we are the only user result =FSpOpenDF(&fileSpec, fsRdPerm, (short *)phFile); if(result) return NCS_FILE_OPEN_FAILED; else return NCS_SUCCESS; break; default: return NCS_SUCCESS; break; } #else /* __POWERPC__ */ int i,length, result; Str255 pascalString; // We have a C string, we need a PASCAL string. length = strlen(szFilename) + 1; for(i = 1; i < length; ++i) pascalString[i] = szFilename[i - 1]; pascalString[0] = strlen(szFilename); result =FSOpen(pascalString, 0, (short *)phFile); if(result) return TRUE; else return FALSE; #endif /* __POWERPC__ */ #elif defined PALM NCS_FILE_HANDLE hFile; Err eErr; UInt32 nMode = 0; if(hFile = (NCS_FILE_HANDLE)NCSMalloc(sizeof(NCS_FILE_HANDLE_STRUCT), TRUE)) { hFile->dbID = DmFindDatabase(0, szFilename); if(hFile->dbID) { Char nameP[dmDBNameLength]; UInt16 attributes; UInt16 version; UInt32 crDate; UInt32 modDate; UInt32 bckUpDate; UInt32 modNum; LocalID appInfoID; LocalID sortInfoID; UInt32 type; UInt32 creator; DmDatabaseInfo(0, hFile->dbID, nameP, &attributes, &version, &crDate, &modDate, &bckUpDate, &modNum, &appInfoID, &sortInfoID, &type, &creator); if(creator == NCS_PALM_CREATOR_ID) { if(hFile->dbRef = DmOpenDatabase(0, hFile->dbID, dmModeReadOnly|dmModeShowSecret)) { UInt32 nRecords; UInt32 nTotalBytes; UInt32 nDataBytes; eErr = DmDatabaseSize(0, hFile->dbID, &nRecords, &nTotalBytes, &nDataBytes); if(eErr == errNone) { MemHandle hRecord; hFile->nRecords = nRecords; hFile->nDBSize = nDataBytes; #ifdef NOTDEF if(hRecord = DmGetRecord(hFile->dbRef, 0)) { MemPtr pData; if(pData = MemHandleLock(hRecord)) { hFile->nRecordSize = ((UINT16*)pData)[0]; MemHandleUnlock(hRecord); } DmReleaseRecord(hFile->dbRef, 0, false); } #endif *phFile = hFile; return(NCS_SUCCESS); } DmCloseDatabase(hFile->dbRef); return(NCSPalmGetNCSError(eErr)); } } } } else { return(NCS_COULDNT_ALLOC_MEMORY); } /* if(iFlags & NCS_FILE_READ) nMode = fileModeReadOnly|fileModeAnyTypeCreator; if(iFlags & NCS_FILE_READ_WRITE) nMode = fileModeUpdate|fileModeAnyTypeCreator; if(iFlags & NCS_FILE_CREATE) nMode = fileModeReadWrite|fileModeAnyTypeCreator; if(iFlags & NCS_FILE_CREATE_UNIQUE) nMode = fileModeReadWrite|fileModeDontOverwrite|fileModeAnyTypeCreator; if(iFlags & NCS_FILE_APPEND) nMode = fileModeAppend|fileModeAnyTypeCreator; *phFile = FileOpen(0, (char*)szFilename, 0, 0, nMode, &eErr); return(NCSPalmGetNCSError(eErr)); */ #elif defined(POSIX) int flags = O_RDONLY; if(iFlags & NCS_FILE_READ) flags = O_RDONLY; if(iFlags & NCS_FILE_READ_WRITE) flags = O_RDWR; if(iFlags & NCS_FILE_CREATE) flags |= O_CREAT; if(iFlags & NCS_FILE_CREATE_UNIQUE) flags |= O_CREAT|O_EXCL; if(iFlags & NCS_FILE_APPEND) flags |= O_APPEND; #if defined SOLARIS || (defined(HPUX) && !defined(__LP64__)) // Enable 64bit! flags |= O_LARGEFILE; #endif #ifdef HPUX *phFile = open64((const char*)CHAR_STRING(szFilename), (int)flags); #ifdef NOTDEF if (*phFile < 0) { fprintf(stderr, "Error opening file : %ld\n", errno); if (errno == EOVERFLOW) { fprintf(stderr, "The named file is a regular file and the size " "of the file cannot be represented correctly in an object of " "size off_t."); } } #endif #else *phFile = open((const char*)CHAR_STRING(szFilename), (int)flags, S_IRUSR|S_IWUSR); #endif if(*phFile != -1) { return(NCS_SUCCESS); } else { return(NCS_FILE_OPEN_FAILED); } #else /* SOLARIS||IRIX */ #error ERROR EcwFileCreate() routine is not defined for this platform #endif /* WIN32 */ }
/*------------------------------------------------------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; }
// Save preferences previously set via ErrSet*() calls to a database. // If something goes wrong, returns an error // Possible errors: // memErrNotEnoughSpace - not enough memory to allocate needed structures // errors from Dm*() calls Err PrefsStoreWriter::ErrSavePreferences() { Err err = errNone; long blobSize; void * prefsBlob = SerializeItems(_items, _itemsCount, &blobSize); if ( NULL == prefsBlob ) return memErrNotEnoughSpace; DmOpenRef db = DmOpenDatabaseByTypeCreator(_dbType, _dbCreator, dmModeReadWrite); if (!db) { err = DmCreateDatabase(0, _dbName, _dbCreator, _dbType, false); if ( err) return err; db = DmOpenDatabaseByTypeCreator(_dbType, _dbCreator, dmModeReadWrite); if (!db) return DmGetLastErr(); } // set backup bit on the database. code adapted from DataStore.cpp // DataStore::open() if (errNone == err) { LocalID localId; UInt16 cardNo; UInt16 attribs; err = DmOpenDatabaseInfo(db, &localId, NULL, NULL, &cardNo, NULL); if (errNone != err) goto Continue; err = DmDatabaseInfo(cardNo, localId, NULL, &attribs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (errNone != err) goto Continue; if (0 != attribs & dmHdrAttrBackup) goto Continue; attribs |= dmHdrAttrBackup; err = DmSetDatabaseInfo(cardNo, localId, NULL, &attribs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); Continue: err = errNone; } UInt16 recNo = 0; UInt16 recsCount = DmNumRecords(db); MemHandle recHandle; Boolean fRecordBusy = false; Boolean fRecFound = false; void * recData; long recSize; while (recNo < recsCount) { recHandle = DmGetRecord(db, recNo); fRecordBusy = true; recData = MemHandleLock(recHandle); recSize = MemHandleSize(recHandle); if (IsValidPrefRecord(recData)) { fRecFound = true; break; } MemPtrUnlock(recData); DmReleaseRecord(db, recNo, true); fRecordBusy = false; ++recNo; } if (fRecFound && blobSize>recSize) { /* need to resize the record */ MemPtrUnlock(recData); DmReleaseRecord(db,recNo,true); fRecordBusy = false; recHandle = DmResizeRecord(db, recNo, blobSize); if ( NULL == recHandle ) return DmGetLastErr(); recData = MemHandleLock(recHandle); Assert( MemHandleSize(recHandle) == blobSize ); } if (!fRecFound) { recNo = 0; recHandle = DmNewRecord(db, &recNo, blobSize); if (!recHandle) { err = DmGetLastErr(); goto CloseDbExit; } recData = MemHandleLock(recHandle); fRecordBusy = true; } err = DmWrite(recData, 0, prefsBlob, blobSize); MemPtrUnlock(recData); if (fRecordBusy) DmReleaseRecord(db, recNo, true); CloseDbExit: // if had error before - preserve that error // otherwise return error code from DmCloseDatabase() if (err) DmCloseDatabase(db); else err = DmCloseDatabase(db); new_free( prefsBlob ); return err; }
void IntlInit(void) { Err result; MemHandle localeCodeH; MemHandle tableListH; MemHandle featureTableH; ROMFtrTableType* featureTableP; ROMFtrCreatorType* creatorTableP; UInt16 creators; Boolean fastSort = true; Boolean fastSearch = true; Boolean fastAttr = true; UInt16 index; UInt32 intlFtrFlags; #if (EMULATION_LEVEL == EMULATION_NONE) UInt16 systemCard; LocalID systemID; DmSearchStateType* searchStateP; MemHandle localeNameH; LocalID moduleID; DmOpenRef moduleRef; // Locate the system DB, so that we know where to look (which card) // for the locale module. searchStateP = (DmSearchStateType*)MemPtrNew(sizeof(DmSearchStateType)); result = DmGetNextDatabaseByTypeCreator( true, searchStateP, sysFileTSystem, sysFileCSystem, true, // onlyLatestVers &systemCard, &systemID); ErrNonFatalDisplayIf((result != errNone) || (systemID == 0), "Can't find system DB"); MemPtrFree((MemPtr)searchStateP); localeNameH = DmGetResource(strRsc, localeModuleNameStrID); ErrNonFatalDisplayIf(localeNameH == NULL, "Missing locale module name string"); moduleID = DmFindDatabaseWithTypeCreator( systemCard, (Char*)MemHandleLock(localeNameH), sysFileTLocaleModule, sysFileCSystem); MemHandleUnlock(localeNameH); if (moduleID != 0) { moduleRef = DmOpenDatabase(systemCard, moduleID, dmModeReadOnly | dmModeLeaveOpen); ErrNonFatalDisplayIf(moduleRef == 0, "Can't open locale module"); if (ResLoadConstant(kIntlLMVersResID) != kIntlLMVersion) { DmCloseDatabase(moduleRef); moduleID = 0; } } // If we couldn't find the locale module, or it has the wrong version, then // default to the ROM locale's locale module. if (moduleID == 0) { SysNVParamsType* romParamsP; OmLocaleType romLocale; Char* overlayName; LocalID overlayID; DmOpenRef overlayRef; Char* systemName; // Open up the system overlay that corresponds to the ROM's locale. // Note that (assuming the ROM locale != current locale) we have to // try to open up the overlay explicitly, since the Overlay Mgr // won't be opening it automatically. We also have to handle the case // of a ROM built without overlays, in which case the ROM locale's // locale module name string is located in the base, which means we // have to make a low-level resource call to get it (otherwise we'll // get the string from the system overlay). romParamsP = (SysNVParamsType*)MemPtrNew(sizeof(SysNVParamsType)); MemGetRomNVParams(romParamsP); romLocale.country = romParamsP->localeCountry; romLocale.language = romParamsP->localeLanguage; MemPtrFree((MemPtr)romParamsP); // Get the name of the system DB, so that we can construct the overlay // name. systemName = (Char*)MemPtrNew(dmDBNameLength); overlayName = (Char*)MemPtrNew(dmDBNameLength); result = DmDatabaseInfo(systemCard, systemID, systemName, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ErrNonFatalDisplayIf(result != errNone, "Can't get system DB info"); result = OmLocaleToOverlayDBName(systemName, &romLocale, overlayName); ErrNonFatalDisplayIf(result != errNone, "Can't make ROM locale system overlay name"); overlayID = DmFindDatabaseWithTypeCreator(systemCard, overlayName, sysFileTOverlay, sysFileCSystem); MemPtrFree(systemName); MemPtrFree((MemPtr)overlayName); if (overlayID != 0) { overlayRef = DmOpenDatabase(systemCard, overlayID, dmModeReadOnly); ErrNonFatalDisplayIf(overlayRef == 0, "Can't open system overlay"); // Now load the locale module name string from this overlay, and use // it to find the locale module. localeNameH = DmGet1Resource(strRsc, localeModuleNameStrID); ErrNonFatalDisplayIf(localeNameH == NULL, "Missing locale module name string"); moduleID = DmFindDatabaseWithTypeCreator( systemCard, (Char*)MemHandleLock(localeNameH), sysFileTLocaleModule, sysFileCSystem); MemHandleUnlock(localeNameH); DmCloseDatabase(overlayRef); } else { // Assume it's a ROM built without overlays, in which case we need to // get the locale name handle from the system base. DmOpenRef sysRef = NULL; Int16 index; do { LocalID dbID; sysRef = DmNextOpenResDatabase(sysRef); if ((sysRef != NULL) && (DmOpenDatabaseInfo(sysRef, &dbID, NULL, NULL, NULL, NULL) == errNone) && (dbID == systemID)) { break; } } while (sysRef != NULL); ErrNonFatalDisplayIf(sysRef == NULL, "Can't find system DB"); index = DmFindResource(sysRef, strRsc, localeModuleNameStrID, NULL); ErrNonFatalDisplayIf(index == -1, "Missing locale module name string"); localeNameH = DmGetResourceIndex(sysRef, index); ErrNonFatalDisplayIf(localeNameH == NULL, "Missing locale module name string"); moduleID = DmFindDatabaseWithTypeCreator( systemCard, (Char*)MemHandleLock(localeNameH), sysFileTLocaleModule, sysFileCSystem); } // If we found the locale module DB, open it up and make sure it has // the right version. if (moduleID != 0) { moduleRef = DmOpenDatabase(systemCard, moduleID, dmModeReadOnly | dmModeLeaveOpen); if ((moduleRef == 0) || (ResLoadConstant(kIntlLMVersResID) != kIntlLMVersion)) { // Trigger fatal alert below. No need to close the DB in that case. moduleID = 0; } else { // We found a valid locale module, using the ROM locale, so set // the current locale to be the ROM locale. result = FtrSet(sysFtrCreator, sysFtrNumLanguage, romLocale.language); if (result == errNone) { result = FtrSet(sysFtrCreator, sysFtrNumCountry, romLocale.country); } ErrNonFatalDisplayIf(result != errNone, "Can't switch current locale to ROM locale"); } } ErrFatalDisplayIf(moduleID == 0, "No valid locale module"); } result = DmDatabaseProtect(systemCard, moduleID, true); if (result != dmErrROMBased) { ErrNonFatalDisplayIf(result != errNone, "Can't protect locale module"); } #else // Give the locale module code in the Simulator a chance to // initialize itself. If there's no such code (e.g. with latin) then the // routine in SimStubs.cp does nothing. StubPalmOSInitLocaleModule(); #endif // If there's a locale module code resource, load & call it now. localeCodeH = DmGet1Resource(kIntlLMCodeType, kIntlLMCodeResID); if (localeCodeH != NULL) { ProcPtr localeCodeP = (ProcPtr)MemHandleLock(localeCodeH); (*localeCodeP)(); MemHandleUnlock(localeCodeH); } // If the IntlMgr data ptr hasn't been set up by the locale module code, // allocate it now. if (GIntlMgrGlobalsP == NULL) { UInt16 numCustomTransTables; MemPtr globalPtr; numCustomTransTables = ResLoadConstant(kIntlLMCustomTransCountID); ErrNonFatalDisplayIf(numCustomTransTables > kIntlMaxCustomTransliterations, "Too many custom transliterations"); globalPtr = MemPtrNew(sizeof(IntlGlobalsType) + (numCustomTransTables * sizeof(void*))); ErrNonFatalDisplayIf(globalPtr == NULL, "Out of memory"); MemSet(globalPtr, sizeof(IntlGlobalsType) + (numCustomTransTables * sizeof(void*)), 0); GIntlMgrGlobalsP = globalPtr; GIntlData->numCustomTransliterations = numCustomTransTables; } else { // If any of the sorting tables are already configured, we can't do // our fast sorting optimization. for (index = 0; index < kIntlMaxSortLevels; index++) { if (GIntlData->sortTables[index] != NULL) { fastSort = false; break; } } // If the word start or word match tables are already configured, we // can't do our fast word search optimization. if ((GIntlData->findWordStartTable != NULL) || (GIntlData->findWordMatchTable != NULL)) { fastSearch = false; } // If the character attribute table is already configured, we can't do // our fast attribute optimization. if (GIntlData->charAttrTable != NULL) { fastAttr = false; } } // Loop over all of the table resources, locking & setting up pointers in // the IntlMgr global data structure. tableListH = DmGet1Resource(kIntlLMTableListType, kIntlLMTableListResID); if (tableListH != NULL) { IntlLMTableEntryType* curTable; UInt8* globalsP = (UInt8*)GIntlMgrGlobalsP; IntlLMTableResType* tableListP = (IntlLMTableResType*)MemHandleLock(tableListH); for (index = 0, curTable = tableListP->resources; index < tableListP->numResources; index++, curTable++) { void** ptrLocation; MemHandle tableH; tableH = DmGet1Resource(curTable->resType, curTable->resID); ErrFatalDisplayIf(tableH == NULL, "Missing table resource from locale module"); ErrFatalDisplayIf(curTable->tableIndex >= intlLMNumTableIndexes, "Invalid table index"); ptrLocation = (void**)(globalsP + kIntlGlobalOffsets[curTable->tableIndex]); ErrFatalDisplayIf(*ptrLocation != NULL, "Resource overriding existing table ptr"); *ptrLocation = MemHandleLock(tableH); } MemHandleUnlock(tableListH); } // Note that we can't check for the presence of tables here, as a table that // is required by a Text Mgr routine might be NULL if the locale module has // patched out that routine. // As an optimization, see if all of the sorting tables are byte-indexed 8-bit // values. If so, then replace the table ptrs with ptrs to the actual data, // and set the fast sorting intl mgr flag. for (index = 0; (index < kIntlMaxSortLevels) && fastSort; index++) { void* sortTable = GIntlData->sortTables[index]; if (sortTable == NULL) { break; } else if (PrvGetByteIndexedTable(sortTable, 8) == NULL) { fastSort = false; } } if (fastSort) { GIntlData->intlFlags |= kByteSortingFlag; for (index = 0; index < kIntlMaxSortLevels; index++) { GIntlData->sortTables[index] = PrvGetByteIndexedTable(GIntlData->sortTables[index], 8); } } // As an optimization, see if all of the searching tables are byte-indexed 8-bit // values. If so, then replace the table ptrs with ptrs to the actual data, // and set the fast searching intl mgr flag. Note that PrvGetByteIndexedTable // will return NULL if findWordMatchTable is NULL, which is OK because then // TxtFindString must be patched out anyway. The findWordStartTable is optional, // and thus it can either be NULL or a byte indexed byte table. if ((fastSearch) && ((GIntlData->findWordStartTable == NULL) || (PrvGetByteIndexedTable(GIntlData->findWordStartTable, 8) != NULL)) && (PrvGetByteIndexedTable(GIntlData->findWordMatchTable, 8) != NULL)) { GIntlData->intlFlags |= kByteSearchingFlag; GIntlData->findWordStartTable = PrvGetByteIndexedTable(GIntlData->findWordStartTable, 8); GIntlData->findWordMatchTable = PrvGetByteIndexedTable(GIntlData->findWordMatchTable, 8); } // As an optimization, see if the character attribute table is a byte-indexed // table of 16-bit values. If so, then replace the table ptr with a ptr to // the data, and set the kByteCharAttrFlag flag. if (fastAttr && (PrvGetByteIndexedTable(GIntlData->charAttrTable, 16) != NULL)) { GIntlData->intlFlags |= kByteCharAttrFlag; GIntlData->charAttrTable = PrvGetByteIndexedTable(GIntlData->charAttrTable, 16); // As an optimization, see if the character attribute table is a stage index map // table of 16-bit values. If so, then replace the table ptr with a ptr to // the sub-table offsets, set up the result table ptr, and set the // kStageCharAttrFlag flag. } else if (fastAttr && PrvGetStageIndexMapTable(GIntlData->charAttrTable, 16)) { GIntlData->intlFlags |= kStageCharAttrFlag; GIntlData->charAttrTable = PrvGetStageIndexMapTable(GIntlData->charAttrTable, 16); } // If there's a doubleCharTable, we want to (a) verify that it's a byte-indexed // byte table, and (b) set up the pointer now. if (GIntlData->doubleCharTable != NULL) { void* tableP = PrvGetByteIndexedTable(GIntlData->doubleCharTable, 8); ErrNonFatalDisplayIf(tableP == NULL, "Double-char table isn't byte-indexed byte table"); GIntlData->doubleCharTable = tableP; } // Load the 'feat' resource from the locale module, and use it to initialize // various locale-specific features. Typically this includes sysFtrNumCharEncodingFlags, // sysFtrNumEncoding, sysFtrDefaultFont, and sysFtrDefaultBoldFont. // Try to load the 'feat' resource. featureTableH = DmGet1Resource(sysResTFeatures, kIntlLMFeatureResID); ErrFatalDisplayIf(featureTableH == NULL, "Missing feature table"); featureTableP = (ROMFtrTableType*)MemHandleLock(featureTableH); creatorTableP = featureTableP->creator; for (creators = 0; creators < featureTableP->numEntries; creators++) { UInt16 features; for (features = 0; features < creatorTableP->numEntries; features++) { result = FtrSet( creatorTableP->creator, creatorTableP->feature[features].num, creatorTableP->feature[features].value); ErrNonFatalDisplayIf(result != errNone, "Can't set locale feature"); } // Advance to next creator table. creatorTableP = (ROMFtrCreatorType*)((UInt8*)creatorTableP + sizeof(ROMFtrCreatorType) + (creatorTableP->numEntries * sizeof(ROMFtrFeatureType))); } MemHandleUnlock(featureTableH); // Now, set up our internal kByteSearchingFlag flag based on the sysFtrNumCharEncodingFlags // feature value. This means that sysFtrNumCharEncodingFlags is read-only, since if // anybody uses FtrSet to change the settings of the flags, that won't update // our internal flag(s). if ((FtrGet(sysFtrCreator, sysFtrNumCharEncodingFlags, &intlFtrFlags) == errNone) && ((intlFtrFlags & charEncodingOnlySingleByte) != 0)) { GIntlData->intlFlags |= kSingleByteOnlyFlag; } // Finally set the bit that tells everybody we're ready to support IntlMgr/TextMgr calls. FtrSet(sysFtrCreator, sysFtrNumIntlMgr, intlMgrExists); } // IntlInit