hexagram/py/hexagram/app.pyx

112 lines
2.8 KiB
Cython
Executable file

import sys
import cairo
from Xlib.X import MapNotify, Expose
from libc.stdio cimport printf
from libc.string cimport memcpy
from posix.select cimport *
from hexagram.can cimport *
from hexagram.window cimport *
from hexagram.cluster import Cluster
CLUSTER_RPM_MIN = 1200
CLUSTER_RPM_REDLINE = 6500
CLUSTER_RPM_MAX = 8000
def usage(message=None):
if message:
print(message, file=sys.stderr)
print("usage: %s canif" % sys.argv[0], file=sys.stderr)
cdef handle_xevents(hexagram_window *window,
cluster: Cluster,
Display *display,
fg: cairo.Context):
cdef XEvent e
while XPending(display) > 0:
XNextEvent(display, &e)
if e.type == MapNotify or e.type == Expose:
hexagram_window_refresh_bg(window)
cluster.draw_fg(fg)
hexagram_window_swap_buffer(window)
cdef cluster_update(cluster: Cluster,
fg: cairo.Context,
hexagram_window *window,
can_frame *frame):
hexagram_window_refresh_bg(window)
cluster.draw_fg(fg)
hexagram_window_swap_buffer(window)
def main():
cdef fd_set rfds, rready
cdef can_frame frame
import_cairo()
if len(sys.argv) != 2:
usage("No CAN interface specified")
can_if = hexagram_can_if_open(bytes(sys.argv[1], 'utf8'))
if can_if is NULL:
raise Exception("hexagram_can_if_open()")
window = hexagram_window_new_x11(NULL, Cluster.WIDTH, Cluster.HEIGHT)
if window is NULL:
raise Exception("hexagram_window_new_x11()")
cluster = Cluster(CLUSTER_RPM_MIN, CLUSTER_RPM_REDLINE, CLUSTER_RPM_MAX)
if hexagram_cluster_filter_can_if(can_if) < 0:
raise Exception("hexagram_cluster_filter_can_if()")
display = hexagram_window_display(window)
fd = hexagram_can_if_fd(can_if)
fd2 = hexagram_window_display_fd(window)
#
# Set up rendering surfaces
#
fg = PycairoContext_FromContext(hexagram_window_get_fg_context(window),
ctx_type(),
NULL)
bg = PycairoContext_FromContext(hexagram_window_get_bg_context(window),
ctx_type(),
NULL)
cluster.draw_bg(<object>bg)
hexagram_window_show(window)
FD_ZERO(&rfds)
FD_SET(fd, &rfds)
FD_SET(fd2, &rfds)
while True:
nfds = fd2 + 1
handle_xevents(window, cluster, display, <object>fg)
memcpy(&rready, &rfds, sizeof(rfds))
if select(nfds, &rready, NULL, NULL, NULL) < 0:
break
if FD_ISSET(fd, &rready):
hexagram_can_if_read(can_if, &frame)
cluster_update(cluster, <object>fg, window, &frame)
hexagram_window_destroy(window)
return 0