hexagram/examples/cluster.c

178 lines
3.8 KiB
C
Raw Normal View History

2019-05-27 01:32:21 -05:00
#include <stdio.h>
#include <stdlib.h>
2019-06-07 15:34:13 -05:00
#include <stdarg.h>
2019-05-27 01:32:21 -05:00
#include <string.h>
#include <math.h>
#include <sys/time.h>
2019-05-27 01:32:21 -05:00
#include <hexagram/can.h>
2019-05-28 00:41:54 -05:00
#include <hexagram/window.h>
#include <hexagram/cluster.h>
2019-06-11 21:12:56 -05:00
static void handle_xevents(hexagram_window *window,
hexagram_cluster *cluster,
Display *display,
cairo_t *fg) {
while (XPending(display)) {
XEvent e;
XNextEvent(display, &e);
switch (e.type) {
case MapNotify:
case Expose:
hexagram_window_refresh_bg(window);
hexagram_cluster_draw_fg(cluster, fg);
hexagram_window_swap_buffer(window);
break;
case ButtonPress:
case KeyPress:
break;
default:
break;
}
}
}
static void cluster_update(hexagram_cluster *cluster,
2019-06-09 19:36:19 -05:00
cairo_t *cr,
hexagram_window *window,
struct can_frame *frame,
struct timeval *last) {
struct timeval now;
if (!hexagram_cluster_update(cluster, frame)) {
return;
2019-06-09 19:36:19 -05:00
}
gettimeofday(&now, NULL);
if (now.tv_sec - last->tv_sec || now.tv_usec - last->tv_usec > 16666) {
hexagram_window_refresh_bg(window);
hexagram_cluster_draw_fg(cluster, cr);
hexagram_window_swap_buffer(window);
memcpy(last, &now, sizeof(now));
2019-05-28 01:09:44 -05:00
}
}
2019-06-07 15:34:13 -05:00
static int usage(int argc, char **argv, const char *message, ...) {
if (message) {
va_list args;
va_start(args, message);
vfprintf(stderr, message, args);
fprintf(stderr, "\n");
va_end(args);
}
fprintf(stderr, "usage: %s canif\n", argv[0]);
return 1;
2019-05-26 10:13:42 -05:00
}
int main(int argc, char **argv) {
Display *display;
fd_set rfds, rready;
2019-05-27 01:32:21 -05:00
hexagram_can_if *can_if;
2019-05-28 00:41:54 -05:00
hexagram_window *window;
2019-06-09 15:46:41 -05:00
hexagram_cluster *cluster;
2019-05-27 01:32:21 -05:00
int fd, fd2,
width = 1024,
height = 480;
2019-06-09 19:36:19 -05:00
cairo_t *fg, *bg;
struct timeval last = {
.tv_sec = 0,
.tv_usec = 0
};
2019-06-07 15:34:13 -05:00
if (argc != 2) {
return usage(argc, argv, "No CAN interface specified");
}
2019-06-07 15:34:13 -05:00
if ((can_if = hexagram_can_if_open(argv[1])) == NULL) {
2019-06-28 18:09:08 -05:00
perror("hexagram_can_if_open()");
2019-06-07 15:34:13 -05:00
return 1;
}
if ((window = hexagram_window_new_x11(NULL, width, height)) == NULL) {
2019-06-28 18:09:08 -05:00
perror("hexagram_window_new_x11()");
2019-06-07 15:34:13 -05:00
return 1;
}
2019-06-09 15:46:41 -05:00
if ((cluster = hexagram_cluster_new(width, height)) == NULL) {
2019-06-28 18:09:08 -05:00
perror("hexagram_cluster_new()");
return 1;
}
if (hexagram_cluster_filter_can_if(can_if) < 0) {
perror("hexagram_cluster_filter_can_if()");
2019-06-09 15:46:41 -05:00
return 1;
}
2019-05-28 00:58:18 -05:00
display = hexagram_window_display(window);
fd = hexagram_can_if_fd(can_if);
fd2 = hexagram_window_display_fd(window);
2019-05-27 15:32:53 -05:00
/*
* Set up the rendering surfaces
2019-05-27 15:32:53 -05:00
*/
fg = hexagram_window_get_fg_context(window);
bg = hexagram_window_get_bg_context(window);
2019-05-27 15:32:53 -05:00
/*
* Draw the background layer
2019-05-27 15:32:53 -05:00
*/
2019-06-09 15:46:41 -05:00
hexagram_cluster_draw_bg(cluster, bg);
/*
* Present the background layer
*/
hexagram_window_show(window);
2019-05-27 15:32:53 -05:00
/*
* Set up file descriptors to monitor
*/
2019-05-27 01:32:21 -05:00
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
FD_SET(fd2, &rfds);
while (1) {
2019-06-11 21:12:56 -05:00
int nfds = fd2 + 1;
2019-05-27 01:32:21 -05:00
2019-06-11 21:12:56 -05:00
handle_xevents(window, cluster, display, fg);
2019-05-27 01:32:21 -05:00
memcpy(&rready, &rfds, sizeof(rfds));
if (select(nfds, &rready, NULL, NULL, NULL) < 0) {
2019-05-27 01:32:21 -05:00
break;
}
2019-05-27 01:32:21 -05:00
if (FD_ISSET(fd, &rready)) {
struct can_frame frame;
2019-05-27 01:32:21 -05:00
hexagram_can_if_read(can_if, &frame);
2019-06-09 19:36:19 -05:00
cluster_update(cluster, fg, window, &frame, &last);
}
}
hexagram_window_destroy(window);
return 0;
}