FreeBASIC  0.91.0
gfx_joystick.c
Go to the documentation of this file.
1 /* joystick handling, linux */
2 
3 #include "../fb_gfx.h"
4 #include "fb_gfx_linux.h"
5 #include <fcntl.h>
6 #include <sys/ioctl.h>
7 
8 /* From linux/joystick.h */
9 
10 #define JS_EVENT_BUTTON 0x01
11 #define JS_EVENT_AXIS 0x02
12 #define JS_EVENT_INIT 0x80
13 
14 typedef struct _JS_EVENT {
15  unsigned int time;
16  short value;
17  unsigned char type;
18  unsigned char number;
19 } JS_EVENT;
20 
21 #define JSIOCGVERSION _IOR('j', 0x01, unsigned int)
22 
23 typedef struct _JOYDATA {
24  int fd;
25  float axis[8];
26  int buttons;
27 } JOYDATA;
28 
29 static JOYDATA joydata[16];
30 static int inited = FALSE;
31 
32 FBCALL int fb_GfxGetJoystick(int id, ssize_t *buttons, float *a1, float *a2, float *a3, float *a4, float *a5, float *a6, float *a7, float *a8)
33 {
34  const char *device[] = { "/dev/input/js",
35  "/dev/js",
36  NULL };
37  char device_name[16];
38  JOYDATA *joy;
39  JS_EVENT event;
40  int i, j, k, count = 0;
41  int version;
42 
43  if (!inited) {
44  fb_hMemSet(joydata, 0, sizeof(JOYDATA) * 16);
45  for (i = 0; i < 16; i++)
46  joydata[i].fd = -1;
47  joy = joydata;
48  for (i = 0; device[i] && (count < 16); i++) {
49  for (j = 0; (j < 16) && (count < 16); j++) {
50  sprintf(device_name, "%s%d", device[i], j);
51  joy->fd = open(device_name, O_NONBLOCK);
52  if (joy->fd >= 0) {
53  ioctl(joy->fd, JSIOCGVERSION, &version);
54  if (version < 0x10000) {
55  close(joy->fd);
56  continue;
57  }
58  for (k = 0; k < 8; k++)
59  joy->axis[k] = -1000.0;
60  joy++;
61  count++;
62  }
63  }
64  }
65  inited = TRUE;
66  }
67 
68  *buttons = -1;
69  *a1 = *a2 = *a3 = *a4 = *a5 = *a6 = *a7 = *a8 = -1000.0;
70 
71  if ((id < 0) || (id > 15))
73  joy = &joydata[id];
74 
75  if (joy->fd < 0)
77 
78  while (read(joy->fd, &event, sizeof(event)) > 0) {
79  switch (event.type & ~JS_EVENT_INIT) {
80 
81  case JS_EVENT_AXIS:
82  if (event.number < 8)
83  joy->axis[event.number] = (float)event.value / 32767.0;
84  break;
85 
86  case JS_EVENT_BUTTON:
87  if (event.number < 32) {
88  if (event.value)
89  joy->buttons |= (1 << event.number);
90  else
91  joy->buttons &= ~(1 << event.number);
92  }
93  break;
94  }
95  }
96 
97  *a1 = joy->axis[0];
98  *a2 = joy->axis[1];
99  *a3 = joy->axis[2];
100  *a4 = joy->axis[3];
101  *a5 = joy->axis[4];
102  *a6 = joy->axis[5];
103  *a7 = joy->axis[6];
104  *a8 = joy->axis[7];
105  *buttons = joy->buttons;
106 
107  return fb_ErrorSetNum( FB_RTERROR_OK );
108 }