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>
36 #ifndef JOY_AXIS_DELTA
37 #define JOY_AXIS_DELTA 500
41 #define JS_DEV "/dev/input/js0"
44 #include <linux/joystick.h>
49 int mp_input_joystick_init(char* dev
) {
54 mp_msg(MSGT_INPUT
,MSGL_V
,MSGTR_INPUT_JOYSTICK_Opening
,dev
? dev
: JS_DEV
);
56 fd
= open( dev
? dev
: JS_DEV
, O_RDONLY
| O_NONBLOCK
);
58 mp_msg(MSGT_INPUT
,MSGL_ERR
,MSGTR_INPUT_JOYSTICK_CantOpen
,dev
? dev
: JS_DEV
,strerror(errno
));
62 while(! initialized
) {
64 while((unsigned int)l
< sizeof(struct js_event
)) {
65 int r
= read(fd
,((char*)&ev
)+l
,sizeof(struct js_event
)-l
);
69 else if(errno
== EAGAIN
) {
73 mp_msg(MSGT_INPUT
,MSGL_ERR
,MSGTR_INPUT_JOYSTICK_ErrReading
,strerror(errno
));
79 if((unsigned int)l
< sizeof(struct js_event
)) {
81 mp_msg(MSGT_INPUT
,MSGL_WARN
,MSGTR_INPUT_JOYSTICK_LoosingBytes
,l
);
84 if(ev
.type
== JS_EVENT_BUTTON
)
85 btns
|= (ev
.value
<< ev
.number
);
86 if(ev
.type
== JS_EVENT_AXIS
)
87 axis
[ev
.number
] = ev
.value
;
93 int mp_input_joystick_read(void *ctx
, int fd
) {
97 while((unsigned int)l
< sizeof(struct js_event
)) {
98 int r
= read(fd
,&ev
+l
,sizeof(struct js_event
)-l
);
102 else if(errno
== EAGAIN
)
103 return MP_INPUT_NOTHING
;
105 mp_msg(MSGT_INPUT
,MSGL_ERR
,MSGTR_INPUT_JOYSTICK_ErrReading
,strerror(errno
));
107 mp_msg(MSGT_INPUT
,MSGL_ERR
,MSGTR_INPUT_JOYSTICK_ErrReading
,"EOF");
108 return MP_INPUT_DEAD
;
113 if((unsigned int)l
< sizeof(struct js_event
)) {
115 mp_msg(MSGT_INPUT
,MSGL_WARN
,MSGTR_INPUT_JOYSTICK_LoosingBytes
,l
);
116 return MP_INPUT_NOTHING
;
119 if(ev
.type
& JS_EVENT_INIT
) {
120 mp_msg(MSGT_INPUT
,MSGL_WARN
,MSGTR_INPUT_JOYSTICK_WarnLostSync
);
121 ev
.type
&= ~JS_EVENT_INIT
;
122 if(ev
.type
== JS_EVENT_BUTTON
) {
123 int s
= (btns
>> ev
.number
) & 1;
124 if(s
== ev
.value
) // State is the same : ignore
125 return MP_INPUT_NOTHING
;
127 if(ev
.type
== JS_EVENT_AXIS
) {
128 if( ( axis
[ev
.number
] == 1 && ev
.value
> JOY_AXIS_DELTA
) ||
129 (axis
[ev
.number
] == -1 && ev
.value
< -JOY_AXIS_DELTA
) ||
130 (axis
[ev
.number
] == 0 && ev
.value
>= -JOY_AXIS_DELTA
&& ev
.value
<= JOY_AXIS_DELTA
)
131 ) // State is the same : ignore
132 return MP_INPUT_NOTHING
;
136 if(ev
.type
& JS_EVENT_BUTTON
) {
137 btns
&= ~(1 << ev
.number
);
138 btns
|= (ev
.value
<< ev
.number
);
140 return (JOY_BTN0
+ ev
.number
) | MP_KEY_DOWN
;
142 return JOY_BTN0
+ ev
.number
;
143 } else if(ev
.type
& JS_EVENT_AXIS
) {
144 if(ev
.value
< -JOY_AXIS_DELTA
&& axis
[ev
.number
] != -1) {
145 axis
[ev
.number
] = -1;
146 return (JOY_AXIS0_MINUS
+(2*ev
.number
)) | MP_KEY_DOWN
;
147 } else if(ev
.value
> JOY_AXIS_DELTA
&& axis
[ev
.number
] != 1) {
149 return (JOY_AXIS0_PLUS
+(2*ev
.number
)) | MP_KEY_DOWN
;
150 } else if(ev
.value
<= JOY_AXIS_DELTA
&& ev
.value
>= -JOY_AXIS_DELTA
&& axis
[ev
.number
] != 0) {
151 int r
= axis
[ev
.number
] == 1 ? JOY_AXIS0_PLUS
+(2*ev
.number
) : JOY_AXIS0_MINUS
+(2*ev
.number
);
155 return MP_INPUT_NOTHING
;
157 mp_msg(MSGT_INPUT
,MSGL_WARN
,MSGTR_INPUT_JOYSTICK_WarnUnknownEvent
,ev
.type
);
158 return MP_INPUT_ERROR
;
161 return MP_INPUT_NOTHING
;