cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

joystick-api.rst (10480B)


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