summaryrefslogtreecommitdiff
path: root/xgpsspeed.c
blob: 1c878576cdc4b914c06b6fb16948412861316829 (plain)
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
/* GPS speedometer as a wrapper around an Athena widget Tachometer
 * - Derrick J Brashear <shadow@dementia.org>
 * Tachometer widget from Kerberometer (xklife)
 */
#include "config.h"

#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <math.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Paned.h>
#include <Tachometer.h>

#include "xgpsspeed.icon"
#include "gps.h"

static XrmOptionDescRec options[] = {
{"-rv",		"*reverseVideo",	XrmoptionNoArg,		"TRUE"},
{"-nc",         "*needleColor",         XrmoptionSepArg,        NULL},
{"-needlecolor","*needleColor",         XrmoptionSepArg,        NULL},
};

String fallback_resources[] = {NULL};

static struct gps_data_t *gpsdata;
static Widget tacho;

static void update_display(char *buf UNUSED)
{
  int new = rint(gpsdata->speed * KNOTS_TO_MPH);
  if (new > 100)
    new = 100;
  TachometerSetValue(tacho, new);
}

static void handle_input(XtPointer client_data UNUSED,
			 int *source UNUSED,
			 XtInputId * id UNUSED)
{
    gps_poll(gpsdata);
}

int main(int argc, char **argv)
{
    Arg             args[10];
    XtAppContext app;
    int option;
    char *colon, *server = NULL;
    char *port = DEFAULT_GPSD_PORT;
    Widget toplevel, base;

    toplevel = XtVaAppInitialize(&app, "xpsspeed.ad", 
				 options, XtNumber(options),
				 &argc, argv, fallback_resources, NULL);
    while ((option = getopt(argc, argv, "?hv")) != -1) {
	switch (option) {
	case 'v':
	    printf("xgpsspeed %s\n", VERSION);
	    exit(0);
	case 'h': case '?': default:
	    fputs("usage: gps [-?] [-h] [-v] [-rv] [-nc] [-needlecolor] [server[:port]]\n", stderr);
	    exit(1);
	}
    }
    if (optind < argc) {
	server = strdup(argv[optind]);
	colon = strchr(server, ':');
	if (colon != NULL) {
	    server[colon - server] = '\0';
	    port = colon + 1;
	}
    }

   /**** Shell Widget ****/
    XtSetArg(args[0], XtNiconPixmap,
	     XCreateBitmapFromData(XtDisplay(toplevel),
				   XtScreen(toplevel)->root, (char*)xgps_bits,
				   xgps_width, xgps_height));
    XtSetValues(toplevel, args, 1);
    
    /**** Form widget ****/
    base = XtCreateManagedWidget("pane", panedWidgetClass, toplevel, NULL, 0);

    /**** Label widget (Title) ****/
    XtSetArg(args[0], XtNlabel, "GPS Speedometer");
    XtCreateManagedWidget("title", labelWidgetClass, base, args, 1);

    /**** Label widget ****/
    XtSetArg(args[0], XtNlabel, "Miles per Hour");
    XtCreateManagedWidget("name", labelWidgetClass, base, args, 1);
    
    /**** Tachometer widget ****/
    tacho = XtCreateManagedWidget("meter",
				  tachometerWidgetClass, base, NULL, 0);    
    XtRealizeWidget(toplevel);

    if (!(gpsdata = gps_open(server, DEFAULT_GPSD_PORT))) {
	fprintf(stderr, "xgpsspeed: no gpsd running or network error (%d).\n", errno);
	exit(2);
    }

    XtAppAddInput(app, gpsdata->gps_fd, (XtPointer) XtInputReadMask,
		  handle_input, NULL);
    
    gps_set_raw_hook(gpsdata, update_display);
    gps_query(gpsdata, "w+x\n");

    XtAppMainLoop(app);

    gps_close(gpsdata);
    return 0;
}