- added jstest and evtest for convenience
This commit is contained in:
parent
a069219fb7
commit
984a1194d7
6 changed files with 499 additions and 8 deletions
8
README
8
README
|
@ -116,13 +116,15 @@ Along with all the "Unknown data" lines you get.
|
|||
|
||||
3) Program starts and then just does nothing
|
||||
--------------------------------------------
|
||||
|
||||
This is what the program is supposed to do. After you started it will
|
||||
give you basically two devices, a new /dev/input/eventX and a
|
||||
/dev/input/jsX. You can access and test your controller with jstest
|
||||
and evtest applications. Or in case you want just see if your driver
|
||||
is working correctly you can pass the -v option:
|
||||
and evtest applications (available from your distribution or in the
|
||||
tools/ subdirectory). Or in case you want just see if your driver is
|
||||
working correctly you can pass the -v option:
|
||||
|
||||
% ./xboxdrv -v
|
||||
% ./xboxdrv -v
|
||||
|
||||
This will cause the driver to output all the events that it received
|
||||
from the controller.
|
||||
|
|
5
TODO
5
TODO
|
@ -1,10 +1,5 @@
|
|||
* document /dev/input/eventX device
|
||||
|
||||
* document "modprobe joydev"
|
||||
|
||||
* add jstest, evtest into the source
|
||||
|
||||
|
||||
* disconnecting the pad in use will just let the driver wait forever
|
||||
for new data, any way we can catch a disconnect?
|
||||
|
||||
|
|
3
tools/.gitignore
vendored
Normal file
3
tools/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*~
|
||||
evtest
|
||||
jstest
|
177
tools/evtest.c
Normal file
177
tools/evtest.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* $Id: evtest.c,v 1.1 2004/01/17 16:59:46 js Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2000 Vojtech Pavlik
|
||||
*
|
||||
* Event device test program
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Should you need to contact me, the author, you can do so either by
|
||||
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
|
||||
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
|
||||
*/
|
||||
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *events[EV_MAX + 1] = { "Reset", "Key", "Relative", "Absolute", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, "LED", "Sound", NULL, "Repeat", "ForceFeedback", NULL, "ForceFeedbackStatus"};
|
||||
char *keys[KEY_MAX + 1] = { "Reserved", "Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Minus", "Equal", "Backspace",
|
||||
"Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "LeftBrace", "RightBrace", "Enter", "LeftControl", "A", "S", "D", "F", "G",
|
||||
"H", "J", "K", "L", "Semicolon", "Apostrophe", "Grave", "LeftShift", "BackSlash", "Z", "X", "C", "V", "B", "N", "M", "Comma", "Dot",
|
||||
"Slash", "RightShift", "KPAsterisk", "LeftAlt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
|
||||
"NumLock", "ScrollLock", "KP7", "KP8", "KP9", "KPMinus", "KP4", "KP5", "KP6", "KPPlus", "KP1", "KP2", "KP3", "KP0", "KPDot", "103rd",
|
||||
"F13", "102nd", "F11", "F12", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "KPEnter", "RightCtrl", "KPSlash", "SysRq",
|
||||
"RightAlt", "LineFeed", "Home", "Up", "PageUp", "Left", "Right", "End", "Down", "PageDown", "Insert", "Delete", "Macro", "Mute",
|
||||
"VolumeDown", "VolumeUp", "Power", "KPEqual", "KPPlusMinus", "Pause", "F21", "F22", "F23", "F24", "KPComma", "LeftMeta", "RightMeta",
|
||||
"Compose", "Stop", "Again", "Props", "Undo", "Front", "Copy", "Open", "Paste", "Find", "Cut", "Help", "Menu", "Calc", "Setup",
|
||||
"Sleep", "WakeUp", "File", "SendFile", "DeleteFile", "X-fer", "Prog1", "Prog2", "WWW", "MSDOS", "Coffee", "Direction",
|
||||
"CycleWindows", "Mail", "Bookmarks", "Computer", "Back", "Forward", "CloseCD", "EjectCD", "EjectCloseCD", "NextSong", "PlayPause",
|
||||
"PreviousSong", "StopCD", "Record", "Rewind", "Phone", "ISOKey", "Config", "HomePage", "Refresh", "Exit", "Move", "Edit", "ScrollUp",
|
||||
"ScrollDown", "KPLeftParenthesis", "KPRightParenthesis",
|
||||
"International1", "International2", "International3", "International4", "International5",
|
||||
"International6", "International7", "International8", "International9",
|
||||
"Language1", "Language2", "Language3", "Language4", "Language5", "Language6", "Language7", "Language8", "Language9",
|
||||
NULL,
|
||||
"PlayCD", "PauseCD", "Prog3", "Prog4", "Suspend", "Close",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7", "Btn8", "Btn9",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn",
|
||||
"BaseBtn", "BaseBtn2", "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6",
|
||||
NULL, NULL, NULL, "BtnDead",
|
||||
"BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR", "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode",
|
||||
"BtnThumbL", "BtnThumbR", NULL,
|
||||
"ToolPen", "ToolRubber", "ToolBrush", "ToolPencil", "ToolAirbrush", "ToolFinger", "ToolMouse", "ToolLens", NULL, NULL,
|
||||
"Touch", "Stylus", "Stylus2", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"Ok", "Select", "Goto", "Clear", "Power2", "Option", "Info", "Time", "Vendor",
|
||||
"Archive", "Program", "Channel", "Favorites", "EPG", "PVR", "MHP", "Language",
|
||||
"Title", "Subtitle", "Angle", "Zoom", "Mode", "Keyboard", "Screen", "PC", "TV",
|
||||
"TV2", "VCR", "VCR2", "Sat", "Sat2", "CD", "Tape", "Radio", "Tuner", "Player",
|
||||
"Text", "DVD", "Aux", "MP3", "Audio", "Video", "Directory", "List", "Memo",
|
||||
"Calendar", "Red", "Green", "Yellow", "Blue", "ChannelUp", "ChannelDown",
|
||||
"First", "Last", "AB", "Play", "Restart", "Slow", "Shuffle", "FastForward",
|
||||
"Previous", "Next", "Digits", "Teen", "Twen", "Break" };
|
||||
|
||||
char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };
|
||||
char *relatives[REL_MAX + 1] = { "X", "Y", "Z", NULL, NULL, NULL, "HWheel", "Dial", "Wheel" };
|
||||
char *absolutes[ABS_MAX + 1] = { "X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder", "Wheel", "Gas", "Brake",
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
"Hat0X", "Hat0Y", "Hat1X", "Hat1Y", "Hat2X", "Hat2Y", "Hat3X", "Hat 3Y", "Pressure", "Distance", "XTilt", "YTilt"};
|
||||
char *leds[LED_MAX + 1] = { "NumLock", "CapsLock", "ScrollLock", "Compose", "Kana", "Sleep", "Suspend", "Mute" };
|
||||
char *repeats[REP_MAX + 1] = { "Delay", "Period" };
|
||||
char *sounds[SND_MAX + 1] = { "Bell", "Click" };
|
||||
|
||||
char **names[EV_MAX + 1] = { events, keys, relatives, absolutes, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, leds, sounds, NULL, repeats, NULL, NULL, NULL };
|
||||
|
||||
#define BITS_PER_LONG (sizeof(long) * 8)
|
||||
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
|
||||
#define OFF(x) ((x)%BITS_PER_LONG)
|
||||
#define BIT(x) (1UL<<OFF(x))
|
||||
#define LONG(x) ((x)/BITS_PER_LONG)
|
||||
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int fd, rd, i, j, k;
|
||||
struct input_event ev[64];
|
||||
int version;
|
||||
unsigned short id[4];
|
||||
unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
|
||||
char name[256] = "Unknown";
|
||||
int abs[5];
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: evtest /dev/input/eventX\n");
|
||||
printf("Where X = input device number\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
|
||||
perror("evtest");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ioctl(fd, EVIOCGVERSION, &version)) {
|
||||
perror("evtest: can't get version");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Input driver version is %d.%d.%d\n",
|
||||
version >> 16, (version >> 8) & 0xff, version & 0xff);
|
||||
|
||||
ioctl(fd, EVIOCGID, id);
|
||||
printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
|
||||
id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
|
||||
|
||||
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
|
||||
printf("Input device name: \"%s\"\n", name);
|
||||
|
||||
memset(bit, 0, sizeof(bit));
|
||||
ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
|
||||
printf("Supported events:\n");
|
||||
|
||||
for (i = 0; i < EV_MAX; i++)
|
||||
if (test_bit(i, bit[0])) {
|
||||
printf(" Event type %d (%s)\n", i, events[i] ? events[i] : "?");
|
||||
ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
|
||||
for (j = 0; j < KEY_MAX; j++)
|
||||
if (test_bit(j, bit[i])) {
|
||||
printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
|
||||
if (i == EV_ABS) {
|
||||
ioctl(fd, EVIOCGABS(j), abs);
|
||||
for (k = 0; k < 5; k++)
|
||||
if ((k < 3) || abs[k])
|
||||
printf(" %s %6d\n", absval[k], abs[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("Testing ... (interrupt to exit)\n");
|
||||
|
||||
while (1) {
|
||||
rd = read(fd, ev, sizeof(struct input_event) * 64);
|
||||
|
||||
if (rd < (int) sizeof(struct input_event)) {
|
||||
printf("yyy\n");
|
||||
perror("\nevtest: error reading");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
for (i = 0; i < rd / sizeof(struct input_event); i++)
|
||||
printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
|
||||
ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
|
||||
events[ev[i].type] ? events[ev[i].type] : "?",
|
||||
ev[i].code,
|
||||
names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
|
||||
ev[i].value);
|
||||
|
||||
}
|
||||
}
|
||||
|
33
tools/jstest.1
Normal file
33
tools/jstest.1
Normal file
|
@ -0,0 +1,33 @@
|
|||
.TH JSTEST 1
|
||||
.SH NAME
|
||||
jstest \- joystick test program
|
||||
.SH SYNOPSIS
|
||||
.B jstest
|
||||
[--normal] [--old] [--event] [--nonblock] [--select] <device-name>
|
||||
.SH DESCRIPTION
|
||||
.B jstest
|
||||
can be used to test all the features of the Linux
|
||||
joystick API, including non-blocking and \fBselect\fP(2) access, as
|
||||
well as version 0.x compatibility mode.
|
||||
.PP
|
||||
It is also intended to
|
||||
serve as an example implementation for those who wish to learn
|
||||
how to write their own joystick using applications.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I \--normal
|
||||
One-line mode showing immediate status.
|
||||
.TP
|
||||
.I \--old
|
||||
Same as --normal, using 0.x interface.
|
||||
.TP
|
||||
.I \--event
|
||||
Prints events as they come in.
|
||||
.TP
|
||||
.I \--nonblock
|
||||
Same as --event, in nonblocking mode.
|
||||
.TP
|
||||
.I \--select
|
||||
Same as --event, using \fBselect\fP(2) call.
|
||||
.SH SEE ALSO
|
||||
\fBjscal\fP(1), \fBinputattach\fP(1), \fBselect\fP(2).
|
281
tools/jstest.c
Normal file
281
tools/jstest.c
Normal file
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* jstest.c Version 1.2
|
||||
*
|
||||
* Copyright (c) 1996-1999 Vojtech Pavlik
|
||||
*
|
||||
* Sponsored by SuSE
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program can be used to test all the features of the Linux
|
||||
* joystick API, including non-blocking and select() access, as
|
||||
* well as version 0.x compatibility mode. It is also intended to
|
||||
* serve as an example implementation for those who wish to learn
|
||||
* how to write their own joystick using applications.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Should you need to contact me, the author, you can do so either by
|
||||
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
|
||||
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/joystick.h>
|
||||
|
||||
char *axis_names[ABS_MAX + 1] = {
|
||||
"X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder",
|
||||
"Wheel", "Gas", "Brake", "?", "?", "?", "?", "?",
|
||||
"Hat0X", "Hat0Y", "Hat1X", "Hat1Y", "Hat2X", "Hat2Y", "Hat3X", "Hat3Y",
|
||||
"?", "?", "?", "?", "?", "?", "?",
|
||||
};
|
||||
|
||||
char *button_names[KEY_MAX - BTN_MISC + 1] = {
|
||||
"Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7", "Btn8", "Btn9", "?", "?", "?", "?", "?", "?",
|
||||
"LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn", "TaskBtn", "?", "?", "?", "?", "?", "?", "?", "?",
|
||||
"Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn", "BaseBtn", "BaseBtn2", "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6", "BtnDead",
|
||||
"BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR", "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode", "BtnThumbL", "BtnThumbR", "?",
|
||||
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
|
||||
"WheelBtn", "Gear up",
|
||||
};
|
||||
|
||||
#define NAME_LENGTH 128
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int fd, i;
|
||||
unsigned char axes = 2;
|
||||
unsigned char buttons = 2;
|
||||
int version = 0x000800;
|
||||
char name[NAME_LENGTH] = "Unknown";
|
||||
uint16_t btnmap[KEY_MAX - BTN_MISC + 1];
|
||||
uint8_t axmap[ABS_MAX + 1];
|
||||
|
||||
if (argc < 2 || argc > 3 || !strcmp("--help", argv[1])) {
|
||||
puts("");
|
||||
puts("Usage: jstest [<mode>] <device>");
|
||||
puts("");
|
||||
puts("Modes:");
|
||||
puts(" --normal One-line mode showing immediate status");
|
||||
puts(" --old Same as --normal, using 0.x interface");
|
||||
puts(" --event Prints events as they come in");
|
||||
puts(" --nonblock Same as --event, in nonblocking mode");
|
||||
puts(" --select Same as --event, using select() call");
|
||||
puts("");
|
||||
return 1;
|
||||
}
|
||||
if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
|
||||
perror("jstest");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ioctl(fd, JSIOCGVERSION, &version);
|
||||
ioctl(fd, JSIOCGAXES, &axes);
|
||||
ioctl(fd, JSIOCGBUTTONS, &buttons);
|
||||
ioctl(fd, JSIOCGNAME(NAME_LENGTH), name);
|
||||
ioctl(fd, JSIOCGAXMAP, axmap);
|
||||
ioctl(fd, JSIOCGBTNMAP, btnmap);
|
||||
|
||||
|
||||
printf("Driver version is %d.%d.%d.\n",
|
||||
version >> 16, (version >> 8) & 0xff, version & 0xff);
|
||||
|
||||
if (buttons > 0 && btnmap[0] < BTN_MISC) {
|
||||
/* btnmap out of range for names. Don't print any. */
|
||||
printf("Joystick (%s) has %d axes ", name, axes);
|
||||
printf("and %d buttons.\n", buttons);
|
||||
} else {
|
||||
printf("Joystick (%s) has %d axes (", name, axes);
|
||||
for (i = 0; i < axes; i++)
|
||||
printf("%s%s", i > 0 ? ", " : "", axis_names[axmap[i]]);
|
||||
puts(")");
|
||||
|
||||
printf("and %d buttons (", buttons);
|
||||
for (i = 0; i < buttons; i++)
|
||||
printf("%s%s", i > 0 ? ", " : "", button_names[btnmap[i] - BTN_MISC]);
|
||||
puts(").");
|
||||
}
|
||||
|
||||
printf("Testing ... (interrupt to exit)\n");
|
||||
|
||||
/*
|
||||
* Old (0.x) interface.
|
||||
*/
|
||||
|
||||
if ((argc == 2 && version < 0x010000) || !strcmp("--old", argv[1])) {
|
||||
|
||||
struct JS_DATA_TYPE js;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (read(fd, &js, JS_RETURN) != JS_RETURN) {
|
||||
perror("\njstest: error reading");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Axes: X:%3d Y:%3d Buttons: A:%s B:%s\r",
|
||||
js.x, js.y, (js.buttons & 1) ? "on " : "off", (js.buttons & 2) ? "on " : "off");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Event interface, single line readout.
|
||||
*/
|
||||
|
||||
if (argc == 2 || !strcmp("--normal", argv[1])) {
|
||||
|
||||
int *axis;
|
||||
char *button;
|
||||
int i;
|
||||
struct js_event js;
|
||||
|
||||
axis = calloc(axes, sizeof(int));
|
||||
button = calloc(buttons, sizeof(char));
|
||||
|
||||
while (1) {
|
||||
if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
|
||||
perror("\njstest: error reading");
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch(js.type & ~JS_EVENT_INIT) {
|
||||
case JS_EVENT_BUTTON:
|
||||
button[js.number] = js.value;
|
||||
break;
|
||||
case JS_EVENT_AXIS:
|
||||
axis[js.number] = js.value;
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\r");
|
||||
|
||||
if (axes) {
|
||||
printf("Axes: ");
|
||||
for (i = 0; i < axes; i++)
|
||||
printf("%2d:%6d ", i, axis[i]);
|
||||
}
|
||||
|
||||
if (buttons) {
|
||||
printf("Buttons: ");
|
||||
for (i = 0; i < buttons; i++)
|
||||
printf("%2d:%s ", i, button[i] ? "on " : "off");
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Event interface, events being printed.
|
||||
*/
|
||||
|
||||
if (!strcmp("--event", argv[1])) {
|
||||
|
||||
struct js_event js;
|
||||
|
||||
while (1) {
|
||||
if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
|
||||
perror("\njstest: error reading");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Event: type %d, time %d, number %d, value %d\n",
|
||||
js.type, js.time, js.number, js.value);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reading in nonblocking mode.
|
||||
*/
|
||||
|
||||
if (!strcmp("--nonblock", argv[1])) {
|
||||
|
||||
struct js_event js;
|
||||
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
while (1) {
|
||||
|
||||
while (read(fd, &js, sizeof(struct js_event)) == sizeof(struct js_event)) {
|
||||
printf("Event: type %d, time %d, number %d, value %d\n",
|
||||
js.type, js.time, js.number, js.value);
|
||||
}
|
||||
|
||||
if (errno != EAGAIN) {
|
||||
perror("\njstest: error reading");
|
||||
return 1;
|
||||
}
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Using select() on joystick fd.
|
||||
*/
|
||||
|
||||
if (!strcmp("--select", argv[1])) {
|
||||
|
||||
struct js_event js;
|
||||
struct timeval tv;
|
||||
fd_set set;
|
||||
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
FD_ZERO(&set);
|
||||
FD_SET(fd, &set);
|
||||
|
||||
if (select(fd+1, &set, NULL, NULL, &tv)) {
|
||||
|
||||
if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
|
||||
perror("\njstest: error reading");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Event: type %d, time %d, number %d, value %d\n",
|
||||
js.type, js.time, js.number, js.value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
printf("jstest: unknown mode: %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
Loading…
Add table
Reference in a new issue