Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <linux/joystick.h>
00012 #include <iostream>
00013 #include <time.h>
00014
00015 #include "common/common.h"
00016 #include "perf/perf.h"
00017 #include "util/file.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026 static void
00027 doTest
00028 (
00029 IN const char * path
00030 )
00031 {
00032 THROW(path, "null device path");
00033
00034 DPRINTF("path: %s", path);
00035 smart_fd fd;
00036 THROW(fd.open(path, O_RDONLY), "Failed to open device path: " << path);
00037
00038
00039 const int bufsize = 1024;
00040 char devname[bufsize];
00041 THROW(ioctl(fd, JSIOCGNAME(bufsize), devname) >= 0,
00042 "Failed to acquire device name");
00043 DPRINTF("Device name: '%s'", devname);
00044
00045
00046 unsigned char nAxes;
00047 THROW(ioctl(fd, JSIOCGAXES, &nAxes) >= 0,
00048 "Failed to determine number of axes");
00049 DPRINTF("Number of axes: %d", nAxes);
00050
00051
00052 unsigned char nButtons;
00053 THROW(ioctl(fd, JSIOCGBUTTONS, &nButtons) >= 0,
00054 "Failed to determine number of buttons");
00055 DPRINTF("Number of buttons: %d", nButtons);
00056
00057
00058 THROW(!fcntl(fd, F_SETFL, O_NONBLOCK),
00059 "Failed to set device path as nonblocking");
00060
00061
00062 const int desiredHz = 100;
00063 int msSleep = 1000 / desiredHz;
00064 DPRINTF("Want to run at %d Hz", desiredHz);
00065 DPRINTF(" That means polling every %d milliseconds", msSleep);
00066 long nsSleep = 1000 * 1000 * msSleep;
00067 DPRINTF(" Which is %ld nanoseconds", nsSleep);
00068 struct timespec ts;
00069 ts.tv_sec = 0;
00070 ts.tv_nsec = nsSleep;
00071
00072
00073 const int nMax = 128;
00074 THROW(nAxes <= nMax, "Too many axes!");
00075 THROW(nButtons <= nMax, "Too many buttons!");
00076 short axes[nMax];
00077 byte_t buttons[nMax];
00078
00079
00080 printf("\n");
00081 for (;;) {
00082 nanosleep(&ts, NULL);
00083
00084
00085 int nEvents = 0;
00086 struct js_event events[32];
00087 int mask = 0x0f;
00088 while (true) {
00089 int len = read(fd, events, sizeof(events));
00090 if (len <= 0)
00091 break;
00092
00093 nEvents = len / sizeof(events[0]);
00094 for (int i = 0; i < nEvents; ++i) {
00095 switch (events[i].type & mask) {
00096 case JS_EVENT_AXIS:
00097
00098
00099
00100 axes[events[i].number] = events[i].value;
00101 break;
00102
00103 case JS_EVENT_BUTTON:
00104
00105
00106
00107 if (events[i].value) {
00108 buttons[events[i].number] = 1;
00109 }
00110 break;
00111
00112 default:
00113 DPRINTF("Unknown event type: %d",
00114 events[i].type);
00115 }
00116 }
00117 }
00118
00119
00120
00121 printf("%02d", nEvents);
00122 for (int i = 0; i < nAxes; ++i) {
00123 printf(" %6d", axes[i]);
00124 }
00125 printf(":");
00126 for (int i = 0; i < nButtons; ++i) {
00127 if (buttons[i]) {
00128 printf(" b%02d", i);
00129 buttons[i] = 0;
00130 }
00131 }
00132 printf(" ");
00133 printf("\n");
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 int
00146 main
00147 (
00148 IN int argc,
00149 IN const char * argv[]
00150 )
00151 {
00152 const char * path = "/dev/input/js0";
00153 if (argc < 2) {
00154 DPRINTF("No device path specified, using default: %s", path);
00155 } else {
00156 path = argv[1];
00157 }
00158
00159 int retval = 0;
00160 try {
00161 perf::Timer timer("overall timer");
00162
00163 doTest(path);
00164
00165 } catch (std::exception& e) {
00166 DPRINTF("EXCEPTION: %s", e.what());
00167 retval = 1;
00168 }
00169
00170 perf::dumpTimingSummary(std::cerr);
00171
00172 return retval;
00173 }
00174