home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
linuxmafia.com 2016
/
linuxmafia.com.tar
/
linuxmafia.com
/
pub
/
palmos
/
linkmaster-src-1.0.4.tar.gz
/
linkmaster-src-1.0.4.tar
/
linkmaster-1.0.4
/
linkmaster.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-10-12
|
15KB
|
628 lines
/* linkmaster.c
Copyright (C) 1999 Ben Darnell
This file is a part of LinkMaster,
which is distributed under the GNU GPL.
*/
/* prefs info:
pref 0: histprefs (from linkaware.h)
pref 1: pending link (unsaved)
pref 2: history time limit
*/
#include <Pilot.h>
#include "callback.h"
#include "linkaware.h"
#include "linkmaster.h"
#include "linkmasterRsc.h"
static DmOpenRef LinkDB;
static Word mode;
static void LinkListDrawFunc(UInt item, RectanglePtr bounds, CharPtr* text)
{
VoidHand h;
Ptr p;
CALLBACK_PROLOGUE;
h=DmQueryRecord(LinkDB, item);
p=MemHandleLock(h);
WinDrawChars(p+64, StrLen(p+64), bounds->topLeft.x, bounds->topLeft.y);
MemHandleUnlock(h);
CALLBACK_EPILOGUE;
}
static void InitForm(FormPtr frm)
{
ListPtr list;
list=FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, MainLinkList));
LstSetListChoices(list, NULL, DmNumRecords(LinkDB));
LstSetDrawFunction(list, LinkListDrawFunc);
if (mode==linkAppLaunchRequestLink) {
CtlHideControl(FrmGetObjectPtr(frm,
FrmGetObjectIndex(frm, MainDelLink)));
CtlHideControl(FrmGetObjectPtr(frm,
FrmGetObjectIndex(frm, MainGo)));
};
}
static void NewLink()
{
FrmPopupForm(NewLinkForm);
}
static void DelLink()
{
FormPtr frm;
ListPtr list;
Word sel;
frm=FrmGetActiveForm();
list=FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, MainLinkList));
sel=LstGetSelection(list);
if (sel==-1) return;
DmRemoveRecord(LinkDB, sel);
FrmUpdateForm(MainForm, frmRedrawUpdateCode);
}
static void Go()
{
FormPtr frm;
ListPtr list;
Word sel;
VoidHand hrec;
Ptr prec, tmpptr;
frm=FrmGetActiveForm();
list=FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, MainLinkList));
sel=LstGetSelection(list);
if (sel==-1) return;
hrec=DmQueryRecord(LinkDB, sel);
prec=MemHandleLock(hrec);
tmpptr=MemPtrNew(64);
MemMove(tmpptr, prec, 64);
MemHandleUnlock(hrec);
LinkFollow((LinkInfoPtr)prec);
MemPtrFree(tmpptr);
}
static void AddTitle(VoidHand h)
{
LinkInfoPtr p;
Char name[32];
Err err;
DmSearchStateType searchstate;
UInt cardno;
LocalID dbid;
Char title[64];
DateTimeType date;
if (MemHandleSize(h)>64)
return; /* it already has a title */
p=(LinkInfoPtr)MemHandleLock(h);
err=DmGetNextDatabaseByTypeCreator(true, &searchstate, 'appl', p->creator,
true, &cardno, &dbid);
MemHandleUnlock(h);
if (err)
name[0]=0;
else
DmDatabaseInfo(cardno, dbid, name,
NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL);
TimSecondsToDateTime(TimGetSeconds(), &date);
StrPrintF(title, "%s %d:%d", name, date.hour, date.minute);
MemHandleResize(h, 65+StrLen(title));
p=MemHandleLock(h);
DmWrite(p, 64, title, StrLen(title)+1);
MemHandleUnlock(h);
}
/* if there is a link pending, sends this link to it and returns true.
else returns false
*/
static Boolean PendingLink(LinkInfoPtr info)
{
LinkInfoType preflink;
Ptr output;
Err err;
DmSearchStateType searchstate;
UInt cardno;
LocalID dbid;
Word size=64;
if (PrefGetAppPreferences('Link', 1, &preflink, &size, false)
==noPreferenceFound) {
return false;
};
output=MemPtrNew(MemPtrSize(info)+64);
MemMove(output, &preflink, 64);
MemMove(output+64, info, MemPtrSize(info));
err=DmGetNextDatabaseByTypeCreator(true, &searchstate,
'appl', preflink.creator,
true, &cardno, &dbid);
if (err) return false;
MemPtrSetOwner(output, 0);
SysUIAppSwitch(cardno, dbid, linkAppLaunchReturnLink, (Ptr)output);
/* remove preference */
PrefSetAppPreferences('Link', 1, 0, NULL, 0, false);
return true;
}
static void StoreLink(LinkInfoPtr info)
{
VoidHand hrec;
Ptr prec;
UInt index=0;
hrec=DmNewRecord(LinkDB, &index, MemPtrSize(info));
prec=MemHandleLock(hrec);
DmWrite(prec, 0, info, MemPtrSize(info));
MemHandleUnlock(hrec);
AddTitle(hrec);
DmReleaseRecord(LinkDB, index, true);
}
static void HistoryPush(LinkInfoPtr linkinfo)
{
DmOpenRef db;
VoidHand hrec;
Ptr prec;
UInt index=0;
int i;
LinkHistoryPrefsType histprefs;
LinkHistoryPrefsType2 histprefs2;
Word prefssize;
UInt cardno;
LocalID dbid;
ULong moddate;
SWord prefsver;
db=DmOpenDatabaseByTypeCreator('HIST', 'Link', dmModeReadWrite);
/* the database is already open if HistoryBack/Forward is called
with the LinkHistoryHack loggin app use. In this case, the link
just passed is already in the history, so it's safe to ignore */
if ((!db)&&(DmGetLastErr()!=dmErrCantFind))
return;
if (!db) {
UInt cardno;
LocalID dbid;
UInt attr;
if (DmCreateDatabase(0, "LinkMasterHist", 'Link', 'HIST', false))
ErrDisplay("Error creating database");
db=DmOpenDatabaseByTypeCreator('HIST', 'Link', dmModeReadWrite);
DmOpenDatabaseInfo(db, &dbid, NULL, NULL, &cardno, NULL);
DmDatabaseInfo(cardno, dbid, NULL, &attr, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
attr|=dmHdrAttrBackup;
DmSetDatabaseInfo(cardno, dbid, NULL, &attr, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
/* set preference */
prefssize=sizeof(histprefs);
if (PrefGetAppPreferences('Link', 0, &histprefs, &prefssize, true)
==noPreferenceFound) {
histprefs.max=50;
};
histprefs.current=0;
PrefSetAppPreferences('Link', 0, 0, &histprefs, prefssize, true);
};
prefssize=sizeof(histprefs);
PrefGetAppPreferences('Link', 0, &histprefs, &prefssize, true);
prefssize=sizeof(histprefs2);
prefsver=PrefGetAppPreferences('Link', 2, &histprefs2, &prefssize, true);
if (prefsver<0) {
histprefs2.mintime=2;
histprefs2.allowdups=0;
};
/* if the previous item was created too recently, replace it */
DmOpenDatabaseInfo(db, &dbid, NULL, NULL, &cardno, NULL);
DmDatabaseInfo(cardno, dbid, NULL,NULL,NULL,NULL, &moddate,
NULL,NULL,NULL,NULL,NULL,NULL);
if ((moddate>(TimGetSeconds()-histprefs2.mintime))
&&(DmNumRecords(db)>histprefs.current))
DmRemoveRecord(db, histprefs.current);
/* always disallow consecutive duplicates */
if (DmNumRecords(db)>histprefs.current) {
hrec=DmQueryRecord(db, histprefs.current);
if (hrec) {
Boolean match=true;
prec=MemHandleLock(hrec);
/* use longs here for speed */
for (i=0; i<(64/sizeof(long)); i++) {
if (((LongPtr)prec)[i]!=((LongPtr)linkinfo)[i]) {
match=false;
break;
}
};
MemHandleUnlock(hrec);
if (match) {
DmCloseDatabase(db);
return;
};
};
};
if (!histprefs2.allowdups) {
int j;
for (j=DmNumRecords(db); j>=0; j--) {
hrec=DmQueryRecord(db, j);
if (hrec) {
Boolean match=true;
prec=MemHandleLock(hrec);
for (i=0; i<(64/sizeof(long)); i++) {
if (((LongPtr)prec)[i]!=((LongPtr)linkinfo)[i]) {
match=false;
break;
}
};
MemHandleUnlock(hrec);
if (match) {
DmRemoveRecord(db, j);
break; /* we can stop looking for matches here */
};
}
}
}
/* clear "forward" buffer */
for (i=0; i<histprefs.current; i++)
DmRemoveRecord(db, 0);
histprefs.current=0;
PrefSetAppPreferences('Link', 0, 0, &histprefs, prefssize, true);
hrec=DmNewRecord(db, &index, MemPtrSize(linkinfo));
prec=MemHandleLock(hrec);
DmWrite(prec, 0, linkinfo, MemPtrSize(linkinfo));
MemHandleUnlock(hrec);
AddTitle(hrec);
DmReleaseRecord(db, index, true);
/* check max size */
for (i=DmNumRecords(db)-1; i>histprefs.max; i--)
DmRemoveRecord(db, i);
DmCloseDatabase(db);
}
static DWord HistoryBack()
{
DmOpenRef db;
VoidHand hrec;
Ptr prec;
LinkHistoryPrefsType histprefs;
Word prefssize;
Ptr tmpptr;
db=DmOpenDatabaseByTypeCreator('HIST', 'Link', dmModeReadOnly);
if (!db) return appErrorClass;
prefssize=sizeof(histprefs);
PrefGetAppPreferences('Link', 0, &histprefs, &prefssize, true);
if (histprefs.current>=DmNumRecords(db)) {
DmCloseDatabase(db);
return appErrorClass;
};
/* increment position */
histprefs.current++;
PrefSetAppPreferences('Link', 0,0, &histprefs, prefssize, true);
/* follow link */
/* allocate a temporary here because the record should be unlocked
when we call linkfollow (because it could start a chain of events
that alters the history, possibly deleting the record)
*/
hrec=DmQueryRecord(db, histprefs.current);
prec=MemHandleLock(hrec);
tmpptr=MemPtrNew(64);
MemMove(tmpptr, prec, 64);
MemHandleUnlock(hrec);
LinkFollow((LinkInfoPtr)tmpptr);
MemPtrFree(tmpptr);
DmCloseDatabase(db);
return 0;
}
static DWord HistoryForward()
{
DmOpenRef db;
VoidHand hrec;
Ptr prec;
LinkHistoryPrefsType histprefs;
Word prefssize;
Ptr tmpptr;
db=DmOpenDatabaseByTypeCreator('HIST', 'Link', dmModeReadOnly);
if (!db) return appErrorClass;
prefssize=sizeof(histprefs);
PrefGetAppPreferences('Link', 0, &histprefs, &prefssize, true);
if (histprefs.current==0) {
DmCloseDatabase(db);
return appErrorClass;
};
/* decrement position */
histprefs.current--;
PrefSetAppPreferences('Link', 0,0, &histprefs, prefssize, true);
/* follow link */
/* see note in HistoryBack */
hrec=DmQueryRecord(db, histprefs.current);
prec=MemHandleLock(hrec);
tmpptr=MemPtrNew(64);
MemMove(tmpptr, prec, 64);
MemHandleUnlock(hrec);
LinkFollow((LinkInfoPtr)tmpptr);
MemPtrFree(tmpptr);
DmCloseDatabase(db);
return 0;
}
static Boolean MainFormHandleEvent (EventPtr e)
{
Boolean handled = false;
FormPtr frm;
CALLBACK_PROLOGUE
switch (e->eType) {
case frmOpenEvent:
frm = FrmGetActiveForm();
InitForm(frm);
FrmDrawForm(frm);
handled = true;
break;
case frmUpdateEvent:
InitForm(FrmGetActiveForm());
break;
case menuEvent:
MenuEraseStatus(NULL);
switch(e->data.menu.itemID) {
case MainMenuNewLink:
NewLink();
break;
case MainMenuDelLink:
DelLink();
break;
case MainMenuPrefs:
FrmPopupForm(PrefsForm);
break;
case MainMenuAbout:
FrmAlert(AboutAlert);
break;
}
handled = true;
break;
case ctlSelectEvent:
switch(e->data.ctlSelect.controlID) {
case MainNewLink:
NewLink();
break;
case MainDelLink:
DelLink();
break;
case MainGo:
Go();
break;
}
break;
case lstSelectEvent:
if (e->data.lstSelect.listID!=MainLinkList)
break;
if (mode==linkAppLaunchRequestLink) {
VoidHand hrec;
Ptr prec;
hrec=DmQueryRecord(LinkDB, e->data.lstSelect.selection);
prec=MemHandleLock(hrec);
PendingLink((LinkInfoPtr)prec);
MemHandleUnlock(hrec);
}
break;
case popSelectEvent:
if (e->data.popSelect.listID!=MainModeList)
break;
switch (e->data.popSelect.selection) {
case 0: /* published links */
DmCloseDatabase(LinkDB);
LinkDB=DmOpenDatabaseByTypeCreator('DATA', 'Link', dmModeReadWrite);
frm=FrmGetActiveForm();
CtlShowControl(FrmGetObjectPtr(frm,
FrmGetObjectIndex(frm, MainDelLink)));
InitForm(frm);
FrmDrawForm(frm);
break;
case 1: /* history */
DmCloseDatabase(LinkDB);
LinkDB=DmOpenDatabaseByTypeCreator('HIST', 'Link', dmModeReadOnly);
if (!LinkDB) {
if (DmCreateDatabase(0, "LinkMasterHist", 'Link', 'HIST', false))
ErrDisplay("Error creating database");
LinkDB=DmOpenDatabaseByTypeCreator('HIST', 'Link',
dmModeReadOnly);
};
frm=FrmGetActiveForm();
CtlHideControl(FrmGetObjectPtr(frm,
FrmGetObjectIndex(frm, MainDelLink)));
InitForm(frm);
FrmDrawForm(frm);
break;
default: break;
};
break;
default:
break;
}
CALLBACK_EPILOGUE
return handled;
}
static Boolean ApplicationHandleEvent(EventPtr e)
{
FormPtr frm;
Word formId;
Boolean handled = false;
if (e->eType == frmLoadEvent) {
formId = e->data.frmLoad.formID;
frm = FrmInitForm(formId);
FrmSetActiveForm(frm);
switch(formId) {
case MainForm:
FrmSetEventHandler(frm, MainFormHandleEvent);
break;
case NewLinkForm:
FrmSetEventHandler(frm, NewLinkFormHandleEvent);
break;
case PrefsForm:
FrmSetEventHandler(frm, PrefsFormHandleEvent);
break;
}
handled = true;
}
return handled;
}
/* Get preferences, open (or create) app database */
static Word StartApplication(void)
{
LinkDB=DmOpenDatabaseByTypeCreator('DATA', 'Link', dmModeReadWrite);
if (!LinkDB) {
if (DmCreateDatabase(0, "LinkMasterDB", 'Link', 'DATA', false))
ErrDisplay("Error creating database");
LinkDB=DmOpenDatabaseByTypeCreator('DATA', 'Link', dmModeReadWrite);
};
FrmGotoForm(MainForm);
return 0;
}
/* Save preferences, close forms, close app database */
static void StopApplication(void)
{
DmCloseDatabase(LinkDB);
FrmSaveAllForms();
FrmCloseAllForms();
}
/* The main event loop */
static void EventLoop(void)
{
Word err;
EventType e;
do {
EvtGetEvent(&e, evtWaitForever);
if (! SysHandleEvent (&e))
if (! MenuHandleEvent (NULL, &e, &err))
if (! ApplicationHandleEvent (&e))
FrmDispatchEvent (&e);
} while (e.eType != appStopEvent);
}
/* Main entry point; it is unlikely you will need to change this except to
handle other launch command codes */
DWord PilotMain(Word cmd, Ptr cmdPBP, Word launchFlags)
{
Word err;
switch (cmd) {
case linkAppLaunchRequestLink:
/* store link in prefs */
PrefSetAppPreferences('Link', 1, 0, cmdPBP, 64, false);
/* fall thru */
case sysAppLaunchCmdNormalLaunch:
mode=cmd;
err = StartApplication();
if (err) return err;
EventLoop();
StopApplication();
break;
case linkAppLaunchReturnLink:
if (PendingLink((LinkInfoPtr)cmdPBP))
break;
err=StartApplication();
if (err) return err;
StoreLink((LinkInfoPtr)cmdPBP);
EventLoop();
StopApplication();
break;
case linkAppLaunchHistoryPush:
HistoryPush((LinkInfoPtr)cmdPBP);
break;
case linkAppLaunchHistoryBack:
return HistoryBack();
break;
case linkAppLaunchHistoryForward:
return HistoryForward();
break;
default:
return sysErrParamErr;
};
return 0;
}