123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565 |
- #include "gpsd_config.h"
- #include <X11/IntrinsicP.h>
- #include <X11/StringDefs.h>
- #include <TachometerP.h>
- #include <math.h>
- #include "gps.h"
- #define D2R 0.0174532925199432957692369076848861271
- typedef struct
- {
- unsigned char digit[7];
- } DigitRec;
- typedef struct
- {
- int nofline;
- XPoint point_list[5];
- } StringRec;
- static DigitRec num_segment[] = {
- {{1, 1, 1, 1, 1, 1, 0}},
- {{0, 1, 1, 0, 0, 0, 0}},
- {{1, 1, 0, 1, 1, 0, 1}},
- {{1, 1, 1, 1, 0, 0, 1}},
- {{0, 1, 1, 0, 0, 1, 1}},
- {{1, 0, 1, 1, 0, 1, 1}},
- {{1, 0, 1, 1, 1, 1, 1}},
- {{1, 1, 1, 0, 0, 0, 0}},
- {{1, 1, 1, 1, 1, 1, 1}},
- {{1, 1, 1, 1, 0, 1, 1}}
- };
- static XSegment offset[] = {
- {-10, -10, 10, -10},
- {10, -10, 10, 0},
- {10, 0, 10, 10},
- {10, 10, -10, 10},
- {-10, 10, -10, 0},
- {-10, 0, -10, -10},
- {-10, 0, 10, 0}
- };
- static StringRec char_data[] = {
- {2,
- {{-17, -5},
- {-7, 5}}},
- {2,
- {{-7, -5},
- {-17, 5}}},
- {2,
- {{-2, -5},
- {-2, 5}}},
- {5,
- {{2, -5},
- {12, -5},
- {12, 5},
- {2, 5},
- {2, -5}}}
- };
- #define offst(field) XtOffset(TachometerWidget, field)
- static XtResource resources[] = {
- {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
- offst(tachometer.scale), XtRString, "XtDefaultForeground"}
- ,
- {XtNtachometerCircleColor, XtCBorderColor, XtRPixel, sizeof(Pixel),
- offst(tachometer.circle), XtRString, "XtDefaultForeground"}
- ,
- {XtNtachometerNeedleColor, XtCBorderColor, XtRPixel, sizeof(Pixel),
- offst(tachometer.needle), XtRString, "XtDefaultForeground"}
- ,
- {XtNtachometerNeedleSpeed, XtCtachometerNeedleSpeed, XtRInt,
- sizeof(int), offst(tachometer.speed), XtRImmediate, (caddr_t) 1},
- {XtNvalue, XtCValue, XtRInt, sizeof(int),
- offst(tachometer.value), XtRImmediate, (caddr_t) 0},
- {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
- offst(core.height), XtRImmediate, (caddr_t) 100}
- ,
- {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
- offst(core.width), XtRImmediate, (caddr_t) 100}
- ,
- {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
- offst(core.border_width), XtRImmediate, (caddr_t) 0}
- ,
- {XtNinternalBorderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
- offst(tachometer.internal_border), XtRImmediate, (caddr_t) 0}
- ,
- };
- static void Initialize(Widget request, Widget new),
- Realize(Widget w, Mask * valueMask, XSetWindowAttributes * attributes),
- Resize(Widget w), Redisplay(Widget w, XEvent * event, Region region),
- Destroy(Widget w);
- static Boolean SetValues(Widget current, Widget request UNUSED, Widget new);
- TachometerClassRec tachometerClassRec = {
- {
- #define superclass (&simpleClassRec)
- (WidgetClass) superclass,
- "Tachometer",
- sizeof(TachometerRec),
- NULL,
- NULL,
- FALSE,
- (XtInitProc) Initialize,
- NULL,
- Realize,
- NULL,
- 0,
- resources,
- XtNumber(resources),
- NULLQUARK,
- TRUE,
- TRUE,
- TRUE,
- FALSE,
- Destroy,
- Resize,
- Redisplay,
- (XtSetValuesFunc) SetValues,
- NULL,
- XtInheritSetValuesAlmost,
- NULL,
- NULL,
- XtVersion,
- NULL,
- NULL,
- NULL,
- XtInheritDisplayAccelerator,
- NULL
- }
- ,
- {
- XtInheritChangeSensitive
- }
- };
- WidgetClass tachometerWidgetClass = (WidgetClass) & tachometerClassRec;
- static void FastFillCircle(Display * d, Drawable w, GC gc,
- Cardinal center_x, Cardinal center_y,
- Cardinal radius_x, Cardinal radius_y)
- {
- XPoint points[360];
- Cardinal angle;
- for (angle = 0; angle < 360; angle++) {
- points[angle].x = (short)(sin((double)angle * D2R) *
- (double)radius_x + (double)center_x);
- points[angle].y = (short)(cos((double)angle * D2R) *
- (double)radius_y + (double)center_y);
- }
- (void)XFillPolygon(d, w, gc, points, 360, Complex, CoordModeOrigin);
- }
- static void DrawSingleNumber(TachometerWidget w, int which, Cardinal x,
- Cardinal y)
- {
- XSegment segments[7];
- Cardinal nsegments, width, height, count;
- width = (Cardinal) ((w->core.width / 2) - w->tachometer.internal_border);
- height =
- (Cardinal) ((w->core.height / 2) - w->tachometer.internal_border);
- if ((width == 0) || (height == 0))
- return;
- 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++;
- }
- (void)XDrawSegments(XtDisplay(w), XtWindow(w),
- w->tachometer.scale_GC, segments, (int)nsegments);
- }
- static void DrawNumbers(TachometerWidget w, int which, Cardinal x, Cardinal y)
- {
- if (which == 10) {
- DrawSingleNumber(w, 1, (Cardinal) ((double)x * 0.9), y);
- DrawSingleNumber(w, 0, x, y);
- } else
- DrawSingleNumber(w, which, x, y);
- }
- static void DrawLabelString(TachometerWidget w)
- {
- XPoint points[5];
- int char_count, data_count;
- Cardinal ry, center_x, center_y, radius_x, radius_y;
- GC gc;
- center_x = (Cardinal) (w->core.width / 2);
- center_y = (Cardinal) (w->core.height / 2);
- radius_x = center_x - w->tachometer.internal_border;
- radius_y = center_y - w->tachometer.internal_border;
- if (!(center_x != 0 && center_y != 0 && (radius_x > 0) && (radius_y > 0)))
- return;
- ry = (Cardinal) (radius_y * 0.35 + center_y);
- gc = w->tachometer.scale_GC;
- for (char_count = 0; char_count < 4; char_count++) {
- for (data_count = 0; data_count < char_data[char_count].nofline;
- data_count++) {
- points[data_count].x = (short)
- ((char_data[char_count].point_list[data_count].x) *
- (double)radius_x * 0.01 + center_x);
- points[data_count].y = (short)
- ((char_data[char_count].point_list[data_count].y) *
- (double)radius_y * 0.01 + ry);
- }
- (void)XDrawLines(XtDisplay(w), XtWindow(w), gc, points,
- char_data[char_count].nofline, CoordModeOrigin);
- }
- }
- static void DrawGauge(TachometerWidget w)
- {
- XPoint points[4];
- Cardinal in_gauge_x, in_gauge_y, out_gauge_x, out_gauge_y;
- Cardinal number_x, number_y, center_x, center_y, radius_x, radius_y;
- GC gc;
- double step, jump = 1.0;
- center_x = w->core.width / 2;
- center_y = w->core.height / 2;
- radius_x = center_x - w->tachometer.internal_border;
- radius_y = center_y - w->tachometer.internal_border;
- if ((center_x == 0) || (center_y == 0) || (radius_x <= 0)
- || (radius_y <= 0))
- return;
- gc = w->tachometer.scale_GC;
- for (step = 330.0; step >= 30.0; step -= jump) {
- if ((Cardinal) (step) % 30 == 0) {
- points[0].x =
- sin((step + 1.0) * D2R) * radius_x * 0.75 + center_x;
- points[0].y =
- cos((step + 1.0) * D2R) * radius_y * 0.75 + center_y;
- points[1].x =
- sin((step - 1.0) * D2R) * radius_x * 0.75 + center_x;
- points[1].y =
- cos((step - 1.0) * D2R) * radius_y * 0.75 + center_y;
- points[2].x =
- sin((step - 1.0) * D2R) * radius_x * 0.85 + center_x;
- points[2].y =
- cos((step - 1.0) * D2R) * radius_y * 0.85 + center_y;
- points[3].x =
- sin((step + 1.0) * D2R) * radius_x * 0.85 + center_x;
- points[3].y =
- cos((step + 1.0) * D2R) * radius_y * 0.85 + center_y;
- (void)XFillPolygon(XtDisplay(w), XtWindow(w), gc, points, 4,
- Complex, CoordModeOrigin);
- number_x = sin((step + 1.0) * D2R) * radius_x * 0.65 + center_x;
- number_y = cos((step + 1.0) * D2R) * radius_y * 0.65 + center_y;
- if ((int)((330.0 - step) / 30.0) == 1)
- jump = 3.0;
- DrawNumbers(w, (unsigned char)((330.0 - step) / 30.0),
- number_x, number_y);
- } else {
- in_gauge_x = sin(step * D2R) * radius_x * 0.8 + center_x;
- in_gauge_y = cos(step * D2R) * radius_y * 0.8 + center_y;
- out_gauge_x = sin(step * D2R) * radius_x * 0.85 + center_x;
- out_gauge_y = cos(step * D2R) * radius_y * 0.85 + center_y;
- (void)XDrawLine(XtDisplay(w), XtWindow(w), gc, in_gauge_x,
- in_gauge_y, out_gauge_x, out_gauge_y);
- }
- }
- DrawLabelString(w);
- }
- static void DrawNeedle(TachometerWidget w, int load)
- {
- XPoint points[6];
- double cur_theta1, cur_theta2, cur_theta3, cur_theta4, cur_theta5;
- Cardinal center_x, center_y, radius_x, radius_y;
- center_x = w->core.width / 2;
- center_y = w->core.height / 2;
- radius_x = center_x - w->tachometer.internal_border;
- radius_y = center_y - w->tachometer.internal_border;
- if ((center_x == 0) || (center_y == 0) || (radius_x <= 0)
- || (radius_y <= 0))
- return;
- cur_theta1 = (double)(330 - (load * 3)) * D2R;
- cur_theta2 = (double)(330 - (load * 3) + 1) * D2R;
- cur_theta3 = (double)(330 - (load * 3) - 1) * D2R;
- cur_theta4 = (330.0 - ((double)load * 3.0) + 7.0) * D2R;
- cur_theta5 = (330.0 - ((double)load * 3.0) - 7.0) * D2R;
- points[0].x = (short)(sin(cur_theta1) * radius_x * 0.75 + center_x);
- points[0].y = (short)(cos(cur_theta1) * radius_y * 0.75 + center_y);
- points[1].x = (short)(sin(cur_theta2) * radius_x * 0.7 + center_x);
- points[1].y = (short)(cos(cur_theta2) * radius_y * 0.7 + center_y);
- points[2].x = (short)(sin(cur_theta4) * radius_x * 0.1 + center_x);
- points[2].y = (short)(cos(cur_theta4) * radius_y * 0.1 + center_y);
- points[3].x = (short)(sin(cur_theta5) * radius_x * 0.1 + center_x);
- points[3].y = (short)(cos(cur_theta5) * radius_y * 0.1 + center_y);
- points[4].x = (short)(sin(cur_theta3) * radius_x * 0.7 + center_x);
- points[4].y = (short)(cos(cur_theta3) * radius_y * 0.7 + center_y);
- points[5].x = points[0].x;
- points[5].y = points[0].y;
- (void)XDrawLines(XtDisplay(w), XtWindow(w),
- w->tachometer.needle_GC, points, 6, CoordModeOrigin);
- }
- static void DrawTachometer(TachometerWidget w)
- {
- Cardinal center_x, center_y, radius_x, radius_y;
- center_x = w->core.width / 2;
- center_y = w->core.height / 2;
- radius_x = center_x - w->tachometer.internal_border;
- radius_y = center_y - w->tachometer.internal_border;
- if ((center_x == 0) || (center_y == 0) || (radius_x <= 0)
- || (radius_y <= 0))
- return;
-
- FastFillCircle(XtDisplay(w), XtWindow(w), w->tachometer.circle_GC,
- center_x, center_y, radius_x, radius_y);
-
- FastFillCircle(XtDisplay(w), XtWindow(w), w->tachometer.background_GC,
- center_x, center_y, (Cardinal) (radius_x * 0.95),
- (Cardinal) (radius_y * 0.95));
-
- FastFillCircle(XtDisplay(w), XtWindow(w), w->tachometer.circle_GC,
- center_x, center_y, (Cardinal) (radius_x * 0.1),
- (Cardinal) (radius_y * 0.1));
-
- DrawGauge(w);
- DrawNeedle(w, w->tachometer.value);
- }
- static void MoveNeedle(TachometerWidget w, int new)
- {
- int step, old, loop;
- old = w->tachometer.value;
- if (new > 100)
- new = 100;
- if (old == new)
- return;
- else if (old < new)
- step = (w->tachometer.speed ? w->tachometer.speed : new - old);
- else
- step = (w->tachometer.speed ? -w->tachometer.speed : new - old);
- if (old < new) {
- for (loop = old; loop < new; loop += step)
- DrawNeedle(w, loop);
- for (loop = old + step; loop <= new; loop += step)
- DrawNeedle(w, loop);
- } else {
- for (loop = old; loop > new; loop += step)
- DrawNeedle(w, loop);
- for (loop = old + step; loop >= new; loop += step)
- DrawNeedle(w, loop);
- }
- if (loop != new + step)
- DrawNeedle(w, new);
- w->tachometer.value = new;
- }
- static void GetneedleGC(TachometerWidget ta)
- {
- XGCValues values;
- values.background = ta->core.background_pixel;
- values.foreground = ta->tachometer.needle ^ ta->core.background_pixel;
- values.function = GXxor;
- ta->tachometer.needle_GC = XtGetGC((Widget) ta,
- (unsigned)GCFunction | GCBackground |
- GCForeground, &values);
- }
- static void GetscaleGC(TachometerWidget ta)
- {
- XGCValues values;
- values.foreground = ta->tachometer.scale;
- values.background = ta->core.background_pixel;
- ta->tachometer.scale_GC = XtGetGC((Widget) ta,
- (unsigned)GCForeground | GCBackground,
- &values);
- }
- static void GetcircleGC(TachometerWidget ta)
- {
- XGCValues values;
- values.foreground = ta->tachometer.circle;
- values.background = ta->core.background_pixel;
- ta->tachometer.circle_GC = XtGetGC((Widget) ta,
- (unsigned)GCForeground | GCBackground,
- &values);
- }
- static void GetbackgroundGC(TachometerWidget ta)
- {
- XGCValues values;
- values.foreground = ta->core.background_pixel;
- values.background = ta->core.background_pixel;
- ta->tachometer.background_GC = XtGetGC((Widget) ta,
- (unsigned)GCForeground |
- GCBackground, &values);
- }
- static void Initialize(Widget request UNUSED, Widget new)
- {
- TachometerWidget ta = (TachometerWidget) new;
- GetneedleGC(ta);
- GetcircleGC(ta);
- GetscaleGC(ta);
- GetbackgroundGC(ta);
- ta->tachometer.width = ta->tachometer.height = 0;
- }
- static void Realize(Widget w, Mask * valueMask,
- XSetWindowAttributes * attributes)
- {
- *valueMask |= CWBitGravity;
- attributes->bit_gravity = NorthWestGravity;
- (*superclass->core_class.realize) (w, valueMask, attributes);
- }
- static void Redisplay(Widget w, XEvent * event, Region region UNUSED)
- {
- if (event->xexpose.count == 0)
- DrawTachometer((TachometerWidget) w);
- }
- static void Resize(Widget w)
- {
- TachometerWidget ta = (TachometerWidget) w;
- if ((ta->core.width == ta->tachometer.width) &&
- (ta->core.height == ta->tachometer.height))
-
- return;
- (void)XClearWindow(XtDisplay(w), XtWindow(w));
- if ((ta->core.width <= ta->tachometer.width) &&
- (ta->core.height <= ta->tachometer.height))
-
-
-
- DrawTachometer(ta);
- ta->tachometer.width = ta->core.width;
- ta->tachometer.height = ta->core.height;
- }
- static Boolean SetValues(Widget current, Widget request UNUSED, Widget new)
- {
- Boolean back, changed = (Boolean) False;
- TachometerWidget curta = (TachometerWidget) current;
- TachometerWidget newta = (TachometerWidget) new;
- back = (curta->core.background_pixel != newta->core.background_pixel);
- if (back || (curta->tachometer.needle != newta->tachometer.needle)) {
- (void)XtReleaseGC(new, newta->tachometer.needle_GC);
- GetneedleGC(newta);
- changed = True;
- }
- if (back || (curta->tachometer.scale != newta->tachometer.scale)) {
- (void)XtReleaseGC(new, newta->tachometer.scale_GC);
- GetscaleGC(newta);
- changed = True;
- }
- if (back || (curta->tachometer.circle != newta->tachometer.circle)) {
- (void)XtReleaseGC(new, newta->tachometer.circle_GC);
- GetcircleGC(newta);
- changed = True;
- }
- if (back) {
- (void)XtReleaseGC(new, newta->tachometer.background_GC);
- GetbackgroundGC(newta);
- changed = True;
- }
- if (curta->tachometer.value != newta->tachometer.value) {
- MoveNeedle(newta, newta->tachometer.value);
- changed = True;
- }
- return (changed);
- }
- static void Destroy(Widget w)
- {
- TachometerWidget ta = (TachometerWidget) w;
- (void)XtReleaseGC(w, ta->tachometer.needle_GC);
- (void)XtReleaseGC(w, ta->tachometer.circle_GC);
- (void)XtReleaseGC(w, ta->tachometer.scale_GC);
- (void)XtReleaseGC(w, ta->tachometer.background_GC);
- }
- int TachometerGetValue(Widget w)
- {
- return (((TachometerWidget) w)->tachometer.value);
- }
- int TachometerSetValue(Widget w, int i)
- {
- int old;
- TachometerWidget ta = (TachometerWidget) w;
- old = ta->tachometer.value;
- MoveNeedle(ta, i);
- return (old);
- }
|