1ad649380SDmitry Torokhov.. _joystick-api:
2ad649380SDmitry Torokhov
34c79e98bSDmitry Torokhov=====================
44c79e98bSDmitry TorokhovProgramming Interface
54c79e98bSDmitry Torokhov=====================
64c79e98bSDmitry Torokhov
74c79e98bSDmitry Torokhov:Author: Ragnar Hojland Espinosa <ragnar@macula.net> - 7 Aug 1998
84c79e98bSDmitry Torokhov
94c79e98bSDmitry TorokhovIntroduction
104c79e98bSDmitry Torokhov============
114c79e98bSDmitry Torokhov
124c79e98bSDmitry Torokhov.. important::
134c79e98bSDmitry Torokhov   This document describes legacy ``js`` interface. Newer clients are
144c79e98bSDmitry Torokhov   encouraged to switch to the generic event (``evdev``) interface.
154c79e98bSDmitry Torokhov
164c79e98bSDmitry TorokhovThe 1.0 driver uses a new, event based approach to the joystick driver.
174c79e98bSDmitry TorokhovInstead of the user program polling for the joystick values, the joystick
184c79e98bSDmitry Torokhovdriver now reports only any changes of its state. See joystick-api.txt,
194c79e98bSDmitry Torokhovjoystick.h and jstest.c included in the joystick package for more
204c79e98bSDmitry Torokhovinformation. The joystick device can be used in either blocking or
214c79e98bSDmitry Torokhovnonblocking mode, and supports select() calls.
224c79e98bSDmitry Torokhov
234c79e98bSDmitry TorokhovFor backward compatibility the old (v0.x) interface is still included.
244c79e98bSDmitry TorokhovAny call to the joystick driver using the old interface will return values
254c79e98bSDmitry Torokhovthat are compatible to the old interface. This interface is still limited
264c79e98bSDmitry Torokhovto 2 axes, and applications using it usually decode only 2 buttons, although
274c79e98bSDmitry Torokhovthe driver provides up to 32.
284c79e98bSDmitry Torokhov
294c79e98bSDmitry TorokhovInitialization
304c79e98bSDmitry Torokhov==============
314c79e98bSDmitry Torokhov
324c79e98bSDmitry TorokhovOpen the joystick device following the usual semantics (that is, with open).
334c79e98bSDmitry TorokhovSince the driver now reports events instead of polling for changes,
344c79e98bSDmitry Torokhovimmediately after the open it will issue a series of synthetic events
354c79e98bSDmitry Torokhov(JS_EVENT_INIT) that you can read to obtain the initial state of the
364c79e98bSDmitry Torokhovjoystick.
374c79e98bSDmitry Torokhov
384c79e98bSDmitry TorokhovBy default, the device is opened in blocking mode::
394c79e98bSDmitry Torokhov
404c79e98bSDmitry Torokhov	int fd = open ("/dev/input/js0", O_RDONLY);
414c79e98bSDmitry Torokhov
424c79e98bSDmitry Torokhov
434c79e98bSDmitry TorokhovEvent Reading
444c79e98bSDmitry Torokhov=============
454c79e98bSDmitry Torokhov
464c79e98bSDmitry Torokhov::
474c79e98bSDmitry Torokhov
484c79e98bSDmitry Torokhov	struct js_event e;
494c79e98bSDmitry Torokhov	read (fd, &e, sizeof(e));
504c79e98bSDmitry Torokhov
514c79e98bSDmitry Torokhovwhere js_event is defined as::
524c79e98bSDmitry Torokhov
534c79e98bSDmitry Torokhov	struct js_event {
544c79e98bSDmitry Torokhov		__u32 time;     /* event timestamp in milliseconds */
554c79e98bSDmitry Torokhov		__s16 value;    /* value */
564c79e98bSDmitry Torokhov		__u8 type;      /* event type */
574c79e98bSDmitry Torokhov		__u8 number;    /* axis/button number */
584c79e98bSDmitry Torokhov	};
594c79e98bSDmitry Torokhov
604c79e98bSDmitry TorokhovIf the read is successful, it will return sizeof(e), unless you wanted to read
614c79e98bSDmitry Torokhovmore than one event per read as described in section 3.1.
624c79e98bSDmitry Torokhov
634c79e98bSDmitry Torokhov
644c79e98bSDmitry Torokhovjs_event.type
654c79e98bSDmitry Torokhov-------------
664c79e98bSDmitry Torokhov
674c79e98bSDmitry TorokhovThe possible values of ``type`` are::
684c79e98bSDmitry Torokhov
694c79e98bSDmitry Torokhov	#define JS_EVENT_BUTTON         0x01    /* button pressed/released */
704c79e98bSDmitry Torokhov	#define JS_EVENT_AXIS           0x02    /* joystick moved */
714c79e98bSDmitry Torokhov	#define JS_EVENT_INIT           0x80    /* initial state of device */
724c79e98bSDmitry Torokhov
734c79e98bSDmitry TorokhovAs mentioned above, the driver will issue synthetic JS_EVENT_INIT ORed
74eef8abdaSRandy Dunlapevents on open. That is, if it's issuing an INIT BUTTON event, the
754c79e98bSDmitry Torokhovcurrent type value will be::
764c79e98bSDmitry Torokhov
774c79e98bSDmitry Torokhov	int type = JS_EVENT_BUTTON | JS_EVENT_INIT;	/* 0x81 */
784c79e98bSDmitry Torokhov
794c79e98bSDmitry TorokhovIf you choose not to differentiate between synthetic or real events
804c79e98bSDmitry Torokhovyou can turn off the JS_EVENT_INIT bits::
814c79e98bSDmitry Torokhov
824c79e98bSDmitry Torokhov	type &= ~JS_EVENT_INIT;				/* 0x01 */
834c79e98bSDmitry Torokhov
844c79e98bSDmitry Torokhov
854c79e98bSDmitry Torokhovjs_event.number
864c79e98bSDmitry Torokhov---------------
874c79e98bSDmitry Torokhov
884c79e98bSDmitry TorokhovThe values of ``number`` correspond to the axis or button that
894c79e98bSDmitry Torokhovgenerated the event. Note that they carry separate numeration (that
904c79e98bSDmitry Torokhovis, you have both an axis 0 and a button 0). Generally,
914c79e98bSDmitry Torokhov
924c79e98bSDmitry Torokhov        =============== =======
934c79e98bSDmitry Torokhov	Axis		number
944c79e98bSDmitry Torokhov        =============== =======
954c79e98bSDmitry Torokhov	1st Axis X	0
964c79e98bSDmitry Torokhov	1st Axis Y	1
974c79e98bSDmitry Torokhov	2nd Axis X	2
984c79e98bSDmitry Torokhov	2nd Axis Y	3
994c79e98bSDmitry Torokhov	...and so on
1004c79e98bSDmitry Torokhov        =============== =======
1014c79e98bSDmitry Torokhov
1024c79e98bSDmitry TorokhovHats vary from one joystick type to another. Some can be moved in 8
103eef8abdaSRandy Dunlapdirections, some only in 4. The driver, however, always reports a hat as two
104eef8abdaSRandy Dunlapindependent axes, even if the hardware doesn't allow independent movement.
1054c79e98bSDmitry Torokhov
1064c79e98bSDmitry Torokhov
1074c79e98bSDmitry Torokhovjs_event.value
1084c79e98bSDmitry Torokhov--------------
1094c79e98bSDmitry Torokhov
1104c79e98bSDmitry TorokhovFor an axis, ``value`` is a signed integer between -32767 and +32767
1114c79e98bSDmitry Torokhovrepresenting the position of the joystick along that axis. If you
1124c79e98bSDmitry Torokhovdon't read a 0 when the joystick is ``dead``, or if it doesn't span the
1134c79e98bSDmitry Torokhovfull range, you should recalibrate it (with, for example, jscal).
1144c79e98bSDmitry Torokhov
1154c79e98bSDmitry TorokhovFor a button, ``value`` for a press button event is 1 and for a release
1164c79e98bSDmitry Torokhovbutton event is 0.
1174c79e98bSDmitry Torokhov
1184c79e98bSDmitry TorokhovThough this::
1194c79e98bSDmitry Torokhov
1204c79e98bSDmitry Torokhov	if (js_event.type == JS_EVENT_BUTTON) {
1214c79e98bSDmitry Torokhov		buttons_state ^= (1 << js_event.number);
1224c79e98bSDmitry Torokhov	}
1234c79e98bSDmitry Torokhov
1244c79e98bSDmitry Torokhovmay work well if you handle JS_EVENT_INIT events separately,
1254c79e98bSDmitry Torokhov
1264c79e98bSDmitry Torokhov::
1274c79e98bSDmitry Torokhov
1284c79e98bSDmitry Torokhov	if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) {
1294c79e98bSDmitry Torokhov		if (js_event.value)
1304c79e98bSDmitry Torokhov			buttons_state |= (1 << js_event.number);
1314c79e98bSDmitry Torokhov		else
1324c79e98bSDmitry Torokhov			buttons_state &= ~(1 << js_event.number);
1334c79e98bSDmitry Torokhov	}
1344c79e98bSDmitry Torokhov
1354c79e98bSDmitry Torokhovis much safer since it can't lose sync with the driver. As you would
1364c79e98bSDmitry Torokhovhave to write a separate handler for JS_EVENT_INIT events in the first
1374c79e98bSDmitry Torokhovsnippet, this ends up being shorter.
1384c79e98bSDmitry Torokhov
1394c79e98bSDmitry Torokhov
1404c79e98bSDmitry Torokhovjs_event.time
1414c79e98bSDmitry Torokhov-------------
1424c79e98bSDmitry Torokhov
1434c79e98bSDmitry TorokhovThe time an event was generated is stored in ``js_event.time``. It's a time
1444c79e98bSDmitry Torokhovin milliseconds since ... well, since sometime in the past.  This eases the
1454c79e98bSDmitry Torokhovtask of detecting double clicks, figuring out if movement of axis and button
1464c79e98bSDmitry Torokhovpresses happened at the same time, and similar.
1474c79e98bSDmitry Torokhov
1484c79e98bSDmitry Torokhov
1494c79e98bSDmitry TorokhovReading
1504c79e98bSDmitry Torokhov=======
1514c79e98bSDmitry Torokhov
1524c79e98bSDmitry TorokhovIf you open the device in blocking mode, a read will block (that is,
1534c79e98bSDmitry Torokhovwait) forever until an event is generated and effectively read. There
1544c79e98bSDmitry Torokhovare two alternatives if you can't afford to wait forever (which is,
1554c79e98bSDmitry Torokhovadmittedly, a long time;)
1564c79e98bSDmitry Torokhov
1574c79e98bSDmitry Torokhov	a) use select to wait until there's data to be read on fd, or
1584c79e98bSDmitry Torokhov	   until it timeouts. There's a good example on the select(2)
1594c79e98bSDmitry Torokhov	   man page.
1604c79e98bSDmitry Torokhov
1614c79e98bSDmitry Torokhov	b) open the device in non-blocking mode (O_NONBLOCK)
1624c79e98bSDmitry Torokhov
1634c79e98bSDmitry Torokhov
1644c79e98bSDmitry TorokhovO_NONBLOCK
1654c79e98bSDmitry Torokhov----------
1664c79e98bSDmitry Torokhov
1674c79e98bSDmitry TorokhovIf read returns -1 when reading in O_NONBLOCK mode, this isn't
1684c79e98bSDmitry Torokhovnecessarily a "real" error (check errno(3)); it can just mean there
1694c79e98bSDmitry Torokhovare no events pending to be read on the driver queue. You should read
1704c79e98bSDmitry Torokhovall events on the queue (that is, until you get a -1).
1714c79e98bSDmitry Torokhov
1724c79e98bSDmitry TorokhovFor example,
1734c79e98bSDmitry Torokhov
1744c79e98bSDmitry Torokhov::
1754c79e98bSDmitry Torokhov
1764c79e98bSDmitry Torokhov	while (1) {
1774c79e98bSDmitry Torokhov		while (read (fd, &e, sizeof(e)) > 0) {
1784c79e98bSDmitry Torokhov			process_event (e);
1794c79e98bSDmitry Torokhov		}
1804c79e98bSDmitry Torokhov		/* EAGAIN is returned when the queue is empty */
1814c79e98bSDmitry Torokhov		if (errno != EAGAIN) {
1824c79e98bSDmitry Torokhov			/* error */
1834c79e98bSDmitry Torokhov		}
1844c79e98bSDmitry Torokhov		/* do something interesting with processed events */
1854c79e98bSDmitry Torokhov	}
1864c79e98bSDmitry Torokhov
1874c79e98bSDmitry TorokhovOne reason for emptying the queue is that if it gets full you'll start
1884c79e98bSDmitry Torokhovmissing events since the queue is finite, and older events will get
1894c79e98bSDmitry Torokhovoverwritten.
1904c79e98bSDmitry Torokhov
191eef8abdaSRandy DunlapThe other reason is that you want to know all that happened, and not
1924c79e98bSDmitry Torokhovdelay the processing till later.
1934c79e98bSDmitry Torokhov
194eef8abdaSRandy DunlapWhy can the queue get full? Because you don't empty the queue as
1954c79e98bSDmitry Torokhovmentioned, or because too much time elapses from one read to another
1964c79e98bSDmitry Torokhovand too many events to store in the queue get generated. Note that
1974c79e98bSDmitry Torokhovhigh system load may contribute to space those reads even more.
1984c79e98bSDmitry Torokhov
1994c79e98bSDmitry TorokhovIf time between reads is enough to fill the queue and lose an event,
2004c79e98bSDmitry Torokhovthe driver will switch to startup mode and next time you read it,
2014c79e98bSDmitry Torokhovsynthetic events (JS_EVENT_INIT) will be generated to inform you of
2024c79e98bSDmitry Torokhovthe actual state of the joystick.
2034c79e98bSDmitry Torokhov
2044c79e98bSDmitry Torokhov
2054c79e98bSDmitry Torokhov.. note::
2064c79e98bSDmitry Torokhov
2074c79e98bSDmitry Torokhov As of version 1.2.8, the queue is circular and able to hold 64
2084c79e98bSDmitry Torokhov events. You can increment this size bumping up JS_BUFF_SIZE in
2094c79e98bSDmitry Torokhov joystick.h and recompiling the driver.
2104c79e98bSDmitry Torokhov
2114c79e98bSDmitry Torokhov
2124c79e98bSDmitry TorokhovIn the above code, you might as well want to read more than one event
2134c79e98bSDmitry Torokhovat a time using the typical read(2) functionality. For that, you would
2144c79e98bSDmitry Torokhovreplace the read above with something like::
2154c79e98bSDmitry Torokhov
2164c79e98bSDmitry Torokhov	struct js_event mybuffer[0xff];
2174c79e98bSDmitry Torokhov	int i = read (fd, mybuffer, sizeof(mybuffer));
2184c79e98bSDmitry Torokhov
2194c79e98bSDmitry TorokhovIn this case, read would return -1 if the queue was empty, or some
2204c79e98bSDmitry Torokhovother value in which the number of events read would be i /
2214c79e98bSDmitry Torokhovsizeof(js_event)  Again, if the buffer was full, it's a good idea to
2224c79e98bSDmitry Torokhovprocess the events and keep reading it until you empty the driver queue.
2234c79e98bSDmitry Torokhov
2244c79e98bSDmitry Torokhov
2254c79e98bSDmitry TorokhovIOCTLs
2264c79e98bSDmitry Torokhov======
2274c79e98bSDmitry Torokhov
2284c79e98bSDmitry TorokhovThe joystick driver defines the following ioctl(2) operations::
2294c79e98bSDmitry Torokhov
2304c79e98bSDmitry Torokhov				/* function			3rd arg  */
2314c79e98bSDmitry Torokhov	#define JSIOCGAXES	/* get number of axes		char	 */
2324c79e98bSDmitry Torokhov	#define JSIOCGBUTTONS	/* get number of buttons	char	 */
2334c79e98bSDmitry Torokhov	#define JSIOCGVERSION	/* get driver version		int	 */
2344c79e98bSDmitry Torokhov	#define JSIOCGNAME(len) /* get identifier string	char	 */
2354c79e98bSDmitry Torokhov	#define JSIOCSCORR	/* set correction values	&js_corr */
2364c79e98bSDmitry Torokhov	#define JSIOCGCORR	/* get correction values	&js_corr */
2374c79e98bSDmitry Torokhov
2384c79e98bSDmitry TorokhovFor example, to read the number of axes::
2394c79e98bSDmitry Torokhov
2404c79e98bSDmitry Torokhov	char number_of_axes;
2414c79e98bSDmitry Torokhov	ioctl (fd, JSIOCGAXES, &number_of_axes);
2424c79e98bSDmitry Torokhov
2434c79e98bSDmitry Torokhov
2444c79e98bSDmitry TorokhovJSIOGCVERSION
2454c79e98bSDmitry Torokhov-------------
2464c79e98bSDmitry Torokhov
2474c79e98bSDmitry TorokhovJSIOGCVERSION is a good way to check in run-time whether the running
2484c79e98bSDmitry Torokhovdriver is 1.0+ and supports the event interface. If it is not, the
2494c79e98bSDmitry TorokhovIOCTL will fail. For a compile-time decision, you can test the
2504c79e98bSDmitry TorokhovJS_VERSION symbol::
2514c79e98bSDmitry Torokhov
2524c79e98bSDmitry Torokhov	#ifdef JS_VERSION
2534c79e98bSDmitry Torokhov	#if JS_VERSION > 0xsomething
2544c79e98bSDmitry Torokhov
2554c79e98bSDmitry Torokhov
2564c79e98bSDmitry TorokhovJSIOCGNAME
2574c79e98bSDmitry Torokhov----------
2584c79e98bSDmitry Torokhov
2594c79e98bSDmitry TorokhovJSIOCGNAME(len) allows you to get the name string of the joystick - the same
2604c79e98bSDmitry Torokhovas is being printed at boot time. The 'len' argument is the length of the
2614c79e98bSDmitry Torokhovbuffer provided by the application asking for the name. It is used to avoid
2624c79e98bSDmitry Torokhovpossible overrun should the name be too long::
2634c79e98bSDmitry Torokhov
2644c79e98bSDmitry Torokhov	char name[128];
2654c79e98bSDmitry Torokhov	if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0)
266*f9ce26c5SKees Cook		strscpy(name, "Unknown", sizeof(name));
2674c79e98bSDmitry Torokhov	printf("Name: %s\n", name);
2684c79e98bSDmitry Torokhov
2694c79e98bSDmitry Torokhov
2704c79e98bSDmitry TorokhovJSIOC[SG]CORR
2714c79e98bSDmitry Torokhov-------------
2724c79e98bSDmitry Torokhov
2734c79e98bSDmitry TorokhovFor usage on JSIOC[SG]CORR I suggest you to look into jscal.c  They are
2744c79e98bSDmitry Torokhovnot needed in a normal program, only in joystick calibration software
2754c79e98bSDmitry Torokhovsuch as jscal or kcmjoy. These IOCTLs and data types aren't considered
2764c79e98bSDmitry Torokhovto be in the stable part of the API, and therefore may change without
2774c79e98bSDmitry Torokhovwarning in following releases of the driver.
2784c79e98bSDmitry Torokhov
2794c79e98bSDmitry TorokhovBoth JSIOCSCORR and JSIOCGCORR expect &js_corr to be able to hold
280eef8abdaSRandy Dunlapinformation for all axes. That is, struct js_corr corr[MAX_AXIS];
2814c79e98bSDmitry Torokhov
2824c79e98bSDmitry Torokhovstruct js_corr is defined as::
2834c79e98bSDmitry Torokhov
2844c79e98bSDmitry Torokhov	struct js_corr {
2854c79e98bSDmitry Torokhov		__s32 coef[8];
2864c79e98bSDmitry Torokhov		__u16 prec;
2874c79e98bSDmitry Torokhov		__u16 type;
2884c79e98bSDmitry Torokhov	};
2894c79e98bSDmitry Torokhov
2904c79e98bSDmitry Torokhovand ``type``::
2914c79e98bSDmitry Torokhov
2924c79e98bSDmitry Torokhov	#define JS_CORR_NONE            0x00    /* returns raw values */
2934c79e98bSDmitry Torokhov	#define JS_CORR_BROKEN          0x01    /* broken line */
2944c79e98bSDmitry Torokhov
2954c79e98bSDmitry Torokhov
2964c79e98bSDmitry TorokhovBackward compatibility
2974c79e98bSDmitry Torokhov======================
2984c79e98bSDmitry Torokhov
2994c79e98bSDmitry TorokhovThe 0.x joystick driver API is quite limited and its usage is deprecated.
3004c79e98bSDmitry TorokhovThe driver offers backward compatibility, though. Here's a quick summary::
3014c79e98bSDmitry Torokhov
3024c79e98bSDmitry Torokhov	struct JS_DATA_TYPE js;
3034c79e98bSDmitry Torokhov	while (1) {
3044c79e98bSDmitry Torokhov		if (read (fd, &js, JS_RETURN) != JS_RETURN) {
3054c79e98bSDmitry Torokhov			/* error */
3064c79e98bSDmitry Torokhov		}
3074c79e98bSDmitry Torokhov		usleep (1000);
3084c79e98bSDmitry Torokhov	}
3094c79e98bSDmitry Torokhov
3104c79e98bSDmitry TorokhovAs you can figure out from the example, the read returns immediately,
3114c79e98bSDmitry Torokhovwith the actual state of the joystick::
3124c79e98bSDmitry Torokhov
3134c79e98bSDmitry Torokhov	struct JS_DATA_TYPE {
3144c79e98bSDmitry Torokhov		int buttons;    /* immediate button state */
3154c79e98bSDmitry Torokhov		int x;          /* immediate x axis value */
3164c79e98bSDmitry Torokhov		int y;          /* immediate y axis value */
3174c79e98bSDmitry Torokhov	};
3184c79e98bSDmitry Torokhov
3194c79e98bSDmitry Torokhovand JS_RETURN is defined as::
3204c79e98bSDmitry Torokhov
3214c79e98bSDmitry Torokhov	#define JS_RETURN       sizeof(struct JS_DATA_TYPE)
3224c79e98bSDmitry Torokhov
3234c79e98bSDmitry TorokhovTo test the state of the buttons,
3244c79e98bSDmitry Torokhov
3254c79e98bSDmitry Torokhov::
3264c79e98bSDmitry Torokhov
3274c79e98bSDmitry Torokhov	first_button_state  = js.buttons & 1;
3284c79e98bSDmitry Torokhov	second_button_state = js.buttons & 2;
3294c79e98bSDmitry Torokhov
3304c79e98bSDmitry TorokhovThe axis values do not have a defined range in the original 0.x driver,
331eef8abdaSRandy Dunlapexcept that the values are non-negative. The 1.2.8+ drivers use a
3324c79e98bSDmitry Torokhovfixed range for reporting the values, 1 being the minimum, 128 the
3334c79e98bSDmitry Torokhovcenter, and 255 maximum value.
3344c79e98bSDmitry Torokhov
3354c79e98bSDmitry TorokhovThe v0.8.0.2 driver also had an interface for 'digital joysticks', (now
3364c79e98bSDmitry Torokhovcalled Multisystem joysticks in this driver), under /dev/djsX. This driver
3374c79e98bSDmitry Torokhovdoesn't try to be compatible with that interface.
3384c79e98bSDmitry Torokhov
3394c79e98bSDmitry Torokhov
3404c79e98bSDmitry TorokhovFinal Notes
3414c79e98bSDmitry Torokhov===========
3424c79e98bSDmitry Torokhov
3434c79e98bSDmitry Torokhov::
3444c79e98bSDmitry Torokhov
3454c79e98bSDmitry Torokhov  ____/|	Comments, additions, and specially corrections are welcome.
3464c79e98bSDmitry Torokhov  \ o.O|	Documentation valid for at least version 1.2.8 of the joystick
3474c79e98bSDmitry Torokhov   =(_)=	driver and as usual, the ultimate source for documentation is
3484c79e98bSDmitry Torokhov     U		to "Use The Source Luke" or, at your convenience, Vojtech ;)
349