comparison src/joystick/linux/SDL_sysjoystick.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 2f381b48b05c
children 1d9cd8266e22
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
27 27
28 #include <sys/stat.h> 28 #include <sys/stat.h>
29 #include <unistd.h> 29 #include <unistd.h>
30 #include <fcntl.h> 30 #include <fcntl.h>
31 #include <sys/ioctl.h> 31 #include <sys/ioctl.h>
32 #include <limits.h> /* For the definition of PATH_MAX */ 32 #include <limits.h> /* For the definition of PATH_MAX */
33 #include <linux/joystick.h> 33 #include <linux/joystick.h>
34 #if SDL_INPUT_LINUXEV 34 #if SDL_INPUT_LINUXEV
35 #include <linux/input.h> 35 #include <linux/input.h>
36 #endif 36 #endif
37 37
38 #include "SDL_joystick.h" 38 #include "SDL_joystick.h"
39 #include "../SDL_sysjoystick.h" 39 #include "../SDL_sysjoystick.h"
40 #include "../SDL_joystick_c.h" 40 #include "../SDL_joystick_c.h"
41 41
42 /* Special joystick configurations */ 42 /* Special joystick configurations */
43 static struct { 43 static struct
44 const char *name; 44 {
45 int naxes; 45 const char *name;
46 int nhats; 46 int naxes;
47 int nballs; 47 int nhats;
48 int nballs;
48 } special_joysticks[] = { 49 } special_joysticks[] = {
49 { "MadCatz Panther XL", 3, 2, 1 }, /* We don't handle rudder (axis 8) */ 50 {
50 { "SideWinder Precision Pro", 4, 1, 0 }, 51 "MadCatz Panther XL", 3, 2, 1}, /* We don't handle rudder (axis 8) */
51 { "SideWinder 3D Pro", 4, 1, 0 }, 52 {
52 { "Microsoft SideWinder 3D Pro", 4, 1, 0 }, 53 "SideWinder Precision Pro", 4, 1, 0}, {
53 { "Microsoft SideWinder Dual Strike USB version 1.0", 2, 1, 0 }, 54 "SideWinder 3D Pro", 4, 1, 0}, {
54 { "WingMan Interceptor", 3, 3, 0 }, 55 "Microsoft SideWinder 3D Pro", 4, 1, 0}, {
55 { "WingMan Extreme Digital 3D", 4, 1, 0 }, 56 "Microsoft SideWinder Dual Strike USB version 1.0", 2, 1, 0}, {
56 { "Microsoft SideWinder Precision 2 Joystick", 4, 1, 0 }, 57 "WingMan Interceptor", 3, 3, 0}, {
57 { "Logitech Inc. WingMan Extreme Digital 3D", 4, 1, 0 }, 58 "WingMan Extreme Digital 3D", 4, 1, 0}, {
58 { "Saitek Saitek X45", 6, 1, 0 } 59 "Microsoft SideWinder Precision 2 Joystick", 4, 1, 0}, {
60 "Logitech Inc. WingMan Extreme Digital 3D", 4, 1, 0}, {
61 "Saitek Saitek X45", 6, 1, 0}
59 }; 62 };
60 63
61 #ifndef NO_LOGICAL_JOYSTICKS 64 #ifndef NO_LOGICAL_JOYSTICKS
62 65
63 /* 66 /*
69 be identified by their transparent blue design. It's quite trivial 72 be identified by their transparent blue design. It's quite trivial
70 to add other joysticks with similar quirky behavior. 73 to add other joysticks with similar quirky behavior.
71 -id 74 -id
72 */ 75 */
73 76
74 struct joystick_logical_mapping { 77 struct joystick_logical_mapping
75 int njoy; 78 {
76 int nthing; 79 int njoy;
80 int nthing;
77 }; 81 };
78 82
79 /* 83 /*
80 {logical joy, logical axis}, 84 {logical joy, logical axis},
81 {logical joy, logical hat}, 85 {logical joy, logical hat},
82 {logical joy, logical ball}, 86 {logical joy, logical ball},
83 {logical joy, logical button} 87 {logical joy, logical button}
84 */ 88 */
85 89
86 static struct joystick_logical_mapping mp88xx_1_logical_axismap[] = { 90 static struct joystick_logical_mapping mp88xx_1_logical_axismap[] = {
87 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5} 91 {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}
88 }; 92 };
89 static struct joystick_logical_mapping mp88xx_1_logical_buttonmap[] = { 93 static struct joystick_logical_mapping mp88xx_1_logical_buttonmap[] = {
90 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11} 94 {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8},
95 {0, 9}, {0, 10}, {0, 11}
91 }; 96 };
92 97
93 static struct joystick_logical_mapping mp88xx_2_logical_axismap[] = { 98 static struct joystick_logical_mapping mp88xx_2_logical_axismap[] = {
94 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, 99 {0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {0, 3},
95 {1,2},{1,3},{0,4},{0,5},{1,4},{1,5} 100 {1, 2}, {1, 3}, {0, 4}, {0, 5}, {1, 4}, {1, 5}
96 }; 101 };
97 static struct joystick_logical_mapping mp88xx_2_logical_buttonmap[] = { 102 static struct joystick_logical_mapping mp88xx_2_logical_buttonmap[] = {
98 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, 103 {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8},
99 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11} 104 {0, 9}, {0, 10}, {0, 11},
105 {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8},
106 {1, 9}, {1, 10}, {1, 11}
100 }; 107 };
101 108
102 static struct joystick_logical_mapping mp88xx_3_logical_axismap[] = { 109 static struct joystick_logical_mapping mp88xx_3_logical_axismap[] = {
103 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, 110 {0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {0, 3},
104 {1,2},{1,3},{2,0},{2,1},{2,2},{2,3}, 111 {1, 2}, {1, 3}, {2, 0}, {2, 1}, {2, 2}, {2, 3},
105 {0,4},{0,5},{1,4},{1,5},{2,4},{2,5} 112 {0, 4}, {0, 5}, {1, 4}, {1, 5}, {2, 4}, {2, 5}
106 }; 113 };
107 static struct joystick_logical_mapping mp88xx_3_logical_buttonmap[] = { 114 static struct joystick_logical_mapping mp88xx_3_logical_buttonmap[] = {
108 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, 115 {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8},
109 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}, 116 {0, 9}, {0, 10}, {0, 11},
110 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11} 117 {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8},
118 {1, 9}, {1, 10}, {1, 11},
119 {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8},
120 {2, 9}, {2, 10}, {2, 11}
111 }; 121 };
112 122
113 static struct joystick_logical_mapping mp88xx_4_logical_axismap[] = { 123 static struct joystick_logical_mapping mp88xx_4_logical_axismap[] = {
114 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, 124 {0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {0, 3},
115 {1,2},{1,3},{2,0},{2,1},{2,2},{2,3}, 125 {1, 2}, {1, 3}, {2, 0}, {2, 1}, {2, 2}, {2, 3},
116 {3,0},{3,1},{3,2},{3,3},{0,4},{0,5}, 126 {3, 0}, {3, 1}, {3, 2}, {3, 3}, {0, 4}, {0, 5},
117 {1,4},{1,5},{2,4},{2,5},{3,4},{3,5} 127 {1, 4}, {1, 5}, {2, 4}, {2, 5}, {3, 4}, {3, 5}
118 }; 128 };
119 static struct joystick_logical_mapping mp88xx_4_logical_buttonmap[] = { 129 static struct joystick_logical_mapping mp88xx_4_logical_buttonmap[] = {
120 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, 130 {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8},
121 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}, 131 {0, 9}, {0, 10}, {0, 11},
122 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11}, 132 {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8},
123 {3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},{3,9},{3,10},{3,11} 133 {1, 9}, {1, 10}, {1, 11},
124 }; 134 {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8},
125 135 {2, 9}, {2, 10}, {2, 11},
126 struct joystick_logical_layout { 136 {3, 0}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8},
127 int naxes; 137 {3, 9}, {3, 10}, {3, 11}
128 int nhats; 138 };
129 int nballs; 139
130 int nbuttons; 140 struct joystick_logical_layout
141 {
142 int naxes;
143 int nhats;
144 int nballs;
145 int nbuttons;
131 }; 146 };
132 147
133 static struct joystick_logical_layout mp88xx_1_logical_layout[] = { 148 static struct joystick_logical_layout mp88xx_1_logical_layout[] = {
134 {6, 0, 0, 12} 149 {6, 0, 0, 12}
135 }; 150 };
136 static struct joystick_logical_layout mp88xx_2_logical_layout[] = { 151 static struct joystick_logical_layout mp88xx_2_logical_layout[] = {
137 {6, 0, 0, 12}, 152 {6, 0, 0, 12},
138 {6, 0, 0, 12} 153 {6, 0, 0, 12}
139 }; 154 };
140 static struct joystick_logical_layout mp88xx_3_logical_layout[] = { 155 static struct joystick_logical_layout mp88xx_3_logical_layout[] = {
141 {6, 0, 0, 12}, 156 {6, 0, 0, 12},
142 {6, 0, 0, 12}, 157 {6, 0, 0, 12},
143 {6, 0, 0, 12} 158 {6, 0, 0, 12}
144 }; 159 };
145 static struct joystick_logical_layout mp88xx_4_logical_layout[] = { 160 static struct joystick_logical_layout mp88xx_4_logical_layout[] = {
146 {6, 0, 0, 12}, 161 {6, 0, 0, 12},
147 {6, 0, 0, 12}, 162 {6, 0, 0, 12},
148 {6, 0, 0, 12}, 163 {6, 0, 0, 12},
149 {6, 0, 0, 12} 164 {6, 0, 0, 12}
150 }; 165 };
151 166
152 /* 167 /*
153 This array sets up a means of mapping a single physical joystick to 168 This array sets up a means of mapping a single physical joystick to
154 multiple logical joysticks. (djm) 169 multiple logical joysticks. (djm)
160 an array of layout structures, one to describe each logical joystick 175 an array of layout structures, one to describe each logical joystick
161 176
162 axes, hats, balls, buttons 177 axes, hats, balls, buttons
163 arrays that map a physical thingy to a logical thingy 178 arrays that map a physical thingy to a logical thingy
164 */ 179 */
165 struct joystick_logicalmap { 180 struct joystick_logicalmap
166 const char *name; 181 {
167 int nbuttons; 182 const char *name;
168 int njoys; 183 int nbuttons;
169 struct joystick_logical_layout *layout; 184 int njoys;
170 struct joystick_logical_mapping *axismap; 185 struct joystick_logical_layout *layout;
171 struct joystick_logical_mapping *hatmap; 186 struct joystick_logical_mapping *axismap;
172 struct joystick_logical_mapping *ballmap; 187 struct joystick_logical_mapping *hatmap;
173 struct joystick_logical_mapping *buttonmap; 188 struct joystick_logical_mapping *ballmap;
189 struct joystick_logical_mapping *buttonmap;
174 }; 190 };
175 191
176 static struct joystick_logicalmap joystick_logicalmap[] = { 192 static struct joystick_logicalmap joystick_logicalmap[] = {
177 { 193 {
178 "WiseGroup.,Ltd MP-8866 Dual USB Joypad", 194 "WiseGroup.,Ltd MP-8866 Dual USB Joypad",
179 12, 195 12,
180 1, 196 1,
181 mp88xx_1_logical_layout, 197 mp88xx_1_logical_layout,
182 mp88xx_1_logical_axismap, 198 mp88xx_1_logical_axismap,
183 NULL, 199 NULL,
184 NULL, 200 NULL,
185 mp88xx_1_logical_buttonmap 201 mp88xx_1_logical_buttonmap},
186 }, 202 {
187 { 203 "WiseGroup.,Ltd MP-8866 Dual USB Joypad",
188 "WiseGroup.,Ltd MP-8866 Dual USB Joypad", 204 24,
189 24, 205 2,
190 2, 206 mp88xx_2_logical_layout,
191 mp88xx_2_logical_layout, 207 mp88xx_2_logical_axismap,
192 mp88xx_2_logical_axismap, 208 NULL,
193 NULL, 209 NULL,
194 NULL, 210 mp88xx_2_logical_buttonmap},
195 mp88xx_2_logical_buttonmap 211 {
196 }, 212 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
197 { 213 12,
198 "WiseGroup.,Ltd MP-8800 Quad USB Joypad", 214 1,
199 12, 215 mp88xx_1_logical_layout,
200 1, 216 mp88xx_1_logical_axismap,
201 mp88xx_1_logical_layout, 217 NULL,
202 mp88xx_1_logical_axismap, 218 NULL,
203 NULL, 219 mp88xx_1_logical_buttonmap},
204 NULL, 220 {
205 mp88xx_1_logical_buttonmap 221 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
206 }, 222 24,
207 { 223 2,
208 "WiseGroup.,Ltd MP-8800 Quad USB Joypad", 224 mp88xx_2_logical_layout,
209 24, 225 mp88xx_2_logical_axismap,
210 2, 226 NULL,
211 mp88xx_2_logical_layout, 227 NULL,
212 mp88xx_2_logical_axismap, 228 mp88xx_2_logical_buttonmap},
213 NULL, 229 {
214 NULL, 230 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
215 mp88xx_2_logical_buttonmap 231 36,
216 }, 232 3,
217 { 233 mp88xx_3_logical_layout,
218 "WiseGroup.,Ltd MP-8800 Quad USB Joypad", 234 mp88xx_3_logical_axismap,
219 36, 235 NULL,
220 3, 236 NULL,
221 mp88xx_3_logical_layout, 237 mp88xx_3_logical_buttonmap},
222 mp88xx_3_logical_axismap, 238 {
223 NULL, 239 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
224 NULL, 240 48,
225 mp88xx_3_logical_buttonmap 241 4,
226 }, 242 mp88xx_4_logical_layout,
227 { 243 mp88xx_4_logical_axismap,
228 "WiseGroup.,Ltd MP-8800 Quad USB Joypad", 244 NULL,
229 48, 245 NULL,
230 4, 246 mp88xx_4_logical_buttonmap}
231 mp88xx_4_logical_layout,
232 mp88xx_4_logical_axismap,
233 NULL,
234 NULL,
235 mp88xx_4_logical_buttonmap
236 }
237 }; 247 };
238 248
239 /* find the head of a linked list, given a point in it 249 /* find the head of a linked list, given a point in it
240 */ 250 */
241 #define SDL_joylist_head(i, start)\ 251 #define SDL_joylist_head(i, start)\
254 #define MAX_JOYSTICKS 32 264 #define MAX_JOYSTICKS 32
255 265
256 /* A list of available joysticks */ 266 /* A list of available joysticks */
257 static struct 267 static struct
258 { 268 {
259 char* fname; 269 char *fname;
260 #ifndef NO_LOGICAL_JOYSTICKS 270 #ifndef NO_LOGICAL_JOYSTICKS
261 SDL_Joystick* joy; 271 SDL_Joystick *joy;
262 struct joystick_logicalmap* map; 272 struct joystick_logicalmap *map;
263 int prev; 273 int prev;
264 int next; 274 int next;
265 int logicalno; 275 int logicalno;
266 #endif /* USE_LOGICAL_JOYSTICKS */ 276 #endif /* USE_LOGICAL_JOYSTICKS */
267 } SDL_joylist[MAX_JOYSTICKS]; 277 } SDL_joylist[MAX_JOYSTICKS];
268 278
269 279
270 /* The private structure used to keep track of a joystick */ 280 /* The private structure used to keep track of a joystick */
271 struct joystick_hwdata { 281 struct joystick_hwdata
272 int fd; 282 {
273 /* The current linux joystick driver maps hats to two axes */ 283 int fd;
274 struct hwdata_hat { 284 /* The current linux joystick driver maps hats to two axes */
275 int axis[2]; 285 struct hwdata_hat
276 } *hats; 286 {
277 /* The current linux joystick driver maps balls to two axes */ 287 int axis[2];
278 struct hwdata_ball { 288 } *hats;
279 int axis[2]; 289 /* The current linux joystick driver maps balls to two axes */
280 } *balls; 290 struct hwdata_ball
281 291 {
282 /* Support for the Linux 2.4 unified input interface */ 292 int axis[2];
293 } *balls;
294
295 /* Support for the Linux 2.4 unified input interface */
283 #if SDL_INPUT_LINUXEV 296 #if SDL_INPUT_LINUXEV
284 SDL_bool is_hid; 297 SDL_bool is_hid;
285 Uint8 key_map[KEY_MAX-BTN_MISC]; 298 Uint8 key_map[KEY_MAX - BTN_MISC];
286 Uint8 abs_map[ABS_MAX]; 299 Uint8 abs_map[ABS_MAX];
287 struct axis_correct { 300 struct axis_correct
288 int used; 301 {
289 int coef[3]; 302 int used;
290 } abs_correct[ABS_MAX]; 303 int coef[3];
291 #endif 304 } abs_correct[ABS_MAX];
292 }; 305 #endif
293 306 };
294 307
295 #ifndef NO_LOGICAL_JOYSTICKS 308
296 309 #ifndef NO_LOGICAL_JOYSTICKS
297 static int CountLogicalJoysticks(int max) 310
298 { 311 static int
299 register int i, j, k, ret, prev; 312 CountLogicalJoysticks(int max)
300 const char* name; 313 {
301 int nbuttons, fd; 314 register int i, j, k, ret, prev;
302 unsigned char n; 315 const char *name;
303 316 int nbuttons, fd;
304 ret = 0; 317 unsigned char n;
305 318
306 for(i = 0; i < max; i++) { 319 ret = 0;
307 name = SDL_SYS_JoystickName(i); 320
308 321 for (i = 0; i < max; i++) {
309 fd = open(SDL_joylist[i].fname, O_RDONLY, 0); 322 name = SDL_SYS_JoystickName(i);
310 if ( fd >= 0 ) { 323
311 if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) { 324 fd = open(SDL_joylist[i].fname, O_RDONLY, 0);
312 nbuttons = -1; 325 if (fd >= 0) {
313 } else { 326 if (ioctl(fd, JSIOCGBUTTONS, &n) < 0) {
314 nbuttons = n; 327 nbuttons = -1;
315 } 328 } else {
316 close(fd); 329 nbuttons = n;
317 } 330 }
318 else { 331 close(fd);
319 nbuttons=-1; 332 } else {
320 } 333 nbuttons = -1;
321 334 }
322 if (name) { 335
323 for(j = 0; j < SDL_arraysize(joystick_logicalmap); j++) { 336 if (name) {
324 if (!SDL_strcmp(name, joystick_logicalmap[j].name) && (nbuttons==-1 || nbuttons==joystick_logicalmap[j].nbuttons)) { 337 for (j = 0; j < SDL_arraysize(joystick_logicalmap); j++) {
325 prev = i; 338 if (!SDL_strcmp(name, joystick_logicalmap[j].name)
326 SDL_joylist[prev].map = &(joystick_logicalmap[j]); 339 && (nbuttons == -1
327 340 || nbuttons == joystick_logicalmap[j].nbuttons)) {
328 for(k = 1; k < joystick_logicalmap[j].njoys; k++) { 341 prev = i;
329 SDL_joylist[prev].next = max + ret; 342 SDL_joylist[prev].map = &(joystick_logicalmap[j]);
330 SDL_joylist[max+ret].prev = prev; 343
331 344 for (k = 1; k < joystick_logicalmap[j].njoys; k++) {
332 prev = max + ret; 345 SDL_joylist[prev].next = max + ret;
333 SDL_joylist[prev].logicalno = k; 346 SDL_joylist[max + ret].prev = prev;
334 SDL_joylist[prev].map = &(joystick_logicalmap[j]); 347
335 ret++; 348 prev = max + ret;
336 } 349 SDL_joylist[prev].logicalno = k;
337 350 SDL_joylist[prev].map = &(joystick_logicalmap[j]);
338 break; 351 ret++;
339 } 352 }
340 } 353
341 } 354 break;
342 } 355 }
343 356 }
344 return ret; 357 }
345 } 358 }
346 359
347 static void LogicalSuffix(int logicalno, char* namebuf, int len) 360 return ret;
348 { 361 }
349 register int slen; 362
350 const static char suffixs[] = 363 static void
351 "01020304050607080910111213141516171819" 364 LogicalSuffix(int logicalno, char *namebuf, int len)
352 "20212223242526272829303132"; 365 {
353 const char* suffix; 366 register int slen;
354 slen = SDL_strlen(namebuf); 367 const static char suffixs[] =
355 suffix = NULL; 368 "01020304050607080910111213141516171819" "20212223242526272829303132";
356 369 const char *suffix;
357 if (logicalno*2<sizeof(suffixs)) 370 slen = SDL_strlen(namebuf);
358 suffix = suffixs + (logicalno*2); 371 suffix = NULL;
359 372
360 if (slen + 4 < len && suffix) { 373 if (logicalno * 2 < sizeof(suffixs))
361 namebuf[slen++] = ' '; 374 suffix = suffixs + (logicalno * 2);
362 namebuf[slen++] = '#'; 375
363 namebuf[slen++] = suffix[0]; 376 if (slen + 4 < len && suffix) {
364 namebuf[slen++] = suffix[1]; 377 namebuf[slen++] = ' ';
365 namebuf[slen++] = 0; 378 namebuf[slen++] = '#';
366 } 379 namebuf[slen++] = suffix[0];
380 namebuf[slen++] = suffix[1];
381 namebuf[slen++] = 0;
382 }
367 } 383 }
368 384
369 #endif /* USE_LOGICAL_JOYSTICKS */ 385 #endif /* USE_LOGICAL_JOYSTICKS */
370 386
371 #if SDL_INPUT_LINUXEV 387 #if SDL_INPUT_LINUXEV
372 #define test_bit(nr, addr) \ 388 #define test_bit(nr, addr) \
373 (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0) 389 (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
374 390
375 static int EV_IsJoystick(int fd) 391 static int
376 { 392 EV_IsJoystick(int fd)
377 unsigned long evbit[40]; 393 {
378 unsigned long keybit[40]; 394 unsigned long evbit[40];
379 unsigned long absbit[40]; 395 unsigned long keybit[40];
380 396 unsigned long absbit[40];
381 if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || 397
382 (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || 398 if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
383 (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) ) { 399 (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
384 return(0); 400 (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) {
385 } 401 return (0);
386 if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) && 402 }
387 test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) && 403 if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
388 (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit) || test_bit(BTN_1, keybit)))) return 0; 404 test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) &&
389 return(1); 405 (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit)
406 || test_bit(BTN_1, keybit))))
407 return 0;
408 return (1);
390 } 409 }
391 410
392 #endif /* SDL_INPUT_LINUXEV */ 411 #endif /* SDL_INPUT_LINUXEV */
393 412
394 /* Function to scan the system for joysticks */ 413 /* Function to scan the system for joysticks */
395 int SDL_SYS_JoystickInit(void) 414 int
396 { 415 SDL_SYS_JoystickInit(void)
397 /* The base path of the joystick devices */ 416 {
398 const char *joydev_pattern[] = { 417 /* The base path of the joystick devices */
418 const char *joydev_pattern[] = {
399 #if SDL_INPUT_LINUXEV 419 #if SDL_INPUT_LINUXEV
400 "/dev/input/event%d", 420 "/dev/input/event%d",
401 #endif 421 #endif
402 "/dev/input/js%d", 422 "/dev/input/js%d",
403 "/dev/js%d" 423 "/dev/js%d"
404 }; 424 };
405 int numjoysticks; 425 int numjoysticks;
406 int i, j; 426 int i, j;
407 int fd; 427 int fd;
408 char path[PATH_MAX]; 428 char path[PATH_MAX];
409 dev_t dev_nums[MAX_JOYSTICKS]; /* major/minor device numbers */ 429 dev_t dev_nums[MAX_JOYSTICKS]; /* major/minor device numbers */
410 struct stat sb; 430 struct stat sb;
411 int n, duplicate; 431 int n, duplicate;
412 432
413 numjoysticks = 0; 433 numjoysticks = 0;
414 434
415 /* First see if the user specified a joystick to use */ 435 /* First see if the user specified a joystick to use */
416 if ( SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL ) { 436 if (SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL) {
417 SDL_strlcpy(path, SDL_getenv("SDL_JOYSTICK_DEVICE"), sizeof(path)); 437 SDL_strlcpy(path, SDL_getenv("SDL_JOYSTICK_DEVICE"), sizeof(path));
418 if ( stat(path, &sb) == 0 ) { 438 if (stat(path, &sb) == 0) {
419 fd = open(path, O_RDONLY, 0); 439 fd = open(path, O_RDONLY, 0);
420 if ( fd >= 0 ) { 440 if (fd >= 0) {
421 /* Assume the user knows what they're doing. */ 441 /* Assume the user knows what they're doing. */
422 SDL_joylist[numjoysticks].fname = SDL_strdup(path); 442 SDL_joylist[numjoysticks].fname = SDL_strdup(path);
423 if ( SDL_joylist[numjoysticks].fname ) { 443 if (SDL_joylist[numjoysticks].fname) {
424 dev_nums[numjoysticks] = sb.st_rdev; 444 dev_nums[numjoysticks] = sb.st_rdev;
425 ++numjoysticks; 445 ++numjoysticks;
426 } 446 }
427 close(fd); 447 close(fd);
428 } 448 }
429 } 449 }
430 } 450 }
431 451
432 for ( i=0; i<SDL_arraysize(joydev_pattern); ++i ) { 452 for (i = 0; i < SDL_arraysize(joydev_pattern); ++i) {
433 for ( j=0; j < MAX_JOYSTICKS; ++j ) { 453 for (j = 0; j < MAX_JOYSTICKS; ++j) {
434 SDL_snprintf(path, SDL_arraysize(path), joydev_pattern[i], j); 454 SDL_snprintf(path, SDL_arraysize(path), joydev_pattern[i], j);
435 455
436 /* rcg06302000 replaced access(F_OK) call with stat(). 456 /* rcg06302000 replaced access(F_OK) call with stat().
437 * stat() will fail if the file doesn't exist, so it's 457 * stat() will fail if the file doesn't exist, so it's
438 * equivalent behaviour. 458 * equivalent behaviour.
439 */ 459 */
440 if ( stat(path, &sb) == 0 ) { 460 if (stat(path, &sb) == 0) {
441 /* Check to make sure it's not already in list. 461 /* Check to make sure it's not already in list.
442 * This happens when we see a stick via symlink. 462 * This happens when we see a stick via symlink.
443 */ 463 */
444 duplicate = 0; 464 duplicate = 0;
445 for (n=0; (n<numjoysticks) && !duplicate; ++n) { 465 for (n = 0; (n < numjoysticks) && !duplicate; ++n) {
446 if ( sb.st_rdev == dev_nums[n] ) { 466 if (sb.st_rdev == dev_nums[n]) {
447 duplicate = 1; 467 duplicate = 1;
448 } 468 }
449 } 469 }
450 if (duplicate) { 470 if (duplicate) {
451 continue; 471 continue;
452 } 472 }
453 473
454 fd = open(path, O_RDONLY, 0); 474 fd = open(path, O_RDONLY, 0);
455 if ( fd < 0 ) { 475 if (fd < 0) {
456 continue; 476 continue;
457 } 477 }
458 #if SDL_INPUT_LINUXEV 478 #if SDL_INPUT_LINUXEV
459 #ifdef DEBUG_INPUT_EVENTS 479 #ifdef DEBUG_INPUT_EVENTS
460 printf("Checking %s\n", path); 480 printf("Checking %s\n", path);
461 #endif 481 #endif
462 if ( (i == 0) && ! EV_IsJoystick(fd) ) { 482 if ((i == 0) && !EV_IsJoystick(fd)) {
463 close(fd); 483 close(fd);
464 continue; 484 continue;
465 } 485 }
466 #endif 486 #endif
467 close(fd); 487 close(fd);
468 488
469 /* We're fine, add this joystick */ 489 /* We're fine, add this joystick */
470 SDL_joylist[numjoysticks].fname = SDL_strdup(path); 490 SDL_joylist[numjoysticks].fname = SDL_strdup(path);
471 if ( SDL_joylist[numjoysticks].fname ) { 491 if (SDL_joylist[numjoysticks].fname) {
472 dev_nums[numjoysticks] = sb.st_rdev; 492 dev_nums[numjoysticks] = sb.st_rdev;
473 ++numjoysticks; 493 ++numjoysticks;
474 } 494 }
475 } else 495 } else
476 break; 496 break;
477 } 497 }
478 498
479 #if SDL_INPUT_LINUXEV 499 #if SDL_INPUT_LINUXEV
480 /* This is a special case... 500 /* This is a special case...
481 If the event devices are valid then the joystick devices 501 If the event devices are valid then the joystick devices
482 will be duplicates but without extra information about their 502 will be duplicates but without extra information about their
483 hats or balls. Unfortunately, the event devices can't 503 hats or balls. Unfortunately, the event devices can't
484 currently be calibrated, so it's a win-lose situation. 504 currently be calibrated, so it's a win-lose situation.
485 So : /dev/input/eventX = /dev/input/jsY = /dev/jsY 505 So : /dev/input/eventX = /dev/input/jsY = /dev/jsY
486 */ 506 */
487 if ( (i == 0) && (numjoysticks > 0) ) 507 if ((i == 0) && (numjoysticks > 0))
488 break; 508 break;
489 #endif 509 #endif
490 } 510 }
491 #ifndef NO_LOGICAL_JOYSTICKS 511 #ifndef NO_LOGICAL_JOYSTICKS
492 numjoysticks += CountLogicalJoysticks(numjoysticks); 512 numjoysticks += CountLogicalJoysticks(numjoysticks);
493 #endif 513 #endif
494 514
495 return(numjoysticks); 515 return (numjoysticks);
496 } 516 }
497 517
498 /* Function to get the device-dependent name of a joystick */ 518 /* Function to get the device-dependent name of a joystick */
499 const char *SDL_SYS_JoystickName(int index) 519 const char *
500 { 520 SDL_SYS_JoystickName(int index)
501 int fd; 521 {
502 static char namebuf[128]; 522 int fd;
503 char *name; 523 static char namebuf[128];
504 SDL_logical_joydecl(int oindex = index); 524 char *name;
505 525 SDL_logical_joydecl(int oindex = index);
506 #ifndef NO_LOGICAL_JOYSTICKS 526
507 SDL_joylist_head(index, index); 527 #ifndef NO_LOGICAL_JOYSTICKS
508 #endif 528 SDL_joylist_head(index, index);
509 name = NULL; 529 #endif
510 fd = open(SDL_joylist[index].fname, O_RDONLY, 0); 530 name = NULL;
511 if ( fd >= 0 ) { 531 fd = open(SDL_joylist[index].fname, O_RDONLY, 0);
512 if ( 532 if (fd >= 0) {
533 if (
513 #if SDL_INPUT_LINUXEV 534 #if SDL_INPUT_LINUXEV
514 (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) && 535 (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) &&
515 #endif 536 #endif
516 (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) { 537 (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0)) {
517 name = SDL_joylist[index].fname; 538 name = SDL_joylist[index].fname;
518 } else { 539 } else {
519 name = namebuf; 540 name = namebuf;
520 } 541 }
521 close(fd); 542 close(fd);
522 543
523 544
524 #ifndef NO_LOGICAL_JOYSTICKS 545 #ifndef NO_LOGICAL_JOYSTICKS
525 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next || index!=oindex) 546 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next
526 { 547 || index != oindex) {
527 LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128); 548 LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128);
528 } 549 }
529 #endif 550 #endif
530 } 551 }
531 return name; 552 return name;
532 } 553 }
533 554
534 static int allocate_hatdata(SDL_Joystick *joystick) 555 static int
535 { 556 allocate_hatdata(SDL_Joystick * joystick)
536 int i; 557 {
537 558 int i;
538 joystick->hwdata->hats = (struct hwdata_hat *)SDL_malloc( 559
539 joystick->nhats * sizeof(struct hwdata_hat)); 560 joystick->hwdata->hats =
540 if ( joystick->hwdata->hats == NULL ) { 561 (struct hwdata_hat *) SDL_malloc(joystick->nhats *
541 return(-1); 562 sizeof(struct hwdata_hat));
542 } 563 if (joystick->hwdata->hats == NULL) {
543 for ( i=0; i<joystick->nhats; ++i ) { 564 return (-1);
544 joystick->hwdata->hats[i].axis[0] = 1; 565 }
545 joystick->hwdata->hats[i].axis[1] = 1; 566 for (i = 0; i < joystick->nhats; ++i) {
546 } 567 joystick->hwdata->hats[i].axis[0] = 1;
547 return(0); 568 joystick->hwdata->hats[i].axis[1] = 1;
548 } 569 }
549 570 return (0);
550 static int allocate_balldata(SDL_Joystick *joystick) 571 }
551 { 572
552 int i; 573 static int
553 574 allocate_balldata(SDL_Joystick * joystick)
554 joystick->hwdata->balls = (struct hwdata_ball *)SDL_malloc( 575 {
555 joystick->nballs * sizeof(struct hwdata_ball)); 576 int i;
556 if ( joystick->hwdata->balls == NULL ) { 577
557 return(-1); 578 joystick->hwdata->balls =
558 } 579 (struct hwdata_ball *) SDL_malloc(joystick->nballs *
559 for ( i=0; i<joystick->nballs; ++i ) { 580 sizeof(struct hwdata_ball));
560 joystick->hwdata->balls[i].axis[0] = 0; 581 if (joystick->hwdata->balls == NULL) {
561 joystick->hwdata->balls[i].axis[1] = 0; 582 return (-1);
562 } 583 }
563 return(0); 584 for (i = 0; i < joystick->nballs; ++i) {
564 } 585 joystick->hwdata->balls[i].axis[0] = 0;
565 586 joystick->hwdata->balls[i].axis[1] = 0;
566 static SDL_bool JS_ConfigJoystick(SDL_Joystick *joystick, int fd) 587 }
567 { 588 return (0);
568 SDL_bool handled; 589 }
569 unsigned char n; 590
570 int old_axes, tmp_naxes, tmp_nhats, tmp_nballs; 591 static SDL_bool
571 const char *name; 592 JS_ConfigJoystick(SDL_Joystick * joystick, int fd)
572 char *env, env_name[128]; 593 {
573 int i; 594 SDL_bool handled;
574 595 unsigned char n;
575 handled = SDL_FALSE; 596 int old_axes, tmp_naxes, tmp_nhats, tmp_nballs;
576 597 const char *name;
577 /* Default joystick device settings */ 598 char *env, env_name[128];
578 if ( ioctl(fd, JSIOCGAXES, &n) < 0 ) { 599 int i;
579 joystick->naxes = 2; 600
580 } else { 601 handled = SDL_FALSE;
581 joystick->naxes = n; 602
582 } 603 /* Default joystick device settings */
583 if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) { 604 if (ioctl(fd, JSIOCGAXES, &n) < 0) {
584 joystick->nbuttons = 2; 605 joystick->naxes = 2;
585 } else { 606 } else {
586 joystick->nbuttons = n; 607 joystick->naxes = n;
587 } 608 }
588 609 if (ioctl(fd, JSIOCGBUTTONS, &n) < 0) {
589 name = SDL_SYS_JoystickName(joystick->index); 610 joystick->nbuttons = 2;
590 old_axes = joystick->naxes; 611 } else {
591 612 joystick->nbuttons = n;
592 /* Generic analog joystick support */ 613 }
593 if ( SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat") ) { 614
594 if ( SDL_sscanf(name,"Analog %d-axis %*d-button %d-hat", 615 name = SDL_SYS_JoystickName(joystick->index);
595 &tmp_naxes, &tmp_nhats) == 2 ) { 616 old_axes = joystick->naxes;
596 617
597 joystick->naxes = tmp_naxes; 618 /* Generic analog joystick support */
598 joystick->nhats = tmp_nhats; 619 if (SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat")) {
599 620 if (SDL_sscanf(name, "Analog %d-axis %*d-button %d-hat",
600 handled = SDL_TRUE; 621 &tmp_naxes, &tmp_nhats) == 2) {
601 } 622
602 } 623 joystick->naxes = tmp_naxes;
603 624 joystick->nhats = tmp_nhats;
604 /* Special joystick support */ 625
605 for ( i=0; i < SDL_arraysize(special_joysticks); ++i ) { 626 handled = SDL_TRUE;
606 if ( SDL_strcmp(name, special_joysticks[i].name) == 0 ) { 627 }
607 628 }
608 joystick->naxes = special_joysticks[i].naxes; 629
609 joystick->nhats = special_joysticks[i].nhats; 630 /* Special joystick support */
610 joystick->nballs = special_joysticks[i].nballs; 631 for (i = 0; i < SDL_arraysize(special_joysticks); ++i) {
611 632 if (SDL_strcmp(name, special_joysticks[i].name) == 0) {
612 handled = SDL_TRUE; 633
613 break; 634 joystick->naxes = special_joysticks[i].naxes;
614 } 635 joystick->nhats = special_joysticks[i].nhats;
615 } 636 joystick->nballs = special_joysticks[i].nballs;
616 637
617 /* User environment joystick support */ 638 handled = SDL_TRUE;
618 if ( (env = SDL_getenv("SDL_LINUX_JOYSTICK")) ) { 639 break;
619 *env_name = '\0'; 640 }
620 if ( *env == '\'' && SDL_sscanf(env, "'%[^']s'", env_name) == 1 ) 641 }
621 env += SDL_strlen(env_name)+2; 642
622 else if ( SDL_sscanf(env, "%s", env_name) == 1 ) 643 /* User environment joystick support */
623 env += SDL_strlen(env_name); 644 if ((env = SDL_getenv("SDL_LINUX_JOYSTICK"))) {
624 645 *env_name = '\0';
625 if ( SDL_strcmp(name, env_name) == 0 ) { 646 if (*env == '\'' && SDL_sscanf(env, "'%[^']s'", env_name) == 1)
626 647 env += SDL_strlen(env_name) + 2;
627 if ( SDL_sscanf(env, "%d %d %d", &tmp_naxes, &tmp_nhats, 648 else if (SDL_sscanf(env, "%s", env_name) == 1)
628 &tmp_nballs) == 3 ) { 649 env += SDL_strlen(env_name);
629 650
630 joystick->naxes = tmp_naxes; 651 if (SDL_strcmp(name, env_name) == 0) {
631 joystick->nhats = tmp_nhats; 652
632 joystick->nballs = tmp_nballs; 653 if (SDL_sscanf(env, "%d %d %d", &tmp_naxes, &tmp_nhats,
633 654 &tmp_nballs) == 3) {
634 handled = SDL_TRUE; 655
635 } 656 joystick->naxes = tmp_naxes;
636 } 657 joystick->nhats = tmp_nhats;
637 } 658 joystick->nballs = tmp_nballs;
638 659
639 /* Remap hats and balls */ 660 handled = SDL_TRUE;
640 if (handled) { 661 }
641 if ( joystick->nhats > 0 ) { 662 }
642 if ( allocate_hatdata(joystick) < 0 ) { 663 }
643 joystick->nhats = 0; 664
644 } 665 /* Remap hats and balls */
645 } 666 if (handled) {
646 if ( joystick->nballs > 0 ) { 667 if (joystick->nhats > 0) {
647 if ( allocate_balldata(joystick) < 0 ) { 668 if (allocate_hatdata(joystick) < 0) {
648 joystick->nballs = 0; 669 joystick->nhats = 0;
649 } 670 }
650 } 671 }
651 } 672 if (joystick->nballs > 0) {
652 673 if (allocate_balldata(joystick) < 0) {
653 return(handled); 674 joystick->nballs = 0;
675 }
676 }
677 }
678
679 return (handled);
654 } 680 }
655 681
656 #if SDL_INPUT_LINUXEV 682 #if SDL_INPUT_LINUXEV
657 683
658 static SDL_bool EV_ConfigJoystick(SDL_Joystick *joystick, int fd) 684 static SDL_bool
659 { 685 EV_ConfigJoystick(SDL_Joystick * joystick, int fd)
660 int i, t; 686 {
661 unsigned long keybit[40]; 687 int i, t;
662 unsigned long absbit[40]; 688 unsigned long keybit[40];
663 unsigned long relbit[40]; 689 unsigned long absbit[40];
664 690 unsigned long relbit[40];
665 /* See if this device uses the new unified event API */ 691
666 if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) && 692 /* See if this device uses the new unified event API */
667 (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) && 693 if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
668 (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) ) { 694 (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
669 joystick->hwdata->is_hid = SDL_TRUE; 695 (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) {
670 696 joystick->hwdata->is_hid = SDL_TRUE;
671 /* Get the number of buttons, axes, and other thingamajigs */ 697
672 for ( i=BTN_JOYSTICK; i < KEY_MAX; ++i ) { 698 /* Get the number of buttons, axes, and other thingamajigs */
673 if ( test_bit(i, keybit) ) { 699 for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
700 if (test_bit(i, keybit)) {
674 #ifdef DEBUG_INPUT_EVENTS 701 #ifdef DEBUG_INPUT_EVENTS
675 printf("Joystick has button: 0x%x\n", i); 702 printf("Joystick has button: 0x%x\n", i);
676 #endif 703 #endif
677 joystick->hwdata->key_map[i-BTN_MISC] = 704 joystick->hwdata->key_map[i - BTN_MISC] = joystick->nbuttons;
678 joystick->nbuttons; 705 ++joystick->nbuttons;
679 ++joystick->nbuttons; 706 }
680 } 707 }
681 } 708 for (i = BTN_MISC; i < BTN_JOYSTICK; ++i) {
682 for ( i=BTN_MISC; i < BTN_JOYSTICK; ++i ) { 709 if (test_bit(i, keybit)) {
683 if ( test_bit(i, keybit) ) {
684 #ifdef DEBUG_INPUT_EVENTS 710 #ifdef DEBUG_INPUT_EVENTS
685 printf("Joystick has button: 0x%x\n", i); 711 printf("Joystick has button: 0x%x\n", i);
686 #endif 712 #endif
687 joystick->hwdata->key_map[i-BTN_MISC] = 713 joystick->hwdata->key_map[i - BTN_MISC] = joystick->nbuttons;
688 joystick->nbuttons; 714 ++joystick->nbuttons;
689 ++joystick->nbuttons; 715 }
690 } 716 }
691 } 717 for (i = 0; i < ABS_MAX; ++i) {
692 for ( i=0; i<ABS_MAX; ++i ) { 718 /* Skip hats */
693 /* Skip hats */ 719 if (i == ABS_HAT0X) {
694 if ( i == ABS_HAT0X ) { 720 i = ABS_HAT3Y;
695 i = ABS_HAT3Y; 721 continue;
696 continue; 722 }
697 } 723 if (test_bit(i, absbit)) {
698 if ( test_bit(i, absbit) ) { 724 int values[5];
699 int values[5]; 725
700 726 if (ioctl(fd, EVIOCGABS(i), values) < 0)
701 if ( ioctl(fd, EVIOCGABS(i), values) < 0 ) 727 continue;
702 continue;
703 #ifdef DEBUG_INPUT_EVENTS 728 #ifdef DEBUG_INPUT_EVENTS
704 printf("Joystick has absolute axis: %x\n", i); 729 printf("Joystick has absolute axis: %x\n", i);
705 printf("Values = { %d, %d, %d, %d, %d }\n", 730 printf("Values = { %d, %d, %d, %d, %d }\n",
706 values[0], values[1], 731 values[0], values[1], values[2], values[3], values[4]);
707 values[2], values[3], values[4]);
708 #endif /* DEBUG_INPUT_EVENTS */ 732 #endif /* DEBUG_INPUT_EVENTS */
709 joystick->hwdata->abs_map[i] = joystick->naxes; 733 joystick->hwdata->abs_map[i] = joystick->naxes;
710 if ( values[1] == values[2] ) { 734 if (values[1] == values[2]) {
711 joystick->hwdata->abs_correct[i].used = 0; 735 joystick->hwdata->abs_correct[i].used = 0;
712 } else { 736 } else {
713 joystick->hwdata->abs_correct[i].used = 1; 737 joystick->hwdata->abs_correct[i].used = 1;
714 joystick->hwdata->abs_correct[i].coef[0] = 738 joystick->hwdata->abs_correct[i].coef[0] =
715 (values[2] + values[1]) / 2 - values[4]; 739 (values[2] + values[1]) / 2 - values[4];
716 joystick->hwdata->abs_correct[i].coef[1] = 740 joystick->hwdata->abs_correct[i].coef[1] =
717 (values[2] + values[1]) / 2 + values[4]; 741 (values[2] + values[1]) / 2 + values[4];
718 t = ((values[2] - values[1]) / 2 - 2 * values[4]); 742 t = ((values[2] - values[1]) / 2 - 2 * values[4]);
719 if ( t != 0 ) { 743 if (t != 0) {
720 joystick->hwdata->abs_correct[i].coef[2] = (1 << 29) / t; 744 joystick->hwdata->abs_correct[i].coef[2] =
721 } else { 745 (1 << 29) / t;
722 joystick->hwdata->abs_correct[i].coef[2] = 0; 746 } else {
723 } 747 joystick->hwdata->abs_correct[i].coef[2] = 0;
724 } 748 }
725 ++joystick->naxes; 749 }
726 } 750 ++joystick->naxes;
727 } 751 }
728 for ( i=ABS_HAT0X; i <= ABS_HAT3Y; i += 2 ) { 752 }
729 if ( test_bit(i, absbit) || test_bit(i+1, absbit) ) { 753 for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
754 if (test_bit(i, absbit) || test_bit(i + 1, absbit)) {
730 #ifdef DEBUG_INPUT_EVENTS 755 #ifdef DEBUG_INPUT_EVENTS
731 printf("Joystick has hat %d\n",(i-ABS_HAT0X)/2); 756 printf("Joystick has hat %d\n", (i - ABS_HAT0X) / 2);
732 #endif 757 #endif
733 ++joystick->nhats; 758 ++joystick->nhats;
734 } 759 }
735 } 760 }
736 if ( test_bit(REL_X, relbit) || test_bit(REL_Y, relbit) ) { 761 if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) {
737 ++joystick->nballs; 762 ++joystick->nballs;
738 } 763 }
739 764
740 /* Allocate data to keep track of these thingamajigs */ 765 /* Allocate data to keep track of these thingamajigs */
741 if ( joystick->nhats > 0 ) { 766 if (joystick->nhats > 0) {
742 if ( allocate_hatdata(joystick) < 0 ) { 767 if (allocate_hatdata(joystick) < 0) {
743 joystick->nhats = 0; 768 joystick->nhats = 0;
744 } 769 }
745 } 770 }
746 if ( joystick->nballs > 0 ) { 771 if (joystick->nballs > 0) {
747 if ( allocate_balldata(joystick) < 0 ) { 772 if (allocate_balldata(joystick) < 0) {
748 joystick->nballs = 0; 773 joystick->nballs = 0;
749 } 774 }
750 } 775 }
751 } 776 }
752 return(joystick->hwdata->is_hid); 777 return (joystick->hwdata->is_hid);
753 } 778 }
754 779
755 #endif /* SDL_INPUT_LINUXEV */ 780 #endif /* SDL_INPUT_LINUXEV */
756 781
757 #ifndef NO_LOGICAL_JOYSTICKS 782 #ifndef NO_LOGICAL_JOYSTICKS
758 static void ConfigLogicalJoystick(SDL_Joystick *joystick) 783 static void
759 { 784 ConfigLogicalJoystick(SDL_Joystick * joystick)
760 struct joystick_logical_layout* layout; 785 {
761 786 struct joystick_logical_layout *layout;
762 layout = SDL_joylist[joystick->index].map->layout + 787
763 SDL_joylist[joystick->index].logicalno; 788 layout = SDL_joylist[joystick->index].map->layout +
764 789 SDL_joylist[joystick->index].logicalno;
765 joystick->nbuttons = layout->nbuttons; 790
766 joystick->nhats = layout->nhats; 791 joystick->nbuttons = layout->nbuttons;
767 joystick->naxes = layout->naxes; 792 joystick->nhats = layout->nhats;
768 joystick->nballs = layout->nballs; 793 joystick->naxes = layout->naxes;
794 joystick->nballs = layout->nballs;
769 } 795 }
770 #endif 796 #endif
771 797
772 798
773 /* Function to open a joystick for use. 799 /* Function to open a joystick for use.
774 The joystick to open is specified by the index field of the joystick. 800 The joystick to open is specified by the index field of the joystick.
775 This should fill the nbuttons and naxes fields of the joystick structure. 801 This should fill the nbuttons and naxes fields of the joystick structure.
776 It returns 0, or -1 if there is an error. 802 It returns 0, or -1 if there is an error.
777 */ 803 */
778 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) 804 int
779 { 805 SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
780 int fd; 806 {
781 SDL_logical_joydecl(int realindex); 807 int fd;
782 SDL_logical_joydecl(SDL_Joystick *realjoy = NULL); 808 SDL_logical_joydecl(int realindex);
783 809 SDL_logical_joydecl(SDL_Joystick * realjoy = NULL);
784 /* Open the joystick and set the joystick file descriptor */ 810
785 #ifndef NO_LOGICAL_JOYSTICKS 811 /* Open the joystick and set the joystick file descriptor */
786 if (SDL_joylist[joystick->index].fname == NULL) { 812 #ifndef NO_LOGICAL_JOYSTICKS
787 SDL_joylist_head(realindex, joystick->index); 813 if (SDL_joylist[joystick->index].fname == NULL) {
788 realjoy = SDL_JoystickOpen(realindex); 814 SDL_joylist_head(realindex, joystick->index);
789 815 realjoy = SDL_JoystickOpen(realindex);
790 if (realjoy == NULL) 816
791 return(-1); 817 if (realjoy == NULL)
792 818 return (-1);
793 fd = realjoy->hwdata->fd; 819
794 820 fd = realjoy->hwdata->fd;
795 } else { 821
796 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0); 822 } else {
797 } 823 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
798 SDL_joylist[joystick->index].joy = joystick; 824 }
825 SDL_joylist[joystick->index].joy = joystick;
799 #else 826 #else
800 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0); 827 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
801 #endif 828 #endif
802 829
803 if ( fd < 0 ) { 830 if (fd < 0) {
804 SDL_SetError("Unable to open %s\n", 831 SDL_SetError("Unable to open %s\n", SDL_joylist[joystick->index]);
805 SDL_joylist[joystick->index]); 832 return (-1);
806 return(-1); 833 }
807 } 834 joystick->hwdata = (struct joystick_hwdata *)
808 joystick->hwdata = (struct joystick_hwdata *) 835 SDL_malloc(sizeof(*joystick->hwdata));
809 SDL_malloc(sizeof(*joystick->hwdata)); 836 if (joystick->hwdata == NULL) {
810 if ( joystick->hwdata == NULL ) { 837 SDL_OutOfMemory();
811 SDL_OutOfMemory(); 838 close(fd);
812 close(fd); 839 return (-1);
813 return(-1); 840 }
814 } 841 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
815 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); 842 joystick->hwdata->fd = fd;
816 joystick->hwdata->fd = fd; 843
817 844 /* Set the joystick to non-blocking read mode */
818 /* Set the joystick to non-blocking read mode */ 845 fcntl(fd, F_SETFL, O_NONBLOCK);
819 fcntl(fd, F_SETFL, O_NONBLOCK); 846
820 847 /* Get the number of buttons and axes on the joystick */
821 /* Get the number of buttons and axes on the joystick */ 848 #ifndef NO_LOGICAL_JOYSTICKS
822 #ifndef NO_LOGICAL_JOYSTICKS 849 if (realjoy)
823 if (realjoy) 850 ConfigLogicalJoystick(joystick);
824 ConfigLogicalJoystick(joystick); 851 else
825 else
826 #endif 852 #endif
827 #if SDL_INPUT_LINUXEV 853 #if SDL_INPUT_LINUXEV
828 if ( ! EV_ConfigJoystick(joystick, fd) ) 854 if (!EV_ConfigJoystick(joystick, fd))
829 #endif 855 #endif
830 JS_ConfigJoystick(joystick, fd); 856 JS_ConfigJoystick(joystick, fd);
831 857
832 return(0); 858 return (0);
833 } 859 }
834 860
835 #ifndef NO_LOGICAL_JOYSTICKS 861 #ifndef NO_LOGICAL_JOYSTICKS
836 862
837 static SDL_Joystick* FindLogicalJoystick( 863 static SDL_Joystick *
838 SDL_Joystick *joystick, struct joystick_logical_mapping* v) 864 FindLogicalJoystick(SDL_Joystick * joystick,
839 { 865 struct joystick_logical_mapping *v)
840 SDL_Joystick *logicaljoy; 866 {
841 register int i; 867 SDL_Joystick *logicaljoy;
842 868 register int i;
843 i = joystick->index; 869
844 logicaljoy = NULL; 870 i = joystick->index;
845 871 logicaljoy = NULL;
846 /* get the fake joystick that will receive the event 872
847 */ 873 /* get the fake joystick that will receive the event
848 for(;;) { 874 */
849 875 for (;;) {
850 if (SDL_joylist[i].logicalno == v->njoy) { 876
851 logicaljoy = SDL_joylist[i].joy; 877 if (SDL_joylist[i].logicalno == v->njoy) {
852 break; 878 logicaljoy = SDL_joylist[i].joy;
853 } 879 break;
854 880 }
855 if (SDL_joylist[i].next == 0) 881
856 break; 882 if (SDL_joylist[i].next == 0)
857 883 break;
858 i = SDL_joylist[i].next; 884
859 885 i = SDL_joylist[i].next;
860 } 886
861 887 }
862 return logicaljoy; 888
863 } 889 return logicaljoy;
864 890 }
865 static int LogicalJoystickButton( 891
866 SDL_Joystick *joystick, Uint8 button, Uint8 state){ 892 static int
867 struct joystick_logical_mapping* buttons; 893 LogicalJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state)
868 SDL_Joystick *logicaljoy = NULL; 894 {
869 895 struct joystick_logical_mapping *buttons;
896 SDL_Joystick *logicaljoy = NULL;
897
898 /* if there's no map then this is just a regular joystick
899 */
900 if (SDL_joylist[joystick->index].map == NULL)
901 return 0;
902
903 /* get the logical joystick that will receive the event
904 */
905 buttons = SDL_joylist[joystick->index].map->buttonmap + button;
906 logicaljoy = FindLogicalJoystick(joystick, buttons);
907
908 if (logicaljoy == NULL)
909 return 1;
910
911 SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state);
912
913 return 1;
914 }
915
916 static int
917 LogicalJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
918 {
919 struct joystick_logical_mapping *axes;
920 SDL_Joystick *logicaljoy = NULL;
921
922 /* if there's no map then this is just a regular joystick
923 */
924 if (SDL_joylist[joystick->index].map == NULL)
925 return 0;
926
927 /* get the logical joystick that will receive the event
928 */
929 axes = SDL_joylist[joystick->index].map->axismap + axis;
930 logicaljoy = FindLogicalJoystick(joystick, axes);
931
932 if (logicaljoy == NULL)
933 return 1;
934
935 SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value);
936
937 return 1;
938 }
939 #endif /* USE_LOGICAL_JOYSTICKS */
940
941 static __inline__ void
942 HandleHat(SDL_Joystick * stick, Uint8 hat, int axis, int value)
943 {
944 struct hwdata_hat *the_hat;
945 const Uint8 position_map[3][3] = {
946 {SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP},
947 {SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT},
948 {SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN}
949 };
950 SDL_logical_joydecl(SDL_Joystick * logicaljoy = NULL);
951 SDL_logical_joydecl(struct joystick_logical_mapping *hats = NULL);
952
953 the_hat = &stick->hwdata->hats[hat];
954 if (value < 0) {
955 value = 0;
956 } else if (value == 0) {
957 value = 1;
958 } else if (value > 0) {
959 value = 2;
960 }
961 if (value != the_hat->axis[axis]) {
962 the_hat->axis[axis] = value;
963
964 #ifndef NO_LOGICAL_JOYSTICKS
870 /* if there's no map then this is just a regular joystick 965 /* if there's no map then this is just a regular joystick
871 */ 966 */
872 if (SDL_joylist[joystick->index].map == NULL) 967 if (SDL_joylist[stick->index].map != NULL) {
873 return 0; 968
874 969 /* get the fake joystick that will receive the event
875 /* get the logical joystick that will receive the event 970 */
876 */ 971 hats = SDL_joylist[stick->index].map->hatmap + hat;
877 buttons = SDL_joylist[joystick->index].map->buttonmap+button; 972 logicaljoy = FindLogicalJoystick(stick, hats);
878 logicaljoy = FindLogicalJoystick(joystick, buttons); 973 }
879 974
880 if (logicaljoy == NULL) 975 if (logicaljoy) {
881 return 1; 976 stick = logicaljoy;
882 977 hat = hats->nthing;
883 SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state); 978 }
884
885 return 1;
886 }
887
888 static int LogicalJoystickAxis(
889 SDL_Joystick *joystick, Uint8 axis, Sint16 value)
890 {
891 struct joystick_logical_mapping* axes;
892 SDL_Joystick *logicaljoy = NULL;
893
894 /* if there's no map then this is just a regular joystick
895 */
896 if (SDL_joylist[joystick->index].map == NULL)
897 return 0;
898
899 /* get the logical joystick that will receive the event
900 */
901 axes = SDL_joylist[joystick->index].map->axismap+axis;
902 logicaljoy = FindLogicalJoystick(joystick, axes);
903
904 if (logicaljoy == NULL)
905 return 1;
906
907 SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value);
908
909 return 1;
910 }
911 #endif /* USE_LOGICAL_JOYSTICKS */ 979 #endif /* USE_LOGICAL_JOYSTICKS */
912 980
913 static __inline__ 981 SDL_PrivateJoystickHat(stick, hat,
914 void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value) 982 position_map[the_hat->axis[1]][the_hat->
915 { 983 axis[0]]);
916 struct hwdata_hat *the_hat; 984 }
917 const Uint8 position_map[3][3] = { 985 }
918 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP }, 986
919 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT }, 987 static __inline__ void
920 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN } 988 HandleBall(SDL_Joystick * stick, Uint8 ball, int axis, int value)
921 }; 989 {
922 SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL); 990 stick->hwdata->balls[ball].axis[axis] += value;
923 SDL_logical_joydecl(struct joystick_logical_mapping* hats = NULL);
924
925 the_hat = &stick->hwdata->hats[hat];
926 if ( value < 0 ) {
927 value = 0;
928 } else
929 if ( value == 0 ) {
930 value = 1;
931 } else
932 if ( value > 0 ) {
933 value = 2;
934 }
935 if ( value != the_hat->axis[axis] ) {
936 the_hat->axis[axis] = value;
937
938 #ifndef NO_LOGICAL_JOYSTICKS
939 /* if there's no map then this is just a regular joystick
940 */
941 if (SDL_joylist[stick->index].map != NULL) {
942
943 /* get the fake joystick that will receive the event
944 */
945 hats = SDL_joylist[stick->index].map->hatmap+hat;
946 logicaljoy = FindLogicalJoystick(stick, hats);
947 }
948
949 if (logicaljoy) {
950 stick = logicaljoy;
951 hat = hats->nthing;
952 }
953 #endif /* USE_LOGICAL_JOYSTICKS */
954
955 SDL_PrivateJoystickHat(stick, hat,
956 position_map[the_hat->axis[1]][the_hat->axis[0]]);
957 }
958 }
959
960 static __inline__
961 void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
962 {
963 stick->hwdata->balls[ball].axis[axis] += value;
964 } 991 }
965 992
966 /* Function to update the state of a joystick - called as a device poll. 993 /* Function to update the state of a joystick - called as a device poll.
967 * This function shouldn't update the joystick structure directly, 994 * This function shouldn't update the joystick structure directly,
968 * but instead should call SDL_PrivateJoystick*() to deliver events 995 * but instead should call SDL_PrivateJoystick*() to deliver events
969 * and update joystick device state. 996 * and update joystick device state.
970 */ 997 */
971 static __inline__ void JS_HandleEvents(SDL_Joystick *joystick) 998 static __inline__ void
972 { 999 JS_HandleEvents(SDL_Joystick * joystick)
973 struct js_event events[32]; 1000 {
974 int i, len; 1001 struct js_event events[32];
975 Uint8 other_axis; 1002 int i, len;
976 1003 Uint8 other_axis;
977 #ifndef NO_LOGICAL_JOYSTICKS 1004
978 if (SDL_joylist[joystick->index].fname == NULL) { 1005 #ifndef NO_LOGICAL_JOYSTICKS
979 SDL_joylist_head(i, joystick->index); 1006 if (SDL_joylist[joystick->index].fname == NULL) {
980 JS_HandleEvents(SDL_joylist[i].joy); 1007 SDL_joylist_head(i, joystick->index);
981 return; 1008 JS_HandleEvents(SDL_joylist[i].joy);
982 } 1009 return;
983 #endif 1010 }
984 1011 #endif
985 while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) { 1012
986 len /= sizeof(events[0]); 1013 while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
987 for ( i=0; i<len; ++i ) { 1014 len /= sizeof(events[0]);
988 switch (events[i].type & ~JS_EVENT_INIT) { 1015 for (i = 0; i < len; ++i) {
989 case JS_EVENT_AXIS: 1016 switch (events[i].type & ~JS_EVENT_INIT) {
990 if ( events[i].number < joystick->naxes ) { 1017 case JS_EVENT_AXIS:
991 #ifndef NO_LOGICAL_JOYSTICKS 1018 if (events[i].number < joystick->naxes) {
992 if (!LogicalJoystickAxis(joystick, 1019 #ifndef NO_LOGICAL_JOYSTICKS
993 events[i].number, events[i].value)) 1020 if (!LogicalJoystickAxis(joystick,
994 #endif 1021 events[i].number,
995 SDL_PrivateJoystickAxis(joystick, 1022 events[i].value))
996 events[i].number, events[i].value); 1023 #endif
997 break; 1024 SDL_PrivateJoystickAxis(joystick,
998 } 1025 events[i].number,
999 events[i].number -= joystick->naxes; 1026 events[i].value);
1000 other_axis = (events[i].number / 2); 1027 break;
1001 if ( other_axis < joystick->nhats ) { 1028 }
1002 HandleHat(joystick, other_axis, 1029 events[i].number -= joystick->naxes;
1003 events[i].number%2, 1030 other_axis = (events[i].number / 2);
1004 events[i].value); 1031 if (other_axis < joystick->nhats) {
1005 break; 1032 HandleHat(joystick, other_axis,
1006 } 1033 events[i].number % 2, events[i].value);
1007 events[i].number -= joystick->nhats*2; 1034 break;
1008 other_axis = (events[i].number / 2); 1035 }
1009 if ( other_axis < joystick->nballs ) { 1036 events[i].number -= joystick->nhats * 2;
1010 HandleBall(joystick, other_axis, 1037 other_axis = (events[i].number / 2);
1011 events[i].number%2, 1038 if (other_axis < joystick->nballs) {
1012 events[i].value); 1039 HandleBall(joystick, other_axis,
1013 break; 1040 events[i].number % 2, events[i].value);
1014 } 1041 break;
1015 break; 1042 }
1016 case JS_EVENT_BUTTON: 1043 break;
1017 #ifndef NO_LOGICAL_JOYSTICKS 1044 case JS_EVENT_BUTTON:
1018 if (!LogicalJoystickButton(joystick, 1045 #ifndef NO_LOGICAL_JOYSTICKS
1019 events[i].number, events[i].value)) 1046 if (!LogicalJoystickButton(joystick,
1020 #endif 1047 events[i].number, events[i].value))
1021 SDL_PrivateJoystickButton(joystick, 1048 #endif
1022 events[i].number, events[i].value); 1049 SDL_PrivateJoystickButton(joystick,
1023 break; 1050 events[i].number,
1024 default: 1051 events[i].value);
1025 /* ?? */ 1052 break;
1026 break; 1053 default:
1027 } 1054 /* ?? */
1028 } 1055 break;
1029 } 1056 }
1030 } 1057 }
1058 }
1059 }
1060
1031 #if SDL_INPUT_LINUXEV 1061 #if SDL_INPUT_LINUXEV
1032 static __inline__ int EV_AxisCorrect(SDL_Joystick *joystick, int which, int value) 1062 static __inline__ int
1033 { 1063 EV_AxisCorrect(SDL_Joystick * joystick, int which, int value)
1034 struct axis_correct *correct; 1064 {
1035 1065 struct axis_correct *correct;
1036 correct = &joystick->hwdata->abs_correct[which]; 1066
1037 if ( correct->used ) { 1067 correct = &joystick->hwdata->abs_correct[which];
1038 if ( value > correct->coef[0] ) { 1068 if (correct->used) {
1039 if ( value < correct->coef[1] ) { 1069 if (value > correct->coef[0]) {
1040 return 0; 1070 if (value < correct->coef[1]) {
1041 } 1071 return 0;
1042 value -= correct->coef[1]; 1072 }
1043 } else { 1073 value -= correct->coef[1];
1044 value -= correct->coef[0]; 1074 } else {
1045 } 1075 value -= correct->coef[0];
1046 value *= correct->coef[2]; 1076 }
1047 value >>= 14; 1077 value *= correct->coef[2];
1048 } 1078 value >>= 14;
1049 1079 }
1050 /* Clamp and return */ 1080
1051 if ( value < -32768 ) return -32768; 1081 /* Clamp and return */
1052 if ( value > 32767 ) return 32767; 1082 if (value < -32768)
1053 1083 return -32768;
1054 return value; 1084 if (value > 32767)
1055 } 1085 return 32767;
1056 1086
1057 static __inline__ void EV_HandleEvents(SDL_Joystick *joystick) 1087 return value;
1058 { 1088 }
1059 struct input_event events[32]; 1089
1060 int i, len; 1090 static __inline__ void
1061 int code; 1091 EV_HandleEvents(SDL_Joystick * joystick)
1062 1092 {
1063 #ifndef NO_LOGICAL_JOYSTICKS 1093 struct input_event events[32];
1064 if (SDL_joylist[joystick->index].fname == NULL) { 1094 int i, len;
1065 SDL_joylist_head(i, joystick->index); 1095 int code;
1066 return EV_HandleEvents(SDL_joylist[i].joy); 1096
1067 } 1097 #ifndef NO_LOGICAL_JOYSTICKS
1068 #endif 1098 if (SDL_joylist[joystick->index].fname == NULL) {
1069 1099 SDL_joylist_head(i, joystick->index);
1070 while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) { 1100 return EV_HandleEvents(SDL_joylist[i].joy);
1071 len /= sizeof(events[0]); 1101 }
1072 for ( i=0; i<len; ++i ) { 1102 #endif
1073 code = events[i].code; 1103
1074 switch (events[i].type) { 1104 while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
1075 case EV_KEY: 1105 len /= sizeof(events[0]);
1076 if ( code >= BTN_MISC ) { 1106 for (i = 0; i < len; ++i) {
1077 code -= BTN_MISC; 1107 code = events[i].code;
1078 #ifndef NO_LOGICAL_JOYSTICKS 1108 switch (events[i].type) {
1079 if (!LogicalJoystickButton(joystick, 1109 case EV_KEY:
1080 joystick->hwdata->key_map[code], 1110 if (code >= BTN_MISC) {
1081 events[i].value)) 1111 code -= BTN_MISC;
1082 #endif 1112 #ifndef NO_LOGICAL_JOYSTICKS
1083 SDL_PrivateJoystickButton(joystick, 1113 if (!LogicalJoystickButton(joystick,
1084 joystick->hwdata->key_map[code], 1114 joystick->hwdata->
1085 events[i].value); 1115 key_map[code],
1086 } 1116 events[i].value))
1087 break; 1117 #endif
1088 case EV_ABS: 1118 SDL_PrivateJoystickButton(joystick,
1089 switch (code) { 1119 joystick->hwdata->
1090 case ABS_HAT0X: 1120 key_map[code],
1091 case ABS_HAT0Y: 1121 events[i].value);
1092 case ABS_HAT1X: 1122 }
1093 case ABS_HAT1Y: 1123 break;
1094 case ABS_HAT2X: 1124 case EV_ABS:
1095 case ABS_HAT2Y: 1125 switch (code) {
1096 case ABS_HAT3X: 1126 case ABS_HAT0X:
1097 case ABS_HAT3Y: 1127 case ABS_HAT0Y:
1098 code -= ABS_HAT0X; 1128 case ABS_HAT1X:
1099 HandleHat(joystick, code/2, code%2, 1129 case ABS_HAT1Y:
1100 events[i].value); 1130 case ABS_HAT2X:
1101 break; 1131 case ABS_HAT2Y:
1102 default: 1132 case ABS_HAT3X:
1103 events[i].value = EV_AxisCorrect(joystick, code, events[i].value); 1133 case ABS_HAT3Y:
1104 #ifndef NO_LOGICAL_JOYSTICKS 1134 code -= ABS_HAT0X;
1105 if (!LogicalJoystickAxis(joystick, 1135 HandleHat(joystick, code / 2, code % 2, events[i].value);
1106 joystick->hwdata->abs_map[code], 1136 break;
1107 events[i].value)) 1137 default:
1108 #endif 1138 events[i].value =
1109 SDL_PrivateJoystickAxis(joystick, 1139 EV_AxisCorrect(joystick, code, events[i].value);
1110 joystick->hwdata->abs_map[code], 1140 #ifndef NO_LOGICAL_JOYSTICKS
1111 events[i].value); 1141 if (!LogicalJoystickAxis(joystick,
1112 break; 1142 joystick->hwdata->
1113 } 1143 abs_map[code], events[i].value))
1114 break; 1144 #endif
1115 case EV_REL: 1145 SDL_PrivateJoystickAxis(joystick,
1116 switch (code) { 1146 joystick->hwdata->
1117 case REL_X: 1147 abs_map[code],
1118 case REL_Y: 1148 events[i].value);
1119 code -= REL_X; 1149 break;
1120 HandleBall(joystick, code/2, code%2, 1150 }
1121 events[i].value); 1151 break;
1122 break; 1152 case EV_REL:
1123 default: 1153 switch (code) {
1124 break; 1154 case REL_X:
1125 } 1155 case REL_Y:
1126 break; 1156 code -= REL_X;
1127 default: 1157 HandleBall(joystick, code / 2, code % 2, events[i].value);
1128 break; 1158 break;
1129 } 1159 default:
1130 } 1160 break;
1131 } 1161 }
1162 break;
1163 default:
1164 break;
1165 }
1166 }
1167 }
1132 } 1168 }
1133 #endif /* SDL_INPUT_LINUXEV */ 1169 #endif /* SDL_INPUT_LINUXEV */
1134 1170
1135 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) 1171 void
1136 { 1172 SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
1137 int i; 1173 {
1138 1174 int i;
1175
1139 #if SDL_INPUT_LINUXEV 1176 #if SDL_INPUT_LINUXEV
1140 if ( joystick->hwdata->is_hid ) 1177 if (joystick->hwdata->is_hid)
1141 EV_HandleEvents(joystick); 1178 EV_HandleEvents(joystick);
1142 else 1179 else
1143 #endif 1180 #endif
1144 JS_HandleEvents(joystick); 1181 JS_HandleEvents(joystick);
1145 1182
1146 /* Deliver ball motion updates */ 1183 /* Deliver ball motion updates */
1147 for ( i=0; i<joystick->nballs; ++i ) { 1184 for (i = 0; i < joystick->nballs; ++i) {
1148 int xrel, yrel; 1185 int xrel, yrel;
1149 1186
1150 xrel = joystick->hwdata->balls[i].axis[0]; 1187 xrel = joystick->hwdata->balls[i].axis[0];
1151 yrel = joystick->hwdata->balls[i].axis[1]; 1188 yrel = joystick->hwdata->balls[i].axis[1];
1152 if ( xrel || yrel ) { 1189 if (xrel || yrel) {
1153 joystick->hwdata->balls[i].axis[0] = 0; 1190 joystick->hwdata->balls[i].axis[0] = 0;
1154 joystick->hwdata->balls[i].axis[1] = 0; 1191 joystick->hwdata->balls[i].axis[1] = 0;
1155 SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel); 1192 SDL_PrivateJoystickBall(joystick, (Uint8) i, xrel, yrel);
1156 } 1193 }
1157 } 1194 }
1158 } 1195 }
1159 1196
1160 /* Function to close a joystick after use */ 1197 /* Function to close a joystick after use */
1161 void SDL_SYS_JoystickClose(SDL_Joystick *joystick) 1198 void
1162 { 1199 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
1163 #ifndef NO_LOGICAL_JOYSTICKS 1200 {
1164 register int i; 1201 #ifndef NO_LOGICAL_JOYSTICKS
1165 if (SDL_joylist[joystick->index].fname == NULL) { 1202 register int i;
1166 SDL_joylist_head(i, joystick->index); 1203 if (SDL_joylist[joystick->index].fname == NULL) {
1167 SDL_JoystickClose(SDL_joylist[i].joy); 1204 SDL_joylist_head(i, joystick->index);
1168 } 1205 SDL_JoystickClose(SDL_joylist[i].joy);
1169 #endif 1206 }
1170 1207 #endif
1171 if ( joystick->hwdata ) { 1208
1172 #ifndef NO_LOGICAL_JOYSTICKS 1209 if (joystick->hwdata) {
1173 if (SDL_joylist[joystick->index].fname != NULL) 1210 #ifndef NO_LOGICAL_JOYSTICKS
1174 #endif 1211 if (SDL_joylist[joystick->index].fname != NULL)
1175 close(joystick->hwdata->fd); 1212 #endif
1176 if ( joystick->hwdata->hats ) { 1213 close(joystick->hwdata->fd);
1177 SDL_free(joystick->hwdata->hats); 1214 if (joystick->hwdata->hats) {
1178 } 1215 SDL_free(joystick->hwdata->hats);
1179 if ( joystick->hwdata->balls ) { 1216 }
1180 SDL_free(joystick->hwdata->balls); 1217 if (joystick->hwdata->balls) {
1181 } 1218 SDL_free(joystick->hwdata->balls);
1182 SDL_free(joystick->hwdata); 1219 }
1183 joystick->hwdata = NULL; 1220 SDL_free(joystick->hwdata);
1184 } 1221 joystick->hwdata = NULL;
1222 }
1185 } 1223 }
1186 1224
1187 /* Function to perform any system-specific joystick related cleanup */ 1225 /* Function to perform any system-specific joystick related cleanup */
1188 void SDL_SYS_JoystickQuit(void) 1226 void
1189 { 1227 SDL_SYS_JoystickQuit(void)
1190 int i; 1228 {
1191 1229 int i;
1192 for ( i=0; SDL_joylist[i].fname; ++i ) { 1230
1193 SDL_free(SDL_joylist[i].fname); 1231 for (i = 0; SDL_joylist[i].fname; ++i) {
1194 } 1232 SDL_free(SDL_joylist[i].fname);
1195 SDL_joylist[0].fname = NULL; 1233 }
1234 SDL_joylist[0].fname = NULL;
1196 } 1235 }
1197 1236
1198 #endif /* SDL_JOYSTICK_LINUX */ 1237 #endif /* SDL_JOYSTICK_LINUX */
1238 /* vi: set ts=4 sw=4 expandtab: */