home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume4 / xtacho / part01 / xtacho.c < prev    next >
C/C++ Source or Header  |  1989-07-19  |  12KB  |  481 lines

  1. static char     sccsid[] = "@(#)xtacho.c    1.9   7/18/89";
  2.  
  3. /*
  4.  * xtacho - The cpu load tachometer for X11
  5.  * 
  6.  * Author: Kazuhiko Shutoh, 1989.
  7.  * 
  8.  * Permission to use, copy, modify and distribute without charge this software,
  9.  * documentation, images, etc. is granted, provided that this comment and the
  10.  * author's name is retained.  The author assumes no responsibility for lost
  11.  * sleep as a consequence of use of this software.
  12.  * 
  13.  * Send any comments, bug reports, etc. to: shutoh@isl.yamaha.JUNET or, 
  14.  * for oversea: shutoh%isl.yamaha.JUNET%kddlab@uunet.uu.net  
  15.  *
  16.  */
  17.  
  18. #include <X11/Intrinsic.h>
  19. #include <X11/StringDefs.h>
  20. #include <X11/Shell.h>
  21. #include <X11/Box.h>
  22. #include <X11/Label.h>
  23. #include <X11/Command.h>
  24. #include <X11/Form.h>
  25. #include <stdio.h>
  26. #include <math.h>
  27. #include <rpcsvc/rstat.h>
  28. #include "xtacho.h"
  29. #include "xtacho.icon"
  30.  
  31. XtCallbackProc  redraw_callback();
  32. XtTimerCallbackProc PollingCpuStatus();
  33. void            SetupTacho();
  34. void            GetGraphicContexts();
  35. void            Usage();
  36. void            DrawTachometer();
  37. void            FastFillCircle();
  38. void            DrawGauge();
  39. void            DrawNumbers();
  40. void            DrawLabelString();
  41. void            DrawSingleNumber();
  42. void            DrawNeedle();
  43.  
  44. Widget          toplevel, base, info, meter;
  45. GC              gcForeground, gcBackground, gcNeedle;
  46.  
  47. char            hostname[MAXCHARS];
  48. unsigned char   monitor_item;
  49. long            update;
  50. Cardinal        current_status = 0;
  51. Cardinal        old_status = 0;
  52. Cardinal        old_status_time = 0;
  53.  
  54. main(argc, argv)
  55.     int             argc;
  56.     char          **argv;
  57. {
  58.  
  59.     Arg             args[10];
  60.     Cardinal        i;
  61.     XtIntervalId    intervalId;
  62.     XtTranslations  newTranslations;
  63.     static XtActionsRec redrawActions[] = {
  64.     {"expose", (XtCallbackProc) redraw_callback},
  65.     {"resize", (XtCallbackProc) redraw_callback}};
  66.  
  67.     static char    *overrideTranslations =
  68.     "<Expose>:    expose() \n\
  69.      <ResReq>:    expose()";
  70.  
  71.     struct statstime cpu_status;
  72.     char            label[MAXCHARS];
  73.  
  74.  
  75.     toplevel = XtInitialize("xtacho", "XTacho", NULL, 0, &argc, argv);
  76.  
  77.     i = 0;
  78.     XtSetArg(args[0], XtNiconPixmap,
  79.          XCreateBitmapFromData(XtDisplay(toplevel),
  80.                        XtScreen(toplevel)->root, xtacho_bits,
  81.                        xtacho_width, xtacho_height));i++;
  82.     XtSetValues(toplevel, args, i);
  83.  
  84.     SetupTacho(argc, argv);
  85.  
  86.     base = XtCreateManagedWidget("base", formWidgetClass, toplevel, NULL, 0);
  87.  
  88.     switch (monitor_item) {
  89.     case USER_CPU:
  90.         sprintf(label, "%s : User", hostname);
  91.         break;
  92.  
  93.     case SYSTEM_CPU:
  94.         sprintf(label, "%s : System", hostname);
  95.         break;
  96.  
  97.     case IDLE_CPU:
  98.         sprintf(label, "%s : Idle", hostname);
  99.         break;
  100.  
  101.     default:
  102.         break;
  103.     }
  104.  
  105.     i = 0;
  106.     XtSetArg(args[i], XtNlabel, label);i++;
  107.     XtSetArg(args[i], XtNwidth, 100);i++;
  108.     info = XtCreateManagedWidget("info", labelWidgetClass, base, args, i);
  109.  
  110.     i = 0;
  111.     XtSetArg(args[i], XtNwidth, 100);i++;
  112.     XtSetArg(args[i], XtNheight, 100);i++;
  113.     XtSetArg(args[i], XtNborderWidth, 0);i++;
  114.     XtSetArg(args[i], XtNfromVert, info);i++;
  115.     meter = XtCreateManagedWidget("meter", boxWidgetClass, base, args, i);
  116.  
  117.     GetGraphicContexts(meter);
  118.  
  119.     XtAddActions(redrawActions, XtNumber(redrawActions));
  120.     newTranslations = XtParseTranslationTable(overrideTranslations);
  121.     XtOverrideTranslations(meter, newTranslations);
  122.  
  123.     rstat(hostname, &cpu_status);
  124.  
  125.     old_status_time = cpu_status.cp_time[monitor_item];
  126.  
  127.  
  128.     /* Interval timer start     */
  129.  
  130.     intervalId = XtAddTimeOut(update, PollingCpuStatus, NULL);
  131.  
  132.     XtRealizeWidget(toplevel);
  133.     XtMainLoop();
  134. }
  135.  
  136. void
  137. SetupTacho(ac, av)
  138.     int             ac;
  139.     char          **av;
  140. {
  141.  
  142.     Cardinal        count;
  143.  
  144.     /* Setup default     */
  145.  
  146.     gethostname(hostname, 256);
  147.     monitor_item = USER_CPU;
  148.     update = 3000;
  149.  
  150.     if (ac > 2)
  151.         for (count = 1; count < ac; count++) {
  152.             if ((strcmp("-host", av[count]) == 0) && (count + 1 <= ac))
  153.                 strcpy(hostname, av[++count]);
  154.             else if ((strcmp("-update", av[count]) == 0) && (count + 1 <= ac))
  155.                 update = atol(av[++count]) * (long) 1000;
  156.             else if ((strcmp("-mon", av[count]) == 0) && (count + 1 <= ac)) {
  157.                 if (strcmp("sys", av[count + 1]) == 0)
  158.                     monitor_item = SYSTEM_CPU;
  159.                 else if (strcmp("user", av[count + 1]) == 0)
  160.                     monitor_item = USER_CPU;
  161.                 else if (strcmp("idle", av[count + 1]) == 0)
  162.                     monitor_item = IDLE_CPU;
  163.                 else
  164.                     Usage();
  165.                 count++;
  166.             } else
  167.                 Usage();
  168.         }
  169. }
  170.  
  171. void
  172. GetGraphicContexts(w)
  173.     Widget          w;
  174. {
  175.  
  176.     Arg             args[2];
  177.     XGCValues       gcv;
  178.  
  179.     XtSetArg(args[0], XtNbackground, 0);
  180.     XtSetArg(args[1], XtNborderColor, 0);
  181.     XtGetValues(w, args, XtNumber(args));
  182.  
  183.     gcv.foreground = args[1].value;
  184.     gcForeground = XtGetGC(w, GCForeground, &gcv);
  185.  
  186.     gcv.foreground = args[0].value;
  187.     gcBackground = XtGetGC(w, GCForeground, &gcv);
  188.  
  189.     gcv.foreground = args[0].value;
  190.     gcv.foreground = args[0].value;
  191.     gcv.function = GXinvert;
  192.     gcNeedle = XtGetGC(w, GCFunction, &gcv);
  193. }
  194.  
  195. void
  196. Usage()
  197. {
  198.  
  199.     fprintf(stderr, "xtacho <Toolkit Options> [-host hostname] [-mon sys|user|idle] [-update second]\n");
  200.  
  201.     exit(-1);
  202.  
  203. }
  204.  
  205. XtCallbackProc
  206. redraw_callback(w, event, params, nparams)
  207.     Widget          w;
  208.     XEvent         *event;
  209.     String         *params;
  210.     Cardinal       *nparams;
  211. {
  212.  
  213.     DrawTachometer(w);
  214. }
  215.  
  216. void
  217. DrawTachometer(w)
  218.     Widget          w;
  219. {
  220.  
  221.     double          tmp;
  222.     Arg             args[2];
  223.     Cardinal        d_rx;
  224.     Cardinal        d_ry;
  225.     Cardinal        d_width;
  226.     Cardinal        d_height;
  227.  
  228.  
  229.     XtSetArg(args[0], XtNwidth, 0);
  230.     XtSetArg(args[1], XtNheight, 0);
  231.     XtGetValues(w, args, XtNumber(args));
  232.  
  233.     d_rx = args[0].value / 2 + 1;
  234.     d_ry = args[1].value / 2 + 1;
  235.  
  236.     /* Draw meter shape */
  237.  
  238.     d_width = args[0].value;
  239.     d_height = args[1].value;
  240.  
  241.     FastFillCircle(w, gcForeground, d_rx, d_ry, d_width, d_height);
  242.  
  243.     d_width = (double) (args[0].value) * 0.95;
  244.     d_height = (double) (args[1].value) * 0.95;
  245.  
  246.     FastFillCircle(w, gcBackground, d_rx, d_ry, d_width, d_height);
  247.  
  248.     d_width = (double) (args[0].value) * 0.1;
  249.     d_height = (double) (args[1].value) * 0.1;
  250.  
  251.     FastFillCircle(w, gcForeground, d_rx, d_ry, d_width, d_height);
  252.  
  253.     /* Draw gauge */
  254.  
  255.     DrawGauge(w, gcForeground, d_rx, d_ry);
  256.  
  257.     DrawNeedle(w, gcNeedle, current_status);
  258.  
  259. }
  260.  
  261. void
  262. FastFillCircle(w, gc, dx, dy, wx, wy)
  263.     Widget          w;
  264.     GC              gc;
  265.     Cardinal        dx;
  266.     Cardinal        dy;
  267.     Cardinal        wx;
  268.     Cardinal        wy;
  269. {
  270.  
  271.     XPoint          points[360];
  272.     Cardinal        angle;
  273.  
  274.     for (angle = 0; angle < 360; angle++) {
  275.         points[angle].x = (short) (sin((double) angle * PI / 180.0) * ((double) wx / 2.0) + (double) dx);
  276.         points[angle].y = (short) (cos((double) angle * PI / 180.0) * ((double) wy / 2.0) + (double) dy);
  277.     }
  278.  
  279.     XFillPolygon(XtDisplay(w), XtWindow(w), gc, points, 360, Complex, CoordModeOrigin);
  280.  
  281. }
  282.  
  283. void
  284. DrawGauge(w, gc, rx, ry)
  285.     Widget          w;
  286.     GC              gc;
  287.     Cardinal        rx;
  288.     Cardinal        ry;
  289. {
  290.  
  291.     XPoint          points[4];
  292.     double          step;
  293.     Cardinal        in_gauge_x, in_gauge_y;
  294.     Cardinal        out_gauge_x, out_gauge_y;
  295.     Cardinal        number_x, number_y;
  296.  
  297.     for (step = 330.0; step >= 30.0; step -= 3) {
  298.         in_gauge_x = sin(step * PI / 180.0) * rx * 0.8 + rx;
  299.         in_gauge_y = cos(step * PI / 180.0) * ry * 0.8 + ry;
  300.         out_gauge_x = sin(step * PI / 180.0) * rx * 0.85 + rx;
  301.         out_gauge_y = cos(step * PI / 180.0) * ry * 0.85 + ry;
  302.  
  303.         if ((Cardinal) (step) % 30 == 0) {
  304.             points[0].x = sin((step + 1.0) * PI / 180.0) * rx * 0.75 + rx;
  305.             points[0].y = cos((step + 1.0) * PI / 180.0) * ry * 0.75 + ry;
  306.             points[1].x = sin((step - 1.0) * PI / 180.0) * rx * 0.75 + rx;
  307.             points[1].y = cos((step - 1.0) * PI / 180.0) * ry * 0.75 + ry;
  308.             points[2].x = sin((step - 1.0) * PI / 180.0) * rx * 0.85 + rx;
  309.             points[2].y = cos((step - 1.0) * PI / 180.0) * ry * 0.85 + ry;
  310.             points[3].x = sin((step + 1.0) * PI / 180.0) * rx * 0.85 + rx;
  311.             points[3].y = cos((step + 1.0) * PI / 180.0) * ry * 0.85 + ry;
  312.  
  313.             XFillPolygon(XtDisplay(w), XtWindow(w), gc, points, 4, Complex, CoordModeOrigin);
  314.  
  315.             number_x = sin((step + 1.0) * PI / 180.0) * rx * 0.65 + rx;
  316.             number_y = cos((step + 1.0) * PI / 180.0) * ry * 0.65 + ry;
  317.  
  318.             DrawNumbers(w, gc, (unsigned char) ((330.0 - step) / 30.0), number_x, number_y, rx, ry);
  319.  
  320.         } else
  321.             XDrawLine(XtDisplay(w), XtWindow(w), gc, in_gauge_x, in_gauge_y, out_gauge_x, out_gauge_y);
  322.  
  323.     }
  324.  
  325.     DrawLabelString(w, gc, rx, ry);
  326.  
  327. }
  328.  
  329. void
  330. DrawNumbers(w, gc, which, x, y, width, height)
  331.     Widget          w;
  332.     GC              gc;
  333.     unsigned char   which;
  334.     Cardinal        x, y, width, height;
  335. {
  336.  
  337.     /* Draw Numbers     */
  338.  
  339.     if (which == 10) {
  340.         DrawSingleNumber(w, gc, 1, (Cardinal) ((double) x * 0.9), y, width, height);
  341.         DrawSingleNumber(w, gc, 0, x, y, width, height);
  342.     } else
  343.         DrawSingleNumber(w, gc, which, x, y, width, height);
  344.  
  345. }
  346.  
  347.  
  348. void
  349. DrawLabelString(w, gc, width, height)
  350.     Widget          w;
  351.     GC              gc;
  352.     Cardinal        width;
  353.     Cardinal        height;
  354. {
  355.  
  356.     XPoint          points[5];
  357.     Cardinal        ry;
  358.     unsigned char   char_count;
  359.     unsigned char   data_count;
  360.  
  361.     ry = (double) height *0.35 + height;
  362.  
  363.     for (char_count = 0; char_count < 7; char_count++) {
  364.         for (data_count = 0; data_count < char_data[char_count].nofline
  365.              ; data_count++) {
  366.             points[data_count].x = (double) (char_data[char_count].point_list[data_count].x) * (double) width *0.01 + width;
  367.             points[data_count].y = (double) (char_data[char_count].point_list[data_count].y) * (double) height *0.01 + ry;
  368.         }
  369.         XDrawLines(XtDisplay(w), XtWindow(w), gc, points, char_data[char_count].nofline, CoordModeOrigin);
  370.     }
  371. }
  372.  
  373. void
  374. DrawSingleNumber(w, gc, which, x, y, width, height)
  375.     Widget          w;
  376.     GC              gc;
  377.     Cardinal        x, y, width, height;
  378. {
  379.  
  380.     XSegment        segments[7];
  381.     Cardinal        nsegments;
  382.     unsigned char   count;
  383.  
  384.     for (count = 0, nsegments = 0; count < 7; count++) {
  385.         if (num_segment[which].digit[count] == 1) {
  386.             segments[nsegments].x1 = (short) (x + ((double) offset[count].x1 * ((double) width / 200.0)));
  387.             segments[nsegments].y1 = (short) (y + ((double) offset[count].y1 * ((double) height / 200.0)));
  388.             segments[nsegments].x2 = (short) (x + ((double) offset[count].x2 * ((double) width / 200.0)));
  389.             segments[nsegments].y2 = (short) (y + ((double) offset[count].y2 * ((double) height / 200.0)));
  390.             nsegments++;
  391.         }
  392.     }
  393.  
  394.     XDrawSegments(XtDisplay(w), XtWindow(w), gc, segments, nsegments);
  395.  
  396. }
  397.  
  398. void
  399. DrawNeedle(w, gc, load)
  400.     Widget          w;
  401.     GC              gc;
  402.     Cardinal        load;
  403. {
  404.  
  405.     Arg             args[2];
  406.     XPoint          points[6];
  407.     Cardinal        rx, ry;
  408.     double          cur_theta1, cur_theta2, cur_theta3, cur_theta4, cur_theta5;
  409.  
  410.  
  411.     XtSetArg(args[0], XtNwidth, 0);
  412.     XtSetArg(args[1], XtNheight, 0);
  413.     XtGetValues(w, args, XtNumber(args));
  414.  
  415.  
  416.     rx = args[0].value / 2 + 1;
  417.     ry = args[1].value / 2 + 1;
  418.  
  419.     cur_theta1 = (double) (330 - (load * 3)) * PI / 180.0;
  420.     cur_theta2 = (double) (330 - (load * 3) + 1) * PI / 180.0;
  421.     cur_theta3 = (double) (330 - (load * 3) - 1) * PI / 180.0;
  422.     cur_theta4 = (330.0 - ((double) load * 3.0) + 7.0) * PI / 180.0;
  423.     cur_theta5 = (330.0 - ((double) load * 3.0) - 7.0) * PI / 180.0;
  424.  
  425.     points[0].x = sin(cur_theta1) * rx * 0.75 + rx;
  426.     points[0].y = cos(cur_theta1) * ry * 0.75 + ry;
  427.     points[1].x = sin(cur_theta2) * rx * 0.7 + rx;
  428.     points[1].y = cos(cur_theta2) * ry * 0.7 + ry;
  429.     points[2].x = sin(cur_theta4) * rx * 0.1 + rx;
  430.     points[2].y = cos(cur_theta4) * ry * 0.1 + ry;
  431.     points[3].x = sin(cur_theta5) * rx * 0.1 + rx;
  432.     points[3].y = cos(cur_theta5) * ry * 0.1 + ry;
  433.     points[4].x = sin(cur_theta3) * rx * 0.7 + rx;
  434.     points[4].y = cos(cur_theta3) * ry * 0.7 + ry;
  435.     points[5].x = points[0].x;
  436.     points[5].y = points[0].y;
  437.  
  438.     XDrawLines(XtDisplay(w), XtWindow(w), gc, points, 6, CoordModeOrigin);
  439.  
  440. }
  441.  
  442. XtTimerCallbackProc
  443. PollingCpuStatus(client_data, id)
  444.     caddr_t         client_data;
  445.     XtIntervalId    id;
  446. {
  447.  
  448.     struct statstime system_status;
  449.     Cardinal        load_count, step;
  450.  
  451.     /* Get new CpuTime     */
  452.  
  453.     rstat(hostname, &system_status);
  454.     current_status = (double) (system_status.cp_time[monitor_item] - old_status_time) / ((double) update / 2000.0);
  455.     old_status_time = system_status.cp_time[monitor_item];
  456.  
  457.     if (current_status > 100)
  458.         current_status /= 2;
  459.  
  460.     if (current_status != old_status) {
  461.         /* Move Needle */
  462.  
  463.         if (current_status < old_status)
  464.             step = -1;
  465.         else
  466.             step = 1;
  467.  
  468.         for (load_count = old_status; load_count != current_status; load_count += step)
  469.             DrawNeedle(meter, gcNeedle, load_count);
  470.  
  471.         for (load_count = old_status + step; load_count != current_status + step; load_count += step)
  472.             DrawNeedle(meter, gcNeedle, load_count);
  473.  
  474.     }
  475.  
  476.     XtAddTimeOut(update, PollingCpuStatus, NULL);
  477.  
  478.     old_status = current_status;
  479.  
  480. }
  481.