Annotation of researchv9/X11/src/X.V11R1/lib/Xtk/Load.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char rcsid[] = "$Header: Load.c,v 1.12 87/09/13 22:50:22 newman Exp $";
                      3: #endif lint
                      4: 
                      5: /*
                      6:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      7:  * 
                      8:  *                         All Rights Reserved
                      9:  * 
                     10:  * Permission to use, copy, modify, and distribute this software and its 
                     11:  * documentation for any purpose and without fee is hereby granted, 
                     12:  * provided that the above copyright notice appear in all copies and that
                     13:  * both that copyright notice and this permission notice appear in 
                     14:  * supporting documentation, and that the name of Digital Equipment
                     15:  * Corporation not be used in advertising or publicity pertaining to
                     16:  * distribution of the software without specific, written prior permission.  
                     17:  * 
                     18:  * 
                     19:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     20:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     21:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     22:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     23:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     24:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     25:  * SOFTWARE.
                     26:  */
                     27: #ifndef lint
                     28: static char *sccsid = "@(#)Load.c      1.15    2/25/87";
                     29: #endif lint
                     30: 
                     31: #include <stdio.h>
                     32: #include <string.h>
                     33: #include "Xlib.h"
                     34: #include "Xutil.h"
                     35: #include "Intrinsic.h"
                     36: #include "Load.h"
                     37: #include "LoadP.h"
                     38: #include "Atoms.h"
                     39: #include <nlist.h>
                     40: #include <sys/time.h>
                     41: #include <sys/file.h>
                     42: #include <sys/param.h>
                     43: 
                     44: extern long lseek();
                     45: extern void exit();
                     46: 
                     47: /* Private Data */
                     48: 
                     49: #define offset(field) XtOffset(LoadWidget,load.field)
                     50: #define goffset(field) XtOffset(Widget,core.field)
                     51: 
                     52: static XtResource resources[] = {
                     53:     {XtNwidth, XtCWidth, XrmRInt, sizeof(int),
                     54:        goffset(width), XrmRString, "120"},
                     55:     {XtNheight, XtCHeight, XrmRInt, sizeof(int),
                     56:        goffset(height), XrmRString, "120"},
                     57:     {XtNupdate, XtCInterval, XrmRInt, sizeof(int),
                     58:         offset(update), XrmRString, "5"},
                     59:     {XtNscale, XtCScale, XrmRInt, sizeof(int),
                     60:         offset(scale), XrmRString, "1"},
                     61:     {XtNminScale, XtCScale, XrmRInt, sizeof(int),
                     62:         offset(min_scale), XrmRString, "1"},
                     63:     {XtNlabel, XtCLabel, XrmRString, sizeof(char *),
                     64:         offset(text), XrmRString, "Amnesia"},
                     65:     {XtNforeground, XtCForeground, XrmRPixel, sizeof(Pixel),
                     66:         offset(fgpixel), XrmRString, "Black"},
                     67:     {XtNfont, XtCFont, XrmRFontStruct, sizeof(XFontStruct *),
                     68:         offset(font), XrmRString, "fixed"},
                     69: };
                     70: 
                     71: #undef offset
                     72: #undef goffset
                     73: 
                     74: static void Initialize(), Realize(), Destroy(), Redisplay();
                     75: static Boolean SetValues();
                     76: static int repaint_window();
                     77: 
                     78: LoadClassRec loadClassRec = {
                     79:     { /* core fields */
                     80:     /* superclass */      &widgetClassRec,
                     81:     /* class_name */       "Load",
                     82:     /* size */            sizeof(LoadRec),
                     83:     /* class_initialize */ NULL,
                     84:     /* class_inited */     FALSE,
                     85:     /* initialize */      Initialize,
                     86:     /* realize */         Realize,
                     87:     /* actions */         NULL,
                     88:     /* num_actions */      0,
                     89:     /* resources */       resources,
                     90:     /* resource_count*/    XtNumber(resources),
                     91:     /* xrm_class */        NULL,
                     92:     /* compress_motion */  TRUE,
                     93:     /* compress_exposure*/ TRUE,
                     94:     /* visible_interest */ FALSE,
                     95:     /* destroy */          Destroy,
                     96:     /* resize */           NULL,
                     97:     /* expose */          Redisplay,
                     98:     /* set_values */       SetValues,
                     99:     /* accept_focus */     NULL,
                    100:     }
                    101: };
                    102: 
                    103: WidgetClass loadWidgetClass = (WidgetClass) &loadClassRec;
                    104: 
                    105: /****************************************************************
                    106:  *
                    107:  * Private Procedures
                    108:  *
                    109:  ****************************************************************/
                    110: 
                    111: static void draw_it();
                    112: 
                    113: static void EventHandler(gw, closure, event)
                    114:     Widget gw;
                    115:     char *closure;
                    116:     XEvent *event;
                    117: {
                    118:     if (event->type == ClientMessage && event->xclient.message_type == XtTimerExpired)
                    119:         draw_it ((LoadWidget)gw);
                    120: }
                    121: 
                    122: static void Initialize (greq, gnew)
                    123:     Widget greq, gnew;
                    124: {
                    125:     LoadWidget w = (LoadWidget)gnew;
                    126:     XtGCMask   valuemask;
                    127:     XGCValues  myXGCV;
                    128: 
                    129:     valuemask = GCForeground | GCFont | GCBackground;
                    130:     myXGCV.foreground = w->load.fgpixel;
                    131:     myXGCV.font = w->load.font->fid;
                    132:     myXGCV.background = w->core.background_pixel;
                    133:     w->load.myGC = XtGetGC(w, valuemask, &myXGCV);
                    134: 
                    135:     XtAddEventHandler (gnew, 0, TRUE, EventHandler, NULL);
                    136: 
                    137:     w->load.interval_id = XtAddTimeOut(gnew, w->load.update*1000);
                    138:     w->load.interval = 0;
                    139:     w->load.max_value = 0.0;
                    140: }
                    141:  
                    142: static void Realize (gw, valueMask, attrs)
                    143:      Widget gw;
                    144:      XtValueMask valueMask;
                    145:      XSetWindowAttributes *attrs;
                    146: {
                    147:      gw->core.window = XCreateWindow (XtDisplay(gw), gw->core.parent->core.window,
                    148:          gw->core.x, gw->core.y, gw->core.width, gw->core.height, gw->core.border_width,
                    149:           gw->core.depth, InputOutput, /* visualID */ CopyFromParent, valueMask, attrs);
                    150: }
                    151: 
                    152: static void Destroy (gw)
                    153:      Widget gw;
                    154: {
                    155:      LoadWidget w = (LoadWidget)gw;
                    156:      XtRemoveTimeOut (w->load.interval_id);
                    157:      XtDestroyGC (w->load.myGC);
                    158: }
                    159: 
                    160: static void Redisplay(gw)
                    161:      Widget gw;
                    162: {
                    163:      (void) repaint_window ((LoadWidget)gw);
                    164: }
                    165: 
                    166: static void draw_it(w)
                    167: LoadWidget w;
                    168: {
                    169:        double value, GetLoadPoint();
                    170: 
                    171:        if (w->load.interval >= w->core.width) 
                    172:          w->load.interval = 
                    173:            repaint_window(w);
                    174:        /* Get the value, stash the point and draw corresponding line. */
                    175:      
                    176:        value = GetLoadPoint();
                    177:        /* Keep w->load.max_value up to date, and if this data point is off the
                    178:           graph, change the scale to make it fit. */
                    179:        if (value > w->load.max_value) {
                    180:            w->load.max_value = value;
                    181:            if (w->load.max_value > w->load.scale) {
                    182:                w->load.scale = ((int)w->load.max_value) + 1;
                    183:                w->load.interval = 
                    184:                  repaint_window(w);
                    185:            }
                    186:        }
                    187: 
                    188:        w->load.valuedata[w->load.interval] = value;
                    189:        if (XtIsRealized(w)) {
                    190:            XDrawLine(XtDisplay(w), XtWindow(w), w->load.myGC,
                    191:                  w->load.interval, w->core.height, w->load.interval, 
                    192:                    (int)(w->core.height - (w->core.height * value) /w->load.scale));
                    193:            XFlush(XtDisplay(w));                   /* Flush output buffers */
                    194:        }
                    195:        w->load.interval++;                 /* Next point */
                    196: } /* draw_it */
                    197: 
                    198: /* Blts data according to current size, then redraws the load average window.
                    199:  * Next represents the number of valid points in data.  Returns the (possibly)
                    200:  * adjusted value of next.  If next is 0, this routine draws an empty window
                    201:  * (scale - 1 lines for graph).  If next is less than the current window width,
                    202:  * the returned value is identical to the initial value of next and data is
                    203:  * unchanged.  Otherwise keeps half a window's worth of data.  If data is
                    204:  * changed, then w->load.max_value is updated to reflect the largest data point.
                    205:  */
                    206: 
                    207: static int repaint_window(w)
                    208: LoadWidget w;
                    209: {
                    210:     register int i, j;
                    211:     register int next = w->load.interval;
                    212:     extern void bcopy();
                    213: 
                    214:     if (next >= w->core.width) {
                    215:        j = w->core.width >> 1;
                    216:        bcopy((char *)(w->load.valuedata + next - j),
                    217:              (char *)(w->load.valuedata), j * sizeof(double));
                    218:        next = j;
                    219:        /* Since we just lost some data, recompute the w->load.max_value. */
                    220:        w->load.max_value = 0.0;
                    221:        for (i = 0; i < next; i++) {
                    222:            if (w->load.valuedata[i] > w->load.max_value) 
                    223:              w->load.max_value = w->load.valuedata[i];
                    224:        }
                    225:     }
                    226: 
                    227:     /* Compute the minimum scale required to graph the data, but don't go
                    228:        lower than min_scale. */
                    229:     if (w->load.max_value > w->load.min_scale) 
                    230:       w->load.scale = ((int)w->load.max_value) + 1;
                    231:     else 
                    232:       w->load.scale = w->load.min_scale;
                    233: 
                    234:     if (XtIsRealized(w)) {
                    235:        Display *dpy = XtDisplay(w);
                    236:        Window win = XtWindow(w);
                    237: 
                    238:        XClearWindow(dpy, win);
                    239: 
                    240:        /* Print hostname */
                    241:        XDrawString(dpy, win, w->load.myGC, 2, 
                    242:              2 + w->load.font->ascent, w->load.text, strlen(w->load.text));
                    243: 
                    244:        /* Draw graph reference lines */
                    245:        for (i = 1; i < w->load.scale; i++) {
                    246:            j = (i * w->core.height) / w->load.scale;
                    247:            XDrawLine(dpy, win, w->load.myGC, 0, j,
                    248:                      (int)w->core.width, j);
                    249:        }
                    250: 
                    251:        /* Draw data point lines. */
                    252:        for (i = 0; i < next; i++)
                    253:            XDrawLine(dpy, win, w->load.myGC, i, w->core.height,
                    254:                  i, (int)(w->core.height-(w->load.valuedata[i] * w->core.height)
                    255:                          /w->load.scale));
                    256:         }
                    257: 
                    258:     return(next);
                    259: }
                    260: 
                    261: #define KMEM_FILE "/dev/kmem"
                    262: #define KMEM_ERROR "cannot open /dev/kmem"
                    263: 
                    264: static struct nlist namelist[] = {         /* namelist for vmunix grubbing */
                    265: #define LOADAV 0
                    266:     {"_avenrun"},
                    267:     {0}
                    268: };
                    269: 
                    270: static double GetLoadPoint()
                    271: {
                    272:        double loadavg;
                    273:        static int init = 0;
                    274:        static kmem;
                    275:        static long loadavg_seek;
                    276:        extern void nlist();
                    277:        
                    278:        if(!init)   {
                    279:            nlist( "/vmunix", namelist);
                    280:            if (namelist[LOADAV].n_type == 0){
                    281:                xload_error("xload: cannot get name list");
                    282:                exit(-1);
                    283:            }
                    284:            loadavg_seek = namelist[LOADAV].n_value;
                    285:            kmem = open(KMEM_FILE, O_RDONLY);
                    286:            if (kmem < 0) xload_error(KMEM_ERROR);
                    287:            init = 1;
                    288:        }
                    289:        
                    290: 
                    291:        (void) lseek(kmem, loadavg_seek, 0);
                    292: #ifdef sun
                    293:        {
                    294:                long temp;
                    295:                (void) read(kmem, (char *)&temp, sizeof(long));
                    296:                loadavg = (double)temp/FSCALE;
                    297:        }
                    298: #else
                    299:        (void) read(kmem, (char *)&loadavg, sizeof(double));
                    300: #endif
                    301:        return(loadavg);
                    302: }
                    303: 
                    304: static xload_error(str)
                    305: char *str;
                    306: {
                    307:     (void) fprintf(stderr,"xload: %s\n",str);
                    308:     exit(-1);
                    309: }
                    310: 
                    311: static Boolean SetValues (w, newvals)
                    312:    Widget w, newvals;
                    313: {
                    314: return (FALSE);
                    315: }
                    316: 
                    317: #ifdef notdef
                    318: void XtLoadSetValues (dpy, window, arglist, argCount)
                    319: Display *dpy;
                    320: Window window;
                    321: ArgList arglist;
                    322: int argCount;
                    323: {
                    324:     WidgetData data;
                    325:     data = DataFromWindow(dpy, window);
                    326:     globaldata = *data;
                    327:     if (data == NULL) return;
                    328: 
                    329:     XtSetValues(resourcelist, XtNumber(resourcelist), arglist, argCount);
                    330: 
                    331:     if (globaldata.update != data->update) {
                    332:        (void) XtClearTimeOut(data->window, data->cookie);
                    333:        XtSetTimeOut(data->window, data->cookie, globaldata.update*1000);
                    334:        data->update = globaldata.update;
                    335:     }
                    336:     if (globaldata.brpixel != data->brpixel) {
                    337:        data->brpixel = globaldata.brpixel;
                    338:        if (data->brwidth != 0)
                    339:            XSetWindowBorder(data->dpy, data->window, data->brpixel);
                    340:     }
                    341:     if(!strcmp(globaldata.text, data->text)) {
                    342:        data->interval = repaint_window(data);
                    343:     }
                    344:     if(w->core.width >= 2048) w->core.width = 2047;
                    345:       
                    346:     *data = globaldata;
                    347: }
                    348: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.