From 92425a8479e97441a268816e701d2cee1c4c9604 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 18 Oct 2016 13:29:41 +0300 Subject: [PATCH] main was really unix-specific, moved under src/unix --- src/main.c | 340 ------------------------------------------------------- src/unix/main.c | 340 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 340 insertions(+), 340 deletions(-) delete mode 100644 src/main.c create mode 100644 src/unix/main.c diff --git a/src/main.c b/src/main.c deleted file mode 100644 index a936a74..0000000 --- a/src/main.c +++ /dev/null @@ -1,340 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vmath.h" -#include "device.h" - -int create_gfx(int xsz, int ysz); -void destroy_gfx(void); -void set_window_title(const char *title); -void redraw(void); -void draw_cube(void); -int handle_event(XEvent *xev); -int handle_dev_event(device_event *ev); - -Display *dpy; -Atom wm_prot, wm_del_win; -GLXContext ctx; -Window win; - -vec3_t pos = {0, 0, -6}; -quat_t rot = {0, 0, 0, 1}; /* that's 1 + 0i + 0j + 0k */ - -int redisplay; - -/* serial 6dof device */ -struct device *dev; - -int main(void) -{ - int xsock, devfd, maxfd; - - register_all(); - set_port("/dev/ttyS0"); - - if(!(dev = dev_init(0))) { - fprintf(stderr, "failed to initialize 6dof serial device at /dev/ttyS0\n"); - return 1; - } - if((devfd = dev->start()) == -1) { - return 1; - } - - if(!(dpy = XOpenDisplay(0))) { - fprintf(stderr, "failed to connect to the X server\n"); - return 1; - } - xsock = ConnectionNumber(dpy); - - if(create_gfx(512, 512) == -1) { - return 1; - } - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - maxfd = xsock > devfd ? xsock : devfd; - - for(;;) { - fd_set rdset; - - FD_ZERO(&rdset); - FD_SET(xsock, &rdset); - FD_SET(devfd, &rdset); - - while(select(maxfd + 1, &rdset, 0, 0, 0) == -1 && errno == EINTR); - - if(FD_ISSET(xsock, &rdset)) { - while(XPending(dpy)) { - XEvent xev; - XNextEvent(dpy, &xev); - - if(handle_event(&xev) != 0) { - goto end; - } - } - } - - if(FD_ISSET(devfd, &rdset)) { - device_event ev; - - while(dev->getevent(&ev)) { - handle_dev_event(&ev); - } - } - - if(redisplay) { - redraw(); - redisplay = 0; - } - } - -end: - destroy_gfx(); - XCloseDisplay(dpy); - return 0; -} - -int create_gfx(int xsz, int ysz) -{ - int scr; - Window root; - XVisualInfo *vis; - XSetWindowAttributes xattr; - unsigned int events; - XClassHint class_hint; - - int attr[] = { - GLX_RGBA, GLX_DOUBLEBUFFER, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_DEPTH_SIZE, 24, - None - }; - - wm_prot = XInternAtom(dpy, "WM_PROTOCOLS", False); - wm_del_win = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - - scr = DefaultScreen(dpy); - root = RootWindow(dpy, scr); - - if(!(vis = glXChooseVisual(dpy, scr, attr))) { - fprintf(stderr, "requested GLX visual is not available\n"); - return -1; - } - - if(!(ctx = glXCreateContext(dpy, vis, 0, True))) { - fprintf(stderr, "failed to create GLX context\n"); - XFree(vis); - return -1; - } - - xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, scr); - xattr.colormap = XCreateColormap(dpy, root, vis->visual, AllocNone); - - if(!(win = XCreateWindow(dpy, root, 0, 0, xsz, ysz, 0, vis->depth, InputOutput, - vis->visual, CWColormap | CWBackPixel | CWBorderPixel, &xattr))) { - fprintf(stderr, "failed to create X window\n"); - return -1; - } - XFree(vis); - - /* set the window event mask */ - events = ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | - ButtonReleaseMask | ButtonPressMask | PointerMotionMask; - XSelectInput(dpy, win, events); - - XSetWMProtocols(dpy, win, &wm_del_win, 1); - - set_window_title("libspnav cube"); - - class_hint.res_name = "cube"; - class_hint.res_class = "cube"; - XSetClassHint(dpy, win, &class_hint); - - if(glXMakeCurrent(dpy, win, ctx) == False) { - fprintf(stderr, "glXMakeCurrent failed\n"); - glXDestroyContext(dpy, ctx); - XDestroyWindow(dpy, win); - return -1; - } - - XMapWindow(dpy, win); - XFlush(dpy); - - return 0; -} - -void destroy_gfx(void) -{ - glXDestroyContext(dpy, ctx); - XDestroyWindow(dpy, win); - glXMakeCurrent(dpy, None, 0); -} - -void set_window_title(const char *title) -{ - XTextProperty wm_name; - - XStringListToTextProperty((char**)&title, 1, &wm_name); - XSetWMName(dpy, win, &wm_name); - XSetWMIconName(dpy, win, &wm_name); - XFree(wm_name.value); -} - -void redraw(void) -{ - mat4_t xform; - - quat_to_mat(xform, rot); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(pos.x, pos.y, pos.z); - glMultTransposeMatrixf((float*)xform); - - draw_cube(); - - glXSwapBuffers(dpy, win); -} - -void draw_cube(void) -{ - glBegin(GL_QUADS); - /* face +Z */ - glNormal3f(0, 0, 1); - glColor3f(1, 0, 0); - glVertex3f(-1, -1, 1); - glVertex3f(1, -1, 1); - glVertex3f(1, 1, 1); - glVertex3f(-1, 1, 1); - /* face +X */ - glNormal3f(1, 0, 0); - glColor3f(0, 1, 0); - glVertex3f(1, -1, 1); - glVertex3f(1, -1, -1); - glVertex3f(1, 1, -1); - glVertex3f(1, 1, 1); - /* face -Z */ - glNormal3f(0, 0, -1); - glColor3f(0, 0, 1); - glVertex3f(1, -1, -1); - glVertex3f(-1, -1, -1); - glVertex3f(-1, 1, -1); - glVertex3f(1, 1, -1); - /* face -X */ - glNormal3f(-1, 0, 0); - glColor3f(1, 1, 0); - glVertex3f(-1, -1, -1); - glVertex3f(-1, -1, 1); - glVertex3f(-1, 1, 1); - glVertex3f(-1, 1, -1); - /* face +Y */ - glNormal3f(0, 1, 0); - glColor3f(0, 1, 1); - glVertex3f(-1, 1, 1); - glVertex3f(1, 1, 1); - glVertex3f(1, 1, -1); - glVertex3f(-1, 1, -1); - /* face -Y */ - glNormal3f(0, -1, 0); - glColor3f(1, 0, 1); - glVertex3f(-1, -1, -1); - glVertex3f(1, -1, -1); - glVertex3f(1, -1, 1); - glVertex3f(-1, -1, 1); - glEnd(); -} - -int handle_event(XEvent *xev) -{ - static int win_mapped; - KeySym sym; - - switch(xev->type) { - case MapNotify: - win_mapped = 1; - break; - - case UnmapNotify: - win_mapped = 0; - break; - - case Expose: - if(win_mapped && xev->xexpose.count == 0) { - redraw(); - } - break; - - case KeyPress: - sym = XLookupKeysym((XKeyEvent*)&xev->xkey, 0); - if((sym & 0xff) == 27) { - return 1; - } - break; - - case ConfigureNotify: - { - int x = xev->xconfigure.width; - int y = xev->xconfigure.height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(45.0, (float)x / (float)y, 1.0, 1000.0); - - glViewport(0, 0, x, y); - } - break; - - default: - break; - } - return 0; -} - -#define TX(ev) ((ev)->motion.motion[0]) -#define TY(ev) ((ev)->motion.motion[1]) -#define TZ(ev) ((ev)->motion.motion[2]) -#define RX(ev) ((ev)->motion.motion[3]) -#define RY(ev) ((ev)->motion.motion[4]) -#define RZ(ev) ((ev)->motion.motion[5]) - -int handle_dev_event(device_event *ev) -{ - switch(ev->type) { - case DEV_EV_MOTION: - if(RX(ev) | RY(ev) | RZ(ev)) { - float axis_len = sqrt(RX(ev) * RX(ev) + RY(ev) * RY(ev) + RZ(ev) * RZ(ev)); - if(axis_len != 0.0) { - rot = quat_rotate(rot, axis_len * 0.001, -RX(ev) / axis_len, - -RY(ev) / axis_len, -RZ(ev) / axis_len); - } - } - - pos.x += TX(ev) * 0.001; - pos.y += TY(ev) * 0.001; - pos.z += TZ(ev) * 0.001; - redisplay = 1; - break; - - case DEV_EV_BUTTON: - if(ev->button.pressed) { - pos = v3_cons(0, 0, -6); - rot = quat_cons(1, 0, 0, 0); - redisplay = 1; - } - break; - } - - return 0; -} diff --git a/src/unix/main.c b/src/unix/main.c new file mode 100644 index 0000000..a936a74 --- /dev/null +++ b/src/unix/main.c @@ -0,0 +1,340 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vmath.h" +#include "device.h" + +int create_gfx(int xsz, int ysz); +void destroy_gfx(void); +void set_window_title(const char *title); +void redraw(void); +void draw_cube(void); +int handle_event(XEvent *xev); +int handle_dev_event(device_event *ev); + +Display *dpy; +Atom wm_prot, wm_del_win; +GLXContext ctx; +Window win; + +vec3_t pos = {0, 0, -6}; +quat_t rot = {0, 0, 0, 1}; /* that's 1 + 0i + 0j + 0k */ + +int redisplay; + +/* serial 6dof device */ +struct device *dev; + +int main(void) +{ + int xsock, devfd, maxfd; + + register_all(); + set_port("/dev/ttyS0"); + + if(!(dev = dev_init(0))) { + fprintf(stderr, "failed to initialize 6dof serial device at /dev/ttyS0\n"); + return 1; + } + if((devfd = dev->start()) == -1) { + return 1; + } + + if(!(dpy = XOpenDisplay(0))) { + fprintf(stderr, "failed to connect to the X server\n"); + return 1; + } + xsock = ConnectionNumber(dpy); + + if(create_gfx(512, 512) == -1) { + return 1; + } + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + maxfd = xsock > devfd ? xsock : devfd; + + for(;;) { + fd_set rdset; + + FD_ZERO(&rdset); + FD_SET(xsock, &rdset); + FD_SET(devfd, &rdset); + + while(select(maxfd + 1, &rdset, 0, 0, 0) == -1 && errno == EINTR); + + if(FD_ISSET(xsock, &rdset)) { + while(XPending(dpy)) { + XEvent xev; + XNextEvent(dpy, &xev); + + if(handle_event(&xev) != 0) { + goto end; + } + } + } + + if(FD_ISSET(devfd, &rdset)) { + device_event ev; + + while(dev->getevent(&ev)) { + handle_dev_event(&ev); + } + } + + if(redisplay) { + redraw(); + redisplay = 0; + } + } + +end: + destroy_gfx(); + XCloseDisplay(dpy); + return 0; +} + +int create_gfx(int xsz, int ysz) +{ + int scr; + Window root; + XVisualInfo *vis; + XSetWindowAttributes xattr; + unsigned int events; + XClassHint class_hint; + + int attr[] = { + GLX_RGBA, GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_DEPTH_SIZE, 24, + None + }; + + wm_prot = XInternAtom(dpy, "WM_PROTOCOLS", False); + wm_del_win = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + + scr = DefaultScreen(dpy); + root = RootWindow(dpy, scr); + + if(!(vis = glXChooseVisual(dpy, scr, attr))) { + fprintf(stderr, "requested GLX visual is not available\n"); + return -1; + } + + if(!(ctx = glXCreateContext(dpy, vis, 0, True))) { + fprintf(stderr, "failed to create GLX context\n"); + XFree(vis); + return -1; + } + + xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, scr); + xattr.colormap = XCreateColormap(dpy, root, vis->visual, AllocNone); + + if(!(win = XCreateWindow(dpy, root, 0, 0, xsz, ysz, 0, vis->depth, InputOutput, + vis->visual, CWColormap | CWBackPixel | CWBorderPixel, &xattr))) { + fprintf(stderr, "failed to create X window\n"); + return -1; + } + XFree(vis); + + /* set the window event mask */ + events = ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | + ButtonReleaseMask | ButtonPressMask | PointerMotionMask; + XSelectInput(dpy, win, events); + + XSetWMProtocols(dpy, win, &wm_del_win, 1); + + set_window_title("libspnav cube"); + + class_hint.res_name = "cube"; + class_hint.res_class = "cube"; + XSetClassHint(dpy, win, &class_hint); + + if(glXMakeCurrent(dpy, win, ctx) == False) { + fprintf(stderr, "glXMakeCurrent failed\n"); + glXDestroyContext(dpy, ctx); + XDestroyWindow(dpy, win); + return -1; + } + + XMapWindow(dpy, win); + XFlush(dpy); + + return 0; +} + +void destroy_gfx(void) +{ + glXDestroyContext(dpy, ctx); + XDestroyWindow(dpy, win); + glXMakeCurrent(dpy, None, 0); +} + +void set_window_title(const char *title) +{ + XTextProperty wm_name; + + XStringListToTextProperty((char**)&title, 1, &wm_name); + XSetWMName(dpy, win, &wm_name); + XSetWMIconName(dpy, win, &wm_name); + XFree(wm_name.value); +} + +void redraw(void) +{ + mat4_t xform; + + quat_to_mat(xform, rot); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(pos.x, pos.y, pos.z); + glMultTransposeMatrixf((float*)xform); + + draw_cube(); + + glXSwapBuffers(dpy, win); +} + +void draw_cube(void) +{ + glBegin(GL_QUADS); + /* face +Z */ + glNormal3f(0, 0, 1); + glColor3f(1, 0, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + /* face +X */ + glNormal3f(1, 0, 0); + glColor3f(0, 1, 0); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + /* face -Z */ + glNormal3f(0, 0, -1); + glColor3f(0, 0, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + /* face -X */ + glNormal3f(-1, 0, 0); + glColor3f(1, 1, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, -1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, 1, -1); + /* face +Y */ + glNormal3f(0, 1, 0); + glColor3f(0, 1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(1, 1, 1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + /* face -Y */ + glNormal3f(0, -1, 0); + glColor3f(1, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, -1, 1); + glVertex3f(-1, -1, 1); + glEnd(); +} + +int handle_event(XEvent *xev) +{ + static int win_mapped; + KeySym sym; + + switch(xev->type) { + case MapNotify: + win_mapped = 1; + break; + + case UnmapNotify: + win_mapped = 0; + break; + + case Expose: + if(win_mapped && xev->xexpose.count == 0) { + redraw(); + } + break; + + case KeyPress: + sym = XLookupKeysym((XKeyEvent*)&xev->xkey, 0); + if((sym & 0xff) == 27) { + return 1; + } + break; + + case ConfigureNotify: + { + int x = xev->xconfigure.width; + int y = xev->xconfigure.height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, (float)x / (float)y, 1.0, 1000.0); + + glViewport(0, 0, x, y); + } + break; + + default: + break; + } + return 0; +} + +#define TX(ev) ((ev)->motion.motion[0]) +#define TY(ev) ((ev)->motion.motion[1]) +#define TZ(ev) ((ev)->motion.motion[2]) +#define RX(ev) ((ev)->motion.motion[3]) +#define RY(ev) ((ev)->motion.motion[4]) +#define RZ(ev) ((ev)->motion.motion[5]) + +int handle_dev_event(device_event *ev) +{ + switch(ev->type) { + case DEV_EV_MOTION: + if(RX(ev) | RY(ev) | RZ(ev)) { + float axis_len = sqrt(RX(ev) * RX(ev) + RY(ev) * RY(ev) + RZ(ev) * RZ(ev)); + if(axis_len != 0.0) { + rot = quat_rotate(rot, axis_len * 0.001, -RX(ev) / axis_len, + -RY(ev) / axis_len, -RZ(ev) / axis_len); + } + } + + pos.x += TX(ev) * 0.001; + pos.y += TY(ev) * 0.001; + pos.z += TZ(ev) * 0.001; + redisplay = 1; + break; + + case DEV_EV_BUTTON: + if(ev->button.pressed) { + pos = v3_cons(0, 0, -6); + rot = quat_cons(1, 0, 0, 0); + redisplay = 1; + } + break; + } + + return 0; +} -- 1.7.10.4