commit 908973408ab087868a8eaad7cb280ba67db7b00f Author: bch Date: Sat Feb 18 21:03:44 2017 +0000 initial import diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..89072fc --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +CFLAGS += -I/usr/X11R6/include/ +xmem: xmem.o get_mem.o MemStripChart.o + gcc $(CFLAGS) -o xmem xmem.o get_mem.o MemStripChart.o -L/usr/X11R6/lib -lX11 -lXt -lXaw -lXmu + +xmem.o: xmem.c + gcc $(CFLAGS) -c xmem.c + +get_mem.o: get_mem.c + gcc $(CFLAGS) -c get_mem.c + +MemStripChart.o: MemStripChart.c + gcc $(CFLAGS) -c MemStripChart.c + +clean: + -rm xmem *.o + +install: xmem + install -d -m 755 $(DESTDIR)/usr/bin/ + install -d -m 755 $(DESTDIR)/etc/X11/app-defaults/ + install -m 755 xmem $(DESTDIR)/usr/bin/ + install -m 644 XMem.ad $(DESTDIR)/etc/X11/app-defaults/XMem diff --git a/MemStripCharP.h b/MemStripCharP.h new file mode 100644 index 0000000..0f0611c --- /dev/null +++ b/MemStripCharP.h @@ -0,0 +1,80 @@ +/*********************************************************************** + * + * MemStripChart Widget + * from StripChart Widget derived + * + * Author: Hans-Helmut B"uhmann 20. Jan. 1996 + * + ***********************************************************************/ + +#ifndef _XawMemStripChartP_h +#define _XawMemStripChartP_h + +#include "MemStripChart.h" +#include + +#define NO_GCS 0 +#define FOREGROUND (1 << 0) +#define HIGHLIGHT (1 << 1) +#define CODE (1 << 2) +#define SHARED (1 << 3) +#define BUFFER (1 << 4) +#define FREE (1 << 5) +#define SWAP (1 << 6) +#define ALL_GCS (FOREGROUND | HIGHLIGHT | CODE | SHARED | BUFFER | FREE | SWAP) + +/* New fields for the memStripChart widget instance record */ + +typedef struct { + Pixel fgpixel; /* color index for text */ + Pixel hipixel; /* color index for lines */ + Pixel codepixel; /* color index for code memory */ + Pixel cachedpixel; /* color index for cached memory */ + Pixel bufferpixel; /* color index for buffer memory */ + Pixel freepixel; /* color index for free memory */ + Pixel swappixel; /* color index for used swap memory */ + + GC fgGC; /* graphics context for fgpixel */ + GC hiGC; /* graphics context for hipixel */ + GC codeGC; /* graphics context for codepixel */ + GC cachedGC; /* graphics context for cachedpixel */ + GC bufferGC; /* graphics context for bufferpixel */ + GC freeGC; /* graphics context for freepixel */ + GC swapGC; /* graphics context for swappixel */ + + /* start of graph stuff */ + + int update; /* update frequence */ + int scale; /* scale factor */ + int min_scale; /* smallest scale factor */ + int interval; /* data point interval */ + XPoint * points ; /* Poly point for repairing graph lines. */ + double max_value; /* Max Value in window */ + MemStripChartCallbackData + valuedata[1024]; /* record of data points */ + XtIntervalId interval_id; + XtCallbackList get_value; /* proc to call to fetch load pt */ + int jump_val; /* Amount to jump on each scroll. */ +} MemStripChartPart; + +/* Full instance record declaration */ +typedef struct _MemStripChartRec { + CorePart core; + SimplePart simple; + MemStripChartPart mem_strip_chart; +} MemStripChartRec; + +/* New fields for the StripChart widget class record */ +typedef struct {int dummy;} MemStripChartClassPart; + +/* Full class record declaration. */ +typedef struct _MemStripChartClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + MemStripChartClassPart mem_strip_chart_class; +} MemStripChartClassRec; + +/* Class pointer. */ +extern MemStripChartClassRec MemstripChartClassRec; + +#endif /* _XawMemStripChartP_h */ diff --git a/MemStripChart.c b/MemStripChart.c new file mode 100644 index 0000000..3c7ec57 --- /dev/null +++ b/MemStripChart.c @@ -0,0 +1,611 @@ +/*********************************************************************** + * + * MemStripChart Widget + * from StripChart Widget derived + * + * Author: Hans-Helmut B"uhmann 20. Jan. 1996 + * + ***********************************************************************/ + +#include +#include +#include +#include +#include "MemStripCharP.h" +#include + +#define MS_PER_SEC 1000 + +/* Private Data */ + +#define offset(field) XtOffsetOf(MemStripChartRec, field) + +static XtResource resources[] = { + {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension), + offset(core.width), XtRImmediate, (XtPointer) 120}, + {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension), + offset(core.height), XtRImmediate, (XtPointer) 120}, + {XtNupdate, XtCInterval, XtRInt, sizeof(int), + offset(mem_strip_chart.update), XtRImmediate, (XtPointer) 10}, + {XtNminScale, XtCScale, XtRInt, sizeof(int), + offset(mem_strip_chart.min_scale), XtRImmediate, (XtPointer) 1}, + {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + offset(mem_strip_chart.fgpixel), XtRString, XtDefaultForeground}, + {XtNhighlight, XtCForeground, XtRPixel, sizeof(Pixel), + offset(mem_strip_chart.hipixel), XtRString, XtDefaultForeground}, + {XtNcodecolor, XtCForeground, XtRPixel, sizeof(Pixel), + offset(mem_strip_chart.codepixel), XtRString, XtDefaultForeground}, + {XtNcachedcolor, XtCForeground, XtRPixel, sizeof(Pixel), + offset(mem_strip_chart.cachedpixel), XtRString, XtDefaultBackground}, + {XtNbuffercolor, XtCForeground, XtRPixel, sizeof(Pixel), + offset(mem_strip_chart.bufferpixel), XtRString, XtDefaultForeground}, + {XtNfreecolor, XtCForeground, XtRPixel, sizeof(Pixel), + offset(mem_strip_chart.freepixel), XtRString, XtDefaultBackground}, + {XtNswapcolor, XtCForeground, XtRPixel, sizeof(Pixel), + offset(mem_strip_chart.swappixel), XtRString, XtDefaultForeground}, + {XtNgetValue, XtCCallback, XtRCallback, sizeof(XtPointer), + offset(mem_strip_chart.get_value), XtRImmediate, (XtPointer) NULL}, + {XtNjumpScroll, XtCJumpScroll, XtRInt, sizeof(int), + offset(mem_strip_chart.jump_val), XtRImmediate, (XtPointer) DEFAULT_JUMP}, +}; + +#undef offset + +static void Initialize(), Destroy(), Redisplay(), MoveChart(), SetPoints(); +static Boolean SetValues(); +static int repaint_window(); + +MemStripChartClassRec memStripChartClassRec = { + { /* core fields */ + /* superclass */ (WidgetClass) &simpleClassRec, + /* class_name */ "MemStripChart", + /* size */ sizeof(MemStripChartRec), + /* class_initialize */ XawInitializeWidgetSet, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ XtInheritRealize, + /* actions */ NULL, + /* num_actions */ 0, + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ XtExposeCompressMultiple | + XtExposeGraphicsExposeMerged, + /* compress_enterleave */ TRUE, + /* visible_interest */ FALSE, + /* destroy */ Destroy, + /* resize */ SetPoints, + /* expose */ Redisplay, + /* set_values */ SetValues, + /* set_values_hook */ NULL, + /* set_values_almost */ NULL, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ NULL, + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, + { /* Simple class fields */ + /* change_sensitive */ XtInheritChangeSensitive + } +}; + +WidgetClass memStripChartWidgetClass = (WidgetClass) &memStripChartClassRec; + +/**************************************************************** + * + * Private Procedures + * + ****************************************************************/ + +static void draw_it(); + +/* Function Name: CreateGC + * Description: Creates the GC's + * Arguments: w - the mem strip chart widget. + * which - which GC's to create. + * Returns: none + */ + +static void +CreateGC(w, which) + MemStripChartWidget w; + unsigned int which; +{ + XGCValues myXGCV; + + if (which & FOREGROUND) { + myXGCV.foreground = w->mem_strip_chart.fgpixel; + w->mem_strip_chart.fgGC = XtGetGC((Widget) w, GCForeground, &myXGCV); + } + + if (which & HIGHLIGHT) { + myXGCV.foreground = w->mem_strip_chart.hipixel; + w->mem_strip_chart.hiGC = XtGetGC((Widget) w, GCForeground, &myXGCV); + } + + if (which & CODE) { + myXGCV.foreground = w->mem_strip_chart.codepixel; + w->mem_strip_chart.codeGC = XtGetGC((Widget) w, GCForeground, &myXGCV); + } + + if (which & SHARED) { + myXGCV.foreground = w->mem_strip_chart.cachedpixel; + w->mem_strip_chart.cachedGC = XtGetGC((Widget) w, GCForeground, &myXGCV); + } + + if (which & BUFFER) { + myXGCV.foreground = w->mem_strip_chart.bufferpixel; + w->mem_strip_chart.bufferGC = XtGetGC((Widget) w, GCForeground, &myXGCV); + } + + if (which & FREE) { + myXGCV.foreground = w->mem_strip_chart.freepixel; + w->mem_strip_chart.freeGC = XtGetGC((Widget) w, GCForeground, &myXGCV); + } + + if (which & SWAP) { + myXGCV.foreground = w->mem_strip_chart.swappixel; + w->mem_strip_chart.swapGC = XtGetGC((Widget) w, GCForeground, &myXGCV); + } + +} + +/* Function Name: DestroyGC + * Description: Destroys the GC's + * Arguments: w - the mem strip chart widget. + * which - which GC's to destroy. + * Returns: none + */ + +static void +DestroyGC(w, which) + MemStripChartWidget w; + unsigned int which; +{ + if (which & FOREGROUND) + XtReleaseGC((Widget) w, w->mem_strip_chart.fgGC); + + if (which & HIGHLIGHT) + XtReleaseGC((Widget) w, w->mem_strip_chart.hiGC); + + if (which & CODE) { + XtReleaseGC((Widget) w, w->mem_strip_chart.codeGC); + } + + if (which & SHARED) { + XtReleaseGC((Widget) w, w->mem_strip_chart.cachedGC); + } + + if (which & BUFFER) { + XtReleaseGC((Widget) w, w->mem_strip_chart.bufferGC); + } + + if (which & FREE) { + XtReleaseGC((Widget) w, w->mem_strip_chart.freeGC); + } + + if (which & SWAP) { + XtReleaseGC((Widget) w, w->mem_strip_chart.swapGC); + } +} + + +/* Function Name: DrawMemStrip + * Description: Draw a mem strip + * Arguments: w - the mem strip chart widget. + * x - the x-position. + * Returns: none + */ + +static void +DrawMemStrip(w, x) + MemStripChartWidget w; + unsigned int x; +{ + int top, bottom; + + bottom = w->core.height; + if (w->mem_strip_chart.valuedata[x].code != 0.0) { + top = (int) (w->core.height + - (int)(w->core.height * w->mem_strip_chart.valuedata[x].code) + / w->mem_strip_chart.scale); + + XFillRectangle(XtDisplay(w), XtWindow(w), w->mem_strip_chart.codeGC, + x, top, (unsigned int) 1, bottom - top); + bottom = top; + } + + if (w->mem_strip_chart.valuedata[x].cached != 0.0) { + top = (int) (w->core.height + - (int)(w->core.height * (w->mem_strip_chart.valuedata[x].code + + w->mem_strip_chart.valuedata[x].cached)) + / w->mem_strip_chart.scale); + XFillRectangle(XtDisplay(w), XtWindow(w), w->mem_strip_chart.cachedGC, + x, top, (unsigned int) 1, bottom - top); + + bottom = top; + } + + if (w->mem_strip_chart.valuedata[x].buffer != 0.0) { + top = (int) (w->core.height + - (int)(w->core.height * (1.0 - w->mem_strip_chart.valuedata[x].free)) + / w->mem_strip_chart.scale); + XFillRectangle(XtDisplay(w), XtWindow(w), w->mem_strip_chart.bufferGC, + x, top, (unsigned int) 1, bottom - top); + bottom = top; + } + + if (w->mem_strip_chart.valuedata[x].free != 0.0) { + top = (int) (w->core.height + - (int)(w->core.height) + / w->mem_strip_chart.scale); + XFillRectangle(XtDisplay(w), XtWindow(w), w->mem_strip_chart.freeGC, + x, top, (unsigned int) 1, bottom - top); + bottom = top; + } + if (w->mem_strip_chart.valuedata[x].swap != 0.0) { + top = (int) (w->core.height + - (int)(w->core.height * (1.0 + w->mem_strip_chart.valuedata[x].swap)) + / w->mem_strip_chart.scale); + XFillRectangle(XtDisplay(w), XtWindow(w), w->mem_strip_chart.swapGC, + x, top, (unsigned int) 1, bottom - top); + } +} + +/* ARGSUSED */ +static void Initialize (greq, gnew, args, num_args) + Widget greq, gnew; + ArgList args; + Cardinal *num_args; +{ + MemStripChartWidget w = (MemStripChartWidget)gnew; + + if (w->mem_strip_chart.update > 0) + w->mem_strip_chart.interval_id = XtAppAddTimeOut( + XtWidgetToApplicationContext(gnew), + w->mem_strip_chart.update * MS_PER_SEC, + draw_it, (XtPointer) gnew); + CreateGC(w, (unsigned int) ALL_GCS); + + w->mem_strip_chart.scale = w->mem_strip_chart.min_scale; + w->mem_strip_chart.interval = 0; + w->mem_strip_chart.max_value = 0.0; + w->mem_strip_chart.points = NULL; + SetPoints(w); +} + +static void Destroy (gw) + Widget gw; +{ + MemStripChartWidget w = (MemStripChartWidget)gw; + + if (w->mem_strip_chart.update > 0) + XtRemoveTimeOut (w->mem_strip_chart.interval_id); + if (w->mem_strip_chart.points) + XtFree((char *) w->mem_strip_chart.points); + DestroyGC(w, (unsigned int) ALL_GCS); +} + +/* + * NOTE: This function really needs to recieve graphics exposure + * events, but since this is not easily supported until R4 I am + * going to hold off until then. + */ + +/* ARGSUSED */ +static void Redisplay(w, event, region) + Widget w; + XEvent *event; + Region region; +{ + if (event->type == GraphicsExpose) + (void) repaint_window ((MemStripChartWidget)w, event->xgraphicsexpose.x, + event->xgraphicsexpose.width); + else + (void) repaint_window ((MemStripChartWidget)w, event->xexpose.x, + event->xexpose.width); +} + +/* ARGSUSED */ +static void +draw_it(client_data, id) + XtPointer client_data; + XtIntervalId *id; /* unused */ +{ + MemStripChartWidget w = (MemStripChartWidget)client_data; + MemStripChartCallbackData value; + double usedmem; + + if (w->mem_strip_chart.update > 0) + w->mem_strip_chart.interval_id = + XtAppAddTimeOut(XtWidgetToApplicationContext( (Widget) w), + w->mem_strip_chart.update * MS_PER_SEC, draw_it,client_data); + + if (w->mem_strip_chart.interval >= (int)w->core.width) + MoveChart( (MemStripChartWidget) w, TRUE); + + /* Get the value, stash the point and draw corresponding line. */ + + if (w->mem_strip_chart.get_value == NULL) + return; + + XtCallCallbacks( (Widget)w, XtNgetValue, (XtPointer)&value ); + + /* + * Keep w->mem_strip_chart.max_value up to date, and if this data + * point is off the graph, change the scale to make it fit. + */ + + usedmem = 1.0 + value.swap; + if (usedmem > w->mem_strip_chart.max_value) { + w->mem_strip_chart.max_value = usedmem; + if (XtIsRealized((Widget)w) && + w->mem_strip_chart.max_value > w->mem_strip_chart.scale) { + XClearWindow( XtDisplay (w), XtWindow (w)); + w->mem_strip_chart.interval = repaint_window(w, 0, (int) w->core.width); + } + } + + w->mem_strip_chart.valuedata[w->mem_strip_chart.interval] = value; + if (XtIsRealized((Widget)w)) { + + DrawMemStrip(w, w->mem_strip_chart.interval, value); + + /* + * Fill in the graph lines we just painted over. + */ + + if (w->mem_strip_chart.points != NULL) { + w->mem_strip_chart.points[0].x = w->mem_strip_chart.interval; + XDrawPoints(XtDisplay(w), XtWindow(w), w->mem_strip_chart.hiGC, + w->mem_strip_chart.points, w->mem_strip_chart.scale - 1, + CoordModePrevious); + } + + XFlush(XtDisplay(w)); /* Flush output buffers */ + } + w->mem_strip_chart.interval++; /* Next point */ +} /* draw_it */ + +/* Blts data according to current size, then redraws the stripChart window. + * Next represents the number of valid points in data. Returns the (possibly) + * adjusted value of next. If next is 0, this routine draws an empty window + * (scale - 1 lines for graph). If next is less than the current window width, + * the returned value is identical to the initial value of next and data is + * unchanged. Otherwise keeps half a window's worth of data. If data is + * changed, then w->mem_strip_chart.max_value is updated to reflect the + * largest data point. + */ + +static int +repaint_window(w, left, width) + MemStripChartWidget w; + int left, width; +{ + int i, j; + int next = w->mem_strip_chart.interval; + int scale = w->mem_strip_chart.scale; + int scalewidth = 0; + + /* Compute the minimum scale required to graph the data, but don't go + lower than min_scale. */ + if (w->mem_strip_chart.interval != 0 || scale <= (int)w->mem_strip_chart.max_value) + scale = ((int) (w->mem_strip_chart.max_value)) + 1; + if (scale < w->mem_strip_chart.min_scale) + scale = w->mem_strip_chart.min_scale; + + if (scale != w->mem_strip_chart.scale) { + w->mem_strip_chart.scale = scale; + left = 0; + width = next; + scalewidth = w->core.width; + + SetPoints(w); + + if (XtIsRealized ((Widget) w)) + XClearWindow (XtDisplay (w), XtWindow (w)); + + } + + if (XtIsRealized((Widget)w)) { + Display *dpy = XtDisplay(w); + Window win = XtWindow(w); + + width += left - 1; + if (!scalewidth) scalewidth = width; + + if (next < ++width) width = next; + + /* Draw data point lines. */ + for (i = left; i < width; i++) { + DrawMemStrip(w, i, w->mem_strip_chart.valuedata[i]); + } + + /* Draw graph reference lines */ + for (i = 1; i < w->mem_strip_chart.scale; i++) { + j = i * ((int)w->core.height / w->mem_strip_chart.scale); + XDrawLine(dpy, win, w->mem_strip_chart.hiGC, left, j, scalewidth, j); + } + } + return(next); +} + +/* Function Name: MoveChart + * Description: moves the chart over when it would run off the end. + * Arguments: w - the load widget. + * blit - blit the bits? (TRUE/FALSE). + * Returns: none. + */ + +static void +MoveChart(w, blit) + MemStripChartWidget w; + Boolean blit; +{ + double old_max; + int left, i, j; + int next = w->mem_strip_chart.interval; + + if (!XtIsRealized((Widget) w)) return; + + if (w->mem_strip_chart.jump_val < 0) w->mem_strip_chart.jump_val = DEFAULT_JUMP; + if (w->mem_strip_chart.jump_val == DEFAULT_JUMP) + j = w->core.width >> 1; /* Half the window width. */ + else { + j = w->core.width - w->mem_strip_chart.jump_val; + if (j < 0) j = 0; + } + + (void) memmove((char *)(w->mem_strip_chart.valuedata), + (char *)(w->mem_strip_chart.valuedata + next - j), + j * sizeof(MemStripChartCallbackData)); + next = w->mem_strip_chart.interval = j; + + /* + * Since we just lost some data, recompute the + * w->mem_strip_chart.max_value. + */ + + old_max = w->mem_strip_chart.max_value; + w->mem_strip_chart.max_value = 0.0; + for (i = 0; i < next; i++) { + if (w->mem_strip_chart.valuedata[i].swap + 1.0 > w->mem_strip_chart.max_value) + w->mem_strip_chart.max_value = w->mem_strip_chart.valuedata[i].swap + 1.0; + } + + if (!blit) return; /* we are done... */ + + if ( ((int) old_max) != ( (int) w->mem_strip_chart.max_value) ) { + XClearWindow(XtDisplay(w), XtWindow(w)); + repaint_window(w, 0, (int) w->core.width); + return; + } + + XCopyArea(XtDisplay((Widget)w), XtWindow((Widget)w), XtWindow((Widget)w), + w->mem_strip_chart.hiGC, (int) w->core.width - j, 0, + (unsigned int) j, (unsigned int) w->core.height, + 0, 0); + + XClearArea(XtDisplay((Widget)w), XtWindow((Widget)w), + (int) j, 0, + (unsigned int) w->core.width - j, (unsigned int)w->core.height, + FALSE); + + /* Draw graph reference lines */ + left = j; + for (i = 1; i < w->mem_strip_chart.scale; i++) { + j = i * ((int)w->core.height / w->mem_strip_chart.scale); + XDrawLine(XtDisplay((Widget) w), XtWindow( (Widget) w), + w->mem_strip_chart.hiGC, left, j, (int)w->core.width, j); + } + return; +} + +/* ARGSUSED */ +static Boolean SetValues (current, request, new, args, num_args) + Widget current, request, new; + ArgList args; + Cardinal *num_args; +{ + MemStripChartWidget old = (MemStripChartWidget)current; + MemStripChartWidget w = (MemStripChartWidget)new; + Boolean ret_val = FALSE; + unsigned int new_gc = NO_GCS; + + if (w->mem_strip_chart.update != old->mem_strip_chart.update) { + if (old->mem_strip_chart.update > 0) + XtRemoveTimeOut (old->mem_strip_chart.interval_id); + if (w->mem_strip_chart.update > 0) + w->mem_strip_chart.interval_id = + XtAppAddTimeOut(XtWidgetToApplicationContext(new), + w->mem_strip_chart.update * MS_PER_SEC, + draw_it, (XtPointer)w); + } + + if ( w->mem_strip_chart.min_scale > (int) ((w->mem_strip_chart.max_value) + 1) ) + ret_val = TRUE; + + if ( w->mem_strip_chart.fgpixel != old->mem_strip_chart.fgpixel ) { + new_gc |= FOREGROUND; + ret_val = True; + } + + if ( w->mem_strip_chart.hipixel != old->mem_strip_chart.hipixel ) { + new_gc |= HIGHLIGHT; + ret_val = True; + } + + if ( w->mem_strip_chart.codepixel != old->mem_strip_chart.codepixel ) { + new_gc |= CODE; + ret_val = True; + } + + if ( w->mem_strip_chart.cachedpixel != old->mem_strip_chart.cachedpixel ) { + new_gc |= SHARED; + ret_val = True; + } + + if ( w->mem_strip_chart.bufferpixel != old->mem_strip_chart.bufferpixel ) { + new_gc |= BUFFER; + ret_val = True; + } + + if ( w->mem_strip_chart.freepixel != old->mem_strip_chart.freepixel ) { + new_gc |= FREE; + ret_val = True; + } + + if ( w->mem_strip_chart.swappixel != old->mem_strip_chart.swappixel ) { + new_gc |= SWAP; + ret_val = True; + } + + DestroyGC(old, new_gc); + CreateGC(w, new_gc); + + return( ret_val ); +} + +/* Function Name: SetPoints + * Description: Sets up the polypoint that will be used to draw in + * the graph lines. + * Arguments: w - the MemStripChart widget. + * Returns: none. + */ + +#define HEIGHT ( (unsigned int) w->core.height) + +static void +SetPoints(widget) + Widget widget; +{ + MemStripChartWidget w = (MemStripChartWidget) widget; + XPoint * points; + Cardinal size; + int i; + + if (w->mem_strip_chart.scale <= 1) { /* no scale lines. */ + XtFree ((char *) w->mem_strip_chart.points); + w->mem_strip_chart.points = NULL; + return; + } + + size = sizeof(XPoint) * (w->mem_strip_chart.scale - 1); + + points = (XPoint *) XtRealloc( (XtPointer) w->mem_strip_chart.points, size); + w->mem_strip_chart.points = points; + + /* Draw graph reference lines into clip mask */ + + for (i = 1; i < w->mem_strip_chart.scale; i++) { + points[i - 1].x = 0; + points[i - 1].y = HEIGHT / w->mem_strip_chart.scale; + } +} diff --git a/MemStripChart.h b/MemStripChart.h new file mode 100644 index 0000000..5920801 --- /dev/null +++ b/MemStripChart.h @@ -0,0 +1,92 @@ +#ifndef _XawMemStripChart_h +#define _XawMemStripChart_h + +/*********************************************************************** + * + * MemStripChart Widget + * from StripChart Widget derived + * + * Author: Hans-Helmut B"uhmann 20. Jan. 1996 + * + ***********************************************************************/ + +/* StripChart resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + accelerators Accelerators AcceleratorTable NULL + ancestorSensitive AncestorSensitive Boolean True + background Background Pixel XtDefaultBackground + backgroundPixmap Pixmap Pixmap XtUnspecifiedPixmap + borderColor BorderColor Pixel XtDefaultForeground + borderPixmap Pixmap Pixmap XtUnspecifiedPixmap + borderWidth BorderWidth Dimension 1 + colormap Colormap Colormap parent's colormap + cursor Cursor Cursor None + cursorName Cursor String NULL + depth Depth int parent's depth + destroyCallback Callback XtCallbackList NULL + foreground Foreground Pixel XtDefaultForeground + getValue Callback XtCallbackList NULL + height Height Dimension 120 + highlight Foreground Pixel XtDefaultForeground + insensitiveBorder Insensitive Pixmap GreyPixmap + jumpScroll JumpScroll int 1/2 width + mappedWhenManaged MappedWhenManaged Boolean True + minScale Scale int 1 + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + screen Screen Screen parent's screen + sensitive Sensitive Boolean True + translations Translations TranslationTable NULL + update Interval int 10 (seconds) + width Width Dimension 120 + x Position Position 0 + y Position Position 0 + + codecolor Foreground Pixel "red" + cachedcolor Foreground Pixel "yellow" + buffercolor Foreground Pixel "blue" + freecolor Foreground Pixel "green" + swapcolor Foreground Pixel "red" + +*/ + +#define DEFAULT_JUMP -1 + +#ifndef _XtStringDefs_h_ +#define XtNhighlight "highlight" +#define XtNupdate "update" +#endif +#define XtNcodecolor "codecolor" +#define XtNcachedcolor "cachedcolor" +#define XtNbuffercolor "buffercolor" +#define XtNfreecolor "freecolor" +#define XtNswapcolor "swapcolor" + +#define XtCJumpScroll "JumpScroll" +#define XtCScale "Scale" + +#define XtNgetValue "getValue" +#define XtNjumpScroll "jumpScroll" +#define XtNminScale "minScale" +#define XtNscale "scale" +#define XtNvmunix "vmunix" + +/* struct for callback */ +/* code + shared + buffer + free == 1.0 */ +typedef struct { + double code; + double cached; + double buffer; + double free; + double swap; +} MemStripChartCallbackData; + +typedef struct _MemStripChartRec *MemStripChartWidget; +typedef struct _MemStripChartClassRec *MemStripChartWidgetClass; + +extern WidgetClass memStripChartWidgetClass; + +#endif /* _XawMemStripChart_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/MemStripChart.o b/MemStripChart.o new file mode 100644 index 0000000..bcc7b5c Binary files /dev/null and b/MemStripChart.o differ diff --git a/XMem.ad b/XMem.ad new file mode 100644 index 0000000..8363e45 --- /dev/null +++ b/XMem.ad @@ -0,0 +1,10 @@ +XMem.input: false +*Label*Justify: left +*JumpScroll: 1 +*internalBorderWidth: 0 +*showGrip: FALSE +*codecolor: red +*cachedcolor: orange +*buffercolor: yellow +*freecolor: green +*swapcolor: blue diff --git a/get_mem.c b/get_mem.c new file mode 100644 index 0000000..c12d9a7 --- /dev/null +++ b/get_mem.c @@ -0,0 +1,42 @@ +/* + * get_mem.c + * get memory usage, from get_load.c derived + * + * Author: Hans-Helmut Buehmann 20. Jan. 1996 + * + * Modified for more recent kernels Helmut Geyer Oct. 1996 + */ + +#include +#include +#include +#include +#include "MemStripChart.h" + + +void GetMemLoadPoint(w, closure, call_data) /* Linux version */ + Widget w; /* unused */ + caddr_t closure; /* unused */ + caddr_t call_data; /* pointer to (MemStripChartCallbackData) return value */ +{ + MemStripChartCallbackData ret; + /* meminfo();*/ + + /*et.code = (double)(kb_main_used - kb_main_buffers - kb_main_cached) / kb_main_total; + ret.cached = (double)kb_main_cached / (double)kb_main_total; + ret.buffer = (double)kb_main_buffers / (double)kb_main_total; + ret.free = (double)kb_main_free / (double)kb_main_total; + ret.swap = (double)kb_swap_used / (double)kb_main_total; + + */ + + printf("test?\n"); + ret.code = 0.5; + ret.cached = 0.5; + ret.buffer = 0.5; + ret.free = 0.5; + ret.swap = 0.5; + + memcpy(call_data, &ret, sizeof(MemStripChartCallbackData)); +} + diff --git a/get_mem.h b/get_mem.h new file mode 100644 index 0000000..06b2e76 --- /dev/null +++ b/get_mem.h @@ -0,0 +1,18 @@ +/*********************************************************************** + * + * function prototypes for get_mem.c + * + * Author: Hans-Helmut B"uhmann 20. Jan. 1996 + * + ***********************************************************************/ +#ifndef __get_mem_h +#define __get_mem_h + +#include "MemStripChart.h" + +void GetMemLoadPoint( /* Linux version */ + Widget w, /* unused */ + caddr_t closure, /* unused */ + caddr_t call_data /* pointer to (MemStripChartCallbackData) return value */ +); +#endif /* __get_mem_h */ diff --git a/xmem.1x b/xmem.1x new file mode 100644 index 0000000..cc371fa --- /dev/null +++ b/xmem.1x @@ -0,0 +1,120 @@ +.TH XMEM 1x "Release 5, X Version 11" "memory display utility" +.SH NAME +xmem \- memory/swap usage display utility for X +.SH SYNOPSIS +.B xmem +.RB [\| \-toolkitoption ... \|] +.RB [\| \-update +.IR seconds \|] +.RB [\| \-hl +.IR color \|] +.RB [\| \-highlight +.IR color \|] +.RB [\| \-jumpscroll +.IR pixels \|] +.RB [\| \-label +.IR string \|] +.RB [\| \-nolabel \|] +.SH DESCRIPTION +The +.B XMEM +program displays the used amount of memory/swap. +.SH OPTIONS +.B XMEM +accepts all of the standard X Toolkit command line options (see X(1)). The order +of the options in unimportant. +.B XMEM +also accepts the following additional options: +.TP +.B \-hl color, \-highlight color +This option specifies the color of the scale lines. +(Xresource: *mem.highlight) +.TP +.B \-jumpscroll number-of-pixels +The number of pixels to shift the graph to the left when the graph reaches the +right edge of the window. The default value is 1/2 the width of the current +window. Smooth scrolling can be achieved by setting it to 1. +(Xresource: *mem.jumpScroll) +.TP +.B \-label string +The string to put into the label in the +.B XMEM +window. (default: hostname alias) +(Xresource: *label.label) +.TP +.B \-nolabel +If this command line option is specified then no label will be displayed above +the memory usage graph. +(Xresource: *showLabel) +.TP +.B \-update seconds +This option specifies the interval in seconds at which +.B XMEM +updates its display. The minimum amount of time allowed between updates is 1 +second. The default is 10. +(Xresource: *mem.update) +.TP +.B \-codecolor color +Color for used code and stack memory. The default is red. +(Xresource: *mem.codecolor) +.TP +.B \-cachedcolor color +Color for cached memory. The default is yellow. +(Xresource: *mem.cachedcolor) +.TP +.B \-buffercolor color +Color for buffer memory. The default is blue. +(Xresource: *mem.buffercolor) +.TP +.B \-freecolor color +Color for free memory. The default is green. +(Xresource: *mem.freecolor) +.TP +.B \-swapcolor color +Color for swap memory. The default is red. +(Xresource: *mem.swapcolor) +.SH RESOURCES +In addition to the resources available to each of the widgets used by +.B XMEM +there is one resource defined by the application itself. +.TP +.B showLabel (class Boolean) +If False then no label will be displayed. +.SH WIDGETS +In order to specify resources, it is useful to know the hierarchy of the widgets +which compose +.B XMEM. +In the notation below, indentation indicates hierarchical structure. The widget +class name is given first, followed by the widget instance name. +.sp +.nf +.ta .5i 1.0i 1.5i 2.0i +Xmem xmem + Paned paned + Label label + StripChart load +.fi +.sp +.SH ENVIRONMENT +.PP +.TP +.B DISPLAY +to get the default host and display number. +.TP +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH FILES +/etc/X11/app-defaults/XMem - specifies required resources +.SH SEE ALSO +X(1), xrdb(1), mem(4), Athena StripChart Widget. +.SH COPYRIGHT +Copyright 1988, Massachusetts Institute of Technology. +.br +See X(1) for a full statement of rights and permissions. +.SH AUTHORS +K. Shane Hartman (MIT-LCS) and Stuart A. Malone (MIT-LCS); +with features added by Jim Gettys (MIT-Athena), Bob Scheifler (MIT-LCS), Tony +Della Fera (MIT-Athena), and Chris Peterson (MIT-LCS). +.P +Updated 2007/04 by Michelle Konzack diff --git a/xmem.bit b/xmem.bit new file mode 100644 index 0000000..b4b038a --- /dev/null +++ b/xmem.bit @@ -0,0 +1,16 @@ +#define xload_width 32 +#define xload_height 32 +#define xload_x_hot 15 +#define xload_y_hot 16 +static unsigned char xload_bits[] = { + 0x00, 0x00, 0xc0, 0x03, 0x1e, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf8, 0x03, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xfe, 0x03, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0xff, 0x03, 0x00, 0xc0, 0xff, 0x03, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xe0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x03, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x03, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, + 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x03, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03}; diff --git a/xmem.c b/xmem.c new file mode 100644 index 0000000..126a18e --- /dev/null +++ b/xmem.c @@ -0,0 +1,242 @@ +/* + * xload - display system load average in a window + * + * Copyright 1989 Massachusetts Institute of Technology + * + * $XConsortium: xload.c,v 1.36 91/05/24 16:57:46 converse Exp $ + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "MemStripChart.h" +#include +#include + +/* #include */ + +#include "xmem.bit" + +extern void exit(); + +#include "get_mem.h" + +static void quit(); + +/* + * Definition of the Application resources structure. + */ + +typedef struct _XLoadResources { + Boolean show_label; + Boolean use_lights; +} XLoadResources; + +/* + * Command line options table. Only resources are entered here...there is a + * pass over the remaining options after XtParseCommand is let loose. + */ + +static XrmOptionDescRec options[] = { + {"-scale", "*load.minScale", XrmoptionSepArg, NULL}, + {"-update", "*load.update", XrmoptionSepArg, NULL}, + {"-hl", "*load.highlight", XrmoptionSepArg, NULL}, + {"-highlight", "*load.highlight", XrmoptionSepArg, NULL}, + {"-jumpscroll", "*load.jumpScroll", XrmoptionSepArg, NULL}, + {"-label", "*label.label", XrmoptionSepArg, NULL}, + {"-nolabel", "*showLabel", XrmoptionNoArg, "False"}, + {"-lights", "*useLights", XrmoptionNoArg, "True"}, +}; + +static XrmOptionDescRec options_mem[] = { + {"-scale", "*mem.minScale", XrmoptionSepArg, NULL}, + {"-update", "*mem.update", XrmoptionSepArg, NULL}, + {"-hl", "*mem.highlight", XrmoptionSepArg, NULL}, + {"-highlight", "*mem.highlight", XrmoptionSepArg, NULL}, + {"-codecolor", "*mem.codecolor", XrmoptionSepArg, NULL}, + {"-cahedcolor", "*mem.cachedcolor", XrmoptionSepArg, NULL}, + {"-buffercolor", "*mem.buffercolor", XrmoptionSepArg, NULL}, + {"-freecolor", "*mem.freecolor", XrmoptionSepArg, NULL}, + {"-swapcolor", "*mem.swapcolor", XrmoptionSepArg, NULL}, + {"-jumpscroll", "*mem.jumpScroll", XrmoptionSepArg, NULL}, + {"-label", "*label.label", XrmoptionSepArg, NULL}, + {"-nolabel", "*showLabel", XrmoptionNoArg, "False"}, + {"-lights", "*useLights", XrmoptionNoArg, "True"}, +}; + +/* + * The structure containing the resource information for the + * Xload application resources. + */ + +#define Offset(field) (XtOffsetOf(XLoadResources, field)) + +static XtResource my_resources[] = { + {"showLabel", XtCBoolean, XtRBoolean, sizeof(Boolean), + Offset(show_label), XtRImmediate, (XtPointer) TRUE}, + {"useLights", XtCBoolean, XtRBoolean, sizeof(Boolean), + Offset(use_lights), XtRImmediate, (XtPointer) FALSE}, +}; + +static XtResource my_resources_mem[] = { + {"showLabel", XtCBoolean, XtRBoolean, sizeof(Boolean), + Offset(show_label), XtRImmediate, (XtPointer) TRUE}, +}; + +#undef Offset + +static XLoadResources resources; + +static XtActionsRec xload_actions[] = { + { "quit", quit }, +}; +static Atom wm_delete_window; +static int light_update = 10 * 1000; + +/* + * Exit with message describing command line format. + */ + +void usage(char *progname) +{ + fprintf (stderr, "usage: %s [-options ...]\n\n", progname); + fprintf (stderr, "where options include:\n"); + fprintf (stderr, + " -display dpy X server on which to display\n"); + fprintf (stderr, + " -geometry geom size and location of window\n"); + fprintf (stderr, + " -fn font font to use in label\n"); + fprintf (stderr, + " -update seconds interval between updates\n"); + fprintf (stderr, + " -label string annotation text\n"); + fprintf (stderr, + " -bg color background color\n"); + fprintf (stderr, + " -fg color text color\n"); + + fprintf (stderr, + " -hl color scale color\n"); + fprintf (stderr, + " -codecolor color used code and stack memory color\n"); + fprintf (stderr, + " -cachedcolor color used cached memory color\n"); + fprintf (stderr, + " -buffercolor color used buffer memory color\n"); + fprintf (stderr, + " -freecolor color used free memory color\n"); + fprintf (stderr, + " -swapcolor color used swap memory color\n"); + fprintf (stderr, + " -nolabel removes the label from above the chart.\n"); + fprintf (stderr, + " -jumpscroll value number of pixels to scroll on overflow\n"); + fprintf (stderr, + "The reference line refers to the avaible installed ram\n"); + + fprintf (stderr, "\n"); + exit(1); +} + +int main(argc, argv) + int argc; + char **argv; +{ + XtAppContext app_con; + Widget toplevel, load, pane, label_wid, load_parent; + Arg args[1]; + Pixmap icon_pixmap = None; + char *label, host[256]; + char *lastslash; + + /* For security reasons, we reset our uid/gid after doing the necessary + system initialization and before calling any X routines. */ + + setgid(getgid()); /* reset gid first while still (maybe) root */ + setuid(getuid()); + + toplevel = XtAppInitialize(&app_con, "XMem", options_mem, XtNumber(options_mem), + &argc, argv, NULL, NULL, (Cardinal) 0); + + if (argc != 1) usage(argv[0]); + + XtGetApplicationResources( toplevel, (XtPointer) &resources, + my_resources_mem, XtNumber(my_resources_mem), + NULL, (Cardinal) 0); + /* + * This is a hack so that f.delete will do something useful in this + * single-window application. + */ + XtAppAddActions (app_con, xload_actions, XtNumber(xload_actions)); + XtOverrideTranslations(toplevel, + XtParseTranslationTable ("WM_PROTOCOLS: quit()")); + + XtSetArg (args[0], XtNiconPixmap, &icon_pixmap); + XtGetValues(toplevel, args, ONE); + if (icon_pixmap == None) { + XtSetArg(args[0], XtNiconPixmap, + XCreateBitmapFromData(XtDisplay(toplevel), + XtScreen(toplevel)->root, + (char *)xload_bits, + xload_width, xload_height)); + XtSetValues (toplevel, args, ONE); + } + + if (resources.show_label) { + pane = XtCreateManagedWidget ("paned", panedWidgetClass, + toplevel, NULL, ZERO); + + label_wid = XtCreateManagedWidget ("label", labelWidgetClass, + pane, NULL, ZERO); + + XtSetArg (args[0], XtNlabel, &label); + XtGetValues(label_wid, args, ONE); + + if ( strcmp("label", label) == 0 ) { + (void) XmuGetHostname (host, 255); + XtSetArg (args[0], XtNlabel, host); + XtSetValues (label_wid, args, ONE); + } + + load_parent = pane; + } + else + load_parent = toplevel; + + + load = XtCreateManagedWidget ("mem", memStripChartWidgetClass, + load_parent, NULL, ZERO); + XtAddCallback(load, XtNgetValue, (void*)GetMemLoadPoint, NULL); + + XtRealizeWidget (toplevel); + wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW", + False); + (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel), + &wm_delete_window, 1); + + XtAppMainLoop(app_con); +} + + +static void quit (w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (event->type == ClientMessage && + event->xclient.data.l[0] != wm_delete_window) { + XBell (XtDisplay(w), 0); + return; + } + XtDestroyApplicationContext(XtWidgetToApplicationContext(w)); + exit (0); +}