home *** CD-ROM | disk | FTP | other *** search
- /*
- VolumeWatch
- -----------
-
- whooa! again a 2 hours production ;-)
-
- - should have been used BOOPSI objects for the frames
-
- Copyright ©1996 by Daniel Balster. Freeware!
- */
-
- #include <exec/exec.h>
- #include <proto/exec.h>
- #include <dos/dos.h>
- #include <proto/dos.h>
- #include <intuition/intuition.h>
- #include <devices/timer.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
-
- #include <stdio.h>
- #include <string.h>
-
- #define SCANFLAGS LDF_VOLUMES|LDF_READ
- #define TEMPLATE "PUBSCREEN/K,WIDTH/K/N,LEFT/K/N,TOP/K/N,INTERVAL/K/N,NOFULL/S,QUIET/S"
-
- #define LOCALETEMP "%ld%% full, %ld%c free, %ld%c used"
- //#define LOCALETEMP "%ld%% voll, %ld%c frei, %ld%c benutzt"
-
- UBYTE *version = "$VER: VolumeWatch 1.1 (29.01.96) Copyright ©1996 by Daniel Balster";
-
- struct {
- STRPTR pubscreen;
- ULONG *Width, *Left, *Top, *interval;
- ULONG nofull;
- ULONG quiet;
- } args = {0};
-
- struct VolumeInfo
- {
- struct Node node; // to link
- WORD pad; // force the next one to a 32bit boundary
- struct InfoData data; // Info'ed
- UBYTE *name; // AllocVec'ed
- };
-
- SHORT zoom[4] = { 0,0,100,14 };
-
- char *units = "KMG"; // Kilo-Mega-Giga
-
- // *** timer
-
- struct MsgPort *time_mp = 0;
- struct timerequest *time_ior = 0;
-
- #define TIMESIGNAL (1l<<time_mp->mp_SigBit)
-
- int inittimer()
- {
- if (time_mp = CreateMsgPort())
- {
- if (time_ior = (struct timerequest*) CreateIORequest (time_mp,sizeof(struct timerequest)))
- {
- if (OpenDevice ("timer.device",UNIT_MICROHZ,time_ior,0)==0)
- {
- time_ior->tr_node.io_Command = TR_ADDREQUEST;
- time_ior->tr_node.io_Flags = IOF_QUICK;
- time_ior->tr_time.tv_secs = 1;
- time_ior->tr_time.tv_micro = 0;
- SendIO (time_ior);
-
- return 1;
- }
- }
- }
-
- return 0;
- }
-
- VOID freetimer()
- {
- if (time_mp)
- {
- if (time_ior)
- {
- AbortIO (time_ior);
- WaitIO (time_ior);
- CloseDevice (time_ior);
- DeleteIORequest ((struct IORequest*) time_ior);
- }
- DeleteMsgPort (time_mp);
- }
- }
-
- VOID WindowMagic (struct Window *win, struct List *list, UWORD items)
- {
- if (win)
- {
- struct RastPort *RP = win->RPort;
- ULONG height,width;
- struct VolumeInfo *vinfo;
- struct TextExtent te;
- int i,j,x,y;
- ULONG free,inuse,percent,total;
- char buf[80], unit1, unit2;
- LONG sigs;
- BOOL waiting = TRUE;
- BYTE dark,light,fill,hilight,backfill;
- struct DrawInfo *dri;
-
- if (win->Flags & WFLG_ZOOMED) return;
-
- if (dri = GetScreenDrawInfo(win->WScreen))
- {
- SetFont(RP,dri->dri_Font);
-
- dark = dri->dri_Pens[SHADOWPEN];
- light = dri->dri_Pens[SHINEPEN];
- fill = dri->dri_Pens[FILLPEN];
- hilight = dri->dri_Pens[TEXTPEN];
- backfill = dri->dri_Pens[BACKGROUNDPEN];
-
- FreeScreenDrawInfo(win->WScreen,dri);
- }
- else // old method...
- {
- dark = 1;
- light = 2;
- fill = 3;
- hilight = 1;
- backfill = 0;
-
- SetFont(RP,win->WScreen->RastPort.Font);
- }
-
- height = (items*RP->TxHeight*3) + win->BorderTop + win->BorderBottom;
- width = (win->Width-(win->BorderLeft+win->BorderRight))/2;
-
- if (win->Height != height)
- {
- ChangeWindowBox(win,win->LeftEdge,win->TopEdge,win->Width,height);
-
- while (waiting)
- {
- sigs = Wait(SIGBREAKF_CTRL_D|(1L << win->UserPort->mp_SigBit));
-
- if (sigs & SIGBREAKF_CTRL_D) waiting = FALSE;
-
- if (sigs & (1L << win->UserPort->mp_SigBit))
- {
- struct IntuiMessage *imsg;
-
- while (imsg = (struct IntuiMessage*) GetMsg(win->UserPort))
- {
- switch (imsg->Class)
- {
- case IDCMP_CHANGEWINDOW:
- waiting = FALSE;
- break;
- default:
- break;
- } // switch
- ReplyMsg((struct Message*)imsg);
- } // while
- } // if WindowSignal
- } // while
- } // if
-
- // a list parser
- i=0;
- for (vinfo = (struct VolumeInfo*)list->lh_Head;vinfo->node.ln_Succ;vinfo=(struct VolumeInfo*)vinfo->node.ln_Succ)
- {
- x = win->BorderLeft+4;
- y = win->BorderTop+i+(RP->TxHeight/2);
-
- SetABPenDrMd(RP,hilight,backfill,JAM2);
- SetSoftStyle(RP,2,7);
- // width is the half window width (minus borders) and each 4 pixels left and right
- Move (RP,x,y+RP->TxBaseline);
- Text (RP,vinfo->name,TextFit(RP,vinfo->name,strlen(vinfo->name)-1,&te,NULL,1,width-8,32737));
- SetAPen(RP,backfill);
- RectFill(RP,RP->cp_x,y,x+width-4,y+RP->TxHeight-1);
-
- x += width; // drift to the right
-
- total = vinfo->data.id_NumBlocks*vinfo->data.id_BytesPerBlock;
- inuse = vinfo->data.id_NumBlocksUsed*vinfo->data.id_BytesPerBlock;
- free = total-inuse;
- percent = (vinfo->data.id_NumBlocksUsed*100)/vinfo->data.id_NumBlocks;
-
- // well, this is ugly; should have used locale.lib ;-(
-
- j=0; unit2 = 'K'; inuse &=~ 0x3ff;
- while (inuse >= 1024)
- {
- inuse /= 1024;
- unit2 = units[j++];
- } // while
- j=0; unit1 = 'K'; free &=~ 0x3ff;
- while (free >= 1024)
- {
- free /= 1024;
- unit1 = units[j++];
- } // while
-
- sprintf(buf,LOCALETEMP,percent,free,unit1,inuse,unit2);
-
- SetABPenDrMd(RP,hilight,backfill,JAM2);
- SetSoftStyle(RP,0,7);
- // width is the half window width (minus borders) and each 4 pixels left and right
- Move (RP,win->BorderLeft+4,y+RP->TxBaseline+4+RP->TxHeight);
- Text (RP,buf,TextFit(RP,buf,strlen(buf),&te,NULL,1,win->Width-(8+win->BorderLeft+win->BorderRight),32737));
-
- SetAPen(RP,backfill);
- RectFill(RP,RP->cp_x,y+4+RP->TxHeight,win->Width-(win->BorderLeft+win->BorderRight),y+4+(2*RP->TxHeight)-1);
-
- SetAPen(RP,dark);
- Move (RP,x+width-8-1,y);
- Draw (RP,x,y);
- Draw (RP,x,y+RP->TxHeight);
- SetAPen(RP,light);
- Move (RP,x+1,y+RP->TxHeight);
- Draw (RP,x+width-8,y+RP->TxHeight);
- Draw (RP,x+width-8,y);
- SetAPen(RP,fill);
- RectFill(RP,x+1,y+1,x+(((width-10)*percent)/100)+1,y+RP->TxHeight-1);
- SetAPen(RP,backfill);
- if ((((width-10)*percent)/100)!=width-10) RectFill(RP,x+(((width-10)*percent)/100)+1,y+1,x+(width-10),y+RP->TxHeight-1);
-
- i += RP->TxHeight*3;
- } // for
- } // if
- }
-
- int main ()
- {
- struct RDArgs *rda;
- VOID *mypool;
- struct Process *proc = (struct Process*) FindTask(NULL);
- APTR old;
-
- old = proc->pr_WindowPtr;
- proc->pr_WindowPtr = -1;
-
- if (rda = ReadArgs(TEMPLATE,(LONG*)&args,NULL))
- {
- struct Screen *scr;
- struct Window *win;
-
- if (!args.quiet) PutStr(
- "*** VolumeWatch 1.1 ***\n"
- "Copyright © 1996 by Daniel Balster\n"
- "All Rights Reserved.\n");
-
-
- if (args.interval) if (!(inittimer())) goto toobad;
-
- // if no pubscreen is given as argument, default is used
- if (scr = LockPubScreen(args.pubscreen))
- {
- zoom[0] = args.Left ? *args.Left : ~0,
- zoom[1] = args.Top ? *args.Top : ~0,
- zoom[2] = args.Width ? *args.Width : scr->Width/5;
- zoom[3] = scr->BarHeight+1;
-
- win = OpenWindowTags(NULL,
- WA_PubScreen , scr,
- WA_Width , args.Width ? *args.Width : scr->Width/5,
- WA_Left , args.Left ? *args.Left : ~0,
- WA_Top , args.Top ? *args.Top : ~0,
- WA_Height , scr->BarHeight+1,
- WA_CloseGadget , TRUE,
- WA_DepthGadget , TRUE,
- WA_DragBar , TRUE,
- WA_RMBTrap , TRUE,
- WA_Zoom , zoom,
- WA_Title , "VolumeWatch",
- WA_IDCMP , IDCMP_CLOSEWINDOW |
- IDCMP_DISKINSERTED |
- IDCMP_MOUSEBUTTONS |
- IDCMP_CHANGEWINDOW |
- IDCMP_DISKREMOVED,
- TAG_DONE);
-
- // we don't need to hold the screen any longer
- UnlockPubScreen(NULL,scr);
-
- if (win)
- {
- if (mypool = CreatePool(MEMF_PUBLIC|MEMF_CLEAR,4096,4096))
- {
- struct List mylist;
- struct DosList *dlist;
- struct VolumeInfo *vinfo;
- BPTR mylock;
- BOOL running = TRUE;
- UWORD entries;
- LONG signals;
-
- while (running)
- {
- NewList(&mylist);
- entries = 0;
-
- dlist = LockDosList(SCANFLAGS);
- while (dlist = NextDosEntry(dlist,SCANFLAGS))
- {
- UBYTE *name = BADDR(dlist->dol_Name);
- ULONG length = (ULONG)name[0];
- BOOL fail = TRUE;
-
- if (vinfo = AllocPooled(mypool,sizeof(*vinfo)))
- {
- if (vinfo->name = AllocPooled(mypool,length+2))
- {
- CopyMem(++name,vinfo->name,length);
- vinfo->name[length] = ':';
-
- if (mylock = Lock(vinfo->name,ACCESS_READ))
- {
- if (Info(mylock,&vinfo->data))
- {
- if (args.nofull)
- {
- if (vinfo->data.id_NumBlocks != vinfo->data.id_NumBlocksUsed)
- {
- AddHead(&mylist,(struct Node*)vinfo);
- entries++;
- fail = FALSE;
- } // if
- } // if
- else
- {
- AddHead(&mylist,(struct Node*)vinfo);
- entries++;
- fail = FALSE;
- } // if..else
- } // if Info
- UnLock(mylock);
- } // if Lock
- if (fail) FreePooled(mypool,vinfo->name,strlen(vinfo->name)+1);
- } // if AllocPooled
- if (fail) FreePooled(mypool,vinfo,sizeof(*vinfo));
- } // if AllocPooled
- } // while NextDosEntry
-
- WindowMagic(win,&mylist,entries);
-
- // cleanup
- while (!IsListEmpty(&mylist))
- {
- if (vinfo = (struct VolumeInfo*) RemHead(&mylist))
- {
- // note: we have added a nonzero character, so the length is now +1, not +2
- if (vinfo->name) FreePooled(mypool,vinfo->name,strlen(vinfo->name)+1);
- FreePooled(mypool,vinfo,sizeof(*vinfo));
- } // if RemHead
- } // while IsListEmpty
-
- UnLockDosList(SCANFLAGS);
-
- signals = Wait(TIMESIGNAL|SIGBREAKF_CTRL_C|(1L << win->UserPort->mp_SigBit));
-
- if (signals & SIGBREAKF_CTRL_C) running = FALSE;
-
- if (!(win->Flags & WFLG_ZOOMED)) if (time_mp) if (signals & TIMESIGNAL)
- {
- time_ior->tr_node.io_Command = TR_ADDREQUEST;
- time_ior->tr_node.io_Flags = IOF_QUICK;
- time_ior->tr_time.tv_secs = *args.interval;
- time_ior->tr_time.tv_micro = 0;
- SendIO (time_ior);
- }
-
- if (signals & (1L << win->UserPort->mp_SigBit))
- {
- struct IntuiMessage *imsg;
-
- while (imsg = (struct IntuiMessage*) GetMsg(win->UserPort))
- {
- switch (imsg->Class)
- {
- case IDCMP_CLOSEWINDOW:
- running = FALSE;
- break;
- // no need
- // case IDCMP_DISKINSERTED:
- // case IDCMP_DISKREMOVED:
- // break;
- default:
- break;
- }
- ReplyMsg((struct Message*)imsg);
- }
- } // if WindowSignal
-
- } // while
- DeletePool(mypool);
- } // if CreatePool
- if (win) CloseWindow (win);
- } // if OpenWindow
- } // if LockPubScreen
-
- toobad:
- freetimer(); // bad style ?
-
- FreeArgs(rda);
- } // if ReadArgs
-
- proc->pr_WindowPtr = old;
-
- return 0;
- }
-