a5014603bf74867302c2b3520c83fe083f827afd
[vlc.git] / modules / control / lirc / lirc.c
1 /*****************************************************************************
2  * lirc.c : lirc plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2002 VideoLAN
5  * $Id: lirc.c,v 1.3 2003/01/12 15:38:35 sigmunau Exp $
6  *
7  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <string.h>
29
30 #include <fcntl.h>
31
32 #include <vlc/vlc.h>
33 #include <vlc/intf.h>
34 #include <vlc/vout.h>
35
36 #include <lirc/lirc_client.h>
37
38 /*****************************************************************************
39  * intf_sys_t: description and status of FB interface
40  *****************************************************************************/
41 struct intf_sys_t
42 {
43     struct lirc_config *config;
44     vlc_mutex_t         change_lock;
45
46     input_thread_t *    p_input;
47 };
48
49 /*****************************************************************************
50  * Local prototypes
51  *****************************************************************************/
52 static int  Open    ( vlc_object_t * );
53 static void Close   ( vlc_object_t * );
54 static void Run     ( intf_thread_t * );
55
56 /*****************************************************************************
57  * Module descriptor
58  *****************************************************************************/
59 vlc_module_begin();
60     set_description( _("infrared remote control module") );
61     set_capability( "interface", 0 );
62     set_callbacks( Open, Close );
63 vlc_module_end();
64
65 /*****************************************************************************
66  * Open: initialize interface
67  *****************************************************************************/
68 static int Open( vlc_object_t *p_this )
69 {
70     intf_thread_t *p_intf = (intf_thread_t *)p_this;
71     int i_fd;
72
73     /* Allocate instance and initialize some members */
74     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
75     if( p_intf->p_sys == NULL )
76     {
77         msg_Err( p_intf, "out of memory" );
78         return 1;
79     }
80
81     p_intf->pf_run = Run;
82
83     i_fd = lirc_init( "vlc", 1 );
84     if( i_fd == -1 )
85     {
86         msg_Err( p_intf, "lirc_init failed" );
87         free( p_intf->p_sys );
88         return 1;
89     }
90
91     /* We want polling */
92     fcntl( i_fd, F_SETFL, fcntl( i_fd, F_GETFL ) | O_NONBLOCK );
93
94     if( lirc_readconfig( NULL, &p_intf->p_sys->config, NULL ) != 0 )
95     {
96         msg_Err( p_intf, "lirc_readconfig failed" );
97         lirc_deinit();
98         free( p_intf->p_sys );
99         return 1;
100     }
101
102     p_intf->p_sys->p_input = NULL;
103
104     return 0;
105 }
106
107 /*****************************************************************************
108  * Close: destroy interface
109  *****************************************************************************/
110 static void Close( vlc_object_t *p_this )
111 {
112     intf_thread_t *p_intf = (intf_thread_t *)p_this;
113
114     if( p_intf->p_sys->p_input )
115     {
116         vlc_object_release( p_intf->p_sys->p_input );
117     }
118
119     /* Destroy structure */
120     lirc_freeconfig( p_intf->p_sys->config );
121     lirc_deinit();
122     free( p_intf->p_sys );
123 }
124
125 /*****************************************************************************
126  * Run: main loop
127  *****************************************************************************/
128 static void Run( intf_thread_t *p_intf )
129 {
130     char *code, *c;
131     playlist_t *p_playlist;
132     input_thread_t *p_input;
133
134     while( !p_intf->b_die )
135     {
136         /* Sleep a bit */
137         msleep( INTF_IDLE_SLEEP );
138
139         /* Update the input */
140         if( p_intf->p_sys->p_input == NULL )
141         {
142             p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
143                                                               FIND_ANYWHERE );
144         }
145         else if( p_intf->p_sys->p_input->b_dead )
146         {
147             vlc_object_release( p_intf->p_sys->p_input );
148             p_intf->p_sys->p_input = NULL;
149         }
150         p_input = p_intf->p_sys->p_input;
151
152         /* We poll the lircsocket */
153         if( lirc_nextcode(&code) != 0 )
154         {
155             break;
156         }
157
158         if( code == NULL )
159         {
160             continue;
161         }
162
163         while( !p_intf->b_die 
164                 && lirc_code2char( p_intf->p_sys->config, code, &c ) == 0
165                 && c != NULL )
166         {
167             if( !strcmp( c, "QUIT" ) )
168             {
169                 p_intf->p_vlc->b_die = VLC_TRUE;
170                 continue;
171             }
172
173             if( !strcmp( c, "FULLSCREEN" ) )
174             {
175                 vout_thread_t *p_vout;
176                 p_vout = vlc_object_find( p_intf->p_sys->p_input,
177                                           VLC_OBJECT_VOUT, FIND_CHILD );
178                 if( p_vout )
179                 {
180                     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
181                     vlc_object_release( p_vout );
182                 }
183                 continue;
184             }
185             if( !strcmp( c, "ACTIVATE" ) )
186             {
187                 vout_thread_t *p_vout;
188                 p_vout = vlc_object_find( p_intf->p_sys->p_input,
189                                           VLC_OBJECT_VOUT, FIND_CHILD );
190                 if( p_vout )
191                 {
192                     vlc_value_t val;
193                     val.psz_string = "ENTER";
194                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
195                     {
196                         msg_Warn( p_intf, "key-press failed" );
197                     }
198                     vlc_object_release( p_vout );
199                 }
200                 continue;
201             }
202
203             if( !strcmp( c, "LEFT" ) )
204             {
205                 vout_thread_t *p_vout;
206                 p_vout = vlc_object_find( p_intf->p_sys->p_input,
207                                           VLC_OBJECT_VOUT, FIND_CHILD );
208                 if( p_vout )
209                 {
210                     vlc_value_t val;
211                     val.psz_string = "LEFT";
212                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
213                     {
214                         msg_Warn( p_intf, "key-press failed" );
215                     }
216                     vlc_object_release( p_vout );
217                 }
218                 continue;
219             }
220
221             if( !strcmp( c, "RIGHT" ) )
222             {
223                 vout_thread_t *p_vout;
224                 p_vout = vlc_object_find( p_intf->p_sys->p_input,
225                                           VLC_OBJECT_VOUT, FIND_CHILD );
226                 if( p_vout )
227                 {
228                     vlc_value_t val;
229                     val.psz_string = "RIGHT";
230                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
231                     {
232                         msg_Warn( p_intf, "key-press failed" );
233                     }
234                     vlc_object_release( p_vout );
235                 }
236                 continue;
237             }
238
239             if( !strcmp( c, "UP" ) )
240             {
241                 vout_thread_t *p_vout;
242                 p_vout = vlc_object_find( p_intf->p_sys->p_input,
243                                           VLC_OBJECT_VOUT, FIND_CHILD );
244                 if( p_vout )
245                 {
246                     vlc_value_t val;
247                     val.psz_string = "UP";
248                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
249                     {
250                         msg_Warn( p_intf, "key-press failed" );
251                     }
252                     vlc_object_release( p_vout );
253                 }
254                 continue;
255             }
256
257             if( !strcmp( c, "DOWN" ) )
258             {
259                 vout_thread_t *p_vout;
260                 p_vout = vlc_object_find( p_intf->p_sys->p_input,
261                                           VLC_OBJECT_VOUT, FIND_CHILD );
262                 if( p_vout )
263                 {
264                     vlc_value_t val;
265                     val.psz_string = "DOWN";
266                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
267                     {
268                         msg_Warn( p_intf, "key-press failed" );
269                     }
270                     vlc_object_release( p_vout );
271                 }
272                 continue;
273             }
274
275             if( !strcmp( c, "PLAY" ) )
276             {
277                 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
278                                                       FIND_ANYWHERE );
279                 if( p_playlist )
280                 {
281                     vlc_mutex_lock( &p_playlist->object_lock );
282                     if( p_playlist->i_size )
283                     {
284                         vlc_mutex_unlock( &p_playlist->object_lock );
285                         playlist_Play( p_playlist );
286                         vlc_object_release( p_playlist );
287                     }
288                 }
289             }
290             if( !strcmp( c, "PLAYPAUSE" ) )
291             {
292                 if( p_input &&
293                     p_input->stream.control.i_status != PAUSE_S )
294                 {
295                     input_SetStatus( p_input, INPUT_STATUS_PAUSE );
296                 }
297                 else
298                 {
299                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
300                                                   FIND_ANYWHERE );
301                     if( p_playlist )
302                     {
303                         vlc_mutex_lock( &p_playlist->object_lock );
304                         if( p_playlist->i_size )
305                         {
306                             vlc_mutex_unlock( &p_playlist->object_lock );
307                             playlist_Play( p_playlist );
308                             vlc_object_release( p_playlist );
309                         }
310                     }
311                 }                    
312             }                
313             else if( p_input )
314             {
315                 if( !strcmp( c, "PAUSE" ) )
316                 {
317                     input_SetStatus( p_input, INPUT_STATUS_PAUSE );
318                 }
319                 else if( !strcmp( c, "NEXT" ) )
320                 {
321                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
322                                                           FIND_ANYWHERE );
323                     if( p_playlist )
324                     {
325                         playlist_Next( p_playlist );
326                         vlc_object_release( p_playlist );
327                     }
328                 }
329                 else if( !strcmp( c, "PREV" ) )
330                 {
331                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
332                                                           FIND_ANYWHERE );
333                     if( p_playlist )
334                     {
335                         playlist_Prev( p_playlist );
336                         vlc_object_release( p_playlist );
337                     }
338                 }
339                 else if( !strcmp( c, "STOP" ) )
340                 {
341                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
342                                                           FIND_ANYWHERE );
343                     if( p_playlist )
344                     {
345                         playlist_Stop( p_playlist );
346                         vlc_object_release( p_playlist );
347                     }
348                 }
349                 else if( !strcmp( c, "FAST" ) )
350                 {
351                     input_SetStatus( p_input, INPUT_STATUS_FASTER );
352                 }
353                 else if( !strcmp( c, "SLOW" ) )
354                 {
355                     input_SetStatus( p_input, INPUT_STATUS_SLOWER );
356                 }
357             }
358         }
359
360         free( code );
361     }
362 }
363