#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 @*/
syntax highlighted by Code2HTML, v. 0.9.1