diff --git a/examples/cluster.c b/examples/cluster.c index ccc62e1..35cd4e3 100644 --- a/examples/cluster.c +++ b/examples/cluster.c @@ -3,9 +3,19 @@ #include #include +#include + #include #include +typedef struct _hexagram_cluster_state { + double rpm, rps, temp, level; +} hexagram_cluster_state; + +static hexagram_cluster_state state = { + 0, 0, 0, 0 +}; + static void draw_needle(cairo_t *cr, double x, double y, @@ -266,9 +276,9 @@ static void draw_mfd(cairo_t *cr, cairo_stroke(cr); } -static void draw_gauge_cluster_bg(cairo_t *cr, - double width, - double height) { +static void cluster_draw_bg(cairo_t *cr, + double width, + double height) { /* * Paint canvas black */ @@ -302,62 +312,57 @@ static void draw_gauge_cluster_bg(cairo_t *cr, height * 0.5); } -static void update_gauge_cluster(cairo_t *cr, - struct can_frame *frame, - double x, - double y, - double width, - double height) { - static double rpm = 0; - static double kph = 0; - static double temp = 0; - static double level = 0; - +static void cluster_update(struct can_frame *frame) { switch (frame->can_id) { case 0x280: { - rpm = 0.25 * (double)(frame->data[2] | (frame->data[3] << 8)); + state.rpm = 0.25 * + (double)(frame->data[2] | (frame->data[3] << 8)); break; } case 0x288: { - temp = (double)(frame->data[1] - 48 * 0.75); + state.temp = (double)(frame->data[1] - 48 * 0.75); break; } case 0x320: { - level = (double)(frame->data[2]); + state.level = (double)(frame->data[2]); break; } case 0x5a0: { - double rps = 0.001 * (double)((frame->data[1] >> 1) - | (frame->data[2] << 8)); - - kph = (2.032 * rps * 3600) / 1000.0; + state.rps = 0.001 * (double)((frame->data[1] >> 1) + | (frame->data[2] << 8)); break; } } +} +static void cluster_draw(cairo_t *cr, + double x, + double y, + double width, + double height) { draw_tachometer_needle(cr, x + width * 0.2, y + height * 0.5, height * 0.4, - rpm); + state.rpm); draw_speedometer_needle(cr, width * 0.8, height * 0.5, height * 0.4, - kph); + (2.032 * state.rps * 3600) / 1000.0); draw_thermometer_needle(cr, width * 0.43, height * 0.76, height * 0.11, - temp); + state.temp); draw_fuel_gauge_needle(cr, width * 0.57, @@ -377,6 +382,12 @@ int main(int argc, char **argv) { width = 1024, height = 480; + struct timeval now, + last = { + .tv_sec = 0, + .tv_usec = 0 + }; + cairo_t *fg, *bg; if ((can_if = hexagram_can_if_open("vcan0")) == NULL) @@ -399,7 +410,7 @@ int main(int argc, char **argv) { /* * Draw the background layer */ - draw_gauge_cluster_bg(bg, width, height); + cluster_draw_bg(bg, width, height); hexagram_window_show(window); @@ -414,6 +425,8 @@ int main(int argc, char **argv) { while (1) { int pending; + (void)gettimeofday(&now, NULL); + while ((pending = XPending(display)) != 0) { XEvent e; @@ -450,11 +463,16 @@ int main(int argc, char **argv) { case 0x288: case 0x320: case 0x5a0: { - hexagram_window_refresh_bg(window); + cluster_update(&frame); - update_gauge_cluster(fg, &frame, 0, 0, width, height); + if (now.tv_sec - last.tv_sec + || now.tv_usec - last.tv_usec > 16666) { + hexagram_window_refresh_bg(window); + cluster_draw(fg, 0, 0, width, height); + hexagram_window_swap_buffer(window); - hexagram_window_swap_buffer(window); + (void)memcpy(&last, &now, sizeof(now)); + } } } }