aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/input/joystick-api.txt
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/input/joystick-api.txt
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'Documentation/input/joystick-api.txt')
-rw-r--r--Documentation/input/joystick-api.txt316
1 files changed, 316 insertions, 0 deletions
diff --git a/Documentation/input/joystick-api.txt b/Documentation/input/joystick-api.txt
new file mode 100644
index 000000000000..acbd32b88454
--- /dev/null
+++ b/Documentation/input/joystick-api.txt
@@ -0,0 +1,316 @@
1 Joystick API Documentation -*-Text-*-
2
3 Ragnar Hojland Espinosa
4 <ragnar@macula.net>
5
6 7 Aug 1998
7
8 $Id: joystick-api.txt,v 1.2 2001/05/08 21:21:23 vojtech Exp $
9
101. Initialization
11~~~~~~~~~~~~~~~~~
12
13Open the joystick device following the usual semantics (that is, with open).
14Since the driver now reports events instead of polling for changes,
15immediately after the open it will issue a series of synthetic events
16(JS_EVENT_INIT) that you can read to check the initial state of the
17joystick.
18
19By default, the device is opened in blocking mode.
20
21 int fd = open ("/dev/js0", O_RDONLY);
22
23
242. Event Reading
25~~~~~~~~~~~~~~~~
26
27 struct js_event e;
28 read (fd, &e, sizeof(struct js_event));
29
30where js_event is defined as
31
32 struct js_event {
33 __u32 time; /* event timestamp in milliseconds */
34 __s16 value; /* value */
35 __u8 type; /* event type */
36 __u8 number; /* axis/button number */
37 };
38
39If the read is successful, it will return sizeof(struct js_event), unless
40you wanted to read more than one event per read as described in section 3.1.
41
42
432.1 js_event.type
44~~~~~~~~~~~~~~~~~
45
46The possible values of ``type'' are
47
48 #define JS_EVENT_BUTTON 0x01 /* button pressed/released */
49 #define JS_EVENT_AXIS 0x02 /* joystick moved */
50 #define JS_EVENT_INIT 0x80 /* initial state of device */
51
52As mentioned above, the driver will issue synthetic JS_EVENT_INIT ORed
53events on open. That is, if it's issuing a INIT BUTTON event, the
54current type value will be
55
56 int type = JS_EVENT_BUTTON | JS_EVENT_INIT; /* 0x81 */
57
58If you choose not to differentiate between synthetic or real events
59you can turn off the JS_EVENT_INIT bits
60
61 type &= ~JS_EVENT_INIT; /* 0x01 */
62
63
642.2 js_event.number
65~~~~~~~~~~~~~~~~~~~
66
67The values of ``number'' correspond to the axis or button that
68generated the event. Note that they carry separate numeration (that
69is, you have both an axis 0 and a button 0). Generally,
70
71 number
72 1st Axis X 0
73 1st Axis Y 1
74 2nd Axis X 2
75 2nd Axis Y 3
76 ...and so on
77
78Hats vary from one joystick type to another. Some can be moved in 8
79directions, some only in 4, The driver, however, always reports a hat as two
80independent axis, even if the hardware doesn't allow independent movement.
81
82
832.3 js_event.value
84~~~~~~~~~~~~~~~~~~
85
86For an axis, ``value'' is a signed integer between -32767 and +32767
87representing the position of the joystick along that axis. If you
88don't read a 0 when the joystick is `dead', or if it doesn't span the
89full range, you should recalibrate it (with, for example, jscal).
90
91For a button, ``value'' for a press button event is 1 and for a release
92button event is 0.
93
94Though this
95
96 if (js_event.type == JS_EVENT_BUTTON) {
97 buttons_state ^= (1 << js_event.number);
98 }
99
100may work well if you handle JS_EVENT_INIT events separately,
101
102 if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) {
103 if (js_event.value)
104 buttons_state |= (1 << js_event.number);
105 else
106 buttons_state &= ~(1 << js_event.number);
107 }
108
109is much safer since it can't lose sync with the driver. As you would
110have to write a separate handler for JS_EVENT_INIT events in the first
111snippet, this ends up being shorter.
112
113
1142.4 js_event.time
115~~~~~~~~~~~~~~~~~
116
117The time an event was generated is stored in ``js_event.time''. It's a time
118in milliseconds since ... well, since sometime in the past. This eases the
119task of detecting double clicks, figuring out if movement of axis and button
120presses happened at the same time, and similar.
121
122
1233. Reading
124~~~~~~~~~~
125
126If you open the device in blocking mode, a read will block (that is,
127wait) forever until an event is generated and effectively read. There
128are two alternatives if you can't afford to wait forever (which is,
129admittedly, a long time;)
130
131 a) use select to wait until there's data to be read on fd, or
132 until it timeouts. There's a good example on the select(2)
133 man page.
134
135 b) open the device in non-blocking mode (O_NONBLOCK)
136
137
1383.1 O_NONBLOCK
139~~~~~~~~~~~~~~
140
141If read returns -1 when reading in O_NONBLOCK mode, this isn't
142necessarily a "real" error (check errno(3)); it can just mean there
143are no events pending to be read on the driver queue. You should read
144all events on the queue (that is, until you get a -1).
145
146For example,
147
148 while (1) {
149 while (read (fd, &e, sizeof(struct js_event)) > 0) {
150 process_event (e);
151 }
152 /* EAGAIN is returned when the queue is empty */
153 if (errno != EAGAIN) {
154 /* error */
155 }
156 /* do something interesting with processed events */
157 }
158
159One reason for emptying the queue is that if it gets full you'll start
160missing events since the queue is finite, and older events will get
161overwritten.
162
163The other reason is that you want to know all what happened, and not
164delay the processing till later.
165
166Why can get the queue full? Because you don't empty the queue as
167mentioned, or because too much time elapses from one read to another
168and too many events to store in the queue get generated. Note that
169high system load may contribute to space those reads even more.
170
171If time between reads is enough to fill the queue and lose an event,
172the driver will switch to startup mode and next time you read it,
173synthetic events (JS_EVENT_INIT) will be generated to inform you of
174the actual state of the joystick.
175
176[As for version 1.2.8, the queue is circular and able to hold 64
177 events. You can increment this size bumping up JS_BUFF_SIZE in
178 joystick.h and recompiling the driver.]
179
180
181In the above code, you might as well want to read more than one event
182at a time using the typical read(2) functionality. For that, you would
183replace the read above with something like
184
185 struct js_event mybuffer[0xff];
186 int i = read (fd, mybuffer, sizeof(struct mybuffer));
187
188In this case, read would return -1 if the queue was empty, or some
189other value in which the number of events read would be i /
190sizeof(js_event) Again, if the buffer was full, it's a good idea to
191process the events and keep reading it until you empty the driver queue.
192
193
1944. IOCTLs
195~~~~~~~~~
196
197The joystick driver defines the following ioctl(2) operations.
198
199 /* function 3rd arg */
200 #define JSIOCGAXES /* get number of axes char */
201 #define JSIOCGBUTTONS /* get number of buttons char */
202 #define JSIOCGVERSION /* get driver version int */
203 #define JSIOCGNAME(len) /* get identifier string char */
204 #define JSIOCSCORR /* set correction values &js_corr */
205 #define JSIOCGCORR /* get correction values &js_corr */
206
207For example, to read the number of axes
208
209 char number_of_axes;
210 ioctl (fd, JSIOCGAXES, &number_of_axes);
211
212
2134.1 JSIOGCVERSION
214~~~~~~~~~~~~~~~~~
215
216JSIOGCVERSION is a good way to check in run-time whether the running
217driver is 1.0+ and supports the event interface. If it is not, the
218IOCTL will fail. For a compile-time decision, you can test the
219JS_VERSION symbol
220
221 #ifdef JS_VERSION
222 #if JS_VERSION > 0xsomething
223
224
2254.2 JSIOCGNAME
226~~~~~~~~~~~~~~
227
228JSIOCGNAME(len) allows you to get the name string of the joystick - the same
229as is being printed at boot time. The 'len' argument is the length of the
230buffer provided by the application asking for the name. It is used to avoid
231possible overrun should the name be too long.
232
233 char name[128];
234 if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0)
235 strncpy(name, "Unknown", sizeof(name));
236 printf("Name: %s\n", name);
237
238
2394.3 JSIOC[SG]CORR
240~~~~~~~~~~~~~~~~~
241
242For usage on JSIOC[SG]CORR I suggest you to look into jscal.c They are
243not needed in a normal program, only in joystick calibration software
244such as jscal or kcmjoy. These IOCTLs and data types aren't considered
245to be in the stable part of the API, and therefore may change without
246warning in following releases of the driver.
247
248Both JSIOCSCORR and JSIOCGCORR expect &js_corr to be able to hold
249information for all axis. That is, struct js_corr corr[MAX_AXIS];
250
251struct js_corr is defined as
252
253 struct js_corr {
254 __s32 coef[8];
255 __u16 prec;
256 __u16 type;
257 };
258
259and ``type''
260
261 #define JS_CORR_NONE 0x00 /* returns raw values */
262 #define JS_CORR_BROKEN 0x01 /* broken line */
263
264
2655. Backward compatibility
266~~~~~~~~~~~~~~~~~~~~~~~~~
267
268The 0.x joystick driver API is quite limited and its usage is deprecated.
269The driver offers backward compatibility, though. Here's a quick summary:
270
271 struct JS_DATA_TYPE js;
272 while (1) {
273 if (read (fd, &js, JS_RETURN) != JS_RETURN) {
274 /* error */
275 }
276 usleep (1000);
277 }
278
279As you can figure out from the example, the read returns immediately,
280with the actual state of the joystick.
281
282 struct JS_DATA_TYPE {
283 int buttons; /* immediate button state */
284 int x; /* immediate x axis value */
285 int y; /* immediate y axis value */
286 };
287
288and JS_RETURN is defined as
289
290 #define JS_RETURN sizeof(struct JS_DATA_TYPE)
291
292To test the state of the buttons,
293
294 first_button_state = js.buttons & 1;
295 second_button_state = js.buttons & 2;
296
297The axis values do not have a defined range in the original 0.x driver,
298except for that the values are non-negative. The 1.2.8+ drivers use a
299fixed range for reporting the values, 1 being the minimum, 128 the
300center, and 255 maximum value.
301
302The v0.8.0.2 driver also had an interface for 'digital joysticks', (now
303called Multisystem joysticks in this driver), under /dev/djsX. This driver
304doesn't try to be compatible with that interface.
305
306
3076. Final Notes
308~~~~~~~~~~~~~~
309
310____/| Comments, additions, and specially corrections are welcome.
311\ o.O| Documentation valid for at least version 1.2.8 of the joystick
312 =(_)= driver and as usual, the ultimate source for documentation is
313 U to "Use The Source Luke" or, at your convenience, Vojtech ;)
314
315 - Ragnar
316EOF