home *** CD-ROM | disk | FTP | other *** search
- /*
-
- FreeSpace - graphically displays free space for each mounted volume
- Copyright 1993 Barry McConnell
- bmccnnll@unix1.tcd.ie
-
- */
-
-
- #include <exec/execbase.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <graphics/gfxbase.h>
- #include <intuition/intuition.h>
- #include <intuition/screens.h>
- #include <graphics/text.h>
- #include <libraries/gadtools.h>
- #include <workbench/startup.h>
- #include <workbench/workbench.h>
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/gadtools.h>
- #include <proto/icon.h>
-
- #include <stdio.h>
- #include <string.h>
-
- #define TEXTLENGTH 36 /* max length of volume statistics */
-
- struct volume /* to store volume data */
- {
- struct volume *next;
- struct volume *prev;
- char *name; /* name of volume */
- char *text; /* statistics in ASCII */
- LONG free, used, percentage;
- };
-
- static UBYTE *version = "$VER: FreeSpace 1.0 (27.08.93)";
- extern struct ExecBase *SysBase;
- UWORD osver = 0; /* Kickstart version */
-
- UWORD __chip waitPointer[] =
- {
- 0x0000, 0x0000,
- 0x0400, 0x07c0,
- 0x0000, 0x07c0,
- 0x0100, 0x0380,
- 0x0000, 0x07e0,
- 0x07c0, 0x1ff8,
- 0x1ff0, 0x3fec,
- 0x3ff8, 0x7fde,
- 0x3ff8, 0x7fbe,
- 0x7ffc, 0xff7f,
- 0x7efc, 0xffff,
- 0x7ffc, 0xffff,
- 0x3ff8, 0x7ffe,
- 0x3ff8, 0x7ffe,
- 0x1ff0, 0x3ffc,
- 0x07c0, 0x1ff8,
- 0x0000, 0x07e0,
- 0x0000, 0x0000,
- };
-
-
- /*
- Display a busy pointer in the current window, and prevent user from
- clicking on any gadgets.
- */
-
- void busyPointer(struct Window *myWindow, struct Requester *myReq)
- {
- InitRequester(myReq);
- Request(myReq, myWindow);
- if (osver < 39)
- SetPointer(myWindow, waitPointer, 16, 16, -6, 0);
- else
- SetWindowPointer(myWindow, WA_BusyPointer, TRUE,
- WA_PointerDelay, TRUE,
- TAG_END);
- }
-
-
- /*
- Restore the pointer to normal.
- */
-
- void normalPointer(struct Window *myWindow, struct Requester *myReq)
- {
- ClearPointer(myWindow);
- EndRequest(myReq, myWindow);
- }
-
-
- /*
- Compare two strings. Like "strcmp" but case-insensitive.
- */
-
- int Compare(char *s, char *t)
- {
- for (; ((*s & ~32) == (*t & ~32)) && *s; s++, t++) /* sorry, K&R ;-) */
- ;
- return (*s & ~32) - (*t & ~32);
- }
-
-
- /*
- Alphabetically insert "node" into "list".
- */
-
- void Sort(struct List *list, struct volume *node)
- {
- struct volume *temp = (struct volume *)list -> lh_Head;
-
- while (temp -> next && Compare(temp -> name, node -> name) < 0)
- temp = temp -> next;
-
- Insert(list, (struct Node *)node, (struct Node *)temp -> prev);
- }
-
-
- void main(int argc, char *argv[])
- {
- struct DiskObject *myIcon;
- struct Screen *myScreen;
- struct Window *myWindow;
- struct Requester tinyReq;
- struct VisualInfo *visInfo;
- struct TextFont *propFont;
- struct TextExtent fontSize;
- struct RastPort myRast, *winRast;
- struct DosList *dl;
- struct InfoData info;
- struct Remember *memoryKey;
- struct List volumeList;
- struct IntuiMessage *message;
- struct volume *volume;
- int maxNameLen = 0, maxTextLen = 0, count = 0, memOkay = TRUE, tempLen,
- winLeft = 0, winTop = 0, winWidth, winHeight, pen = 3, title, gap, rectSize;
- ULONG class, code;
- UWORD height;
- BYTE i,j;
- BPTR lock;
- char **tools, *string, *myName, *name, *dest, freeSuffix, usedSuffix;
-
- struct EasyStruct about =
- {
- sizeof(struct EasyStruct),
- 0,
- "About FreeSpace",
- "FreeSpace v1.0 -- Freely Distributable\nCopyright 1993 Barry McConnell\nbmccnnll@unix1.tcd.ie\n\nDedicated to Niall Murphy :-)",
- "Okay"
- };
-
- IntuitionBase = NULL;
- DOSBase = NULL;
- GfxBase = NULL;
- GadToolsBase = NULL;
- osver = SysBase -> LibNode.lib_Version; /* running under 2.0, 3.0, ...? */
-
- if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37))
- if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))
- if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37))
- if (GadToolsBase = OpenLibrary("gadtools.library", 37))
- if (IconBase = OpenLibrary("icon.library", 37))
- {
- if (!argc) /* only look at ToolTypes if started from Workbench */
- {
- myName = ((struct WBStartup *)argv) -> sm_ArgList -> wa_Name; /* find ourselves */
- if (myIcon = GetDiskObject(myName)); /* read in .info file */
- {
- tools = myIcon -> do_ToolTypes;
- if (string = FindToolType(tools, "LEFT"))
- sscanf(string, "%d", &winLeft);
- if (string = FindToolType(tools, "TOP"))
- sscanf(string, "%d", &winTop);
- if (string = FindToolType(tools, "PEN"))
- sscanf(string, "%d", &pen);
- FreeDiskObject(myIcon);
- }
- }
-
- myScreen = LockPubScreen(NULL); /* get a lock on the Workbench screen */
- visInfo = GetVisualInfo(myScreen, TAG_END); /* GadTools needs this */
- propFont = OpenFont(myScreen -> Font);
- FontExtent(propFont, &fontSize); /* figure out pixel size of fonts */
- height = fontSize.te_Height;
-
- InitRastPort(&myRast); /* dummy RastPort for getting string lengths */
- SetFont(&myRast, propFont);
-
- memoryKey = NULL;
- volumeList.lh_Head = (struct Node *)&volumeList.lh_Tail;
- volumeList.lh_Tail = NULL;
- volumeList.lh_TailPred = (struct Node *)&volumeList.lh_Head;
-
- dl = LockDosList(LDF_VOLUMES | LDF_READ);
- while ((dl = NextDosEntry(dl, LDF_VOLUMES)) && memOkay) /* walk through list of volumes */
- {
- if ((volume = AllocRemember(&memoryKey, sizeof(struct volume), MEMF_ANY))
- && (volume -> text = AllocRemember(&memoryKey, TEXTLENGTH, MEMF_ANY)))
- {
- name = (char *)BADDR(dl -> dol_Name); /* BCPL string */
- i = *((BYTE *)name); /* length */
- dest = volume -> name = AllocRemember(&memoryKey, i+2, MEMF_ANY);
- for (j = 1; i; i--)
- *(dest++) = name[j++];
- *(dest++) = ':';
- *(dest) = 0;
-
- lock = Lock(volume -> name, ACCESS_READ); /* get a lock on this volume */
- *(--dest) = 0; /* remove trailing colon */
-
- Info(lock, &info);
- freeSuffix = usedSuffix = 'K'; /* default */
- volume -> free = (info.id_NumBlocks - info.id_NumBlocksUsed) * info.id_BytesPerBlock / 1024;
- volume -> used = info.id_NumBlocksUsed * info.id_BytesPerBlock / 1024;
- volume -> percentage = info.id_NumBlocksUsed * 100 / info.id_NumBlocks;
- if (volume -> free > 9999)
- {
- volume -> free = volume -> free / 1024; /* move up to MB */
- freeSuffix = 'M';
- }
- if (volume -> used > 9999)
- {
- volume -> used = volume -> used / 1024;
- usedSuffix = 'M';
- }
- sprintf(volume -> text, "%d%% full, %d%c free, %d%c in use", volume -> percentage, volume -> free, freeSuffix, volume -> used, usedSuffix);
-
- SetSoftStyle(&myRast, FSF_BOLD, FSF_BOLD);
- tempLen = TextLength(&myRast, volume -> name, j-1);
- if (maxNameLen < tempLen)
- maxNameLen = tempLen;
- SetSoftStyle(&myRast, NULL, FSF_BOLD); /* turn off bold */
- tempLen = TextLength(&myRast, volume -> text, strlen(volume -> text));
- if (maxTextLen < tempLen)
- maxTextLen = tempLen;
-
- Sort(&volumeList, volume);
- UnLock(lock);
- count++;
- }
- else
- memOkay = FALSE;
- }
- UnLockDosList(LDF_VOLUMES | LDF_READ);
-
- if (memOkay)
- {
- title = (myScreen -> WBorTop) + height + 1 + INTERHEIGHT;
- gap = title + propFont -> tf_Baseline;
- winWidth = INTERWIDTH*2 + maxTextLen;
- winHeight = title + count * (height*2 + INTERHEIGHT*3) - INTERHEIGHT + 2; /* allow a couple of pixels for the comma */
-
- if (myWindow = OpenWindowTags(NULL, WA_Title, "FreeSpace",
- WA_Left, winLeft,
- WA_Top, winTop,
- WA_Width, winWidth,
- WA_Height, winHeight,
- WA_DragBar, TRUE,
- WA_DepthGadget, TRUE,
- WA_CloseGadget, TRUE,
- WA_Activate, TRUE,
- WA_RMBTrap, TRUE,
- WA_IDCMP, IDCMP_CLOSEWINDOW | RAWKEY,
- WA_PubScreen, myScreen,
- TAG_END))
- {
- volume = (struct volume *)volumeList.lh_Head;
- winRast = myWindow -> RPort;
- SetFont(winRast, propFont); /* defaults to GfxBase -> DefaultFont, which is not what we want */
-
- for (i = 0; i < count; volume = volume -> next, i++)
- {
- SetAPen(winRast, 1); /* black */
- Move(winRast, INTERWIDTH, gap + i * (height*2 + INTERHEIGHT*3));
- SetSoftStyle(winRast, FSF_BOLD, FSF_BOLD);
- Text(winRast, volume -> name, strlen(volume -> name));
- Move(winRast, INTERWIDTH, gap + height + INTERHEIGHT + i * (height*2 + INTERHEIGHT*3));
- SetSoftStyle(winRast, NULL, FSF_BOLD);
- Text(winRast, volume -> text, strlen(volume -> text));
- DrawBevelBox(winRast, (INTERWIDTH*3) / 2 + maxNameLen, title + i * (height*2 + INTERHEIGHT*3),
- winWidth - maxNameLen - (INTERWIDTH*5) / 2, height,
- GTBB_Recessed, TRUE,
- GT_VisualInfo, visInfo,
- TAG_END);
- SetAPen(winRast, pen); /* pen to fill with (user's choice) */
- rectSize = winWidth - maxNameLen - INTERWIDTH*3;
- rectSize = (rectSize * volume -> percentage) / 100;
- RectFill(winRast, (INTERWIDTH*3) / 2 + maxNameLen + 2, title + i * (height*2 + INTERHEIGHT*3) + 1,
- (INTERWIDTH*3) / 2 + maxNameLen + 1 + rectSize, title + i * (height*2 + INTERHEIGHT*3) + height - 2);
- }
-
- do
- {
- WaitPort(myWindow -> UserPort);
- if (message = (struct IntuiMessage *)GetMsg(myWindow -> UserPort))
- class = message -> Class, code = message -> Code;
- ReplyMsg((struct Message *)message);
- if (class == RAWKEY && code == 95) /* Help key */
- {
- busyPointer(myWindow, &tinyReq);
- EasyRequest(NULL, &about, NULL, NULL);
- normalPointer(myWindow, &tinyReq);
- }
- }
- while (!(class == IDCMP_CLOSEWINDOW));
-
- CloseWindow(myWindow);
- }
- }
- FreeRemember(&memoryKey, TRUE);
- CloseFont(propFont);
- FreeVisualInfo(visInfo);
- UnlockPubScreen(NULL, myScreen);
- }
- CloseLibrary(GadToolsBase); /* safe to pass NULL */
- CloseLibrary((struct Library *)GfxBase);
- CloseLibrary((struct Library *)DOSBase);
- CloseLibrary((struct Library *)IntuitionBase);
- }
-