jvkelley@watcgl.waterloo.edu (Jeff Kelley) (10/30/87)
Attempts to post via comp.{sources,binaries}.amiga were unsuccessful. Briefly, this is somewhat like 'xload' for those familiar with the X Window System, but with Amiga specific features. The program is divided into two components: a 'virtual' device that monitors the use of the CPU (really the ready queue length), the Blitter, and memory, and the 'amyload' program which graphically displays this information. While I'm here, I might as well ask a couple of questions: 1) Why is there an 'added' state for tasks? Why isn't a created task in the 'ready' state? This burned me once when I was expecting a newly created task to preempt its lower priority creator. 2) When a SIMPLE_REFRESH window is moved without exposing previously obscured areas of the window, why doesn't Intuition simply copy the rectangular area to the new location, instead of sending REFRESHWINDOW events to the application? Thanks, and enjoy! -Jeff Kelley -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- UUCP: {ihnp4,watmath}!watcgl!jvkelley | Postal Address: BITNET: jvkelley@cgl.waterloo.bitnet | Jeff Kelley INTERNET: jvkelley@cgl.waterloo.edu | Dept. of Computer Science EAN: jvkelley@cgl.waterloo.cdn | University of Waterloo | Waterloo, Ont., Canada | N2L 3G1 | tel: (519) 578-4514 # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by watcgl!jvkelley on Sat Oct 17 20:16:30 EDT 1987 # Contents: README amyload.doc makefile execdef.h intuidef.h # loadrecord.h windowinfo.h windownode.h amyload.c cleanup.c # closeloadwindow.c drawdataline.c drawreflines.c findmxdatapoint.c # findwindownode.c init.c newdata.c newloadrecord.c newscale.c # newwindowsize.c openloadwindow.c printmessage.c printrecordtype.c # redrawwindow.c scrollwindow.c setwindowinfo.c cleanup.proto # closeloadwindow.proto drawdataline.proto drawscalereferencelines.proto # findmaxdatapoint.proto findwindownode.proto init.proto newdata.proto # newloadrecord.proto newscale.proto newwindowsize.proto # openloadwindow.proto printmessage.proto printrecordtypes.proto # redrawwindow.proto scrollwindow.proto setwindowinfo.proto echo x - README sed 's/^@//' > "README" <<'@//E*O*F README//' Read amyload.doc for documentation. Remember that load.device must be in your DEVS: directory. @//E*O*F README// chmod u=rw,g=r,o=r README echo x - amyload.doc sed 's/^@//' > "amyload.doc" <<'@//E*O*F amyload.doc//' NAME Amyload - graphically monitor Amiga CPU, blitter, and memory usage SYNOPSIS amyload [options] [ '{' [window options] [ '[' [record options] ']' ] ... '}' ] ... DESCRIPTION Amyload is a program which graphically displays information about current CPU, blitter, and memory usage of the Amiga. This information is displayed in one or more windows, each of which may display information about the usage of any or all of the following: CPU usage - The average length of the ready queue over the last n seconds (a settable time interval). When greater than 1, horizontal lines are drawn to reflect a change in the scale that CPU usage is being displayed in. Blitter usage - The fraction of time during the last interval that the blitter was in use. Chip memory usage - The fraction of chip memory in use. Fast memory usage - The fraction of fast memory in use. Both chip and fast memory usage - The combination of both above. Options: (spaces are ignored except between an option requiring an integer parameter, where there had better not be any) i<n> Set the time interval between updates to n seconds. Default is the current setting of load.device, which begins at 5 seconds, but may have been changed. t<n> Set the number of ticks per interval (at which samples of CPU and blitter usage are taken) to n. Default is the current setting of the load.device, which begins at 61. The interval time divided by the number of ticks should form an irregular number, so as to try to avoid aliasing problems. (e.g. 1 second / 10 ticks is probably a bad idea, because the device might get 'in sync' with some other task, and that would distort the results.) p<n> Set the priority of the measuring task to n. It should be higher than any tasks it is trying to measure. Default is the current setting of the load.device, which begins at 25. Following the options selection, window specifications may be given. They are introduced by the '{' character, and terminated by the '}' character. Window Options: =[WIDTH][xHEIGHT][{+-}XOFF[{+-}YOFF]] (similar to an X geometry specification) The '=' character introduces the specification. WIDTH and HEIGHT specify the WIDTH and HEIGHT of the window. XOFF and YOFF specify the position of the window relative to the screen's borders, the '+' or '-' characters indicating a position relative to the left or right border respectively of the screen in the case of XOFF, or top or bottom in the case of YOFF. Distances are measured between the screen's border and the nearest window edge, so the window can be placed in the lower right corner with specifications of -0-0 for XOFF and YOFF. No spaces are allowed within the geometry specification. d<n> Set the window's detail pen color to n. b<n> Set the window's block pen number to n. g<n> Set the background pen number for the window to n. After window options have been specified, one or more record descriptions may be specified. These are introduced with the '[' character, and terminated by the ']' character. The records specified earlier will have their data lines drawn on top of records specified later (first to last == foreground to background). Record Options: C This record will display CPU usage (really ready queue length). This is the default record type. b This record will display blitter usage. c This record will display chip memory usage. f This record will display fast memory usage. m This record will display all memory usage. d<n> Data lines for this record will be drawn with pen n. r<n> References lines (drawn when scaling) will be drawn with pen n. This is irrelevant unless the record is displaying CPU usage. Note that reference lines will be drawn behind all records, regardless of ordering, except that they will be drawn on top of the scaled record's data lines. Note that load.device MUST be in your DEVS: directory (or already loaded into the system). USER INTERFACE Standard system gadgets are present but invisible (except for the drag bar, see BUGS). The menu button causes the types of the records in the windows to be printed in the color of their data lines. EXAMPLES amyload - use the default setup amyload {[C]} - open a single window monitoring CPU usage amyload {=200x200-0-0[C]} - as above, but make the window 200 by 200 and put it in the lower right hand corner of the screen. amyload {[bd2][Cd3]}{[cd3][fd2]} - open one window displaying blitter usage in the foreground using pen 2 for drawing data lines, and CPU usage in the background using pen 3 for data lines and the default pen for scale reference lines. Open a second window with chip memory usage in the foreground using pen 3 for data lines, and fast memory usage in the background using pen 2 for data lines. DIAGNOSTICS Error numbers are returned, rather than a messages, to avoid DOS. Error numbers are: 1 - "Can't open graphics library" 2 - "Can't open intuition library" 3 - "Can't create message port" 4 - "Can't create IO request" 5 - "Can't open load device" 6 - "Can't open window" 7 - "Can't create load record" 8 - "Unexpected end of record description" 9 - "Unexpected end of window description" 10 - "Bad record flag" 11 - "Bad window flag" 12 - "Bad flag" BUGS When the window is activated/deactivated, the not so invisible drag bar is still drawn/masked. Can't seem to figure out how to avoid this. Doesn't do enough checking of options. May crash if bad ones are given, especially zeroes in the wrong places. Doesn't do a 3D representation, yet... There is a bug in the data line drawing procedure (I think it's in there, anyway) that causes scale lines to not be drawn over data lines that are just heigher than the scale line. Should use cback.o, so you don't have to 'run' it, but I haven't looked into that yet. Isn't Intuition friendly. Application gadget and menu support should be added to allow configuration after startup. SEE ALSO devices/load.doc AUTHOR Jeff Kelley Dept. of Computer Science University of Waterloo Waterloo, Ontario, Canada N2L 3G1 Voice: (519)-578-4514 UUCP: {ihnp4,watmath}!watcgl!jvkelley BITNET: jvkelley@cgl.waterloo.bitnet INTERNET: jvkelley@cgl.waterloo.edu EAN: jvkelley@cgl.waterloo.cdn Comments, suggestions, bug reports welcome. ACKNOWLEDGEMENTS Amyload was inspired by the 'xload' program for UN*X workstations running the X Window System, and, to a lesser extent, by 'pm' for the Amiga. Thanks to Matt Dillon for Dme, the Software Distillery for blink, Comspec for getting a 2M RAM expansion to me quickly (NACK to the <unnamed> company whose lies about delivery dates delayed this project by a couple months), everyone on USENET, and the visionaries who created the Amiga. @//E*O*F amyload.doc// chmod u=rw,g=r,o=r amyload.doc echo x - makefile sed 's/^@//' > "makefile" <<'@//E*O*F makefile//' CC = lc CFLAGS = -b -r -v PROG = amyload SRCS = \ amyload.c\ init.c\ cleanup.c\ closeloadwindow.c\ openloadwindow.c\ newdata.c\ scrollwindow.c\ newloadrecord.c\ newscale.c\ findmxdatapoint.c\ drawreflines.c\ newwindowsize.c\ setwindowinfo.c\ drawdataline.c\ redrawwindow.c\ printmessage.c\ printrecordtype.c\ findwindownode.c OBJS = lib:c.o\ amyload.o\ init.o\ cleanup.o\ closeloadwindow.o\ openloadwindow.o\ newdata.o\ scrollwindow.o\ newloadrecord.o\ newscale.o\ findmxdatapoint.o\ drawreflines.o\ newwindowsize.o\ setwindowinfo.o\ drawdataline.o\ redrawwindow.o\ printmessage.o\ printrecordtype.o\ findwindownode.o $(PROG): $(OBJS) blink FROM $(OBJS) TO $(PROG) LIB lib:lc.lib+lib:amiga.lib amyload.o: amyload.c intuidef.h execdef.h\ cleanup.proto init.proto newdata.proto newwindowsize.proto\ redrawwindow.proto closeloadwindow.proto findwindownode.proto $(CC) $(CFLAGS) amyload.c cleanup.o: cleanup.c cleanup.proto\ closeloadwindow.proto\ execdef.h intuidef.h windownode.h $(CC) $(CFLAGS) cleanup.c closeloadwindow.o: closeloadwindow.c closeloadwindow.proto\ execdef.h intuidef.h windownode.h windowinfo.h loadrecord.h $(CC) $(CFLAGS) closeloadwindow.c drawdataline.o: drawdataline.c drawdataline.proto\ execdef.h intuidef.h loadrecord.h windowinfo.h $(CC) $(CFLAGS) drawdataline.c drawreflines.o: drawreflines.c drawscalereferencelines.proto\ execdef.h intuidef.h loadrecord.h windowinfo.h $(CC) $(CFLAGS) drawreflines.c findmxdatapoint.o: findmxdatapoint.c findmaxdatapoint.proto\ execdef.h loadrecord.h $(CC) $(CFLAGS) findmxdatapoint.c findwindownode.o: findwindownode.c findwindownode.proto\ execdef.h intuidef.h windownode.h $(CC) $(CFLAGS) findwindownode.c init.o: init.c init.proto\ openloadwindow.proto newloadrecord.proto\ execdef.h error.h windownode.h windowinfo.h loadrecord.h $(CC) $(CFLAGS) init.c newdata.o: newdata.c newdata.proto\ scrollwindow.proto newscale.proto redrawwindow.proto drawdataline.proto\ execdef.h intuidef.h loadrecord.h windownode.h windowinfo.h $(CC) $(CFLAGS) newdata.c newloadrecord.o: newloadrecord.c newloadrecord.proto\ execdef.h windowinfo.h loadrecord.h $(CC) $(CFLAGS) newloadrecord.c newscale.o: newscale.c newscale.proto\ execdef.h loadrecord.h windowinfo.h $(CC) $(CFLAGS) newscale.c newwindowsize.o: newwindowsize.c newwindowsize.proto\ setwindowinfo.proto findmaxdatapoint.proto redrawwindow.proto\ execdef.h intuidef.h windowinfo.h loadrecord.h $(CC) $(CFLAGS) newwindowsize.c openloadwindow.o: openloadwindow.c openloadwindow.proto\ setwindowinfo.proto\ execdef.h intuidef.h windownode.h windowinfo.h $(CC) $(CFLAGS) openloadwindow.c printmessage.o: printmessage.c printmessage.proto\ execdef.h intuidef.h windowinfo.h printrecordtype.o: printrecordtype.c printrecordtypes.proto\ printmessage.proto\ execdef.h intuidef.h windowinfo.h loadrecord.h redrawwindow.o: redrawwindow.c redrawwindow.proto\ drawscalereferencelines.proto drawdataline.proto\ execdef.h intuidef.h windowinfo.h loadrecord.h $(CC) $(CFLAGS) redrawwindow.c scrollwindow.o: scrollwindow.c scrollwindow.proto\ findmaxdatapoint.proto newscale.proto drawscalereferencelines.proto redrawwindow.proto\ execdef.h intuidef.h windowinfo.h loadrecord.h $(CC) $(CFLAGS) scrollwindow.c setwindowinfo.o: setwindowinfo.c setwindowinfo.proto\ execdef.h intuidef.h windowinfo.h $(CC) $(CFLAGS) setwindowinfo.c @//E*O*F makefile// chmod u=rw,g=r,o=r makefile echo x - execdef.h sed 's/^@//' > "execdef.h" <<'@//E*O*F execdef.h//' #undef TRUE #undef FALSE typedef char Bool; #define TRUE (Bool)1 #define FALSE (Bool)0 typedef struct MinNode MinNode; typedef struct MinList MinList; typedef struct MsgPort MsgPort; typedef struct IORequest IORequest; typedef struct Library Library; @//E*O*F execdef.h// chmod u=rw,g=r,o=r execdef.h echo x - intuidef.h sed 's/^@//' > "intuidef.h" <<'@//E*O*F intuidef.h//' typedef struct Window Window; typedef struct NewWindow NewWindow; typedef struct IntuiMessage IntuiMessage; typedef struct RastPort RastPort; typedef struct Gadget Gadget; @//E*O*F intuidef.h// chmod u=rw,g=r,o=r intuidef.h echo x - loadrecord.h sed 's/^@//' > "loadrecord.h" <<'@//E*O*F loadrecord.h//' #define CPU 0 #define BLITTER 1 #define CHIPMEM 2 #define FASTMEM 3 #define ALLMEM 4 typedef long LoadDataValue; typedef struct { MinNode node; LoadDataValue *start_data; /* (fixed) Beginning of data array. */ LoadDataValue *end_data; /* (fixed) End of data array. */ LoadDataValue *next_data; /* Where next data will go. */ LoadDataValue *max_data; /* Where the max data value is. */ short scale; long scaled_ticks; short deltay; short moduloy; unsigned char type; /* CPU, Blitter, Memory, Chip, Fast */ unsigned char data_pen_num; unsigned char ref_pen_num; } LoadRecord; @//E*O*F loadrecord.h// chmod u=rw,g=r,o=r loadrecord.h echo x - windowinfo.h sed 's/^@//' > "windowinfo.h" <<'@//E*O*F windowinfo.h//' #define BORDERWIDTH 2 #define BORDERHEIGHT 1 #define WINDOWINFO(window) ((WindowInfo *)window->UserData) typedef struct { MinList loadrecords; short leftedge; short rightedge; short width; short topedge; short bottomedge; short height; unsigned char back_pen_num; } WindowInfo; @//E*O*F windowinfo.h// chmod u=rw,g=r,o=r windowinfo.h echo x - windownode.h sed 's/^@//' > "windownode.h" <<'@//E*O*F windownode.h//' #define REFPENNUM 1 #define LOADPENNUM 3 #define BACKPENNUM 0 typedef struct { MinNode node; Window *window; } WindowNode; @//E*O*F windownode.h// chmod u=rw,g=r,o=r windownode.h echo x - amyload.c sed 's/^@//' > "amyload.c" <<'@//E*O*F amyload.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "intuidef.h" #include "execdef.h" #include "windownode.h" #include <exec/proto.h> #include <intuition/proto.h> #include "Cleanup.proto" #include "Init.proto" #include "NewData.proto" #include "NewWindowSize.proto" #include "RedrawWindow.proto" #include "CloseLoadWindow.proto" #include "FindWindowNode.proto" #include "PrintRecordTypes.proto" #define SIGQUIT 12 struct Library *GfxBase; struct IntuitionBase *IntuitionBase; loadrequest *loadRequest; MsgPort *loadPort; MsgPort *windowPort; MinList windowList; void _main(argp) char *argp; { IntuiMessage *msg; Window *message_window; unsigned long message_class; unsigned short message_code; long signals, window_signal_mask, load_signal_mask, combined_signal_mask; long quit_signal_mask; long errno; if (errno = Init(argp)) { Cleanup(); exit(errno); } quit_signal_mask = 1 << SIGQUIT; window_signal_mask = 1 << windowPort->mp_SigBit; load_signal_mask = 1 << loadPort->mp_SigBit; combined_signal_mask = quit_signal_mask | window_signal_mask | load_signal_mask; loadRequest->lr_node.io_Command = CMD_READ; SendIO(&loadRequest->lr_node); while(windowList.mlh_TailPred != (MinNode *)&windowList) { signals = Wait(combined_signal_mask); if (signals & window_signal_mask) { while (msg = (struct IntuiMessage *)GetMsg(windowPort)) { message_window = msg->IDCMPWindow; message_class = msg->Class; message_code = msg->Code; ReplyMsg(msg); switch(message_class) { case MOUSEBUTTONS: if (msg->Code == MENUDOWN) PrintRecordTypes(message_window); break; case CLOSEWINDOW: CloseLoadWindow(FindWindowNode(message_window)); break; case NEWSIZE: if (!NewWindowSize(message_window)) goto bug_out; break; case REFRESHWINDOW: BeginRefresh(message_window); RedrawWindow(message_window); EndRefresh(message_window, TRUE); break; } } } if (signals & load_signal_mask) { (void)GetMsg(loadPort); NewData(&loadRequest->lr_load); SendIO(&loadRequest->lr_node); } if (signals & quit_signal_mask) break; } bug_out: AbortIO(&loadRequest->lr_node); Cleanup(); } @//E*O*F amyload.c// chmod u=rw,g=r,o=r amyload.c echo x - cleanup.c sed 's/^@//' > "cleanup.c" <<'@//E*O*F cleanup.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "execdef.h" #include "intuidef.h" #include "windownode.h" #include "Cleanup.proto" #include <exec/proto.h> #include "CloseLoadWindow.proto" extern Library *GfxBase; extern struct IntuitionBase *IntuitionBase; extern MinList windowList; extern MsgPort *windowPort; extern MsgPort *loadPort; extern loadrequest *loadRequest; void Cleanup() { WindowNode *windownode, *oldwindownode; for (windownode = (WindowNode *)windowList.mlh_Head; windownode->node.mln_Succ; ) { oldwindownode = windownode; windownode = (WindowNode *)windownode->node.mln_Succ; CloseLoadWindow(oldwindownode); } if (loadRequest) { if (loadRequest->lr_node.io_Device) CloseDevice((IORequest *)loadRequest); DeleteExtIO((IORequest *)loadRequest, sizeof(loadrequest)); } if (loadPort) DeletePort(loadPort); if (windowPort) DeletePort(windowPort); if (IntuitionBase) CloseLibrary((Library *)IntuitionBase); if (GfxBase) CloseLibrary(GfxBase); } @//E*O*F cleanup.c// chmod u=rw,g=r,o=r cleanup.c echo x - closeloadwindow.c sed 's/^@//' > "closeloadwindow.c" <<'@//E*O*F closeloadwindow.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "execdef.h" #include "intuidef.h" #include "windownode.h" #include "windowinfo.h" #include "loadrecord.h" #include "CloseLoadWindow.proto" #include <exec/proto.h> #include <intuition/proto.h> void CloseLoadWindow(windownode) WindowNode *windownode; { LoadRecord *record, *oldrecord; Remove(&windownode->node); for (record = (LoadRecord *)WINDOWINFO(windownode->window)->loadrecords.mlh_Head; record->node.mln_Succ; ) { FreeMem((char *)record->start_data, (record->end_data - record->start_data) * sizeof(LoadDataValue)); oldrecord = record; record = (LoadRecord *)record->node.mln_Succ; FreeMem((char *)oldrecord, sizeof(LoadRecord)); } FreeMem((char *)WINDOWINFO(windownode->window), sizeof(WindowInfo)); windownode->window->UserPort = NULL; CloseWindow(windownode->window); FreeMem((char *)windownode, sizeof(WindowNode)); } @//E*O*F closeloadwindow.c// chmod u=rw,g=r,o=r closeloadwindow.c echo x - drawdataline.c sed 's/^@//' > "drawdataline.c" <<'@//E*O*F drawdataline.c//' #include <intuition/intuition.h> #include "execdef.h" #include "intuidef.h" #include "loadrecord.h" #include "windowinfo.h" #include "DrawDataLine.proto" #include <graphics/proto.h> void DrawDataLine(window, record, x, value) Window *window; LoadRecord *record; short x; LoadDataValue value; { WindowInfo *window_info; register short deltay, moduloy, y, miny; unsigned char data_pen_num, ref_pen_num; register RastPort *rport; window_info = WINDOWINFO(window); data_pen_num = record->data_pen_num; ref_pen_num = record->ref_pen_num; x += window_info->leftedge; rport = window->RPort; y = window_info->bottomedge; miny = y - (value * window_info->height) / record->scaled_ticks; Move(rport, x, y); if (record->scale <= 1) { SetAPen(rport, record->data_pen_num); Draw(rport, x, miny); } else { deltay = record->deltay; moduloy = record->moduloy; do { y -= deltay; if (moduloy-- > 0) y--; SetAPen(rport, data_pen_num); if ( y < miny) { Draw(rport, x, miny); break; } Draw(rport, x, y); SetAPen(rport, ref_pen_num); WritePixel(rport, x, y); Move(rport, x, (short)(y-1)); } while (y >= miny); } } @//E*O*F drawdataline.c// chmod u=rw,g=r,o=r drawdataline.c echo x - drawreflines.c sed 's/^@//' > "drawreflines.c" <<'@//E*O*F drawreflines.c//' #include <intuition/intuition.h> #include "execdef.h" #include "intuidef.h" #include "loadrecord.h" #include "windowinfo.h" #include "DrawScaleReferenceLines.proto" #include <graphics/proto.h> void DrawScaleReferenceLines(window, record, xleft) Window *window; LoadRecord *record; short xleft; { WindowInfo *window_info; register short y, deltay, moduloy; /* Draw scale reference lines from xleft to rightedge. */ window_info = WINDOWINFO(window); SetAPen(window->RPort, record->ref_pen_num); xleft += window_info->leftedge; deltay = record->deltay; moduloy = record->moduloy; for (y = window_info->height; (y -= deltay) > 0;) { if (moduloy-- > 0) y--; Move(window->RPort, xleft, y); Draw(window->RPort, window_info->rightedge, y); } } @//E*O*F drawreflines.c// chmod u=rw,g=r,o=r drawreflines.c echo x - findmxdatapoint.c sed 's/^@//' > "findmxdatapoint.c" <<'@//E*O*F findmxdatapoint.c//' #include <exec/types.h> #include <exec/nodes.h> #include "execdef.h" #include "loadrecord.h" #include "FindMaxDataPoint.proto" void FindMaxDataPoint(record) register LoadRecord *record; { register LoadDataValue *cur_data; record->max_data = record->start_data; for (cur_data = record->start_data; cur_data < record->next_data; cur_data++) if (*cur_data > *(record->max_data)) record->max_data = cur_data; } @//E*O*F findmxdatapoint.c// chmod u=rw,g=r,o=r findmxdatapoint.c echo x - findwindownode.c sed 's/^@//' > "findwindownode.c" <<'@//E*O*F findwindownode.c//' #include <intuition/intuition.h> #include "execdef.h" #include "intuidef.h" #include "windownode.h" #include "FindWindowNode.proto" extern MinList windowList; WindowNode * FindWindowNode(window) Window *window; { WindowNode *node; for (node = (WindowNode *)windowList.mlh_Head; node->node.mln_Succ; node = (WindowNode *)node->node.mln_Succ) { if (node->window == window) return node; } return NULL; } @//E*O*F findwindownode.c// chmod u=rw,g=r,o=r findwindownode.c echo x - init.c sed 's/^@//' > "init.c" <<'@//E*O*F init.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "execdef.h" #include "intuidef.h" #include "error.h" #include "windownode.h" #include "windowinfo.h" #include "loadrecord.h" #include "Init.proto" #include <exec/proto.h> #include "OpenLoadWindow.proto" #include "NewLoadRecord.proto" #define LINEWIDTH 1 #define DEFAULT_LEFTEDGE screenWidth-DEFAULT_WIDTH #define DEFAULT_TOPEDGE 10 #define DEFAULT_WIDTH 100 #define DEFAULT_HEIGHT 100 #define MINWIDTH BORDERWIDTH * 2 + LINEWIDTH #define MINHEIGHT BORDERHEIGHT * 2 + LINEWIDTH #define MAXWIDTH -1 #define MAXHEIGHT -1 #define DEFAULT_DETAIL_PEN -1 #define DEFAULT_BLOCK_PEN -1 #define DEFAULT_DATA_PEN 1 #define DEFAULT_REF_PEN 1 #define DEFAULT_BACK_PEN 0 static NewWindow newWindow = { 0, 0, 0, 0, 0, 0, 0, WINDOWSIZING | WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG | SIMPLE_REFRESH | RMBTRAP, 0, 0, 0, 0, 0, MINWIDTH, MINHEIGHT, MAXWIDTH, MAXHEIGHT, WBENCHSCREEN }; extern Library *GfxBase; extern struct IntuitionBase *IntuitionBase; extern MinList windowList; extern MsgPort *loadPort; extern MsgPort *windowPort; extern loadrequest *loadRequest; static short atoi(char **); static void GetScreenDimensions(); static void ParseGeometry(char **); long maxTicks; long maxChip; long maxFast; long maxMem; static char *default_argstr = "{[d3]}"; static short screenWidth, screenHeight; long Init(argstr) char *argstr; { WindowNode *node; struct LoadBase *load_base; Bool getting_record, getting_window; short try_again; unsigned char data_pen_num, ref_pen_num, back_pen_num, record_type; char c; struct Screen screen; if (!(GfxBase = OpenLibrary("graphics.library", 0))) return ENOGFX; if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))) return ENOINTUITION; if (!(windowPort = CreatePort(0,0))) return ENOPORT; NewList(&windowList); if (!(loadPort = CreatePort(0,0))) return ENOPORT; if (!(loadRequest = (loadrequest *)CreateExtIO(loadPort, sizeof(loadrequest)))) return ENOIOREQUEST; if (OpenDevice("load.device",0,(IORequest *)loadRequest,0)) return ENODEVICE; load_base = (struct LoadBase *)loadRequest->lr_node.io_Device; maxTicks = load_base->ld_ticks; maxChip = load_base->ld_max_chip; maxFast = load_base->ld_max_fast; maxMem = maxChip + maxFast; GetScreenDimensions(); while ((c = *argstr) && (c != ' ')) argstr++; node = NULL; for (try_again = 2; try_again--;) { while ((c = *argstr++) && (c != '\n')) { switch(c) { case 'i': loadRequest->lr_interval = atoi(&argstr); break; case 't': loadRequest->lr_ticks = atoi(&argstr); break; case 'p': loadRequest->lr_pri = atoi(&argstr); break; case '{': node = NULL; newWindow.LeftEdge = DEFAULT_LEFTEDGE; newWindow.TopEdge = DEFAULT_TOPEDGE; newWindow.Width = DEFAULT_WIDTH; newWindow.Height = DEFAULT_HEIGHT; newWindow.DetailPen = DEFAULT_DETAIL_PEN; newWindow.BlockPen = DEFAULT_BLOCK_PEN; back_pen_num = DEFAULT_BACK_PEN; for (getting_window = TRUE; getting_window;) { c = *argstr++; switch(c) { case '=': ParseGeometry(&argstr); break; case 'd': newWindow.DetailPen = atoi(&argstr); break; case 'b': newWindow.BlockPen = atoi(&argstr); break; case 'g': back_pen_num = atoi(&argstr); break; case '[': if (!node && !(node = OpenLoadWindow(&newWindow, back_pen_num))) return ENOWINDOW; record_type = CPU; ref_pen_num = DEFAULT_REF_PEN; data_pen_num = DEFAULT_DATA_PEN; for (getting_record = TRUE; getting_record; ) { c = *argstr++; switch(c) { case 'C': record_type = CPU; break; case 'b': record_type = BLITTER; break; case 'm': record_type = ALLMEM; break; case 'c': record_type = CHIPMEM; break; case 'f': record_type = FASTMEM; break; case 'd': data_pen_num = atoi(&argstr); break; case 'r': ref_pen_num = atoi(&argstr); break; case ' ': break; case ']': getting_record = FALSE; break; case '\n': case '\0': /* Error: Unexpected end of record. */ return EUNXEOR; default: /* Error: Unknown record flag. */ return EBADRFLAG; } } if (!(NewLoadRecord(WINDOWINFO(node->window), record_type, data_pen_num, ref_pen_num))) return ENORECORD; break; case ' ': break; case '}': getting_window = FALSE; break; case '\n': case '\0': /* Error: Unexpected end of window. */ return EUNXEOW; default: /* Error: Unknown window flag. */ return EBADWFLAG; } } break; case ' ': break; default: /* Error: Unknown global flag. */ return EBADGFLAG; } } if (!node) argstr = default_argstr; else break; } loadRequest->lr_node.io_Command = LD_SET; DoIO(loadRequest); return 0; } static short atoi(s) register char **s; { register short num; for (num = 0; isdigit(**s); (*s)++) num = num * (short)10 + **s - '0'; return num; } static void GetScreenDimensions() { struct Screen screen; GetScreenData(&screen, sizeof(struct Screen), WBENCHSCREEN, NULL); screenWidth = screen.Width; screenHeight = screen.Height; } static void ParseGeometry(string) register char **string; { register char c; c = **string; if (c != 'x' && c != '+' && c != '-') newWindow.Width = atoi(string); c = *((*string)++); if (c == 'x') { newWindow.Height = atoi(string); c = *((*string)++); } if (c == '+') { newWindow.LeftEdge = atoi(string); c = *((*string)++); } else if (c == '-') { newWindow.LeftEdge = screenWidth - atoi(string) - newWindow.Width; c = *((*string)++); } else return; if (c == '+') newWindow.TopEdge = atoi(string); else if (c == '-') newWindow.TopEdge = screenHeight - atoi(string) - newWindow.Height; } @//E*O*F init.c// chmod u=rw,g=r,o=r init.c echo x - newdata.c sed 's/^@//' > "newdata.c" <<'@//E*O*F newdata.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "execdef.h" #include "intuidef.h" #include "loadrecord.h" #include "windownode.h" #include "windowinfo.h" #include "NewData.proto" #include "ScrollWindow.proto" #include "NewScale.proto" #include "RedrawWindow.proto" #include "DrawDataLine.proto" extern MinList windowList; void NewData(newloadvalue) loadval *newloadvalue; { WindowNode *node; Bool new_scale; LoadRecord *record; LoadDataValue newvalue; for (node = (WindowNode *)windowList.mlh_Head; node->node.mln_Succ; node = (WindowNode *)node->node.mln_Succ) { new_scale = FALSE; for (record = (LoadRecord *)WINDOWINFO(node->window)->loadrecords.mlh_Head; record->node.mln_Succ; record = (LoadRecord *)record->node.mln_Succ) { if (record->next_data == record->end_data) ScrollWindow(node->window); switch (record->type) { case CPU: newvalue = newloadvalue->lv_cpu; break; case BLITTER: newvalue = newloadvalue->lv_blitter; break; case CHIPMEM: newvalue = newloadvalue->lv_chip; break; case FASTMEM: newvalue = newloadvalue->lv_fast; break; case ALLMEM: newvalue = newloadvalue->lv_chip + newloadvalue->lv_fast; break; } *(record->next_data++) = newvalue; if (record->scale && newvalue > *record->max_data) { record->max_data = record->next_data - 1; new_scale = NewScale(WINDOWINFO(node->window), record, newvalue) || new_scale; } if (!new_scale) DrawDataLine(node->window, record, (short)(record->next_data - 1 - record->start_data), newvalue); } if (new_scale) RedrawWindow(node->window); } } @//E*O*F newdata.c// chmod u=rw,g=r,o=r newdata.c echo x - newloadrecord.c sed 's/^@//' > "newloadrecord.c" <<'@//E*O*F newloadrecord.c//' #include <exec/types.h> #include <devices/load.h> #include "execdef.h" #include "windowinfo.h" #include "loadrecord.h" #include "NewLoadRecord.proto" #include <exec/proto.h> extern loadrequest *loadRequest; extern long maxTicks; extern long maxChip; extern long maxFast; extern long maxMem; LoadRecord * NewLoadRecord(window_info, type, data_pen_num, ref_pen_num) register WindowInfo *window_info; unsigned char type; unsigned char data_pen_num, ref_pen_num; { LoadRecord *record; if (!(record = (LoadRecord *)AllocMem(sizeof(LoadRecord), 0))) return NULL; if (!(record->start_data = (LoadDataValue *)AllocMem(window_info->width * sizeof(LoadDataValue), 0))) { FreeMem((char *)record, sizeof(LoadRecord)); return NULL; } record->end_data = record->start_data + window_info->width; record->next_data = record->start_data; record->max_data = record->start_data; switch(type) { case CPU: record->scale = 1; record->scaled_ticks = maxTicks; break; case BLITTER: record->scale = 0; record->scaled_ticks = maxTicks; break; case CHIPMEM: record->scale = 0; record->scaled_ticks = maxChip; break; case FASTMEM: record->scale = 0; record->scaled_ticks = maxFast; break; case ALLMEM: record->scale = 0; record->scaled_ticks = maxMem; break; } record->deltay = window_info->height; record->moduloy = 0; record->type = type; record->data_pen_num = data_pen_num; record->ref_pen_num = ref_pen_num; AddHead(&window_info->loadrecords, &record->node); return record; } @//E*O*F newloadrecord.c// chmod u=rw,g=r,o=r newloadrecord.c echo x - newscale.c sed 's/^@//' > "newscale.c" <<'@//E*O*F newscale.c//' #include <exec/types.h> #include <exec/lists.h> #include <devices/load.h> #include "execdef.h" #include "loadrecord.h" #include "windowinfo.h" #include "NewScale.proto" extern loadrequest *loadRequest; extern long maxTicks; extern long maxChip; extern long maxFast; extern long maxMem; Bool NewScale(window_info, record, data_value) WindowInfo *window_info; LoadRecord *record; LoadDataValue data_value; { short new_scale; long max_value; switch(record->type) { case CPU: case BLITTER: max_value = maxTicks; break; case CHIPMEM: max_value = maxChip; break; case FASTMEM: max_value = maxFast; break; case ALLMEM: max_value = maxMem; break; } new_scale = data_value / max_value + 1; if (new_scale != record->scale) { record->scale = new_scale; record->scaled_ticks = new_scale * max_value; record->deltay = window_info->height / new_scale; record->moduloy = window_info->height % new_scale; return TRUE; } return FALSE; } @//E*O*F newscale.c// chmod u=rw,g=r,o=r newscale.c echo x - newwindowsize.c sed 's/^@//' > "newwindowsize.c" <<'@//E*O*F newwindowsize.c//' #include <intuition/intuition.h> #include <devices/load.h> #include <clib/macros.h> #include "execdef.h" #include "intuidef.h" #include "windowinfo.h" #include "loadrecord.h" #include "NewWindowSize.proto" #include <exec/proto.h> #include "SetWindowInfo.proto" #include "FindMaxDataPoint.proto" #include "RedrawWindow.proto" Bool NewWindowSize(window) Window *window; { LoadDataValue *new_start_data; short number_data_points_to_copy; LoadRecord old_record, *record; SetWindowInfo(window); for (record = (LoadRecord *)WINDOWINFO(window)->loadrecords.mlh_Head; record->node.mln_Succ; record = (LoadRecord *)record->node.mln_Succ) { old_record = *record; if (!(new_start_data = (LoadDataValue *)AllocMem(WINDOWINFO(window)->width * sizeof(LoadDataValue), 0))) return FALSE; record->start_data = new_start_data; record->end_data = record->start_data + WINDOWINFO(window)->width; number_data_points_to_copy = MIN(old_record.next_data - old_record.start_data, WINDOWINFO(window)->width); record->next_data = record->start_data + number_data_points_to_copy; record->max_data = record->start_data + (old_record.max_data - old_record.start_data); CopyMemQuick(old_record.next_data - number_data_points_to_copy, record->start_data, number_data_points_to_copy * sizeof(LoadDataValue)); if (record->max_data >= record->next_data) FindMaxDataPoint(record); FreeMem((char *)old_record.start_data, (old_record.end_data - old_record.start_data) * sizeof(LoadDataValue)); if (record->scale) { record->deltay = WINDOWINFO(window)->height / record->scale; record->moduloy = WINDOWINFO(window)->height / record->scale; } } return TRUE; } @//E*O*F newwindowsize.c// chmod u=rw,g=r,o=r newwindowsize.c echo x - openloadwindow.c sed 's/^@//' > "openloadwindow.c" <<'@//E*O*F openloadwindow.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "execdef.h" #include "intuidef.h" #include "windownode.h" #include "windowinfo.h" #include "OpenLoadWindow.proto" #include <intuition/proto.h> #include <exec/proto.h> #include <graphics/proto.h> #include "SetWindowInfo.proto" #include "PrintMessage.proto" extern MsgPort *windowPort; extern MinList windowList; static ULONG IDCMPFlags = MOUSEBUTTONS | CLOSEWINDOW | NEWSIZE | REFRESHWINDOW; static char *myname = "Amyload by"; static char *myauthor = "Jeff Kelley"; WindowNode * OpenLoadWindow(new_window, back_pen_num) NewWindow *new_window; unsigned char back_pen_num; { WindowNode *windownode; Window *window; WindowInfo *window_info; Gadget *gadget; if (!(windownode = (WindowNode *)AllocMem(sizeof(WindowNode), 0))) return NULL; if (!(window = OpenWindow(new_window))) { FreeMem((char *)windownode, sizeof(WindowNode)); return NULL; } windownode->window = window; if (!(window_info = (WindowInfo *)AllocMem(sizeof(WindowInfo), 0))) { FreeMem((char *)windownode, sizeof(WindowNode)); CloseWindow(window); return NULL; } window->UserData = (char *)window_info; NewList(&window_info->loadrecords); SetWindowInfo(window); window_info->back_pen_num = back_pen_num; for (gadget = window->FirstGadget; gadget; gadget = gadget->NextGadget) { gadget->GadgetRender = NULL; gadget->SelectRender = NULL; } RefreshWindowFrame(window); SetAPen(window->RPort, back_pen_num); RectFill(window->RPort, window_info->leftedge, window_info->topedge, window_info->rightedge, window_info->bottomedge); PrintMessage(window, myname, (short)1, (unsigned char)1); PrintMessage(window, myauthor, (short)2, (unsigned char)3); window->UserPort = windowPort; ModifyIDCMP(window, IDCMPFlags); AddTail(&windowList, &windownode->node); return windownode; } @//E*O*F openloadwindow.c// chmod u=rw,g=r,o=r openloadwindow.c echo x - printmessage.c sed 's/^@//' > "printmessage.c" <<'@//E*O*F printmessage.c//' /* static char *messages[] = { "Blitter Overheating!", "Blitter Temperature Critical!", "CPU Load Critical!", "System Overloaded - Please Log Out.", "Use Me." }; */ #include <intuition/intuition.h> #include "execdef.h" #include "intuidef.h" #include "windowinfo.h" #include "PrintMessage.proto" #include <graphics/proto.h> void PrintMessage(window, message, line_num, pen) Window *window; char *message; short line_num; unsigned char pen; { RastPort *rport; rport = window->RPort; SetAPen(rport, pen); Move(rport, (short)(WINDOWINFO(window)->leftedge + 2), (short)((rport->TxHeight+2) * line_num + WINDOWINFO(window)->topedge + 2)); Text(rport, message, strlen(message)); } @//E*O*F printmessage.c// chmod u=rw,g=r,o=r printmessage.c echo x - printrecordtype.c sed 's/^@//' > "printrecordtype.c" <<'@//E*O*F printrecordtype.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "intuidef.h" #include "execdef.h" #include "windowinfo.h" #include "loadrecord.h" #include "PrintRecordTypes.proto" #include "PrintMessage.proto" static char *recordTypeNames[] = { "CPU", "Blitter", "Chip", "Fast", "Memory" }; void PrintRecordTypes(window) Window *window; { LoadRecord *record; short line_num; line_num = 1; for (record = (LoadRecord *)WINDOWINFO(window)->loadrecords.mlh_TailPred; record->node.mln_Pred; record = (LoadRecord *)record->node.mln_Pred) { PrintMessage(window, recordTypeNames[record->type], line_num, record->data_pen_num); line_num++; } } @//E*O*F printrecordtype.c// chmod u=rw,g=r,o=r printrecordtype.c echo x - redrawwindow.c sed 's/^@//' > "redrawwindow.c" <<'@//E*O*F redrawwindow.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "execdef.h" #include "intuidef.h" #include "windowinfo.h" #include "loadrecord.h" #include "RedrawWindow.proto" #include <graphics/proto.h> #include "DrawScaleReferenceLines.proto" #include "DrawDataLine.proto" void RedrawWindow(window) Window *window; { WindowInfo *window_info; register short x; register LoadDataValue *current_data, *last_data; LoadRecord *record; window_info = WINDOWINFO(window); SetAPen(window->RPort, window_info->back_pen_num); /* Clear the window. */ RectFill(window->RPort, window_info->leftedge, window_info->topedge, window_info->rightedge, window_info->bottomedge); for (record = (LoadRecord *)window_info->loadrecords.mlh_Head; record->node.mln_Succ; record = (LoadRecord *)record->node.mln_Succ) { if (record->scale) DrawScaleReferenceLines(window, record, (short)0); /* Draw data point lines. */ last_data = record->next_data; x = 0; for (current_data = record->start_data; current_data < last_data; current_data++) { DrawDataLine(window, record, x, *current_data); x++; } } } @//E*O*F redrawwindow.c// chmod u=rw,g=r,o=r redrawwindow.c echo x - scrollwindow.c sed 's/^@//' > "scrollwindow.c" <<'@//E*O*F scrollwindow.c//' #include <intuition/intuition.h> #include <devices/load.h> #include "execdef.h" #include "intuidef.h" #include "windowinfo.h" #include "loadrecord.h" #include "ScrollWindow.proto" #include <exec/proto.h> #include <graphics/proto.h> #include "NewScale.proto" #include "FindMaxDataPoint.proto" #include "DrawScaleReferenceLines.proto" #include "RedrawWindow.proto" void ScrollWindow(window) Window *window; { WindowInfo *window_info; short scroll_distance; Bool new_scale; LoadRecord *record; window_info = WINDOWINFO(window); new_scale = FALSE; scroll_distance = (window_info->width + 1) >> 1; for (record = (LoadRecord *)window_info->loadrecords.mlh_Head; record->node.mln_Succ; record = (LoadRecord *)record->node.mln_Succ) { /* Scroll the data. */ CopyMemQuick(record->start_data + scroll_distance, record->start_data, (window_info->width - scroll_distance) * sizeof(LoadDataValue)); record->next_data -= scroll_distance; record->max_data -= scroll_distance; if (record->max_data < record->start_data) FindMaxDataPoint(record); if (record->scale) new_scale = NewScale(window_info, record, *record->max_data) || new_scale; } /* Scroll the window. */ if (new_scale) RedrawWindow(window); else { ScrollRaster(window->RPort, (short)((window_info->width + 1) >> 1), (short)0, window_info->leftedge, window_info->topedge, window_info->rightedge, window_info->bottomedge); for (record = (LoadRecord *)window_info->loadrecords.mlh_Head; record->node.mln_Succ; record = (LoadRecord *)record->node.mln_Succ) if (record->scale) DrawScaleReferenceLines(window, record, (short)(window_info->width - scroll_distance)); } } @//E*O*F scrollwindow.c// chmod u=rw,g=r,o=r scrollwindow.c echo x - setwindowinfo.c sed 's/^@//' > "setwindowinfo.c" <<'@//E*O*F setwindowinfo.c//' #include <intuition/intuition.h> #include "execdef.h" #include "intuidef.h" #include "windowinfo.h" #include "SetWindowInfo.proto" void SetWindowInfo(window) register Window *window; { register WindowInfo *info; info = WINDOWINFO(window); info->leftedge = BORDERWIDTH; info->rightedge = window->Width - BORDERWIDTH - 1; info->width = window->Width - BORDERWIDTH * 2; info->topedge = BORDERHEIGHT; info->bottomedge = window->Height - BORDERHEIGHT - 1; info->height = window->Height - BORDERHEIGHT * 2; } @//E*O*F setwindowinfo.c// chmod u=rw,g=r,o=r setwindowinfo.c echo x - cleanup.proto sed 's/^@//' > "cleanup.proto" <<'@//E*O*F cleanup.proto//' extern void Cleanup(); @//E*O*F cleanup.proto// chmod u=rw,g=r,o=r cleanup.proto echo x - closeloadwindow.proto sed 's/^@//' > "closeloadwindow.proto" <<'@//E*O*F closeloadwindow.proto//' extern void CloseLoadWindow(WindowNode *); @//E*O*F closeloadwindow.proto// chmod u=rw,g=r,o=r closeloadwindow.proto echo x - drawdataline.proto sed 's/^@//' > "drawdataline.proto" <<'@//E*O*F drawdataline.proto//' extern void DrawDataLine(Window *, LoadRecord *, short, LoadDataValue); @//E*O*F drawdataline.proto// chmod u=rw,g=r,o=r drawdataline.proto echo x - drawscalereferencelines.proto sed 's/^@//' > "drawscalereferencelines.proto" <<'@//E*O*F drawscalereferencelines.proto//' extern void DrawScaleReferenceLines(Window *, LoadRecord *, short); @//E*O*F drawscalereferencelines.proto// chmod u=rw,g=r,o=r drawscalereferencelines.proto echo x - findmaxdatapoint.proto sed 's/^@//' > "findmaxdatapoint.proto" <<'@//E*O*F findmaxdatapoint.proto//' extern void FindMaxDataPoint(LoadRecord *); @//E*O*F findmaxdatapoint.proto// chmod u=rw,g=r,o=r findmaxdatapoint.proto echo x - findwindownode.proto sed 's/^@//' > "findwindownode.proto" <<'@//E*O*F findwindownode.proto//' extern WindowNode *FindWindowNode(Window *); @//E*O*F findwindownode.proto// chmod u=rw,g=r,o=r findwindownode.proto echo x - init.proto sed 's/^@//' > "init.proto" <<'@//E*O*F init.proto//' extern long Init(char *); @//E*O*F init.proto// chmod u=rw,g=r,o=r init.proto echo x - newdata.proto sed 's/^@//' > "newdata.proto" <<'@//E*O*F newdata.proto//' extern void NewData(loadval *); @//E*O*F newdata.proto// chmod u=rw,g=r,o=r newdata.proto echo x - newloadrecord.proto sed 's/^@//' > "newloadrecord.proto" <<'@//E*O*F newloadrecord.proto//' extern LoadRecord *NewLoadRecord(WindowInfo *, unsigned char, unsigned char, unsigned char); @//E*O*F newloadrecord.proto// chmod u=rw,g=r,o=r newloadrecord.proto echo x - newscale.proto sed 's/^@//' > "newscale.proto" <<'@//E*O*F newscale.proto//' extern Bool NewScale(WindowInfo *, LoadRecord *, LoadDataValue); @//E*O*F newscale.proto// chmod u=rw,g=r,o=r newscale.proto echo x - newwindowsize.proto sed 's/^@//' > "newwindowsize.proto" <<'@//E*O*F newwindowsize.proto//' extern Bool NewWindowSize(Window *); @//E*O*F newwindowsize.proto// chmod u=rw,g=r,o=r newwindowsize.proto echo x - openloadwindow.proto sed 's/^@//' > "openloadwindow.proto" <<'@//E*O*F openloadwindow.proto//' extern WindowNode *OpenLoadWindow(NewWindow *, unsigned char); @//E*O*F openloadwindow.proto// chmod u=rw,g=r,o=r openloadwindow.proto echo x - printmessage.proto sed 's/^@//' > "printmessage.proto" <<'@//E*O*F printmessage.proto//' extern void PrintMessage(Window *, char *, short, unsigned char); @//E*O*F printmessage.proto// chmod u=rw,g=r,o=r printmessage.proto echo x - printrecordtypes.proto sed 's/^@//' > "printrecordtypes.proto" <<'@//E*O*F printrecordtypes.proto//' extern void PrintRecordTypes(Window *); @//E*O*F printrecordtypes.proto// chmod u=rw,g=r,o=r printrecordtypes.proto echo x - redrawwindow.proto sed 's/^@//' > "redrawwindow.proto" <<'@//E*O*F redrawwindow.proto//' extern void RedrawWindow(Window *); @//E*O*F redrawwindow.proto// chmod u=rw,g=r,o=r redrawwindow.proto echo x - scrollwindow.proto sed 's/^@//' > "scrollwindow.proto" <<'@//E*O*F scrollwindow.proto//' extern void ScrollWindow(Window *); @//E*O*F scrollwindow.proto// chmod u=rw,g=r,o=r scrollwindow.proto echo x - setwindowinfo.proto sed 's/^@//' > "setwindowinfo.proto" <<'@//E*O*F setwindowinfo.proto//' extern void SetWindowInfo(Window *); @//E*O*F setwindowinfo.proto// chmod u=rw,g=r,o=r setwindowinfo.pro Whi 2;cho x