OSDN Git Service

add sdl-1.3
[android-x86/external-stagefright-plugins.git] / SDL-1.3 / android-project / jni / SDL / src / joystick / SDL_joystick.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
4
5   This software is provided 'as-is', without any express or implied
6   warranty.  In no event will the authors be held liable for any damages
7   arising from the use of this software.
8
9   Permission is granted to anyone to use this software for any purpose,
10   including commercial applications, and to alter it and redistribute it
11   freely, subject to the following restrictions:
12
13   1. The origin of this software must not be misrepresented; you must not
14      claim that you wrote the original software. If you use this software
15      in a product, an acknowledgment in the product documentation would be
16      appreciated but is not required.
17   2. Altered source versions must be plainly marked as such, and must not be
18      misrepresented as being the original software.
19   3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22
23 /* This is the joystick API for Simple DirectMedia Layer */
24
25 #include "SDL_events.h"
26 #include "SDL_sysjoystick.h"
27 #include "SDL_joystick_c.h"
28 #include "SDL_assert.h"
29
30 #if !SDL_EVENTS_DISABLED
31 #include "../events/SDL_events_c.h"
32 #endif
33
34 Uint8 SDL_numjoysticks = 0;
35 SDL_Joystick **SDL_joysticks = NULL;
36
37 int
38 SDL_JoystickInit(void)
39 {
40     int arraylen;
41     int status;
42
43     SDL_numjoysticks = 0;
44     status = SDL_SYS_JoystickInit();
45     if (status >= 0) {
46         arraylen = (status + 1) * sizeof(*SDL_joysticks);
47         SDL_joysticks = (SDL_Joystick **) SDL_malloc(arraylen);
48         if (SDL_joysticks == NULL) {
49             SDL_numjoysticks = 0;
50         } else {
51             SDL_memset(SDL_joysticks, 0, arraylen);
52             SDL_numjoysticks = status;
53         }
54         status = 0;
55     }
56     return (status);
57 }
58
59 /*
60  * Count the number of joysticks attached to the system
61  */
62 int
63 SDL_NumJoysticks(void)
64 {
65     return SDL_numjoysticks;
66 }
67
68 /*
69  * Get the implementation dependent name of a joystick
70  */
71 const char *
72 SDL_JoystickName(int device_index)
73 {
74     if ((device_index < 0) || (device_index >= SDL_numjoysticks)) {
75         SDL_SetError("There are %d joysticks available", SDL_numjoysticks);
76         return (NULL);
77     }
78     return (SDL_SYS_JoystickName(device_index));
79 }
80
81 /*
82  * Open a joystick for use - the index passed as an argument refers to
83  * the N'th joystick on the system.  This index is the value which will
84  * identify this joystick in future joystick events.
85  *
86  * This function returns a joystick identifier, or NULL if an error occurred.
87  */
88 SDL_Joystick *
89 SDL_JoystickOpen(int device_index)
90 {
91     int i;
92     SDL_Joystick *joystick;
93
94     if ((device_index < 0) || (device_index >= SDL_numjoysticks)) {
95         SDL_SetError("There are %d joysticks available", SDL_numjoysticks);
96         return (NULL);
97     }
98
99     /* If the joystick is already open, return it */
100     for (i = 0; SDL_joysticks[i]; ++i) {
101         if (device_index == SDL_joysticks[i]->index) {
102             joystick = SDL_joysticks[i];
103             ++joystick->ref_count;
104             return (joystick);
105         }
106     }
107
108     /* Create and initialize the joystick */
109     joystick = (SDL_Joystick *) SDL_malloc((sizeof *joystick));
110     if (joystick == NULL) {
111         SDL_OutOfMemory();
112         return NULL;
113     }
114
115     SDL_memset(joystick, 0, (sizeof *joystick));
116     joystick->index = device_index;
117     if (SDL_SYS_JoystickOpen(joystick) < 0) {
118         SDL_free(joystick);
119         return NULL;
120     }
121     if (joystick->naxes > 0) {
122         joystick->axes = (Sint16 *) SDL_malloc
123             (joystick->naxes * sizeof(Sint16));
124     }
125     if (joystick->nhats > 0) {
126         joystick->hats = (Uint8 *) SDL_malloc
127             (joystick->nhats * sizeof(Uint8));
128     }
129     if (joystick->nballs > 0) {
130         joystick->balls = (struct balldelta *) SDL_malloc
131             (joystick->nballs * sizeof(*joystick->balls));
132     }
133     if (joystick->nbuttons > 0) {
134         joystick->buttons = (Uint8 *) SDL_malloc
135             (joystick->nbuttons * sizeof(Uint8));
136     }
137     if (((joystick->naxes > 0) && !joystick->axes)
138         || ((joystick->nhats > 0) && !joystick->hats)
139         || ((joystick->nballs > 0) && !joystick->balls)
140         || ((joystick->nbuttons > 0) && !joystick->buttons)) {
141         SDL_OutOfMemory();
142         SDL_JoystickClose(joystick);
143         return NULL;
144     }
145     if (joystick->axes) {
146         SDL_memset(joystick->axes, 0, joystick->naxes * sizeof(Sint16));
147     }
148     if (joystick->hats) {
149         SDL_memset(joystick->hats, 0, joystick->nhats * sizeof(Uint8));
150     }
151     if (joystick->balls) {
152         SDL_memset(joystick->balls, 0,
153             joystick->nballs * sizeof(*joystick->balls));
154     }
155     if (joystick->buttons) {
156         SDL_memset(joystick->buttons, 0, joystick->nbuttons * sizeof(Uint8));
157     }
158
159     /* Add joystick to list */
160     ++joystick->ref_count;
161     for (i = 0; SDL_joysticks[i]; ++i)
162         /* Skip to next joystick */ ;
163     SDL_joysticks[i] = joystick;
164
165     return (joystick);
166 }
167
168 /*
169  * Returns 1 if the joystick has been opened, or 0 if it has not.
170  */
171 int
172 SDL_JoystickOpened(int device_index)
173 {
174     int i, opened;
175
176     opened = 0;
177     for (i = 0; SDL_joysticks[i]; ++i) {
178         if (SDL_joysticks[i]->index == (Uint8) device_index) {
179             opened = 1;
180             break;
181         }
182     }
183     return (opened);
184 }
185
186
187 /*
188  * Checks to make sure the joystick is valid.
189  */
190 int
191 SDL_PrivateJoystickValid(SDL_Joystick ** joystick)
192 {
193     int valid;
194
195     if (*joystick == NULL) {
196         SDL_SetError("Joystick hasn't been opened yet");
197         valid = 0;
198     } else {
199         valid = 1;
200     }
201     return valid;
202 }
203
204 /*
205  * Get the device index of an opened joystick.
206  */
207 int
208 SDL_JoystickIndex(SDL_Joystick * joystick)
209 {
210     if (!SDL_PrivateJoystickValid(&joystick)) {
211         return (-1);
212     }
213     return (joystick->index);
214 }
215
216 /*
217  * Get the number of multi-dimensional axis controls on a joystick
218  */
219 int
220 SDL_JoystickNumAxes(SDL_Joystick * joystick)
221 {
222     if (!SDL_PrivateJoystickValid(&joystick)) {
223         return (-1);
224     }
225     return (joystick->naxes);
226 }
227
228 /*
229  * Get the number of hats on a joystick
230  */
231 int
232 SDL_JoystickNumHats(SDL_Joystick * joystick)
233 {
234     if (!SDL_PrivateJoystickValid(&joystick)) {
235         return (-1);
236     }
237     return (joystick->nhats);
238 }
239
240 /*
241  * Get the number of trackballs on a joystick
242  */
243 int
244 SDL_JoystickNumBalls(SDL_Joystick * joystick)
245 {
246     if (!SDL_PrivateJoystickValid(&joystick)) {
247         return (-1);
248     }
249     return (joystick->nballs);
250 }
251
252 /*
253  * Get the number of buttons on a joystick
254  */
255 int
256 SDL_JoystickNumButtons(SDL_Joystick * joystick)
257 {
258     if (!SDL_PrivateJoystickValid(&joystick)) {
259         return (-1);
260     }
261     return (joystick->nbuttons);
262 }
263
264 /*
265  * Get the current state of an axis control on a joystick
266  */
267 Sint16
268 SDL_JoystickGetAxis(SDL_Joystick * joystick, int axis)
269 {
270     Sint16 state;
271
272     if (!SDL_PrivateJoystickValid(&joystick)) {
273         return (0);
274     }
275     if (axis < joystick->naxes) {
276         state = joystick->axes[axis];
277     } else {
278         SDL_SetError("Joystick only has %d axes", joystick->naxes);
279         state = 0;
280     }
281     return (state);
282 }
283
284 /*
285  * Get the current state of a hat on a joystick
286  */
287 Uint8
288 SDL_JoystickGetHat(SDL_Joystick * joystick, int hat)
289 {
290     Uint8 state;
291
292     if (!SDL_PrivateJoystickValid(&joystick)) {
293         return (0);
294     }
295     if (hat < joystick->nhats) {
296         state = joystick->hats[hat];
297     } else {
298         SDL_SetError("Joystick only has %d hats", joystick->nhats);
299         state = 0;
300     }
301     return (state);
302 }
303
304 /*
305  * Get the ball axis change since the last poll
306  */
307 int
308 SDL_JoystickGetBall(SDL_Joystick * joystick, int ball, int *dx, int *dy)
309 {
310     int retval;
311
312     if (!SDL_PrivateJoystickValid(&joystick)) {
313         return (-1);
314     }
315
316     retval = 0;
317     if (ball < joystick->nballs) {
318         if (dx) {
319             *dx = joystick->balls[ball].dx;
320         }
321         if (dy) {
322             *dy = joystick->balls[ball].dy;
323         }
324         joystick->balls[ball].dx = 0;
325         joystick->balls[ball].dy = 0;
326     } else {
327         SDL_SetError("Joystick only has %d balls", joystick->nballs);
328         retval = -1;
329     }
330     return (retval);
331 }
332
333 /*
334  * Get the current state of a button on a joystick
335  */
336 Uint8
337 SDL_JoystickGetButton(SDL_Joystick * joystick, int button)
338 {
339     Uint8 state;
340
341     if (!SDL_PrivateJoystickValid(&joystick)) {
342         return (0);
343     }
344     if (button < joystick->nbuttons) {
345         state = joystick->buttons[button];
346     } else {
347         SDL_SetError("Joystick only has %d buttons", joystick->nbuttons);
348         state = 0;
349     }
350     return (state);
351 }
352
353 /*
354  * Close a joystick previously opened with SDL_JoystickOpen()
355  */
356 void
357 SDL_JoystickClose(SDL_Joystick * joystick)
358 {
359     int i;
360
361     if (!SDL_PrivateJoystickValid(&joystick)) {
362         return;
363     }
364
365     /* First decrement ref count */
366     if (--joystick->ref_count > 0) {
367         return;
368     }
369
370     SDL_SYS_JoystickClose(joystick);
371
372     /* Remove joystick from list */
373     for (i = 0; SDL_joysticks[i]; ++i) {
374         if (joystick == SDL_joysticks[i]) {
375             SDL_memmove(&SDL_joysticks[i], &SDL_joysticks[i + 1],
376                         (SDL_numjoysticks - i) * sizeof(joystick));
377             break;
378         }
379     }
380
381     /* Free the data associated with this joystick */
382     if (joystick->axes) {
383         SDL_free(joystick->axes);
384     }
385     if (joystick->hats) {
386         SDL_free(joystick->hats);
387     }
388     if (joystick->balls) {
389         SDL_free(joystick->balls);
390     }
391     if (joystick->buttons) {
392         SDL_free(joystick->buttons);
393     }
394     SDL_free(joystick);
395 }
396
397 void
398 SDL_JoystickQuit(void)
399 {
400     const int numsticks = SDL_numjoysticks;
401     int i;
402
403     /* Stop the event polling */
404     SDL_numjoysticks = 0;
405
406     for (i = numsticks; i--; ) {
407         SDL_Joystick *stick = SDL_joysticks[i];
408         if (stick && (stick->ref_count >= 1)) {
409             stick->ref_count = 1;
410             SDL_JoystickClose(stick);
411         }
412     }
413
414     /* Quit the joystick setup */
415     SDL_SYS_JoystickQuit();
416     if (SDL_joysticks) {
417         SDL_free(SDL_joysticks);
418         SDL_joysticks = NULL;
419     }
420 }
421
422
423 /* These are global for SDL_sysjoystick.c and SDL_events.c */
424
425 int
426 SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
427 {
428     int posted;
429
430     /* Make sure we're not getting garbage events */
431     if (axis >= joystick->naxes) {
432         return 0;
433     }
434
435     /* Update internal joystick state */
436     joystick->axes[axis] = value;
437
438     /* Post the event, if desired */
439     posted = 0;
440 #if !SDL_EVENTS_DISABLED
441     if (SDL_GetEventState(SDL_JOYAXISMOTION) == SDL_ENABLE) {
442         SDL_Event event;
443         event.type = SDL_JOYAXISMOTION;
444         event.jaxis.which = joystick->index;
445         event.jaxis.axis = axis;
446         event.jaxis.value = value;
447         if ((SDL_EventOK == NULL)
448             || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
449             posted = 1;
450             SDL_PushEvent(&event);
451         }
452     }
453 #endif /* !SDL_EVENTS_DISABLED */
454     return (posted);
455 }
456
457 int
458 SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value)
459 {
460     int posted;
461
462     /* Make sure we're not getting garbage events */
463     if (hat >= joystick->nhats) {
464         return 0;
465     }
466
467     /* Update internal joystick state */
468     joystick->hats[hat] = value;
469
470     /* Post the event, if desired */
471     posted = 0;
472 #if !SDL_EVENTS_DISABLED
473     if (SDL_GetEventState(SDL_JOYHATMOTION) == SDL_ENABLE) {
474         SDL_Event event;
475         event.jhat.type = SDL_JOYHATMOTION;
476         event.jhat.which = joystick->index;
477         event.jhat.hat = hat;
478         event.jhat.value = value;
479         if ((SDL_EventOK == NULL)
480             || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
481             posted = 1;
482             SDL_PushEvent(&event);
483         }
484     }
485 #endif /* !SDL_EVENTS_DISABLED */
486     return (posted);
487 }
488
489 int
490 SDL_PrivateJoystickBall(SDL_Joystick * joystick, Uint8 ball,
491                         Sint16 xrel, Sint16 yrel)
492 {
493     int posted;
494
495     /* Make sure we're not getting garbage events */
496     if (ball >= joystick->nballs) {
497         return 0;
498     }
499
500     /* Update internal mouse state */
501     joystick->balls[ball].dx += xrel;
502     joystick->balls[ball].dy += yrel;
503
504     /* Post the event, if desired */
505     posted = 0;
506 #if !SDL_EVENTS_DISABLED
507     if (SDL_GetEventState(SDL_JOYBALLMOTION) == SDL_ENABLE) {
508         SDL_Event event;
509         event.jball.type = SDL_JOYBALLMOTION;
510         event.jball.which = joystick->index;
511         event.jball.ball = ball;
512         event.jball.xrel = xrel;
513         event.jball.yrel = yrel;
514         if ((SDL_EventOK == NULL)
515             || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
516             posted = 1;
517             SDL_PushEvent(&event);
518         }
519     }
520 #endif /* !SDL_EVENTS_DISABLED */
521     return (posted);
522 }
523
524 int
525 SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state)
526 {
527     int posted;
528 #if !SDL_EVENTS_DISABLED
529     SDL_Event event;
530
531     switch (state) {
532     case SDL_PRESSED:
533         event.type = SDL_JOYBUTTONDOWN;
534         break;
535     case SDL_RELEASED:
536         event.type = SDL_JOYBUTTONUP;
537         break;
538     default:
539         /* Invalid state -- bail */
540         return (0);
541     }
542 #endif /* !SDL_EVENTS_DISABLED */
543
544     /* Make sure we're not getting garbage events */
545     if (button >= joystick->nbuttons) {
546         return 0;
547     }
548
549     /* Update internal joystick state */
550     joystick->buttons[button] = state;
551
552     /* Post the event, if desired */
553     posted = 0;
554 #if !SDL_EVENTS_DISABLED
555     if (SDL_GetEventState(event.type) == SDL_ENABLE) {
556         event.jbutton.which = joystick->index;
557         event.jbutton.button = button;
558         event.jbutton.state = state;
559         if ((SDL_EventOK == NULL)
560             || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
561             posted = 1;
562             SDL_PushEvent(&event);
563         }
564     }
565 #endif /* !SDL_EVENTS_DISABLED */
566     return (posted);
567 }
568
569 void
570 SDL_JoystickUpdate(void)
571 {
572     int i;
573
574     for (i = 0; SDL_joysticks[i]; ++i) {
575         SDL_SYS_JoystickUpdate(SDL_joysticks[i]);
576     }
577 }
578
579 int
580 SDL_JoystickEventState(int state)
581 {
582 #if SDL_EVENTS_DISABLED
583     return SDL_IGNORE;
584 #else
585     const Uint32 event_list[] = {
586         SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYHATMOTION,
587         SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP,
588     };
589     unsigned int i;
590
591     switch (state) {
592     case SDL_QUERY:
593         state = SDL_IGNORE;
594         for (i = 0; i < SDL_arraysize(event_list); ++i) {
595             state = SDL_EventState(event_list[i], SDL_QUERY);
596             if (state == SDL_ENABLE) {
597                 break;
598             }
599         }
600         break;
601     default:
602         for (i = 0; i < SDL_arraysize(event_list); ++i) {
603             SDL_EventState(event_list[i], state);
604         }
605         break;
606     }
607     return (state);
608 #endif /* SDL_EVENTS_DISABLED */
609 }
610
611 /* vi: set ts=4 sw=4 expandtab: */