home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume4
/
xtacho
/
part01
/
xtacho.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-19
|
12KB
|
481 lines
static char sccsid[] = "@(#)xtacho.c 1.9 7/18/89";
/*
* xtacho - The cpu load tachometer for X11
*
* Author: Kazuhiko Shutoh, 1989.
*
* Permission to use, copy, modify and distribute without charge this software,
* documentation, images, etc. is granted, provided that this comment and the
* author's name is retained. The author assumes no responsibility for lost
* sleep as a consequence of use of this software.
*
* Send any comments, bug reports, etc. to: shutoh@isl.yamaha.JUNET or,
* for oversea: shutoh%isl.yamaha.JUNET%kddlab@uunet.uu.net
*
*/
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Box.h>
#include <X11/Label.h>
#include <X11/Command.h>
#include <X11/Form.h>
#include <stdio.h>
#include <math.h>
#include <rpcsvc/rstat.h>
#include "xtacho.h"
#include "xtacho.icon"
XtCallbackProc redraw_callback();
XtTimerCallbackProc PollingCpuStatus();
void SetupTacho();
void GetGraphicContexts();
void Usage();
void DrawTachometer();
void FastFillCircle();
void DrawGauge();
void DrawNumbers();
void DrawLabelString();
void DrawSingleNumber();
void DrawNeedle();
Widget toplevel, base, info, meter;
GC gcForeground, gcBackground, gcNeedle;
char hostname[MAXCHARS];
unsigned char monitor_item;
long update;
Cardinal current_status = 0;
Cardinal old_status = 0;
Cardinal old_status_time = 0;
main(argc, argv)
int argc;
char **argv;
{
Arg args[10];
Cardinal i;
XtIntervalId intervalId;
XtTranslations newTranslations;
static XtActionsRec redrawActions[] = {
{"expose", (XtCallbackProc) redraw_callback},
{"resize", (XtCallbackProc) redraw_callback}};
static char *overrideTranslations =
"<Expose>: expose() \n\
<ResReq>: expose()";
struct statstime cpu_status;
char label[MAXCHARS];
toplevel = XtInitialize("xtacho", "XTacho", NULL, 0, &argc, argv);
i = 0;
XtSetArg(args[0], XtNiconPixmap,
XCreateBitmapFromData(XtDisplay(toplevel),
XtScreen(toplevel)->root, xtacho_bits,
xtacho_width, xtacho_height));i++;
XtSetValues(toplevel, args, i);
SetupTacho(argc, argv);
base = XtCreateManagedWidget("base", formWidgetClass, toplevel, NULL, 0);
switch (monitor_item) {
case USER_CPU:
sprintf(label, "%s : User", hostname);
break;
case SYSTEM_CPU:
sprintf(label, "%s : System", hostname);
break;
case IDLE_CPU:
sprintf(label, "%s : Idle", hostname);
break;
default:
break;
}
i = 0;
XtSetArg(args[i], XtNlabel, label);i++;
XtSetArg(args[i], XtNwidth, 100);i++;
info = XtCreateManagedWidget("info", labelWidgetClass, base, args, i);
i = 0;
XtSetArg(args[i], XtNwidth, 100);i++;
XtSetArg(args[i], XtNheight, 100);i++;
XtSetArg(args[i], XtNborderWidth, 0);i++;
XtSetArg(args[i], XtNfromVert, info);i++;
meter = XtCreateManagedWidget("meter", boxWidgetClass, base, args, i);
GetGraphicContexts(meter);
XtAddActions(redrawActions, XtNumber(redrawActions));
newTranslations = XtParseTranslationTable(overrideTranslations);
XtOverrideTranslations(meter, newTranslations);
rstat(hostname, &cpu_status);
old_status_time = cpu_status.cp_time[monitor_item];
/* Interval timer start */
intervalId = XtAddTimeOut(update, PollingCpuStatus, NULL);
XtRealizeWidget(toplevel);
XtMainLoop();
}
void
SetupTacho(ac, av)
int ac;
char **av;
{
Cardinal count;
/* Setup default */
gethostname(hostname, 256);
monitor_item = USER_CPU;
update = 3000;
if (ac > 2)
for (count = 1; count < ac; count++) {
if ((strcmp("-host", av[count]) == 0) && (count + 1 <= ac))
strcpy(hostname, av[++count]);
else if ((strcmp("-update", av[count]) == 0) && (count + 1 <= ac))
update = atol(av[++count]) * (long) 1000;
else if ((strcmp("-mon", av[count]) == 0) && (count + 1 <= ac)) {
if (strcmp("sys", av[count + 1]) == 0)
monitor_item = SYSTEM_CPU;
else if (strcmp("user", av[count + 1]) == 0)
monitor_item = USER_CPU;
else if (strcmp("idle", av[count + 1]) == 0)
monitor_item = IDLE_CPU;
else
Usage();
count++;
} else
Usage();
}
}
void
GetGraphicContexts(w)
Widget w;
{
Arg args[2];
XGCValues gcv;
XtSetArg(args[0], XtNbackground, 0);
XtSetArg(args[1], XtNborderColor, 0);
XtGetValues(w, args, XtNumber(args));
gcv.foreground = args[1].value;
gcForeground = XtGetGC(w, GCForeground, &gcv);
gcv.foreground = args[0].value;
gcBackground = XtGetGC(w, GCForeground, &gcv);
gcv.foreground = args[0].value;
gcv.foreground = args[0].value;
gcv.function = GXinvert;
gcNeedle = XtGetGC(w, GCFunction, &gcv);
}
void
Usage()
{
fprintf(stderr, "xtacho <Toolkit Options> [-host hostname] [-mon sys|user|idle] [-update second]\n");
exit(-1);
}
XtCallbackProc
redraw_callback(w, event, params, nparams)
Widget w;
XEvent *event;
String *params;
Cardinal *nparams;
{
DrawTachometer(w);
}
void
DrawTachometer(w)
Widget w;
{
double tmp;
Arg args[2];
Cardinal d_rx;
Cardinal d_ry;
Cardinal d_width;
Cardinal d_height;
XtSetArg(args[0], XtNwidth, 0);
XtSetArg(args[1], XtNheight, 0);
XtGetValues(w, args, XtNumber(args));
d_rx = args[0].value / 2 + 1;
d_ry = args[1].value / 2 + 1;
/* Draw meter shape */
d_width = args[0].value;
d_height = args[1].value;
FastFillCircle(w, gcForeground, d_rx, d_ry, d_width, d_height);
d_width = (double) (args[0].value) * 0.95;
d_height = (double) (args[1].value) * 0.95;
FastFillCircle(w, gcBackground, d_rx, d_ry, d_width, d_height);
d_width = (double) (args[0].value) * 0.1;
d_height = (double) (args[1].value) * 0.1;
FastFillCircle(w, gcForeground, d_rx, d_ry, d_width, d_height);
/* Draw gauge */
DrawGauge(w, gcForeground, d_rx, d_ry);
DrawNeedle(w, gcNeedle, current_status);
}
void
FastFillCircle(w, gc, dx, dy, wx, wy)
Widget w;
GC gc;
Cardinal dx;
Cardinal dy;
Cardinal wx;
Cardinal wy;
{
XPoint points[360];
Cardinal angle;
for (angle = 0; angle < 360; angle++) {
points[angle].x = (short) (sin((double) angle * PI / 180.0) * ((double) wx / 2.0) + (double) dx);
points[angle].y = (short) (cos((double) angle * PI / 180.0) * ((double) wy / 2.0) + (double) dy);
}
XFillPolygon(XtDisplay(w), XtWindow(w), gc, points, 360, Complex, CoordModeOrigin);
}
void
DrawGauge(w, gc, rx, ry)
Widget w;
GC gc;
Cardinal rx;
Cardinal ry;
{
XPoint points[4];
double step;
Cardinal in_gauge_x, in_gauge_y;
Cardinal out_gauge_x, out_gauge_y;
Cardinal number_x, number_y;
for (step = 330.0; step >= 30.0; step -= 3) {
in_gauge_x = sin(step * PI / 180.0) * rx * 0.8 + rx;
in_gauge_y = cos(step * PI / 180.0) * ry * 0.8 + ry;
out_gauge_x = sin(step * PI / 180.0) * rx * 0.85 + rx;
out_gauge_y = cos(step * PI / 180.0) * ry * 0.85 + ry;
if ((Cardinal) (step) % 30 == 0) {
points[0].x = sin((step + 1.0) * PI / 180.0) * rx * 0.75 + rx;
points[0].y = cos((step + 1.0) * PI / 180.0) * ry * 0.75 + ry;
points[1].x = sin((step - 1.0) * PI / 180.0) * rx * 0.75 + rx;
points[1].y = cos((step - 1.0) * PI / 180.0) * ry * 0.75 + ry;
points[2].x = sin((step - 1.0) * PI / 180.0) * rx * 0.85 + rx;
points[2].y = cos((step - 1.0) * PI / 180.0) * ry * 0.85 + ry;
points[3].x = sin((step + 1.0) * PI / 180.0) * rx * 0.85 + rx;
points[3].y = cos((step + 1.0) * PI / 180.0) * ry * 0.85 + ry;
XFillPolygon(XtDisplay(w), XtWindow(w), gc, points, 4, Complex, CoordModeOrigin);
number_x = sin((step + 1.0) * PI / 180.0) * rx * 0.65 + rx;
number_y = cos((step + 1.0) * PI / 180.0) * ry * 0.65 + ry;
DrawNumbers(w, gc, (unsigned char) ((330.0 - step) / 30.0), number_x, number_y, rx, ry);
} else
XDrawLine(XtDisplay(w), XtWindow(w), gc, in_gauge_x, in_gauge_y, out_gauge_x, out_gauge_y);
}
DrawLabelString(w, gc, rx, ry);
}
void
DrawNumbers(w, gc, which, x, y, width, height)
Widget w;
GC gc;
unsigned char which;
Cardinal x, y, width, height;
{
/* Draw Numbers */
if (which == 10) {
DrawSingleNumber(w, gc, 1, (Cardinal) ((double) x * 0.9), y, width, height);
DrawSingleNumber(w, gc, 0, x, y, width, height);
} else
DrawSingleNumber(w, gc, which, x, y, width, height);
}
void
DrawLabelString(w, gc, width, height)
Widget w;
GC gc;
Cardinal width;
Cardinal height;
{
XPoint points[5];
Cardinal ry;
unsigned char char_count;
unsigned char data_count;
ry = (double) height *0.35 + height;
for (char_count = 0; char_count < 7; char_count++) {
for (data_count = 0; data_count < char_data[char_count].nofline
; data_count++) {
points[data_count].x = (double) (char_data[char_count].point_list[data_count].x) * (double) width *0.01 + width;
points[data_count].y = (double) (char_data[char_count].point_list[data_count].y) * (double) height *0.01 + ry;
}
XDrawLines(XtDisplay(w), XtWindow(w), gc, points, char_data[char_count].nofline, CoordModeOrigin);
}
}
void
DrawSingleNumber(w, gc, which, x, y, width, height)
Widget w;
GC gc;
Cardinal x, y, width, height;
{
XSegment segments[7];
Cardinal nsegments;
unsigned char count;
for (count = 0, nsegments = 0; count < 7; count++) {
if (num_segment[which].digit[count] == 1) {
segments[nsegments].x1 = (short) (x + ((double) offset[count].x1 * ((double) width / 200.0)));
segments[nsegments].y1 = (short) (y + ((double) offset[count].y1 * ((double) height / 200.0)));
segments[nsegments].x2 = (short) (x + ((double) offset[count].x2 * ((double) width / 200.0)));
segments[nsegments].y2 = (short) (y + ((double) offset[count].y2 * ((double) height / 200.0)));
nsegments++;
}
}
XDrawSegments(XtDisplay(w), XtWindow(w), gc, segments, nsegments);
}
void
DrawNeedle(w, gc, load)
Widget w;
GC gc;
Cardinal load;
{
Arg args[2];
XPoint points[6];
Cardinal rx, ry;
double cur_theta1, cur_theta2, cur_theta3, cur_theta4, cur_theta5;
XtSetArg(args[0], XtNwidth, 0);
XtSetArg(args[1], XtNheight, 0);
XtGetValues(w, args, XtNumber(args));
rx = args[0].value / 2 + 1;
ry = args[1].value / 2 + 1;
cur_theta1 = (double) (330 - (load * 3)) * PI / 180.0;
cur_theta2 = (double) (330 - (load * 3) + 1) * PI / 180.0;
cur_theta3 = (double) (330 - (load * 3) - 1) * PI / 180.0;
cur_theta4 = (330.0 - ((double) load * 3.0) + 7.0) * PI / 180.0;
cur_theta5 = (330.0 - ((double) load * 3.0) - 7.0) * PI / 180.0;
points[0].x = sin(cur_theta1) * rx * 0.75 + rx;
points[0].y = cos(cur_theta1) * ry * 0.75 + ry;
points[1].x = sin(cur_theta2) * rx * 0.7 + rx;
points[1].y = cos(cur_theta2) * ry * 0.7 + ry;
points[2].x = sin(cur_theta4) * rx * 0.1 + rx;
points[2].y = cos(cur_theta4) * ry * 0.1 + ry;
points[3].x = sin(cur_theta5) * rx * 0.1 + rx;
points[3].y = cos(cur_theta5) * ry * 0.1 + ry;
points[4].x = sin(cur_theta3) * rx * 0.7 + rx;
points[4].y = cos(cur_theta3) * ry * 0.7 + ry;
points[5].x = points[0].x;
points[5].y = points[0].y;
XDrawLines(XtDisplay(w), XtWindow(w), gc, points, 6, CoordModeOrigin);
}
XtTimerCallbackProc
PollingCpuStatus(client_data, id)
caddr_t client_data;
XtIntervalId id;
{
struct statstime system_status;
Cardinal load_count, step;
/* Get new CpuTime */
rstat(hostname, &system_status);
current_status = (double) (system_status.cp_time[monitor_item] - old_status_time) / ((double) update / 2000.0);
old_status_time = system_status.cp_time[monitor_item];
if (current_status > 100)
current_status /= 2;
if (current_status != old_status) {
/* Move Needle */
if (current_status < old_status)
step = -1;
else
step = 1;
for (load_count = old_status; load_count != current_status; load_count += step)
DrawNeedle(meter, gcNeedle, load_count);
for (load_count = old_status + step; load_count != current_status + step; load_count += step)
DrawNeedle(meter, gcNeedle, load_count);
}
XtAddTimeOut(update, PollingCpuStatus, NULL);
old_status = current_status;
}