vrmodel

diff inptools/test/src/main.c @ 4:a32b151fb3c6

moving along slowly
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 11 Sep 2014 00:08:23 +0300
parents be91b72ce3f9
children 9e260c091f75
line diff
     1.1 --- a/inptools/test/src/main.c	Mon Sep 01 05:59:31 2014 +0300
     1.2 +++ b/inptools/test/src/main.c	Thu Sep 11 00:08:23 2014 +0300
     1.3 @@ -1,5 +1,174 @@
     1.4  #include <stdio.h>
     1.5 +#include <stdlib.h>
     1.6 +#include <string.h>
     1.7 +#include <limits.h>
     1.8 +#include <errno.h>
     1.9 +#include <assert.h>
    1.10 +#include <unistd.h>
    1.11 +#include <fcntl.h>
    1.12 +#include <sys/socket.h>
    1.13 +#include <arpa/inet.h>
    1.14 +#include <sys/select.h>
    1.15 +#include <sys/time.h>
    1.16 +#include <sys/types.h>
    1.17 +#include <linux/joystick.h>
    1.18 +#include "proto.h"
    1.19 +
    1.20 +struct client {
    1.21 +	int s;
    1.22 +	struct sockaddr_in addr;
    1.23 +	struct client *next;
    1.24 +};
    1.25 +
    1.26 +int open_js(const char *jspath);
    1.27 +int handle_js(int fd);
    1.28 +int start_srv(int port);
    1.29 +int handle_net(int s);
    1.30 +
    1.31 +static int opt_dport = DEF_PORT;
    1.32 +static const char *opt_jspath = "/dev/input/js0";
    1.33 +
    1.34 +static struct client *clients;
    1.35 +
    1.36 +static int js_num_axes;
    1.37 +static float *js_axis_state;
    1.38 +static unsigned int js_bn_state;
    1.39 +
    1.40  
    1.41  int main(int argc, char **argv)
    1.42  {
    1.43 +	int js, sock;
    1.44 +	int maxfd;
    1.45 +
    1.46 +	if((js = open_js(opt_jspath)) == -1) {
    1.47 +		return 1;
    1.48 +	}
    1.49 +	if((sock = start_srv(opt_dport)) == -1) {
    1.50 +		return 1;
    1.51 +	}
    1.52 +	maxfd = js > sock ? js : sock;
    1.53 +
    1.54 +	for(;;) {
    1.55 +		fd_set rdset;
    1.56 +
    1.57 +		FD_ZERO(&rdset);
    1.58 +		FD_SET(js, &rdset);
    1.59 +		FD_SET(sock, &rdset);
    1.60 +
    1.61 +		while(select(maxfd + 1, &rdset, 0, 0, 0) == -1 && errno == EINTR);
    1.62 +
    1.63 +		if(FD_ISSET(js, &rdset)) {
    1.64 +			handle_js(js);
    1.65 +		}
    1.66 +		if(FD_ISSET(sock, &rdset)) {
    1.67 +			handle_net(sock);
    1.68 +		}
    1.69 +	}
    1.70 +
    1.71 +	close(js);
    1.72 +	close(sock);
    1.73 +	return 0;
    1.74  }
    1.75 +
    1.76 +int open_js(const char *jspath)
    1.77 +{
    1.78 +	int fd;
    1.79 +	char buf[256];
    1.80 +	int axes;
    1.81 +
    1.82 +	if((fd = open(jspath, O_RDONLY)) == -1) {
    1.83 +		fprintf(stderr, "failed to open js device: %s: %s\n", jspath, strerror(errno));
    1.84 +		return -1;
    1.85 +	}
    1.86 +	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
    1.87 +
    1.88 +	if(ioctl(fd, JSIOCGAXES, &axes) == -1) {
    1.89 +		fprintf(stderr, "failed to get number of joystick axes\n");
    1.90 +		return -1;
    1.91 +	}
    1.92 +	if(ioctl(fd, JSIOCGNAME(sizeof buf), buf) == -1) {
    1.93 +		strcpy(buf, "unknown");
    1.94 +	}
    1.95 +	printf("opened joystick: %s: %s (%d axes)\n", jspath, buf, axes);
    1.96 +
    1.97 +	js_axis_state = malloc(axes * sizeof *js_axis_state);
    1.98 +	assert(js_axis_state);
    1.99 +	js_num_axes = axes;
   1.100 +
   1.101 +	return fd;
   1.102 +}
   1.103 +
   1.104 +int handle_js(int fd)
   1.105 +{
   1.106 +	int evtype;
   1.107 +	struct js_event ev;
   1.108 +	struct client *c;
   1.109 +
   1.110 +	if(read(fd, &ev, sizeof ev) <= 0) {
   1.111 +		return -1;
   1.112 +	}
   1.113 +
   1.114 +	switch(ev.type) {
   1.115 +	case JS_EVENT_AXIS:
   1.116 +		js_axis_state[ev.number] = (float)ev.value / (float)SHRT_MAX;
   1.117 +		evtype = EV_MOTION;
   1.118 +		break;
   1.119 +
   1.120 +	case JS_EVENT_BUTTON:
   1.121 +		if(ev.value) {
   1.122 +			js_bn_state |= 1 << ev.number;
   1.123 +		} else {
   1.124 +			js_bn_state &= ~(1 << ev.number);
   1.125 +		}
   1.126 +		evtype = EV_BUTTON;
   1.127 +		break;
   1.128 +
   1.129 +	default:
   1.130 +		break;
   1.131 +	}
   1.132 +
   1.133 +	/* send client events */
   1.134 +	c = clients;
   1.135 +	while(c) {
   1.136 +		struct message m;
   1.137 +
   1.138 +		m.magic = MAGIC;
   1.139 +		m.type = evtype;
   1.140 +		m.data.event.x = js_axis_state[0];
   1.141 +		m.data.event.y = js_num_axes > 1 ? js_axis_state[1] : 0;
   1.142 +		m.data.event.z = js_num_axes > 2 ? js_axis_state[2] : 0;
   1.143 +
   1.144 +		sendto(c->s, &m, sizeof m, 0, (struct sockaddr*)&c->addr, sizeof c->addr);
   1.145 +		c = c->next;
   1.146 +	}
   1.147 +	return 0;
   1.148 +}
   1.149 +
   1.150 +int start_srv(int port)
   1.151 +{
   1.152 +	int s;
   1.153 +	struct sockaddr_in sa;
   1.154 +
   1.155 +	if((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
   1.156 +		perror("failed to create socket");
   1.157 +		return -1;
   1.158 +	}
   1.159 +
   1.160 +	memset(&sa, 0, sizeof sa);
   1.161 +	sa.sin_family = AF_INET;
   1.162 +	sa.sin_addr.s_addr = htonl(INADDR_ANY);
   1.163 +	sa.sin_port = htons(opt_dport);
   1.164 +
   1.165 +	if(bind(s, (struct sockaddr*)&sa, sizeof sa) == -1) {
   1.166 +		perror("failed to bind socket");
   1.167 +		close(s);
   1.168 +		return -1;
   1.169 +	}
   1.170 +
   1.171 +	return s;
   1.172 +}
   1.173 +
   1.174 +int handle_net(int s)
   1.175 +{
   1.176 +	return 0;
   1.177 +}