/* * Article 810 of net.micro.amiga: * ion: version B 2.10.2 9/17/84 chuqui version 1.9 3/12/85; site unisoft.UUCP * Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site caip.RUTGERS.EDU * Path: unisoft!lll-lcc!lll-crg!seismo!caip!louie * From: louie@trantor.UMD.EDU * Newsgroups: net.micro.amiga * Subject: GfxMem.c - graphical memory usage (New Version) * Message-ID: <592@caip.RUTGERS.EDU> * Date: 28 Nov 85 22:19:27 GMT * Date-Received: 29 Nov 85 02:20:45 GMT * Sender: daemon@caip.RUTGERS.EDU * Organization: Rutgers Univ., New Brunswick, N.J. * Lines: 377 * */ /* * From: Louis A. Mamakos * * Here's a new and much improved version of my GfxMem.c program. It has been * heavily revised since the last version that was distributed over the * info-amiga@red.rutgers.edu mailing list and net.micro.amiga newsgroup. The * display updating is now much more crisp, and I'm now using the timer.device * rather than the AmigaDOS Delay() subroutine. There was a note that the * previous version could trash a disk while running the READ program. I * tested the new version while downloading a copy of GfxMem.c (to make sure * it got to our VAX ok), and things seemed to run just fine. Just compile * with the Lattice C compiler and go. You should see two compilation warnings; * these can be ignored. * * **** Soapbox time **** * As one of the few folks that posted any amiga programs so far, let me cast * my vote to SOURCE POSTINGS of programs rather than BINHEXed versions. We * can learn a lot from each other, and hopefully avoid making the same * stupid errors or inventing the same wheels over and over again. * **** End Soapbox **** * * The program displays two bar graphics, one for "CHIP" memory, and one for * "FAST" memory. Each bar graph is split into two colors; part for memory in * use and part for memory free. As the window is resized, the graphics are * rescaled to the sized of the window. If you find any bugs or have any * neat features that you'd like to see, let me know. * * Louis A. Mamakos WA3YMH Internet: louie@TRANTOR.UMD.EDU * University of Maryland, Computer Science Center - Systems Programming * * Anyway, here it is: */ /* * gfxmem.c - graphically display available memory. Quick program * that's a freebie. Give it to anyone you please, just don't sell it. * * Version 0.0 - initial version, released on INFO-AMIGA. * Version 0.1 - added numeric indication of available and used memory * in bar graphs. * Version 0.2 - added condition compilation for timer.device code. If * I can figure out how to make it create timer signals, * then I can define USE_TIMER for much more prompt * response to window sizing attempts. Oh well. * Version 0.3 - removed conditional compilation for timer.device * code. We now use the timer, and all seems well. * Version 0.4 - calculate character data placement according to * display preferences. Check for updated preferences * while running. * TODO: * Add menu selection package to display Kbytes or percent of memory * used and free. * * Add requestor to display statistics like min and max for free and * avail, time running, etc.. * * * Copyright (C) 1985, * Louis A. Mamakos * Software & Stuff */ #define PROG_VER "GfxMem 0.4 " #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern struct ExecBase *SysBase; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct MsgPort *timerport, *CreatePort(); struct timerequest timereq; struct NewWindow NewWindow = { 10, 10, 450, 50, /* sizes */ -1, -1, /* pens */ CLOSEWINDOW | ACTIVEWINDOW | SIZEVERIFY | NEWSIZE | NEWPREFS | REFRESHWINDOW, /* IDCMP flags */ WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | WINDOWSIZING | SIMPLE_REFRESH, NULL, NULL, /* gadget, checkmark */ PROG_VER, /* title */ NULL, NULL, /* screen, bitmap */ 100, 30, 640, 100, /* min and max sizing */ WBENCHSCREEN /* on the workbench screen */ }; ULONG AvailMem (); ULONG ChipMax, FastMax, ChipFree, FastFree; ULONG ChipLargest, FastLargest; int dont_draw, char_size; /* * maxsize -- determine the total maximum size for all regions * of the given type. This code must be executed while * FORBIDDEN (it accesses shared system structures). */ ULONG maxsize (t) unsigned long t; { /* THIS CODE MUST ALWAYS BE CALLED WHILE FORBIDDEN */ ULONG size = 0; struct MemHeader *mem; struct ExecBase *eb = SysBase; for (mem = (struct MemHeader *) eb->MemList.lh_Head; mem->mh_Node.ln_Succ; mem = mem->mh_Node.ln_Succ) if (mem -> mh_Attributes & t) size += ((ULONG) mem->mh_Upper - (ULONG) mem->mh_Lower); return size; } getsizes() { if (ChipMax == 0) { /* only do this once */ Forbid (); ChipMax = maxsize (MEMF_CHIP); FastMax = maxsize (MEMF_FAST); Permit(); } ChipFree = AvailMem (MEMF_CHIP); ChipLargest = AvailMem (MEMF_CHIP | MEMF_LARGEST); FastFree = AvailMem (MEMF_FAST); FastLargest = AvailMem (MEMF_FAST | MEMF_LARGEST); } starttimer() { timereq.tr_time.tv_secs = 1; timereq.tr_time.tv_micro = 0; timereq.tr_node.io_Command = TR_ADDREQUEST; timereq.tr_node.io_Flags = 0; timereq.tr_node.io_Error = 0; timereq.tr_node.io_Message.mn_ReplyPort = timerport; SendIO((char *) &timereq.tr_node); } /* * This function is called during startup and when new preferences are * selected. Get the font size from the Preferences structure. */ newprefs() { char FontHeight; GetPrefs(&FontHeight, sizeof (FontHeight)); switch (FontHeight) { case TOPAZ_SIXTY: char_size = 11; break; case TOPAZ_EIGHTY: char_size = 8; break; default: char_size = 12; } } /* * Main function. Call intution to create a new window for us on the * screen. Go from there. */ main(argc, argv) int argc; char **argv; { struct Window *w; struct IntuiMessage *msg, *GetMsg(); int waitmask; timerport = NULL; IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0); if (IntuitionBase == NULL) exit(1); GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0); if (GfxBase == NULL) { CloseLibrary(IntuitionBase); exit(2); } if ((w = (struct Window *) OpenWindow(&NewWindow)) == NULL) { CloseLibrary(GfxBase); CloseLibrary(IntuitionBase); exit(3); } if ((timerport = CreatePort("Timer Port", 0)) == NULL) { CloseWindow(w); CloseLibrary(GfxBase); CloseLibrary(IntuitionBase); exit(5); } if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &timereq, 0) != 0) { DeletePort(timerport); CloseWindow(w); CloseLibrary(GfxBase); CloseLibrary(IntuitionBase); exit(4); } newprefs(); redraw(w, TRUE); starttimer(); waitmask = (1 << w->UserPort->mp_SigBit) | (1 << timerport->mp_SigBit); for(;;) { Wait(waitmask); while (msg = GetMsg(w->UserPort)) { switch (msg->Class) { case CLOSEWINDOW: ReplyMsg(msg); AbortIO(&timereq); CloseDevice(&timereq); DeletePort(timerport); CloseWindow(w); CloseLibrary(GfxBase); CloseLibrary(IntuitionBase); exit(0); case REFRESHWINDOW: BeginRefresh(w); dont_draw = 0; redraw(w, TRUE); EndRefresh(w, TRUE); case ACTIVEWINDOW: /* when window is active, display version */ SetWindowTitles(w, -1, "Graphical memory display by Louis A. Mamakos"); break; case NEWSIZE: dont_draw = 0; redraw(w, TRUE); break; case SIZEVERIFY: dont_draw = 1; break; case NEWPREFS: newprefs(); redraw(w, TRUE); break; } ReplyMsg(msg); } /* while */ if (GetMsg(timerport)) { redraw(w, FALSE); starttimer(); } } /* for */ } #define TOP w->BorderTop #define BOTTOM w->Height - w->BorderBottom #define LEFT w->BorderLeft #define RIGHT w->Width - w->BorderRight #define GUTTER 3 /* pixels of veritical spacing between bars */ /* * Redraw all of the stuff in the window. */ redraw(w, refresh) struct Window *w; int refresh; { register struct RastPort *rp = w->RPort; register short x_min, y_min, x_max, y_max; static short AvailWidth, AvailHeight, HorizSpace, Thickness, Scale; static long old_chipfree, old_fastfree; char txt[10]; if (dont_draw) return 0; getsizes(); if (refresh) { SetAPen(rp, 2); SetBPen(rp, 2); SetOPen(rp, 2); RectFill(rp, LEFT, TOP, RIGHT, BOTTOM); /* recalculate the spacing paramters for this sized window */ AvailWidth = w->Width - w->BorderRight - w->BorderLeft; AvailHeight = w->Height - w->BorderTop - w->BorderBottom; HorizSpace = AvailWidth/20; /* use 5% of available space as margin */ AvailWidth -= HorizSpace * 2; Thickness = (AvailHeight - GUTTER*3) / 2; if (ChipMax > FastMax) Scale = ChipMax/AvailWidth; else Scale = FastMax/AvailWidth; } else if (old_chipfree == ChipFree && old_fastfree == FastFree) return 0; old_chipfree = ChipFree; old_fastfree = FastFree; SetAPen(rp, 3); SetOPen(rp, 1); SetBPen(rp, 2); x_min = HorizSpace; y_min = TOP + GUTTER; x_max = x_min + (ChipMax - ChipFree)/Scale; y_max = y_min + Thickness; RectFill(rp, x_min, y_min, x_max, y_max); if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) { sprintf(txt, "%4dK", (ChipMax - ChipFree) >> 10); SetAPen(rp, 1); SetBPen(rp, 3); Move(rp, x_max - 5*char_size - 6, y_min + Thickness/2 + 3); Text(rp, txt, 5); } x_min = x_max; x_max = x_min + ChipFree/Scale; SetAPen(rp, 0); RectFill(rp, x_min, y_min, x_max, y_max); if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) { sprintf(txt, "%4dK", ChipFree>>10); SetAPen(rp, 1); SetBPen(rp, 0); Move(rp,x_min + 5, y_min + Thickness/2 + 3); Text(rp, txt, 5); } if ((HorizSpace > char_size + 5) && Thickness > char_size + 1) { SetAPen(rp, 1); SetBPen(rp, 2); Move(rp, HorizSpace - char_size - 1, y_min + Thickness/2 + 4); Text(rp, "C", 1); } x_min = HorizSpace; x_max = x_min + (FastMax - FastFree)/Scale; y_min = y_max + GUTTER; y_max = y_min + Thickness; SetAPen(rp, 3); RectFill(rp, x_min, y_min, x_max, y_max); if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) { sprintf(txt, "%4dK", (FastMax - FastFree) >> 10); SetAPen(rp, 1); SetBPen(rp, 3); Move(rp, x_max - 5*char_size - 6, y_min + Thickness/2 + 3); Text(rp, txt, 5); } x_min = x_max; x_max = x_min + FastFree/Scale; SetAPen(rp, 0); RectFill(rp, x_min, y_min, x_max, y_max); if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) { sprintf(txt, "%4dK", FastFree>>10); SetAPen(rp, 1); SetBPen(rp, 0); Move(rp,x_min + 5, y_min + Thickness/2 + 3); Text(rp, txt, 5); } if ((HorizSpace > char_size + 5) && Thickness > char_size + 1) { SetAPen(rp, 1); SetBPen(rp, 2); Move(rp, HorizSpace - char_size - 1, y_min + Thickness/2 + 3); Text(rp, "F", 1); } }