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