1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#include <stdio.h>
#include <math.h>
#include "gps.h"
#include "config.h"
#include "display.h"
#define RM 20
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
static Widget draww;
static GC drawGC;
static Dimension width, height;
static int diameter;
static Pixmap pixmap;
/*@ -usedef -compdef -mustfreefresh @*/
static void set_color(String color)
{
Display *dpy = XtDisplay(draww);
Colormap cmap = DefaultColormapOfScreen(XtScreen(draww));
XColor col, unused;
if (XAllocNamedColor(dpy, cmap, color, &col, &unused)==0) {
char buf[32];
(void)snprintf(buf, sizeof(buf), "Can't alloc %s", color);
XtWarning(buf);
return;
}
(void)XSetForeground(dpy, drawGC, col.pixel);
}
/*@ +usedef @*/
void register_canvas(Widget w, GC gc)
{
draww = w;
drawGC = gc;
XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
pixmap = XCreatePixmap(XtDisplay(w),
RootWindowOfScreen(XtScreen(w)), width, height,
(unsigned int)DefaultDepthOfScreen(XtScreen(w)));
set_color("White");
(void)XFillRectangle(XtDisplay(draww), pixmap, drawGC, 0,0, width,height);
diameter = min(width, height) - RM;
}
static void pol2cart(double azimuth, double elevation,
/*@out@*/int *xout, /*@out@*/int *yout)
{
azimuth *= DEG_2_RAD;
#ifdef PCORRECT
elevation = sin((90.0 - elevation) * DEG_2_RAD);
#else
elevation = ((90.0 - elevation) / 90.0);
#endif
*xout = (int)((width/2) + sin(azimuth) * elevation * (diameter/2));
*yout = (int)((height/2) - cos(azimuth) * elevation * (diameter/2));
}
static void draw_arc(int x, int y, unsigned int diam)
{
(void)XDrawArc(XtDisplay(draww), pixmap, drawGC,
x - diam / 2, y - diam / 2, /* x,y */
diam, diam, /* width, height */
0, 360 * 64); /* angle1, angle2 */
}
/*@ +compdef @*/
void draw_graphics(struct gps_data_t *gpsdata)
{
int i, x, y;
char buf[20];
if (gpsdata->satellites != 0) {
i = (int)min(width, height);
set_color("White");
(void)XFillRectangle(XtDisplay(draww),pixmap,drawGC,0,0,width,height);
/* draw something in the center */
set_color("Grey");
draw_arc(width / 2, height / 2, 6);
/* draw the 45 degree circle */
#ifdef PCORRECT
#define FF 0.7 /* sin(45) ~ 0.7 */
#else
#define FF 0.5
#endif
draw_arc(width / 2, height / 2, (unsigned)((i - RM) * FF));
#undef FF
set_color("Black");
draw_arc(width / 2, height / 2, (unsigned)(i - RM));
pol2cart(0, 0, &x, &y);
set_color("Black");
(void)XDrawString(XtDisplay(draww),pixmap, drawGC, x, y, "N", 1);
pol2cart(90, 0, &x, &y);
set_color("Black");
(void)XDrawString(XtDisplay(draww),pixmap, drawGC, x+2, y, "E", 1);
pol2cart(180, 0, &x, &y);
set_color("Black");
(void)XDrawString(XtDisplay(draww),pixmap, drawGC, x, y+10, "S", 1);
pol2cart(270, 0, &x, &y);
set_color("Black");
(void)XDrawString(XtDisplay(draww),pixmap, drawGC, x-5,y, "W", 1);
/* Now draw the satellites... */
for (i = 0; i < gpsdata->satellites; i++) {
pol2cart((double)gpsdata->azimuth[i],
(double)gpsdata->elevation[i],
&x, &y);
if (gpsdata->ss[i] < 20)
set_color("Grey");
else if (gpsdata->ss[i] < 40)
set_color("Yellow");
else
set_color("Green");
(void)XFillArc(XtDisplay(draww), pixmap, drawGC,
x - 5, y - 5, /* x,y */
11, 11, /* width, height */
0, 360 * 64 /* angle1, angle2 */
);
(void)snprintf(buf, sizeof(buf), "%03d", gpsdata->PRN[i]);
set_color("Blue");
(void)XDrawString(XtDisplay(draww), pixmap, drawGC, x, y + 17, buf, 3);
if (gpsdata->ss[i]) {
set_color("Black");
(void)XDrawPoint(XtDisplay(draww), pixmap, drawGC, x, y);
}
}
(void)XCopyArea(XtDisplay(draww), pixmap, XtWindow(draww), drawGC,
0, 0, width, height, 0, 0);
}
}
void redraw(Widget w UNUSED, XtPointer client_data UNUSED,
XmDrawingAreaCallbackStruct * cbs)
{
(void)XCopyArea(XtDisplay(draww), pixmap, XtWindow(draww), drawGC,
cbs->event->xexpose.x, cbs->event->xexpose.y,
(unsigned int)cbs->event->xexpose.width,
(unsigned int)cbs->event->xexpose.height,
cbs->event->xexpose.x, cbs->event->xexpose.y);
}
/*@ +mustfreefresh @*/
|