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

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

unix.superglobalmegacorp.com

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