]> git.sesse.net Git - vlc/blob - plugins/lirc/lirc.c
b2a68c39bc5fcf706644436b00b29d394af04768
[vlc] / plugins / lirc / lirc.c
1 /*****************************************************************************
2  * lirc.c : lirc plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2002 VideoLAN
5  * $Id: lirc.c,v 1.14 2002/07/20 18:01:42 sam 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 void intf_getfunctions( function_list_t * p_function_list );
53
54 static int  intf_Open      ( intf_thread_t *p_intf );
55 static void intf_Close     ( intf_thread_t *p_intf );
56 static void intf_Run       ( intf_thread_t *p_intf );
57
58 /*****************************************************************************
59  * Build configuration tree.
60  *****************************************************************************/
61 MODULE_CONFIG_START
62
63 MODULE_CONFIG_STOP
64
65 MODULE_INIT_START
66     SET_DESCRIPTION( _("infrared remote control module") )
67     ADD_CAPABILITY( INTF, 8 )
68 MODULE_INIT_STOP
69
70 MODULE_ACTIVATE_START
71     intf_getfunctions( &p_module->p_functions->intf );
72 MODULE_ACTIVATE_STOP
73
74 MODULE_DEACTIVATE_START
75 MODULE_DEACTIVATE_STOP
76
77 /*****************************************************************************
78  * Functions exported as capabilities. They are declared as static so that
79  * we don't pollute the namespace too much.
80  *****************************************************************************/
81 static void intf_getfunctions( function_list_t * p_function_list )
82 {
83     p_function_list->functions.intf.pf_open  = intf_Open;
84     p_function_list->functions.intf.pf_close = intf_Close;
85     p_function_list->functions.intf.pf_run   = intf_Run;
86 }
87
88 /*****************************************************************************
89  * intf_Open: initialize dummy interface
90  *****************************************************************************/
91 static int intf_Open( intf_thread_t *p_intf )
92 {
93     int i_fd;
94
95     /* Allocate instance and initialize some members */
96     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
97     if( p_intf->p_sys == NULL )
98     {
99         msg_Err( p_intf, "out of memory" );
100         return 1;
101     }
102
103     i_fd = lirc_init( "vlc", 1 );
104     if( i_fd == -1 )
105     {
106         msg_Err( p_intf, "lirc_init failed" );
107         free( p_intf->p_sys );
108         return 1;
109     }
110
111     /* We want polling */
112     fcntl( i_fd, F_SETFL, fcntl( i_fd, F_GETFL ) | O_NONBLOCK );
113
114     if( lirc_readconfig( NULL, &p_intf->p_sys->config, NULL ) != 0 )
115     {
116         msg_Err( p_intf, "lirc_readconfig failed" );
117         lirc_deinit();
118         free( p_intf->p_sys );
119         return 1;
120     }
121
122     p_intf->p_sys->p_input = NULL;
123
124     return 0;
125 }
126
127 /*****************************************************************************
128  * intf_Close: destroy dummy interface
129  *****************************************************************************/
130 static void intf_Close( intf_thread_t *p_intf )
131 {
132     if( p_intf->p_sys->p_input )
133     {
134         vlc_object_release( p_intf->p_sys->p_input );
135     }
136
137     /* Destroy structure */
138     lirc_freeconfig( p_intf->p_sys->config );
139     lirc_deinit();
140     free( p_intf->p_sys );
141 }
142
143 /*****************************************************************************
144  * intf_Run: main loop
145  *****************************************************************************/
146 static void intf_Run( intf_thread_t *p_intf )
147 {
148     char *code, *c;
149     playlist_t *p_playlist;
150     input_thread_t *p_input;
151
152     while( !p_intf->b_die )
153     {
154         /* Sleep a bit */
155         msleep( INTF_IDLE_SLEEP );
156
157         /* Update the input */
158         if( p_intf->p_sys->p_input == NULL )
159         {
160             p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
161                                                               FIND_ANYWHERE );
162         }
163         else if( p_intf->p_sys->p_input->b_dead )
164         {
165             vlc_object_release( p_intf->p_sys->p_input );
166             p_intf->p_sys->p_input = NULL;
167         }
168
169         /* We poll the lircsocket */
170         if( lirc_nextcode(&code) != 0 )
171         {
172             break;
173         }
174
175         if( code == NULL )
176         {
177             continue;
178         }
179
180         while( !p_intf->b_die 
181                 && lirc_code2char( p_intf->p_sys->config, code, &c ) == 0
182                 && c != NULL )
183         {
184             if( !strcmp( c, "QUIT" ) )
185             {
186                 p_intf->p_vlc->b_die = VLC_TRUE;
187                 continue;
188             }
189
190             if( !strcmp( c, "FULLSCREEN" ) )
191             {
192                 vout_thread_t *p_vout;
193                 p_vout = vlc_object_find( p_intf->p_sys->p_input,
194                                           VLC_OBJECT_VOUT, FIND_CHILD );
195                 if( p_vout )
196                 {
197                     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
198                     vlc_object_release( p_vout );
199                 }
200                 continue;
201             }
202
203             if( !strcmp( c, "PLAY" ) )
204             {
205                 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
206                                                       FIND_ANYWHERE );
207                 if( p_playlist )
208                 {
209                     vlc_mutex_lock( &p_playlist->object_lock );
210                     if( p_playlist->i_size )
211                     {
212                         vlc_mutex_unlock( &p_playlist->object_lock );
213                         playlist_Play( p_playlist );
214                         vlc_object_release( p_playlist );
215                     }
216                 }
217             }
218             else if( p_intf->p_sys->p_input )
219             {
220                 p_input = p_intf->p_sys->p_input;
221
222                 if( !strcmp( c, "PAUSE" ) )
223                 {
224                     input_SetStatus( p_input, INPUT_STATUS_PAUSE );
225                 }
226                 else if( !strcmp( c, "NEXT" ) )
227                 {
228                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
229                                                           FIND_ANYWHERE );
230                     if( p_playlist )
231                     {
232                         playlist_Next( p_playlist );
233                         vlc_object_release( p_playlist );
234                     }
235                 }
236                 else if( !strcmp( c, "PREV" ) )
237                 {
238                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
239                                                           FIND_ANYWHERE );
240                     if( p_playlist )
241                     {
242                         playlist_Prev( p_playlist );
243                         vlc_object_release( p_playlist );
244                     }
245                 }
246                 else if( !strcmp( c, "STOP" ) )
247                 {
248                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
249                                                           FIND_ANYWHERE );
250                     if( p_playlist )
251                     {
252                         playlist_Stop( p_playlist );
253                         vlc_object_release( p_playlist );
254                     }
255                 }
256                 else if( !strcmp( c, "FAST" ) )
257                 {
258                     input_SetStatus( p_input, INPUT_STATUS_FASTER );
259                 }
260                 else if( !strcmp( c, "SLOW" ) )
261                 {
262                     input_SetStatus( p_input, INPUT_STATUS_SLOWER );
263                 }
264             }
265         }
266
267         free( code );
268     }
269 }
270