home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
tpp400en.lha
/
tpp
/
pd
/
MSClock23.lzh
/
MSClock
/
source
/
MSClock-Handler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-10
|
19KB
|
507 lines
/*
* MSClock-Handler.c © by Martin Steppler
*
* last change: 05.08.91
*/
// prototypes
int GetWidth(LONG DefFlag);
// interrupt register saving functions
VOID int_start(VOID);
VOID int_end(VOID);
struct InputEvent *myhandler(struct InputEvent *ev);
// reference to the absolute address of ciab
extern struct CIA ciab;
// pragma for my interrupt handler
#pragma regcall(myhandler(a0))
// globals
char DateBuf[100];
struct IntuiText TextPrint = { 0,1,JAM2,0,0,NULL,(UBYTE *)DateBuf,NULL};
struct NewWindow ClockWindow = { 146,1,432,8,1,0,EOS, BORDERLESS, NULL,NULL,EOS,NULL,NULL,0,0,0,0,WBENCHSCREEN};
struct Window *Window=NULL;
struct IntuitionBase *IntuitionBase=NULL;
struct GfxBase *GfxBase=NULL;
struct DosLibrary *DosBase=NULL;
struct TheClock *TheClock;
struct MsgPort *inputDevPort=NULL;
struct IOStdReq *inputRequestBlock=NULL;
struct Interrupt *handlerStuff=NULL;
LONG DisplaySig = -1, JumpSig = -1;
// this is my interrupt handler
struct InputEvent *
myhandler(struct InputEvent *ev)
{
register struct InputEvent *ep;
// preserve registers
int_start();
// run down the list of events to see if they pressed the magic buttons
for (ep = ev; ep != NULL; ep = ep->ie_NextEvent) {
if((ep->ie_Class == IECLASS_RAWKEY) &&
(ep->ie_Qualifier & TheClock->JumpQualif) &&
(!((ep->ie_Qualifier & TheClock->JumpQualif) ^ TheClock->JumpQualif)) &&
(ep->ie_Code == TheClock->JumpCode)) {
ep -> ie_Class = IECLASS_NULL;
// now tell myself to jump to the next screen
if(TheClock->Child) Signal(TheClock->Child, SIG_JUMP);
// switch auto-jump to active screen off
if(TheClock->Flags & AUTO_JUMP_FLAG) {
TheClock->FlagsBackup &= (SUM_FLAG - AUTO_JUMP_FLAG);
Signal(TheClock->Child, SIG_CHANGE);
}
}
else if((ep->ie_Class == IECLASS_RAWKEY) &&
(ep->ie_Qualifier & TheClock->HotKeyQualif) &&
(!((ep->ie_Qualifier & TheClock->HotKeyQualif) ^ TheClock->HotKeyQualif)) &&
(ep->ie_Code == TheClock->HotKeyCode)) {
ep -> ie_Class = IECLASS_NULL;
// now tell myself to change the view mode
if(TheClock->Child) Signal(TheClock->Child, SIG_NEWMODE);
}
else if((ep->ie_Class == IECLASS_RAWKEY) &&
(ep->ie_Qualifier & TheClock->StartStopQualif) &&
(!((ep->ie_Qualifier & TheClock->StartStopQualif) ^ TheClock->StartStopQualif)) &&
(ep->ie_Code == TheClock->StartStopCode)) {
ep -> ie_Class = IECLASS_NULL;
// now tell myself to start/stop the counter
Signal(TheClock->Child, SIG_COUNTER);
}
}
// refresh the time display ?
if(ev -> ie_TimeStamp . tv_secs != TheClock -> LastSecs) {
TheClock -> LastSecs = ev -> ie_TimeStamp . tv_secs;
// now tell myself to refresh the display
if(TheClock->Child) Signal(TheClock->Child, SIG_DISPLAY);
}
// restore registers
int_end();
// pass on the pointer to the event
return(ev);
}
// _main():
// no CLI/WB parsing 8-)
LONG
_main()
{
register struct Process *ThatsMe = (struct Process *)FindTask(NULL);
register ULONG SignalSet;
char TempBuf[100];
char *Days[14]={ "Son","Mon","Die","Mit","Don","Fre","Sam",
"Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
struct DateStamp Date;
LONG n,eng,Month,Day,Year,chip_free,fast_free,hh=0,mm=0,ss=0,lastsec=-1;
LONG i, dm=0, pf=0, dmt=0, pft=0, interval=0, Today, mins, hours, secs;
BYTE failed=1;
BPTR file;
// If somebody called us from CLI...
if(ThatsMe -> pr_CLI) return(10);
// Is the TheClock structure anywhere?
if(!(TheClock = (struct TheClock *)FindPort((UBYTE *)PORTNAME))) {
Forbid();
Signal(TheClock -> Father, CHILD_READY);
return(10);
}
TheClock->Child = (struct Task *)ThatsMe;
// open libraries
if(IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)"intuition.library",0)) {
if(GfxBase = (struct GfxBase *)OpenLibrary((UBYTE *)"graphics.library",0)) {
if(DosBase = (struct DosLibrary *)OpenLibrary((UBYTE *)"dos.library",0)) {
if((DisplaySig = AllocSignal(-1)) != -1) {
if((JumpSig = AllocSignal(-1)) != -1) {
// install input handler
if(handlerStuff = (struct Interrupt *)AllocMem(sizeof(struct Interrupt), MEMF_PUBLIC)) {
if((inputDevPort = (struct MsgPort *)CreatePort(NULL,0L)) != NULL) {
if(inputRequestBlock = (struct IOStdReq *)CreateStdIO(inputDevPort)) {
if(OpenDevice((UBYTE *)"input.device",0L,(struct IORequest *)inputRequestBlock,0L) == 0) {
handlerStuff->is_Node.ln_Name = "MSClock-Input-Handler";
handlerStuff->is_Node.ln_Pri = 51;
handlerStuff->is_Code = (VOID *)myhandler;
inputRequestBlock->io_Command = IND_ADDHANDLER;
inputRequestBlock->io_Data = (APTR)handlerStuff;
DoIO((struct IORequest *)inputRequestBlock);
// everything worked *fine*
failed = 0;
}
}
}
}
}
}
}
}
}
// this is the end of the world as we know it ...
if(failed) goto abort;
// ... but I feel fine 8-)
TheClock -> Status = 1;
// read in the amount of telephone charges that have been spent so far
if(file=(BPTR)Open((UBYTE *)TheClock->Logfile, MODE_OLDFILE)) {
Seek(file, -8, OFFSET_END);
i=Read(file, TempBuf, 20);
Close(file);
if(i>=8) {
i = strlen(TempBuf)-2; n=1;
if(isdigit(TempBuf[i]) && isdigit(TempBuf[i-1])) {
pft = TempBuf[i] - '0' + 10 * (TempBuf[i-1] - '0');
i-=3;
}
while(i && isdigit(TempBuf[i])) {
dmt += (TempBuf[i] - '0') * n;
n*=10; i--;
}
}
}
// Go into infinite loop waiting for signals.
FOREVER
{
// switch clock on
if(TheClock -> Status == 1) {
TheClock -> Status = 2;
switch(TheClock->Viewmodes) {
case 0:
TheClock -> Width = GetWidth(TheClock->Flags);
ClockWindow.LeftEdge = TheClock -> OverScan - TheClock->Width - TheClock->FBGadWidth;
ClockWindow.Width = TheClock -> Width;
break;
case 1:
if((TheClock->Flags) & (NO_SECONDS_FLAG)) {
ClockWindow.LeftEdge = TheClock -> OverScan - TheClock->FBGadWidth - (SHORT_TIME_WIDTH + DATE_WIDTH) * TheClock->Font->tf_XSize;
ClockWindow.Width = (SHORT_TIME_WIDTH + DATE_WIDTH) * TheClock->Font->tf_XSize;
}
else {
ClockWindow.LeftEdge = TheClock -> OverScan - TheClock->FBGadWidth - (TIME_WIDTH + DATE_WIDTH) * TheClock->Font->tf_XSize;
ClockWindow.Width = (TIME_WIDTH + DATE_WIDTH) * TheClock->Font->tf_XSize;
}
break;
case 2:
ClockWindow.LeftEdge = TheClock -> OverScan - TheClock->FBGadWidth - LONG_MEM_WIDTH * TheClock->Font->tf_XSize;
ClockWindow.Width = LONG_MEM_WIDTH * TheClock->Font->tf_XSize;
break;
case 3:
ClockWindow.LeftEdge = TheClock -> OverScan - TheClock->FBGadWidth - ONLINE_WIDTH * TheClock->Font->tf_XSize;
ClockWindow.Width = ONLINE_WIDTH * TheClock->Font->tf_XSize;
break;
}
ClockWindow.Height = TheClock->Font->tf_YSize;
if(Window=(struct Window *) OpenWindow(&ClockWindow)) {
SetFont(Window->RPort, TheClock->Font);
SetAPen(Window->RPort, 1);
RectFill(Window->RPort, 0, 0, (LONG)Window->Width, (LONG)Window->Height);
TheClock->Status = 0;
}
}
// show mem, date, online-time and/or time
if(!TheClock->Status) {
chip_free = AvailMem(MEMF_CHIP);
fast_free = AvailMem(MEMF_FAST);
DateStamp((struct DateStamp *)&Date) ;
n = Date.ds_Days - 2251;
Year = (4 * n + 3) / 1461;
n -= 1461 * Year / 4;
Year += 1984;
Month = (5 * n + 2) / 153;
Day = n - (153 * Month + 2) / 5 + 1;
Month += 3;
hours = Date.ds_Minute/60;
mins = Date.ds_Minute%60;
secs = Date.ds_Tick/TICKS_PER_SECOND;
n=TheClock->Flags;
// partial display ?
if(TheClock->Viewmodes) {
// filter all unneeded flags
n &= (SUM_FLAG - ONLINE_FLAG - MEMORY_FLAG - DATE_FLAG - TIME_FLAG);
}
if(Month>12) { Year++; Month -= 12; }
Today = (Day + Year + (Year - (Month < 3)) / 4 + 3 * Month - 2 * (Month > 2) - (Month - 1 - (Month > 8)) / 2 + 2) % 7;
DateBuf[0]=EOS;
// Check port a of cia b. Is there a carrier?
// Is '-s' flag set ?
// Online ?
if(!(ciab . ciapra & CIAF_COMCD) || (n & START_STOP_FLAG))
{
if(!TheClock -> Online) {
// Time reset
dm=hh=mm=ss=0;
pf = TheClock -> Unit;
if((pft = pft + TheClock->Unit)>=100) {
pft -= 100; dmt++;
}
// current hour
i = Date.ds_Minute/60;
// cheap or not cheap this is here the question
// cheap interval, holidy, sunday or saturday
if((i>=TheClock->LowChargesStart || i<TheClock->LowChargesEnd)
|| (n & HOLIDAY_FLAG) || !Today || Today==6)
interval = TheClock->CInterval;
else interval = TheClock ->Interval;
TheClock -> Online = TRUE;
// write log entry
if(!(n & NO_LOGFILE_FLAG)) {
// append to existing logfile
if(file=(BPTR)Open((UBYTE *)TheClock->Logfile, MODE_OLDFILE)) {
Seek(file, 0, OFFSET_END);
}
else file = (BPTR)Open((UBYTE *)TheClock->Logfile, MODE_NEWFILE);
if(file) {
eng = (n & ENGLISH_FLAG) ? 7:0;
if(n & REVERSE_FLAG) sprintf(TempBuf, "%s %02ld-%02ld-%02ld", Days[Today+eng], Month, Day, Year-1900);
else sprintf(TempBuf, "%s %02ld.%02ld.%02ld", Days[Today+eng], Day, Month, Year-1900);
Write(file, TempBuf, strlen(TempBuf));
sprintf(TempBuf, " %02ld:%02ld:%02ld ONLINE\n", hours, mins, secs);
Write(file, TempBuf, strlen(TempBuf));
Close(file);
}
}
}
// Increment time counter.
if(lastsec != secs) {
lastsec = secs;
if(++ss == 60) {
ss=0; if(++mm == 60) { mm=0; ++hh; }
}
// Decrement interval counter.
if(--interval == 0) {
// current hour
i = hours;
// reset interval counter.
// Today 0 == Sunday // 6 == Saturday
if((i>=TheClock->LowChargesStart || i<TheClock->LowChargesEnd) ||
(n & HOLIDAY_FLAG) || !Today || Today==6) interval = TheClock->CInterval;
else interval = TheClock -> Interval;
// increment charges counter.
pf += TheClock->Unit;
pft += TheClock->Unit;
if(pf>=100) {
pf-=100; dm++;
}
if(pft>=100) {
pft-=100; dmt++;
}
}
}
}
else {
if(TheClock->Online == TRUE) {
// write log entry
if(!(n & NO_LOGFILE_FLAG)) {
// append to existing logfile
if(file=(BPTR)Open((UBYTE *)TheClock->Logfile, MODE_OLDFILE)) {
Seek(file, 0, OFFSET_END);
eng = (n & ENGLISH_FLAG) ? 7:0;
if(n & REVERSE_FLAG) sprintf(TempBuf, "%s %02ld-%02ld-%02ld", Days[Today+eng], Month, Day, Year-1900);
else sprintf(TempBuf, "%s %02ld.%02ld.%02ld", Days[Today+eng], Day, Month, Year-1900);
Write(file, TempBuf, strlen(TempBuf));
sprintf(TempBuf, " %02ld:%02ld:%02ld OFFLINE", hours, mins, secs);
Write(file, TempBuf, strlen(TempBuf));
sprintf(TempBuf, " %02ld:%02ld:%02ld %02ld,%02ld TOTAL %03ld,%02ld\n", hh, mm, ss, dm , pf, dmt, pft);
Write(file, TempBuf, strlen(TempBuf));
Close(file);
}
}
}
TheClock -> Online = FALSE;
}
if((n & ONLINE_FLAG) || (TheClock->Viewmodes == DISPLAY_ONLINE_TIME)) {
sprintf(TempBuf, "%02ld:%02ld:%02ld %02ld,%02ld %03ld,%02ld", hh, mm, ss, dm, pf, dmt, pft);
strcat(DateBuf,TempBuf);
}
if(n & MEMORY_FLAG) {
chip_free /= 1000; // no real KByte
fast_free /= 1000; // yields to more RAM :-)
sprintf(TempBuf, " A:%04d C:%04d F:%04d", chip_free+fast_free, chip_free, fast_free);
strcat(DateBuf,TempBuf);
}
else if(TheClock->Viewmodes == DISPLAY_MEMORY) {
sprintf(TempBuf, "F:%08ld C:%07ld", fast_free, chip_free);
strcat(DateBuf,TempBuf);
}
if((n & DATE_FLAG) || (TheClock->Viewmodes == DISPLAY_DATE_AND_TIME)) {
eng = (n & ENGLISH_FLAG) ? 7:0;
if(n & REVERSE_FLAG) sprintf(TempBuf, " %s %02ld-%02ld-%02ld", Days[Today+eng], Month, Day, Year-1900);
else sprintf(TempBuf, " %s %02ld.%02ld.%02ld", Days[Today+eng], Day, Month, Year-1900);
strcat(DateBuf,TempBuf);
}
if((n & TIME_FLAG) || (TheClock->Viewmodes == DISPLAY_DATE_AND_TIME)) {
if(n & NO_SECONDS_FLAG) sprintf(TempBuf, " %02ld:%02ld", hours, mins);
else sprintf(TempBuf, " %02ld:%02ld:%02ld", hours, mins, secs);
strcat(DateBuf, TempBuf);
}
if(n & AUTO_JUMP_FLAG) {
register ULONG IntuiLock;
register struct Screen *ActiveScreen;
IntuiLock = LockIBase(0L);
ActiveScreen = IntuitionBase -> ActiveScreen;
UnlockIBase(IntuiLock);
// If not on active screen -> signal myself to jump
if(ActiveScreen != Window->WScreen) Signal(TheClock->Child, SIG_JUMP);
}
// justify to the right border
if((n=Window->Width-TextLength(Window->RPort, (UBYTE *)DateBuf, strlen(DateBuf))) < 0) n=0;
TextPrint.LeftEdge = n;
PrintIText(Window->RPort,&TextPrint, 0,0);
}
// Tell father to finish.
if(!failed) { Signal(TheClock -> Father, CHILD_READY); failed = 1; }
SignalSet = Wait(SIG_CLOSE | SIG_CHANGE | SIG_COUNTER | SIG_NEWMODE | SIG_DISPLAY | SIG_JUMP);
if(SignalSet & SIG_CLOSE) break;
else if(SignalSet & SIG_CHANGE) {
if(Window) { CloseWindow(Window); Window = NULL; }
TheClock->Flags = TheClock->FlagsBackup;
TheClock->Viewmodes = TheClock->ModesBackup;
TheClock->Status = 1;
// Tell father to finish.
Signal(TheClock -> Father, CHILD_READY);
}
// change
else if(SignalSet & SIG_NEWMODE) {
if(Window) { CloseWindow(Window); Window = NULL; }
TheClock->Status = 1;
TheClock->Viewmodes = TheClock->Viewmodes + 1;
if(TheClock->Viewmodes == 4) TheClock->Viewmodes = 0;
}
// start/stop counter
else if(SignalSet & SIG_COUNTER) {
TheClock->Flags = (TheClock->Flags & 128) ? (TheClock->Flags & 127):(TheClock->Flags | 128);
}
// jump to next screen
else if(SignalSet & SIG_JUMP) {
register struct Screen *NextScreen;
register ULONG IntuiLock;
// start with the first one
IntuiLock = LockIBase(0L);
NextScreen = IntuitionBase -> ActiveScreen;
UnlockIBase(IntuiLock);
// watch out for another screen
// and jump
if(Window) { CloseWindow(Window); Window = NULL; }
TheClock->Status = 1;
// change font
TheClock->Font = NextScreen->RastPort.Font;
// and NewWindow entries
if((NextScreen -> Flags & SCREENTYPE) == WBENCHSCREEN) {
ClockWindow.Screen = NULL;
ClockWindow.Type = WBENCHSCREEN;
}
else {
ClockWindow.Screen = NextScreen;
ClockWindow.Type = CUSTOMSCREEN;
}
ScreenToFront(NextScreen);
}
}
abort:
TheClock -> Child = NULL;
if(inputRequestBlock != NULL) {
if(inputRequestBlock->io_Device != NULL) {
inputRequestBlock->io_Command = IND_REMHANDLER;
inputRequestBlock->io_Data = (APTR)handlerStuff;
DoIO((struct IORequest *)inputRequestBlock);
CloseDevice((struct IORequest *)inputRequestBlock);
}
DeleteStdIO(inputRequestBlock);
}
if(inputDevPort != NULL) DeletePort(inputDevPort);
if(handlerStuff) FreeMem(handlerStuff, sizeof(struct Interrupt));
if(Window) { CloseWindow(Window); Window = NULL; }
if(DisplaySig != -1) FreeSignal(DisplaySig);
if(JumpSig != -1) FreeSignal(JumpSig);
if(DosBase) CloseLibrary((struct Library *)DosBase);
if(GfxBase) CloseLibrary((struct Library *)GfxBase);
if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
// tell daddy to kill us
Forbid();
Signal(TheClock -> Father, CHILD_READY);
return(20);
}
// calculate width of our window
GetWidth(LONG DefFlag)
{
int Width = 0, Fact = TheClock->Font->tf_XSize;
if(DefFlag & TIME_FLAG) {
if(DefFlag & NO_SECONDS_FLAG) Width+= (Fact * (SHORT_TIME_WIDTH));
else Width+= (Fact * (TIME_WIDTH));
}
if(DefFlag & DATE_FLAG) Width+= (Fact * (DATE_WIDTH));
if(DefFlag & MEMORY_FLAG) Width+= (Fact * (MEM_WIDTH));
if(DefFlag & ONLINE_FLAG) Width+= (Fact * (ONLINE_WIDTH));
// default width
if(!Width) Width = (Fact * (TIME_WIDTH));
return(Width);
}