/* VolumeWatch ----------- whooa! again a 2 hours production ;-) - should have been used BOOPSI objects for the frames Copyright ©1996 by Daniel Balster. Freeware! */ #include #include #include #include #include #include #include #include #include #include #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<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; }