Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/Load.c, revision 1.1.1.2

1.1       root        1: /* $Header: Load.c,v 1.2 87/09/12 12:43:16 swick Exp $ */
                      2: #ifndef lint
                      3: static char *sccsid = "@(#)Load.c      1.15    2/25/87";
                      4: #endif lint
                      5: 
                      6: /*
                      7:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      8:  * 
                      9:  *                         All Rights Reserved
                     10:  * 
                     11:  * Permission to use, copy, modify, and distribute this software and its 
                     12:  * documentation for any purpose and without fee is hereby granted, 
                     13:  * provided that the above copyright notice appear in all copies and that
                     14:  * both that copyright notice and this permission notice appear in 
                     15:  * supporting documentation, and that the name of Digital Equipment
                     16:  * Corporation not be used in advertising or publicity pertaining to
                     17:  * distribution of the software without specific, written prior permission.  
                     18:  * 
                     19:  * 
                     20:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     21:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     22:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     23:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     24:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     25:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     26:  * SOFTWARE.
                     27:  */
                     28: 
                     29: 
                     30: #include <stdio.h>
                     31: #include <strings.h>
                     32: #include "Xlib.h"
                     33: #include "Xutil.h"
                     34: #include "Intrinsic.h"
                     35: #include "Load.h"
                     36: #include "Atoms.h"
                     37: #include <nlist.h>
1.1.1.2 ! root       38: #include <time.h>
1.1       root       39: #include <sys/param.h>
                     40: 
                     41: extern long lseek();
                     42: 
                     43: /* Private Definitions */
                     44: 
                     45: typedef struct WidgetDataRec {
                     46:        Display *dpy;           /* widget display connection */
                     47:         Window window;          /* widget window */
                     48:         Dimension brwidth;     /* border width in pixels */
                     49:         Dimension width, height;       /* width/height in pixels */
                     50:         Position x, y;
                     51:         Pixel  fgpixel;        /* color index for text */
                     52:         Pixel  bgpixel;        /* color index for background */
                     53:         Pixel  brpixel;        /* pixel for border */
                     54:         XFontStruct    *fontstruct;    /* font for text */
                     55:         GC     myGC;           /* pointer to GraphicsContext */
                     56: /* start of graph stuff */
                     57:         int    update;         /* update frequence */
                     58:         int    scale;          /* scale factor */
                     59:         int     min_scale;     /* smallest scale factor */
                     60:         int     interval;      /* data point interval */
                     61:         char   *text;          /* label */
                     62:         double max_value;      /* Max Value in window */
                     63:         int    mapped;         /* is exposed */
                     64:         double valuedata[2048];/* record of data points */
                     65: /* start of xload stuff
                     66:         char *vmunix;          /* path of namelist */
                     67:         caddr_t cookie;
                     68:    } WidgetDataRec, *WidgetData;
                     69: 
                     70: 
                     71: /* Private Data */
                     72: 
                     73: static WidgetDataRec globaldata;
                     74: 
                     75: static int  initDone = 0;       /* initialization flag */
                     76: static XContext widgetContext;
                     77: static int def_border = 1;
                     78: static int def_width = 120;
                     79: static int def_height = 120;
                     80: static int def_update = 5;
                     81: static int def_x = 0;
                     82: static int def_y = 0;
                     83: static int def_scale = 1;
                     84: 
                     85: static Resource resourcelist[] = {
                     86:     {XtNwindow, XtCWindow, XrmRWindow,
                     87:        sizeof(Window), (caddr_t)&globaldata.window, (caddr_t)NULL},
                     88:     {XtNborderWidth, XtCBorderWidth, XrmRInt,
                     89:        sizeof(int), (caddr_t)&globaldata.brwidth, (caddr_t) &def_border},
                     90:     {XtNwidth, XtCWidth, XrmRInt,
                     91:        sizeof(int), (caddr_t)&globaldata.width, (caddr_t) &def_width},
                     92:     {XtNheight, XtCHeight, XrmRInt,
                     93:        sizeof(int), (caddr_t)&globaldata.height, (caddr_t) &def_height },
                     94:     {XtNx, XtCX, XrmRInt,
                     95:        sizeof(int), (caddr_t)&globaldata.x, (caddr_t) &def_x },
                     96:     {XtNy, XtCX, XrmRInt,
                     97:        sizeof(int), (caddr_t)&globaldata.y, (caddr_t) &def_y },
                     98:     {XtNupdate, XtCInterval, XrmRInt,
                     99:        sizeof(int), (caddr_t)&globaldata.update, (caddr_t) &def_update },
                    100:     {XtNscale, XtCScale, XrmRInt,
                    101:        sizeof(int), (caddr_t)&globaldata.scale, (caddr_t) &def_scale },
                    102:     {XtNminScale, XtCScale, XrmRInt,
                    103:        sizeof(int), (caddr_t)&globaldata.min_scale, (caddr_t) &def_scale },
                    104:     {XtNlabel, XtCLabel, XrmRString,
                    105:        sizeof(char *), (caddr_t)&globaldata.text, (caddr_t) "Amnesia" },
                    106:     {XtNforeground, XtCColor, XrmRPixel,
                    107:        sizeof(int), (caddr_t)&globaldata.fgpixel, (caddr_t)&XtDefaultFGPixel},
                    108:     {XtNbackground, XtCColor, XrmRPixel,
                    109:        sizeof(int), (caddr_t)&globaldata.bgpixel, (caddr_t)&XtDefaultBGPixel},
                    110:     {XtNborder, XtCColor, XrmRPixel,
                    111:        sizeof(int),(caddr_t)&globaldata.brpixel, (caddr_t)&XtDefaultFGPixel},
                    112:     {XtNfont, XtCFont, XrmRFontStruct,
                    113:        sizeof(XFontStruct *), (caddr_t)&globaldata.fontstruct, (caddr_t)NULL}
                    114: };
                    115: 
                    116: 
                    117: /****************************************************************
                    118:  *
                    119:  * Private Procedures
                    120:  *
                    121:  ****************************************************************/
                    122: 
                    123: static void LoadInitialize (dpy)
                    124: Display        *dpy;
                    125: {
                    126:     if(!initDone)
                    127:       globaldata.fontstruct = XLoadQueryFont(dpy,"fixed");
                    128:     widgetContext = XUniqueContext();
                    129: 
                    130:     initDone = 1;
                    131: }
                    132: 
                    133: 
                    134: /*
                    135:  * Given a display and window, get the widget data.
                    136:  */
                    137: 
                    138: static WidgetData DataFromWindow(dpy, window)
                    139: Display *dpy;
                    140: Window window;
                    141: {
                    142:     WidgetData result;
                    143:     if (XFindContext(dpy, window, widgetContext, (caddr_t *)&result))
                    144:        return NULL;
                    145:     return result;
                    146: }
                    147: 
                    148: static void Destroy();
                    149: 
                    150: /*
                    151:  *
                    152:  * Generic widget event handler
                    153:  *
                    154:  */
                    155: 
                    156: 
                    157: static XtEventReturnCode EventHandler(event, eventdata)
                    158: XEvent *event;
                    159: caddr_t eventdata;
                    160: {
                    161:     WidgetData         data = (WidgetData ) eventdata;
                    162: 
                    163:     switch (event->type) {
                    164:        case ConfigureNotify:
                    165:            data->height = event->xconfigure.height;
                    166:            data->width = event->xconfigure.width;
                    167:            break;
                    168: 
                    169:        case DestroyNotify:
                    170:                Destroy(data);
                    171:            break;
                    172:        
                    173:        case ClientMessage:
                    174:            if (((XClientMessageEvent *)event)->message_type == 
                    175:                  (unsigned) XtTimerExpired)
                    176:                  draw_it(data);
                    177:            break;
                    178:        
                    179:         case Expose:
                    180:            data->mapped = 1;
                    181:            if( ((XExposeEvent *)event)->count == 0)
                    182:                 data->interval = repaint_window(data);
                    183:            break;
                    184: 
                    185:          case NoExpose:
                    186:            data->mapped = 0;
                    187:            break;
                    188:     }
                    189: 
                    190:     return (XteventHandled);
                    191: }
                    192: 
                    193: /*
                    194:  *
                    195:  * Destroy the widget
                    196:  *
                    197:  */
                    198: 
                    199: static void Destroy(data)
                    200: WidgetData data;
                    201: {
                    202: 
                    203:     XtClearEventHandlers(data->dpy, data->window);
                    204:     (void) XtClearTimeOut(data->window, data->cookie);
                    205:     XtFree ((char *) data);
                    206: }
                    207: 
                    208: 
                    209: 
                    210: /****************************************************************
                    211:  *
                    212:  * Public Procedures
                    213:  *
                    214:  ****************************************************************/
                    215: 
                    216: Window XtLoadCreate(dpy, pw, arglist, argCount)
                    217: Display *dpy;
                    218: Window pw;                      /* parent window */
                    219: ArgList arglist;
                    220: int argCount;
                    221: {
                    222:     WidgetData data;
                    223:     int                eventmask;
                    224:     GCMask     valuemask;
                    225:     XrmNameList   names;
                    226:     XrmClassList        classes;
                    227:     XGCValues  myXGCV;
                    228:     if (!initDone)LoadInitialize (dpy);
                    229: 
                    230:     data = (WidgetData ) XtMalloc (sizeof (WidgetDataRec));
                    231: 
                    232:     /* Set Default Values */
                    233:     globaldata.dpy = dpy;
                    234:     XtGetResources(dpy,  resourcelist, XtNumber(resourcelist), arglist, argCount, pw,
                    235:        "load", "Load", &names, &classes);
                    236:     *data = globaldata;
                    237:     valuemask = GCForeground | GCFont | GCBackground;
                    238:     myXGCV.foreground = (*data).fgpixel;
                    239:     myXGCV.font = (*data).fontstruct->fid;
                    240:     myXGCV.background = data->bgpixel;
                    241:     (*data).myGC = XtGetGC(data->dpy, widgetContext, pw, valuemask, &myXGCV);
                    242: 
                    243:     if (data->window != NULL) {
                    244:        XWindowAttributes wi;
                    245:        /* set global data from window parameters */
                    246:        if (! XGetWindowAttributes(data->dpy,data->window, &wi)) {
                    247:            data->window = NULL;
                    248:        } else {
                    249:            data->brwidth = wi.border_width;
                    250:            data->width = wi.width;
                    251:            data->height = wi.height;
                    252:        }
                    253:     }
                    254:     if (data->window == NULL) {
                    255:        /* create the Load window */
                    256:          if(data->width >= 2048) data->width = 2047;
                    257:          data->window = XCreateSimpleWindow(data->dpy, pw, data->x, data->y,
                    258:                              data->width, data->height,
                    259:                              data->brwidth, data->brpixel, data->bgpixel);
                    260:     }
                    261: 
                    262:     XtSetNameAndClass(data->dpy, data->window, names, classes);
                    263:     XrmFreeNameList(names);
                    264:     XrmFreeClassList(classes);
                    265: 
                    266:     (void)XSaveContext(data->dpy, data->window, widgetContext, (caddr_t)data);
                    267: 
                    268:     /* set handler for expose, resize, and message events */
                    269: 
                    270:     eventmask = ExposureMask+StructureNotifyMask;
                    271:     XtSetEventHandler (
                    272:        data->dpy, data->window, (XtEventHandler)EventHandler,
                    273:        (unsigned long) eventmask, (caddr_t)data);
                    274: 
                    275:     XtSetTimeOut(data->window, XtNLoad,data->update*1000);
                    276: 
                    277:     return (data->window);
                    278: }
                    279:  
                    280: /*
                    281:  * Get Attributes
                    282:  */
                    283: 
                    284: void XtLoadGetValues (dpy, window, arglist, argCount)
                    285: Display *dpy;
                    286: Window window;
                    287: ArgList arglist;
                    288: int argCount;
                    289: {
                    290:     WidgetData data;
                    291:     data = DataFromWindow(dpy, window);
                    292:     if (data) {
                    293:        globaldata = *data;
                    294:        XtGetValues(resourcelist, XtNumber(resourcelist), arglist, argCount);
                    295:     }
                    296: }
                    297: 
                    298: /*
                    299:  * Set Attributes
                    300:  */
                    301: 
                    302: void XtLoadSetValues (dpy, window, arglist, argCount)
                    303: Display *dpy;
                    304: Window window;
                    305: ArgList arglist;
                    306: int argCount;
                    307: {
                    308:     WidgetData data;
                    309:     data = DataFromWindow(dpy, window);
                    310:     globaldata = *data;
                    311:     if (data == NULL) return;
                    312: 
                    313:     XtSetValues(resourcelist, XtNumber(resourcelist), arglist, argCount);
                    314: 
                    315:     if (globaldata.update != data->update) {
                    316:        (void) XtClearTimeOut(data->window, data->cookie);
                    317:        XtSetTimeOut(data->window, data->cookie, globaldata.update*1000);
                    318:        data->update = globaldata.update;
                    319:     }
                    320:     if (globaldata.brpixel != data->brpixel) {
                    321:        data->brpixel = globaldata.brpixel;
                    322:        if (data->brwidth != 0)
                    323:            XSetWindowBorder(data->dpy, data->window, data->brpixel);
                    324:     }
                    325:     if(!strcmp(globaldata.text, data->text)) {
                    326:        data->interval = repaint_window(data);
                    327:     }
                    328:     if(data->width >= 2048) data->width = 2047;
                    329:       
                    330:     *data = globaldata;
                    331: }
                    332: 
                    333: 
                    334: static draw_it(data)
                    335: WidgetDataRec *data;
                    336: {
                    337:        double value, GetLoadPoint();
                    338: 
                    339:        if (data->interval >= data->width) 
                    340:          data->interval = 
                    341:            repaint_window(data);
                    342:        /* Get the value, stash the point and draw corresponding line. */
                    343:      
                    344:        value = GetLoadPoint();
                    345:        /* Keep data->max_value up to date, and if this data point is off the
                    346:           graph, change the scale to make it fit. */
                    347:        if (value > data->max_value) {
                    348:            data->max_value = value;
                    349:            if (data->max_value > data->scale) {
                    350:                data->scale = ((int)data->max_value) + 1;
                    351:                data->interval = 
                    352:                  repaint_window(data);
                    353:            }
                    354:        }
                    355: 
                    356:        data->valuedata[data->interval] = value;
                    357:        if (data->mapped) {
                    358: 
                    359:            XDrawLine(data->dpy, data->window, data->myGC,
                    360:                  data->interval, (int)data->height, data->interval, 
                    361:                    (int)(data->height - (data->height * value) /data->scale));
                    362:            XFlush(data->dpy);              /* Flush output buffers */
                    363:        }
                    364:        data->interval++;                   /* Next point */
                    365: } /* draw_it */
                    366: 
                    367: /* Blts data according to current size, then redraws the load average window.
                    368:  * Next represents the number of valid points in data.  Returns the (possibly)
                    369:  * adjusted value of next.  If next is 0, this routine draws an empty window
                    370:  * (scale - 1 lines for graph).  If next is less than the current window width,
                    371:  * the returned value is identical to the initial value of next and data is
                    372:  * unchanged.  Otherwise keeps half a window's worth of data.  If data is
                    373:  * changed, then data->max_value is updated to reflect the largest data point.
                    374:  */
                    375: 
                    376: static int repaint_window(data)
                    377: WidgetDataRec *data;
                    378: {
                    379:     register int i, j;
                    380:     register int next = data->interval;
                    381:     extern void bcopy(), exit();
                    382: 
                    383:     if (data->mapped)
                    384:        XClearWindow(data->dpy, data->window);
                    385:     if (next >= data->width) {
                    386:        j = data->width >> 1;
                    387:        bcopy((char *)(data->valuedata + next - j),
                    388:              (char *)(data->valuedata), j * sizeof(double));
                    389:        next = j;
                    390:        /* Since we just lost some data, recompute the data->max_value. */
                    391:        data->max_value = 0.0;
                    392:        for (i = 0; i < next; i++) {
                    393:            if (data->valuedata[i] > data->max_value) 
                    394:              data->max_value = data->valuedata[i];
                    395:        }
                    396:     }
                    397: 
                    398:     /* Compute the minimum scale required to graph the data, but don't go
                    399:        lower than min_scale. */
                    400:     if (data->max_value > data->min_scale) 
                    401:       data->scale = ((int)data->max_value) + 1;
                    402:     else 
                    403:       data->scale = data->min_scale;
                    404: 
                    405:     if (!data->mapped) return(next);
                    406: 
                    407:     /* Print hostname */
                    408:     XDrawString(data->dpy, data->window, data->myGC, 2, 
                    409:          2 + data->fontstruct->ascent, data->text, strlen(data->text));
                    410: 
                    411:     /* Draw graph reference lines */
                    412:     for (i = 1; i < data->scale; i++) {
                    413:        j = (i * data->height) / data->scale;
                    414:        XDrawLine(data->dpy, data->window, data->myGC, 0, j,
                    415:                  (int)data->width, j);
                    416:     }
                    417: 
                    418:     /* Draw data point lines. */
                    419:     for (i = 0; i < next; i++)
                    420:        XDrawLine(data->dpy, data->window, data->myGC , i, (int)data->height,
                    421:              i, (int)(data->height-(data->valuedata[i] * data->height)
                    422:                      /data->scale));
                    423:     return(next);
                    424: }
                    425: 
                    426: #define KMEM_FILE "/dev/kmem"
                    427: #define KMEM_ERROR "cannot open /dev/kmem"
                    428: 
                    429: static struct nlist namelist[] = {         /* namelist for vmunix grubbing */
                    430: #define LOADAV 0
                    431:     {"_avenrun"},
                    432:     {0}
                    433: };
                    434: 
                    435: static double GetLoadPoint()
                    436: {
1.1.1.2 ! root      437:        float loadavg;
1.1       root      438:        static int init = 0;
                    439:        static kmem;
                    440:        static long loadavg_seek;
                    441:        extern void nlist();
                    442:        
                    443:        if(!init)   {
1.1.1.2 ! root      444:            nlist( "/unix", namelist);
1.1       root      445:            if (namelist[LOADAV].n_type == 0){
                    446:                xload_error("xload: cannot get name list");
                    447:                exit(-1);
                    448:            }
                    449:            loadavg_seek = namelist[LOADAV].n_value;
1.1.1.2 ! root      450:            kmem = open(KMEM_FILE, 0);
1.1       root      451:            if (kmem < 0) xload_error(KMEM_ERROR);
                    452:            init = 1;
                    453:        }
                    454:        
                    455: 
                    456:        (void) lseek(kmem, loadavg_seek, 0);
1.1.1.2 ! root      457:        (void) read(kmem, (char *)&loadavg, sizeof(float));
        !           458:        return((double)loadavg);
1.1       root      459: }
                    460: 
                    461: static xload_error(str)
                    462: char *str;
                    463: {
                    464:     extern void exit();
                    465: 
                    466:     (void) fprintf(stderr,"xload: %s\n",str);
                    467:     exit(-1);
                    468: }

unix.superglobalmegacorp.com

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