2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <sys/types.h>
35 #ifndef JOY_AXIS_DELTA
36 #define JOY_AXIS_DELTA 500
40 #define JS_DEV "/dev/input/js0"
43 #include <linux/joystick.h>
48 int mp_input_joystick_init(char* dev
) {
53 mp_tmsg(MSGT_INPUT
,MSGL_V
,"Opening joystick device %s\n",dev
? dev
: JS_DEV
);
55 fd
= open( dev
? dev
: JS_DEV
, O_RDONLY
| O_NONBLOCK
);
57 mp_tmsg(MSGT_INPUT
,MSGL_ERR
,"Can't open joystick device %s: %s\n",dev
? dev
: JS_DEV
,strerror(errno
));
61 while(! initialized
) {
63 while((unsigned int)l
< sizeof(struct js_event
)) {
64 int r
= read(fd
,((char*)&ev
)+l
,sizeof(struct js_event
)-l
);
68 else if(errno
== EAGAIN
) {
72 mp_tmsg(MSGT_INPUT
,MSGL_ERR
,"Error while reading joystick device: %s\n",strerror(errno
));
78 if((unsigned int)l
< sizeof(struct js_event
)) {
80 mp_tmsg(MSGT_INPUT
,MSGL_WARN
,"Joystick: We lose %d bytes of data\n",l
);
83 if(ev
.type
== JS_EVENT_BUTTON
)
84 btns
|= (ev
.value
<< ev
.number
);
85 if(ev
.type
== JS_EVENT_AXIS
)
86 axis
[ev
.number
] = ev
.value
;
92 int mp_input_joystick_read(void *ctx
, int fd
) {
96 while((unsigned int)l
< sizeof(struct js_event
)) {
97 int r
= read(fd
,&ev
+l
,sizeof(struct js_event
)-l
);
101 else if(errno
== EAGAIN
)
102 return MP_INPUT_NOTHING
;
104 mp_tmsg(MSGT_INPUT
,MSGL_ERR
,"Error while reading joystick device: %s\n",strerror(errno
));
106 mp_tmsg(MSGT_INPUT
,MSGL_ERR
,"Error while reading joystick device: %s\n","EOF");
107 return MP_INPUT_DEAD
;
112 if((unsigned int)l
< sizeof(struct js_event
)) {
114 mp_tmsg(MSGT_INPUT
,MSGL_WARN
,"Joystick: We lose %d bytes of data\n",l
);
115 return MP_INPUT_NOTHING
;
118 if(ev
.type
& JS_EVENT_INIT
) {
119 mp_tmsg(MSGT_INPUT
,MSGL_WARN
,"Joystick: warning init event, we have lost sync with driver.\n");
120 ev
.type
&= ~JS_EVENT_INIT
;
121 if(ev
.type
== JS_EVENT_BUTTON
) {
122 int s
= (btns
>> ev
.number
) & 1;
123 if(s
== ev
.value
) // State is the same : ignore
124 return MP_INPUT_NOTHING
;
126 if(ev
.type
== JS_EVENT_AXIS
) {
127 if( ( axis
[ev
.number
] == 1 && ev
.value
> JOY_AXIS_DELTA
) ||
128 (axis
[ev
.number
] == -1 && ev
.value
< -JOY_AXIS_DELTA
) ||
129 (axis
[ev
.number
] == 0 && ev
.value
>= -JOY_AXIS_DELTA
&& ev
.value
<= JOY_AXIS_DELTA
)
130 ) // State is the same : ignore
131 return MP_INPUT_NOTHING
;
135 if(ev
.type
& JS_EVENT_BUTTON
) {
136 btns
&= ~(1 << ev
.number
);
137 btns
|= (ev
.value
<< ev
.number
);
139 return (JOY_BTN0
+ ev
.number
) | MP_KEY_DOWN
;
141 return JOY_BTN0
+ ev
.number
;
142 } else if(ev
.type
& JS_EVENT_AXIS
) {
143 if(ev
.value
< -JOY_AXIS_DELTA
&& axis
[ev
.number
] != -1) {
144 axis
[ev
.number
] = -1;
145 return (JOY_AXIS0_MINUS
+(2*ev
.number
)) | MP_KEY_DOWN
;
146 } else if(ev
.value
> JOY_AXIS_DELTA
&& axis
[ev
.number
] != 1) {
148 return (JOY_AXIS0_PLUS
+(2*ev
.number
)) | MP_KEY_DOWN
;
149 } else if(ev
.value
<= JOY_AXIS_DELTA
&& ev
.value
>= -JOY_AXIS_DELTA
&& axis
[ev
.number
] != 0) {
150 int r
= axis
[ev
.number
] == 1 ? JOY_AXIS0_PLUS
+(2*ev
.number
) : JOY_AXIS0_MINUS
+(2*ev
.number
);
154 return MP_INPUT_NOTHING
;
156 mp_tmsg(MSGT_INPUT
,MSGL_WARN
,"Joystick warning unknown event type %d\n",ev
.type
);
157 return MP_INPUT_ERROR
;
160 return MP_INPUT_NOTHING
;