Mercurial > sdl-ios-xcode
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: */ |