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