1 /*****************************************************************************
2 * lirc.c : lirc module for vlc
3 *****************************************************************************
4 * Copyright (C) 2004 VideoLAN
7 * Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
38 #include <lirc/lirc_client.h>
40 /*****************************************************************************
41 * intf_sys_t: description and status of FB interface
42 *****************************************************************************/
45 struct lirc_config *config;
46 vlc_mutex_t change_lock;
50 input_thread_t * p_input;
51 vout_thread_t * p_vout;
54 /*****************************************************************************
56 *****************************************************************************/
57 static int Open ( vlc_object_t * );
58 static void Close ( vlc_object_t * );
59 static void Run ( intf_thread_t * );
61 /*****************************************************************************
63 *****************************************************************************/
65 set_category( CAT_INTERFACE );
66 set_subcategory( SUBCAT_INTERFACE_CONTROL );
67 set_description( _("Infrared remote control interface") );
68 set_capability( "interface", 0 );
69 set_callbacks( Open, Close );
72 /*****************************************************************************
73 * Open: initialize interface
74 *****************************************************************************/
75 static int Open( vlc_object_t *p_this )
77 intf_thread_t *p_intf = (intf_thread_t *)p_this;
80 /* Allocate instance and initialize some members */
81 p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
82 if( p_intf->p_sys == NULL )
84 msg_Err( p_intf, "out of memory" );
90 i_fd = lirc_init( "vlc", 1 );
93 msg_Err( p_intf, "lirc_init failed" );
94 free( p_intf->p_sys );
99 fcntl( i_fd, F_SETFL, fcntl( i_fd, F_GETFL ) | O_NONBLOCK );
101 if( lirc_readconfig( NULL, &p_intf->p_sys->config, NULL ) != 0 )
103 msg_Err( p_intf, "lirc_readconfig failed" );
105 free( p_intf->p_sys );
109 p_intf->p_sys->p_input = NULL;
114 /*****************************************************************************
115 * Close: destroy interface
116 *****************************************************************************/
117 static void Close( vlc_object_t *p_this )
119 intf_thread_t *p_intf = (intf_thread_t *)p_this;
121 if( p_intf->p_sys->p_input )
123 vlc_object_release( p_intf->p_sys->p_input );
125 if( p_intf->p_sys->p_vout )
127 vlc_object_release( p_intf->p_sys->p_vout );
129 /* Destroy structure */
130 lirc_freeconfig( p_intf->p_sys->config );
132 free( p_intf->p_sys );
135 /*****************************************************************************
137 *****************************************************************************/
138 static void Run( intf_thread_t *p_intf )
141 playlist_t *p_playlist;
142 input_thread_t *p_input;
143 vout_thread_t *p_vout = NULL;
145 while( !p_intf->b_die )
148 msleep( INTF_IDLE_SLEEP );
150 /* Update the input */
151 if( p_intf->p_sys->p_input == NULL )
153 p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
156 else if( p_intf->p_sys->p_input->b_dead )
158 vlc_object_release( p_intf->p_sys->p_input );
159 p_intf->p_sys->p_input = NULL;
161 p_input = p_intf->p_sys->p_input;
163 /* Update the vout */
166 p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
168 p_intf->p_sys->p_vout = p_vout;
170 else if( p_vout->b_die )
172 vlc_object_release( p_vout );
174 p_intf->p_sys->p_vout = NULL;
177 /* We poll the lircsocket */
178 if( lirc_nextcode(&code) != 0 )
188 while( !p_intf->b_die
189 && lirc_code2char( p_intf->p_sys->config, code, &c ) == 0
193 if( !strcmp( c, "QUIT" ) )
195 p_intf->p_vlc->b_die = VLC_TRUE;
196 vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Quit" ) );
199 else if( !strcmp( c, "VOL_UP" ) )
201 audio_volume_t i_newvol;
202 aout_VolumeUp( p_intf, 1, &i_newvol );
203 vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Vol %%%d"),
204 i_newvol * 100 / AOUT_VOLUME_MAX );
206 else if( !strcmp( c, "VOL_DOWN" ) )
208 audio_volume_t i_newvol;
209 aout_VolumeDown( p_intf, 1, &i_newvol );
210 vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Vol %%%d"),
211 i_newvol * 100 / AOUT_VOLUME_MAX );
213 else if( !strcmp( c, "MUTE" ) )
215 audio_volume_t i_newvol = -1;
216 aout_VolumeMute( p_intf, &i_newvol );
219 vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Mute" ) );
223 vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Vol %d%%"),
224 i_newvol * 100 / AOUT_VOLUME_MAX );
229 if( !strcmp( c, "FULLSCREEN" ) )
231 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
234 if( !strcmp( c, "ACTIVATE" ) )
237 val.psz_string = "ENTER";
238 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
240 msg_Warn( p_intf, "key-press failed" );
245 if( !strcmp( c, "LEFT" ) )
248 val.psz_string = "LEFT";
249 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
251 msg_Warn( p_intf, "key-press failed" );
256 if( !strcmp( c, "RIGHT" ) )
259 val.psz_string = "RIGHT";
260 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
262 msg_Warn( p_intf, "key-press failed" );
267 if( !strcmp( c, "UP" ) )
270 val.psz_string = "UP";
271 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
273 msg_Warn( p_intf, "key-press failed" );
278 if( !strcmp( c, "DOWN" ) )
281 val.psz_string = "DOWN";
282 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
284 msg_Warn( p_intf, "key-press failed" );
290 if( !strcmp( c, "PLAY" ) )
292 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
296 playlist_Play( p_playlist );
297 vlc_object_release( p_playlist );
302 if( !strcmp( c, "PLAYPAUSE" ) )
305 val.i_int = PLAYING_S;
308 var_Get( p_input, "state", &val );
310 if( p_input && val.i_int != PAUSE_S )
312 vout_OSDMessage( VLC_OBJECT(p_intf), DEFAULT_CHAN,
315 var_Set( p_input, "state", val );
319 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
323 vlc_mutex_lock( &p_playlist->object_lock );
324 if( p_playlist->i_size )
326 vlc_mutex_unlock( &p_playlist->object_lock );
327 vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Play" ) );
328 playlist_Play( p_playlist );
329 vlc_object_release( p_playlist );
338 if( !strcmp( c, "AUDIO_TRACK" ) )
340 vlc_value_t val, list, list2;
342 var_Get( p_input, "audio-es", &val );
343 var_Change( p_input, "audio-es", VLC_VAR_GETCHOICES,
345 i_count = list.p_list->i_count;
346 for( i = 0; i < i_count; i++ )
348 if( val.i_int == list.p_list->p_values[i].i_int )
353 /* value of audio-es was not in choices list */
357 "invalid current audio track, selecting 0" );
358 var_Set( p_input, "audio-es",
359 list.p_list->p_values[0] );
362 else if( i == i_count - 1 )
364 var_Set( p_input, "audio-es",
365 list.p_list->p_values[0] );
370 var_Set( p_input, "audio-es",
371 list.p_list->p_values[i+1] );
374 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
375 _("Audio track: %s"),
376 list2.p_list->p_values[i].psz_string );
378 else if( !strcmp( c, "SUBTITLE_TRACK" ) )
380 vlc_value_t val, list, list2;
382 var_Get( p_input, "spu-es", &val );
383 var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,
385 i_count = list.p_list->i_count;
386 for( i = 0; i < i_count; i++ )
388 if( val.i_int == list.p_list->p_values[i].i_int )
393 /* value of audio-es was not in choices list */
396 msg_Warn( p_input, "invalid current subtitle track, selecting 0" );
397 var_Set( p_input, "spu-es", list.p_list->p_values[0] );
400 else if( i == i_count - 1 )
402 var_Set( p_input, "spu-es", list.p_list->p_values[0] );
407 var_Set( p_input, "spu-es", list.p_list->p_values[i+1] );
410 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
411 _("Subtitle track: %s"),
412 list2.p_list->p_values[i].psz_string );
414 else if( !strcmp( c, "PAUSE" ) )
417 vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Pause" ) );
419 var_Set( p_input, "state", val );
421 else if( !strcmp( c, "NEXT" ) )
423 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
427 playlist_Next( p_playlist );
428 vlc_object_release( p_playlist );
431 else if( !strcmp( c, "PREV" ) )
433 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
437 playlist_Prev( p_playlist );
438 vlc_object_release( p_playlist );
441 else if( !strcmp( c, "STOP" ) )
443 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
447 playlist_Stop( p_playlist );
448 vlc_object_release( p_playlist );
451 else if( !strcmp( c, "FAST" ) )
453 vlc_value_t val; val.b_bool = VLC_TRUE;
454 var_Set( p_input, "rate-faster", val );
456 else if( !strcmp( c, "SLOW" ) )
458 vlc_value_t val; val.b_bool = VLC_TRUE;
459 var_Set( p_input, "rate-slower", val );
461 /* beginning of modifications by stephane Thu Jun 19 15:29:49 CEST 2003 */
462 else if ( !strcmp(c, "CHAPTER_N" ) ||
463 !strcmp( c, "CHAPTER_P" ) )
465 unsigned int i_chapter = 0;
467 if( !strcmp( c, "CHAPTER_N" ) )
469 var_SetVoid( p_input, "next-chapter" );
471 else if( !strcmp( c, "CHAPTER_P" ) )
473 var_SetVoid( p_input, "prev-chapter" );
476 /* end of modification by stephane Thu Jun 19 15:29:49 CEST 2003 */