# HG changeset patch # User John Tsiombikas # Date 1405424271 -10800 # Node ID 48dce4ee485014b33897f4b6725ea708c903075c # Parent 374d91dd299665e8d2b413ed8b2fe79cb3e57cea the fake device is working diff -r 374d91dd2996 -r 48dce4ee4850 Makefile --- a/Makefile Tue Jul 15 05:44:26 2014 +0300 +++ b/Makefile Tue Jul 15 14:37:51 2014 +0300 @@ -5,7 +5,7 @@ CFLAGS = -pedantic -Wall -g CXXFLAGS = $(CFLAGS) -LDFLAGS = -lGL -lGLU -lglut -lGLEW -lX11 -lm +LDFLAGS = -lGL -lGLU -lglut -lGLEW -lX11 -lm -lpthread $(bin): $(obj) $(CXX) -o $@ $(obj) $(LDFLAGS) diff -r 374d91dd2996 -r 48dce4ee4850 README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Tue Jul 15 14:37:51 2014 +0300 @@ -0,0 +1,4 @@ +1. Create 2 pseudoterminals: socat -d -d PTY PTY +2. start ./equeue_dummy /dev/pts/one +3. set the php script to use /dev/pts/theother (make sure apache has permission + to rw it). diff -r 374d91dd2996 -r 48dce4ee4850 src/dev.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dev.cc Tue Jul 15 14:37:51 2014 +0300 @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dev.h" +#include "timer.h" + +int customer, ticket; +static int report_inputs, cmd_echo; +static long last_ticket_msec = LONG_MIN; + +static void runcmd(const char *cmd); + +static int fd = -1; +static FILE *fp; +static std::string cur_line; + +int start_dev(const char *devpath) +{ + if((fd = open(devpath, O_RDWR | O_NONBLOCK)) == -1) { + fprintf(stderr, "failed to open device: %s: %s\n", devpath, strerror(errno)); + return -1; + } + if(isatty(fd)) { + struct termios term; + + if(tcgetattr(fd, &term) == -1) { + perror("failed to retrieve terminal attributes"); + stop_dev(); + return -1; + } + term.c_cflag = CS8 | CLOCAL; + term.c_iflag &= ~(IXON | IXOFF); + term.c_lflag = 0; + + cfsetispeed(&term, B38400); + cfsetospeed(&term, B38400); + + if(tcsetattr(fd, TCSANOW, &term) == -1) { + perror("failed to set terminal attributes"); + stop_dev(); + return -1; + } + } + + if(!(fp = fdopen(fd, "r+"))) { + perror("failed to attach an I/O stream to the device file\n"); + stop_dev(); + return -1; + } + setvbuf(fp, 0, _IONBF, 0); + + return fd; +} + +void stop_dev() +{ + if(fp) + fclose(fp); + else if(fd >= 0) + close(fd); +} + + +void proc_dev_input() +{ + int rdbytes; + char buf[256]; + static bool skip_line; + + while((rdbytes = read(fd, buf, sizeof buf - 1)) > 0) { + buf[rdbytes] = 0; + + /* ignore our own crap */ + if(memcmp(buf, "OK,", 3) == 0 || memcmp(buf, "ERR,", 4) == 0) { + skip_line = true; + } + + for(int i=0; i" + +static void runcmd(const char *cmd) +{ + printf("DBG: runcmd(\"%s\")\n", cmd); + + switch(cmd[0]) { + case 'e': + cmd_echo = !cmd_echo; + fprintf(fp, "OK,turning echo %s\n", cmd_echo ? "on" : "off"); + break; + + case 'i': + report_inputs = !report_inputs; + fprintf(fp, "OK,turning input reports %s\n", report_inputs ? "on" : "off"); + break; + + case 'v': + fprintf(fp, "OK,%s\n", VERSTR); + break; + + case 'r': + fprintf(fp, "OK,reseting queues\n"); + customer = 0; + ticket = 0; + last_ticket_msec = LONG_MIN; + break; + + case 't': + fprintf(fp, "OK,ticket: %d\r\n", ticket); + break; + + case 'c': + fprintf(fp, "OK,customer: %d\r\n", customer); + break; + + case 'q': + fprintf(fp, "OK,issuing queue ticket\n"); + issue_ticket(); + break; + + case 'n': + fprintf(fp, "OK,next customer\n"); + next_customer(); + break; + + case 'h': + fprintf(fp, "OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, " + "(n)ext, (q)ueue, (r)eset, (i)nput-reports, (h)elp.\n"); + break; + + default: + fprintf(fp, "ERR,unknown command: %s\n", cmd); + } +} diff -r 374d91dd2996 -r 48dce4ee4850 src/dev.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dev.h Tue Jul 15 14:37:51 2014 +0300 @@ -0,0 +1,16 @@ +#ifndef DEV_H_ +#define DEV_H_ + +extern int customer, ticket; + +int start_dev(const char *devpath); +void stop_dev(); +void proc_dev_input(); + +void next_customer(); +void issue_ticket(); + +int get_display_number(); +int get_led_state(int led); + +#endif /* DEV_H_ */ diff -r 374d91dd2996 -r 48dce4ee4850 src/main.cc --- a/src/main.cc Tue Jul 15 05:44:26 2014 +0300 +++ b/src/main.cc Tue Jul 15 14:37:51 2014 +0300 @@ -20,6 +20,8 @@ static void process_events(); static int translate_keysym(KeySym sym); +static int proc_args(int argc, char **argv); + static Display *dpy; static Window win; static GLXContext ctx; @@ -30,10 +32,15 @@ static bool redisplay_pending; static bool win_mapped; -int main() +static int fakefd = -1; +static char *fake_devpath; + +int main(int argc, char **argv) { + if(proc_args(argc, argv) == -1) { + return 1; + } if(!init()) { - fprintf(stderr, "X11/OpenGL initialization failed\n"); return 1; } atexit(cleanup); @@ -45,12 +52,18 @@ FD_ZERO(&rd); FD_SET(xfd, &rd); + FD_SET(fakefd, &rd); - while(select(xfd + 1, &rd, 0, 0, 0) == -1 && errno == EINTR); + int maxfd = xfd > fakefd ? xfd : fakefd; + + while(select(maxfd + 1, &rd, 0, 0, 0) == -1 && errno == EINTR); if(FD_ISSET(xfd, &rd)) { process_events(); } + if(FD_ISSET(fakefd, &rd)) { + proc_dev_input(); + } if(redisplay_pending) { display(); @@ -62,7 +75,11 @@ static bool init() { - start_dev(); + if(fake_devpath) { + if((fakefd = start_dev(fake_devpath)) == -1) { + return false; + } + } if(!(dpy = XOpenDisplay(0))) { fprintf(stderr, "failed to connect to the X server!\n"); @@ -290,3 +307,24 @@ } return (int)sym; } + +static int proc_args(int argc, char **argv) +{ + for(int i=1; i +#include + +unsigned long get_msec() +{ + static struct timeval tv0; + struct timeval tv; + + gettimeofday(&tv, 0); + if(tv0.tv_sec == 0 && tv0.tv_usec == 0) { + tv0 = tv; + return 0; + } + return (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000; +} diff -r 374d91dd2996 -r 48dce4ee4850 src/timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timer.h Tue Jul 15 14:37:51 2014 +0300 @@ -0,0 +1,6 @@ +#ifndef TIMER_H_ +#define TIMER_H_ + +unsigned long get_msec(); + +#endif /* TIMER_H_ */