* InterfaceWindow.cpp : fixed DVD drag & drop
[vlc.git] / modules / control / rc / rc.c
1 /*****************************************************************************
2  * rc.c : remote control stdin/stdout plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: rc.c,v 1.19 2003/01/14 14:51:02 massiot Exp $
6  *
7  * Authors: Peter Surda <shurdeek@panorama.sth.ac.at>
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 <errno.h>                                                 /* ENOMEM */
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <signal.h>
34
35 #include <vlc/vlc.h>
36 #include <vlc/intf.h>
37 #include <vlc/aout.h>
38 #include <vlc/vout.h>
39
40 #ifdef HAVE_UNISTD_H
41 #    include <unistd.h>
42 #endif
43
44 #ifdef HAVE_SYS_TIME_H
45 #    include <sys/time.h>
46 #endif
47 #include <sys/types.h>
48
49 #if defined( WIN32 )
50 #include <winsock2.h>                                            /* select() */
51 #endif
52
53 #include "error.h"
54
55 #define MAX_LINE_LENGTH 256
56
57 /*****************************************************************************
58  * Local prototypes
59  *****************************************************************************/
60 static int  Activate     ( vlc_object_t * );
61 static void Run          ( intf_thread_t *p_intf );
62
63 static int  Input        ( vlc_object_t *, char const *,
64                            vlc_value_t, vlc_value_t, void * );
65 static int  Playlist     ( vlc_object_t *, char const *,
66                            vlc_value_t, vlc_value_t, void * );
67 static int  Quit         ( vlc_object_t *, char const *,
68                            vlc_value_t, vlc_value_t, void * );
69 static int  Intf         ( vlc_object_t *, char const *,
70                            vlc_value_t, vlc_value_t, void * );
71 static int  Volume       ( vlc_object_t *, char const *,
72                            vlc_value_t, vlc_value_t, void * );
73 static int  VolumeMove   ( vlc_object_t *, char const *,
74                            vlc_value_t, vlc_value_t, void * );
75 static int  AudioConfig  ( vlc_object_t *, char const *,
76                            vlc_value_t, vlc_value_t, void * );
77
78 /*****************************************************************************
79  * Module descriptor
80  *****************************************************************************/
81 #define POS_TEXT N_("show stream position")
82 #define POS_LONGTEXT N_("Show the current position in seconds within the stream from time to time.")
83
84 #define TTY_TEXT N_("fake TTY")
85 #define TTY_LONGTEXT N_("Force the rc plugin to use stdin as if it was a TTY.")
86
87 vlc_module_begin();
88     add_category_hint( N_("Remote control"), NULL );
89     add_bool( "rc-show-pos", 0, NULL, POS_TEXT, POS_LONGTEXT );
90 #ifdef HAVE_ISATTY
91     add_bool( "fake-tty", 0, NULL, TTY_TEXT, TTY_LONGTEXT );
92 #endif
93     set_description( _("remote control interface module") );
94     set_capability( "interface", 20 );
95     set_callbacks( Activate, NULL );
96 vlc_module_end();
97
98 /*****************************************************************************
99  * Activate: initialize and create stuff
100  *****************************************************************************/
101 static int Activate( vlc_object_t *p_this )
102 {
103     intf_thread_t *p_intf = (intf_thread_t*)p_this;
104
105 #ifdef HAVE_ISATTY
106     /* Check that stdin is a TTY */
107     if( !config_GetInt( p_intf, "fake-tty" ) && !isatty( 0 ) )
108     {
109         msg_Warn( p_intf, "fd 0 is not a TTY" );
110         return VLC_EGENERIC;
111     }
112 #endif
113
114     /* Non-buffered stdout */
115     setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
116
117     p_intf->pf_run = Run;
118
119     CONSOLE_INTRO_MSG;
120
121     printf( "remote control interface initialized, `h' for help\n" );
122     return VLC_SUCCESS;
123 }
124
125 /*****************************************************************************
126  * Run: rc thread
127  *****************************************************************************
128  * This part of the interface is in a separate thread so that we can call
129  * exec() from within it without annoying the rest of the program.
130  *****************************************************************************/
131 static void Run( intf_thread_t *p_intf )
132 {
133     input_thread_t * p_input;
134     playlist_t *     p_playlist;
135
136     char       p_buffer[ MAX_LINE_LENGTH + 1 ];
137     vlc_bool_t b_showpos = config_GetInt( p_intf, "rc-show-pos" );
138     input_info_category_t * p_category;
139     input_info_t * p_info;
140
141     int        i_dummy;
142     off_t      i_oldpos = 0;
143     off_t      i_newpos;
144
145     double     f_ratio = 1.0;
146
147     p_input = NULL;
148     p_playlist = NULL;
149
150     /* Register commands that will be cleaned up upon object destruction */
151     var_Create( p_intf, "quit", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
152     var_AddCallback( p_intf, "quit", Quit, NULL );
153     var_Create( p_intf, "intf", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
154     var_AddCallback( p_intf, "intf", Intf, NULL );
155
156     var_Create( p_intf, "add", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
157     var_AddCallback( p_intf, "add", Playlist, NULL );
158     var_Create( p_intf, "playlist", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
159     var_AddCallback( p_intf, "playlist", Playlist, NULL );
160     var_Create( p_intf, "play", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
161     var_AddCallback( p_intf, "play", Playlist, NULL );
162     var_Create( p_intf, "stop", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
163     var_AddCallback( p_intf, "stop", Playlist, NULL );
164     var_Create( p_intf, "prev", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
165     var_AddCallback( p_intf, "prev", Playlist, NULL );
166     var_Create( p_intf, "next", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
167     var_AddCallback( p_intf, "next", Playlist, NULL );
168
169     var_Create( p_intf, "pause", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
170     var_AddCallback( p_intf, "pause", Input, NULL );
171     var_Create( p_intf, "seek", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
172     var_AddCallback( p_intf, "seek", Input, NULL );
173     var_Create( p_intf, "title", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
174     var_AddCallback( p_intf, "title", Input, NULL );
175     var_Create( p_intf, "title_n", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
176     var_AddCallback( p_intf, "title_n", Input, NULL );
177     var_Create( p_intf, "title_p", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
178     var_AddCallback( p_intf, "title_p", Input, NULL );
179     var_Create( p_intf, "chapter", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
180     var_AddCallback( p_intf, "chapter", Input, NULL );
181     var_Create( p_intf, "chapter_n", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
182     var_AddCallback( p_intf, "chapter_n", Input, NULL );
183     var_Create( p_intf, "chapter_p", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
184     var_AddCallback( p_intf, "chapter_p", Input, NULL );
185
186     var_Create( p_intf, "volume", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
187     var_AddCallback( p_intf, "volume", Volume, NULL );
188     var_Create( p_intf, "volup", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
189     var_AddCallback( p_intf, "volup", VolumeMove, NULL );
190     var_Create( p_intf, "voldown", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
191     var_AddCallback( p_intf, "voldown", VolumeMove, NULL );
192     var_Create( p_intf, "adev", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
193     var_AddCallback( p_intf, "adev", AudioConfig, NULL );
194     var_Create( p_intf, "achan", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
195     var_AddCallback( p_intf, "achan", AudioConfig, NULL );
196
197     while( !p_intf->b_die )
198     {
199         fd_set         fds;
200         struct timeval tv;
201         vlc_bool_t     b_complete = VLC_FALSE;
202
203         /* Check stdin */
204         tv.tv_sec = 0;
205         tv.tv_usec = 50000;
206         FD_ZERO( &fds );
207         FD_SET( STDIN_FILENO, &fds );
208
209         i_dummy = select( 32, &fds, NULL, NULL, &tv );
210         if( i_dummy > 0 )
211         {
212             int i_size = 0;
213
214             while( !p_intf->b_die
215                     && i_size < MAX_LINE_LENGTH
216                     && read( STDIN_FILENO, p_buffer + i_size, 1 ) > 0
217                     && p_buffer[ i_size ] != '\r'
218                     && p_buffer[ i_size ] != '\n' )
219             {
220                 i_size++;
221             }
222
223             if( i_size == MAX_LINE_LENGTH
224                  || p_buffer[ i_size ] == '\r'
225                  || p_buffer[ i_size ] == '\n' )
226             {
227                 p_buffer[ i_size ] = 0;
228                 b_complete = VLC_TRUE;
229             }
230         }
231
232         /* Manage the input part */
233         if( p_input == NULL )
234         {
235             if( p_playlist )
236             {
237                 p_input = vlc_object_find( p_playlist, VLC_OBJECT_INPUT,
238                                                        FIND_CHILD );
239             }
240             else
241             {
242                 p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
243                                                    FIND_ANYWHERE );
244                 if( p_input )
245                 {
246                     p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
247                                                            FIND_PARENT );
248                 }
249             }
250         }
251         else if( p_input->b_dead )
252         {
253             vlc_object_release( p_input );
254             p_input = NULL;
255         }
256
257         if( p_input && b_showpos )
258         {
259             /* Get position */
260             vlc_mutex_lock( &p_input->stream.stream_lock );
261             if( !p_input->b_die && p_input->stream.i_mux_rate )
262             {
263 #define A p_input->stream.p_selected_area
264                 f_ratio = 1.0 / ( 50 * p_input->stream.i_mux_rate );
265                 i_newpos = A->i_tell * f_ratio;
266
267                 if( i_oldpos != i_newpos )
268                 {
269                     i_oldpos = i_newpos;
270                     printf( "pos: %li s / %li s\n", (long int)i_newpos,
271                             (long int)(f_ratio * A->i_size) );
272                 }
273 #undef S
274             }
275             vlc_mutex_unlock( &p_input->stream.stream_lock );
276         }
277
278         /* Is there something to do? */
279         if( b_complete )
280         {
281             char *psz_cmd, *psz_arg;
282
283             /* Skip heading spaces */
284             psz_cmd = p_buffer;
285             while( *psz_cmd == ' ' )
286             {
287                 psz_cmd++;
288             }
289
290             /* Split psz_cmd at the first space and make sure that
291              * psz_arg is valid */
292             psz_arg = strchr( psz_cmd, ' ' );
293             if( psz_arg )
294             {
295                 *psz_arg++ = 0;
296                 while( *psz_arg == ' ' )
297                 {
298                     psz_arg++;
299                 }
300             }
301             else
302             {
303                 psz_arg = "";
304             }
305
306             /* If the user typed a registered local command, try it */
307             if( var_Type( p_intf, psz_cmd ) & VLC_VAR_ISCOMMAND )
308             {
309                 vlc_value_t val;
310                 int i_ret;
311
312                 val.psz_string = psz_arg;
313                 i_ret = var_Set( p_intf, psz_cmd, val );
314                 printf( "%s: returned %i (%s)\n",
315                         psz_cmd, i_ret, vlc_error( i_ret ) );
316             }
317             /* Or maybe it's a global command */
318             else if( var_Type( p_intf->p_libvlc, psz_cmd ) & VLC_VAR_ISCOMMAND )
319             {
320                 vlc_value_t val;
321                 int i_ret;
322
323                 val.psz_string = psz_arg;
324                 /* FIXME: it's a global command, but we should pass the
325                  * local object as an argument, not p_intf->p_libvlc. */
326                 i_ret = var_Set( p_intf->p_libvlc, psz_cmd, val );
327                 printf( "%s: returned %i (%s)\n",
328                         psz_cmd, i_ret, vlc_error( i_ret ) );
329             }
330             else if( !strcmp( psz_cmd, "info" ) )
331             {
332                 if ( p_input )
333                 {
334                     vlc_mutex_lock( &p_input->stream.stream_lock );
335                     p_category = p_input->stream.p_info;
336                     while ( p_category )
337                     {
338                         printf( "+----[ %s ]\n", p_category->psz_name );
339                         printf( "| \n" );
340                         p_info = p_category->p_info;
341                         while ( p_info )
342                         {
343                             printf( "| %s: %s\n", p_info->psz_name,
344                                     p_info->psz_value );
345                             p_info = p_info->p_next;
346                         }
347                         p_category = p_category->p_next;
348                         printf( "| \n" );
349                     }
350                     printf( "+----[ end of stream info ]\n" );
351                     vlc_mutex_unlock( &p_input->stream.stream_lock );
352                 }
353                 else
354                 {
355                     printf( "no input\n" );
356                 }
357             }
358             else switch( psz_cmd[0] )
359             {
360             case 'f':
361             case 'F':
362                 if( p_input )
363                 {
364                     vout_thread_t *p_vout;
365                     p_vout = vlc_object_find( p_input,
366                                               VLC_OBJECT_VOUT, FIND_CHILD );
367
368                     if( p_vout )
369                     {
370                         p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
371                         vlc_object_release( p_vout );
372                     }
373                 }
374                 break;
375
376             case 's':
377             case 'S':
378                 ;
379                 break;
380
381             case '?':
382             case 'h':
383             case 'H':
384                 printf("+----[ remote control commands ]\n");
385                 printf("| \n");
386                 printf("| add XYZ  . . . . . . . . . . add XYZ to playlist\n");
387                 printf("| playlist . . .  show items currently in playlist\n");
388                 printf("| play . . . . . . . . . . . . . . . . play stream\n");
389                 printf("| stop . . . . . . . . . . . . . . . . stop stream\n");
390                 printf("| next . . . . . . . . . . . .  next playlist item\n");
391                 printf("| prev . . . . . . . . . .  previous playlist item\n");
392                 printf("| title [X]  . . . . set/get title in current item\n");
393                 printf("| title_n  . . . . . .  next title in current item\n");
394                 printf("| title_p  . . . .  previous title in current item\n");
395                 printf("| chapter [X]  . . set/get chapter in current item\n");
396                 printf("| chapter_n  . . . .  next chapter in current item\n");
397                 printf("| chapter_p  . .  previous chapter in current item\n");
398                 printf("| \n");
399                 printf("| seek X . seek in seconds, for instance `seek 12'\n");
400                 printf("| pause  . . . . . . . . . . . . . .  toggle pause\n");
401                 printf("| f  . . . . . . . . . . . . . . toggle fullscreen\n");
402                 printf("| info . . .  information about the current stream\n");
403                 printf("| \n");
404                 printf("| volume [X] . . . . . . . .  set/get audio volume\n");
405                 printf("| volup [X]  . . . . .  raise audio volume X steps\n");
406                 printf("| voldown [X]  . . . .  lower audio volume X steps\n");
407                 printf("| adev [X] . . . . . . . . .  set/get audio device\n");
408                 printf("| achan [X]. . . . . . . .  set/get audio channels\n");
409                 printf("| \n");
410                 printf("| help . . . . . . . . . . . . . this help message\n");
411                 printf("| quit . . . . . . . . . . . . . . . . .  quit vlc\n");
412                 printf("| \n");
413                 printf("+----[ end of help ]\n");
414                 break;
415             case '\0':
416                 /* Ignore empty lines */
417                 break;
418             default:
419                 printf( "unknown command `%s', type `help' for help\n", psz_cmd );
420                 break;
421             }
422         }
423     }
424
425     if( p_input )
426     {
427         vlc_object_release( p_input );
428         p_input = NULL;
429     }
430
431     if( p_playlist )
432     {
433         vlc_object_release( p_playlist );
434         p_playlist = NULL;
435     }
436 }
437
438 static int Input( vlc_object_t *p_this, char const *psz_cmd,
439                   vlc_value_t oldval, vlc_value_t newval, void *p_data )
440 {
441     input_thread_t * p_input;
442
443     p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
444
445     if( !p_input )
446     {
447         return VLC_ENOOBJ;
448     }
449
450     /* Parse commands that only require an input */
451     if( !strcmp( psz_cmd, "pause" ) )
452     {
453         input_SetStatus( p_input, INPUT_STATUS_PAUSE );
454         vlc_object_release( p_input );
455         return VLC_SUCCESS;
456     }
457     else if( !strcmp( psz_cmd, "seek" ) )
458     {
459         input_Seek( p_input, atoi( newval.psz_string ),
460                     INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
461     }
462     else if( !strcmp( psz_cmd, "chapter" ) ||
463              !strcmp( psz_cmd, "chapter_n" ) ||
464              !strcmp( psz_cmd, "chapter_p" ) )
465     {
466         unsigned int i_chapter = 0;
467
468         if( !strcmp( psz_cmd, "chapter" ) )
469         {
470             if ( *newval.psz_string )
471             {
472                 /* Set. */
473                 i_chapter = atoi( newval.psz_string );
474             }
475             else
476             {
477                 /* Get. */
478                 vlc_mutex_lock( &p_input->stream.stream_lock );
479                 printf( "Currently playing chapter %d\n",
480                         p_input->stream.p_selected_area->i_part );
481                 vlc_mutex_unlock( &p_input->stream.stream_lock );
482
483                 vlc_object_release( p_input );
484                 return VLC_SUCCESS;
485             }
486         }
487         else if( !strcmp( psz_cmd, "chapter_n" ) )
488         {
489             vlc_mutex_lock( &p_input->stream.stream_lock );
490             i_chapter = p_input->stream.p_selected_area->i_part + 1;
491             vlc_mutex_unlock( &p_input->stream.stream_lock );
492         }
493         else if( !strcmp( psz_cmd, "chapter_p" ) )
494         {
495             vlc_mutex_lock( &p_input->stream.stream_lock );
496             i_chapter = p_input->stream.p_selected_area->i_part - 1;
497             vlc_mutex_unlock( &p_input->stream.stream_lock );
498         }
499
500         vlc_mutex_lock( &p_input->stream.stream_lock );
501         if( ( i_chapter > 0 ) && ( i_chapter <=
502             p_input->stream.p_selected_area->i_part_nb ) )
503         {
504           p_input->stream.p_selected_area->i_part = i_chapter;
505           vlc_mutex_unlock( &p_input->stream.stream_lock );
506           input_ChangeArea( p_input,
507                             (input_area_t*)p_input->stream.p_selected_area );
508           input_SetStatus( p_input, INPUT_STATUS_PLAY );
509           vlc_mutex_lock( &p_input->stream.stream_lock );
510         }
511         vlc_mutex_unlock( &p_input->stream.stream_lock );
512
513         vlc_object_release( p_input );
514         return VLC_SUCCESS;
515     }
516     else if( !strcmp( psz_cmd, "title" ) ||
517              !strcmp( psz_cmd, "title_n" ) ||
518              !strcmp( psz_cmd, "title_p" ) )
519     {
520         unsigned int i_title = 0;
521
522         if( !strcmp( psz_cmd, "title" ) )
523         {
524             if ( *newval.psz_string )
525             {
526                 /* Set. */
527                 i_title = atoi( newval.psz_string );
528             }
529             else
530             {
531                 /* Get. */
532                 vlc_mutex_lock( &p_input->stream.stream_lock );
533                 printf( "Currently playing title %d\n",
534                         p_input->stream.p_selected_area->i_id );
535                 vlc_mutex_unlock( &p_input->stream.stream_lock );
536
537                 vlc_object_release( p_input );
538                 return VLC_SUCCESS;
539             }
540         }
541         else if( !strcmp( psz_cmd, "title_n" ) )
542         {
543             vlc_mutex_lock( &p_input->stream.stream_lock );
544             i_title = p_input->stream.p_selected_area->i_id + 1;
545             vlc_mutex_unlock( &p_input->stream.stream_lock );
546         }
547         else if( !strcmp( psz_cmd, "title_p" ) )
548         {
549             vlc_mutex_lock( &p_input->stream.stream_lock );
550             i_title = p_input->stream.p_selected_area->i_id - 1;
551             vlc_mutex_unlock( &p_input->stream.stream_lock );
552         }
553
554         vlc_mutex_lock( &p_input->stream.stream_lock );
555         if( ( i_title > 0 ) && ( i_title <=
556             p_input->stream.p_selected_area->i_part_nb ) )
557         {
558             p_input->stream.p_selected_area->i_part = i_title;
559             vlc_mutex_unlock( &p_input->stream.stream_lock );
560             input_ChangeArea( p_input,
561                      (input_area_t*)p_input->stream.pp_areas[i_title] );
562             input_SetStatus( p_input, INPUT_STATUS_PLAY );
563             vlc_mutex_lock( &p_input->stream.stream_lock );
564         }
565         vlc_mutex_unlock( &p_input->stream.stream_lock );
566
567         vlc_object_release( p_input );
568         return VLC_SUCCESS;
569     }
570
571     /* Never reached. */
572     return VLC_EGENERIC;
573 }
574
575 static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
576                      vlc_value_t oldval, vlc_value_t newval, void *p_data )
577 {
578     playlist_t *     p_playlist;
579
580     p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
581                                            FIND_ANYWHERE );
582     if( !p_playlist )
583     {
584         return VLC_ENOOBJ;
585     }
586
587     /* Parse commands that require a playlist */
588     if( !strcmp( psz_cmd, "prev" ) )
589     {
590         playlist_Prev( p_playlist );
591     }
592     else if( !strcmp( psz_cmd, "next" ) )
593     {
594         playlist_Next( p_playlist );
595     }
596     else if( !strcmp( psz_cmd, "play" ) )
597     {
598         playlist_Play( p_playlist );
599     }
600     else if( !strcmp( psz_cmd, "stop" ) )
601     {
602         playlist_Stop( p_playlist );
603     }
604     else if( !strcmp( psz_cmd, "add" ) )
605     {
606         printf( "trying to add %s to playlist\n", newval.psz_string );
607         playlist_Add( p_playlist, newval.psz_string,
608                       PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
609     }
610     else if( !strcmp( psz_cmd, "playlist" ) )
611     {
612         int i;
613         for ( i = 0; i < p_playlist->i_size; i++ )
614         {
615             printf( "|%s%s   %s|\n", i == p_playlist->i_index?"*":" ",
616                     p_playlist->pp_items[i]->psz_name,
617                     p_playlist->pp_items[i]->psz_uri );
618         }
619         if ( i == 0 )
620         {
621             printf( "| no etries\n" );
622         }
623     }
624     /*
625      * sanity check
626      */
627     else
628     {
629         printf( "unknown command!\n" );
630     }
631
632     vlc_object_release( p_playlist );
633     return VLC_SUCCESS;
634 }
635
636 static int Quit( vlc_object_t *p_this, char const *psz_cmd,
637                  vlc_value_t oldval, vlc_value_t newval, void *p_data )
638 {
639     p_this->p_vlc->b_die = VLC_TRUE;
640     return VLC_SUCCESS;
641 }
642
643 static int Intf( vlc_object_t *p_this, char const *psz_cmd,
644                  vlc_value_t oldval, vlc_value_t newval, void *p_data )
645 {
646     intf_thread_t *p_newintf;
647     char *psz_oldmodule = config_GetPsz( p_this->p_vlc, "intf" );
648
649     config_PutPsz( p_this->p_vlc, "intf", newval.psz_string );
650     p_newintf = intf_Create( p_this->p_vlc );
651     config_PutPsz( p_this->p_vlc, "intf", psz_oldmodule );
652
653     if( psz_oldmodule )
654     {
655         free( psz_oldmodule );
656     }
657
658     if( p_newintf )
659     {
660         p_newintf->b_block = VLC_FALSE;
661         if( intf_RunThread( p_newintf ) )
662         {
663             vlc_object_detach( p_newintf );
664             intf_Destroy( p_newintf );
665         }
666     }
667
668     return VLC_SUCCESS;
669 }
670
671 static int Volume( vlc_object_t *p_this, char const *psz_cmd,
672                    vlc_value_t oldval, vlc_value_t newval, void *p_data )
673 {
674     aout_instance_t * p_aout;
675     int i_error;
676     p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
677     if ( p_aout == NULL ) return VLC_ENOOBJ;
678
679     if ( *newval.psz_string )
680     {
681         /* Set. */
682         audio_volume_t i_volume = atoi( newval.psz_string );
683         if ( i_volume > AOUT_VOLUME_MAX )
684         {
685             printf( "Volume must be in the range %d-%d\n", AOUT_VOLUME_MIN,
686                     AOUT_VOLUME_MAX );
687             i_error = VLC_EBADVAR;
688         }
689         else i_error = aout_VolumeSet( p_aout, i_volume );
690     }
691     else
692     {
693         /* Get. */
694         audio_volume_t i_volume;
695         if ( aout_VolumeGet( p_aout, &i_volume ) < 0 )
696         {
697             i_error = VLC_EGENERIC;
698         }
699         else
700         {
701             printf( "Volume is %d\n", i_volume );
702             i_error = VLC_SUCCESS;
703         }
704     }
705     vlc_object_release( (vlc_object_t *)p_aout );
706
707     return i_error;
708 }
709
710 static int VolumeMove( vlc_object_t *p_this, char const *psz_cmd,
711                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
712 {
713     aout_instance_t * p_aout;
714     audio_volume_t i_volume;
715     int i_nb_steps = atoi(newval.psz_string);
716     int i_error = VLC_SUCCESS;
717
718     if ( i_nb_steps <= 0 || i_nb_steps > (AOUT_VOLUME_MAX/AOUT_VOLUME_STEP) )
719     {
720         i_nb_steps = 1;
721     }
722
723     p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
724     if ( p_aout == NULL ) return VLC_ENOOBJ;
725
726     if ( !strcmp(psz_cmd, "volup") )
727     {
728         if ( aout_VolumeUp( p_aout, i_nb_steps, &i_volume ) < 0 )
729             i_error = VLC_EGENERIC;
730     }
731     else
732     {
733         if ( aout_VolumeDown( p_aout, i_nb_steps, &i_volume ) < 0 )
734             i_error = VLC_EGENERIC;
735     }
736     vlc_object_release( (vlc_object_t *)p_aout );
737
738     if ( !i_error ) printf( "Volume is %d\n", i_volume );
739     return i_error;
740 }
741
742 static int AudioConfig( vlc_object_t *p_this, char const *psz_cmd,
743                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
744 {
745     aout_instance_t * p_aout;
746     const char * psz_variable;
747     const char * psz_name;
748     int i_error;
749
750     p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
751     if ( p_aout == NULL ) return VLC_ENOOBJ;
752
753     if ( !strcmp( psz_cmd, "adev" ) )
754     {
755         psz_variable = "audio-device";
756         psz_name = "audio devices";
757     }
758     else
759     {
760         psz_variable = "audio-channels";
761         psz_name = "audio channels";
762     }
763
764     if ( !*newval.psz_string )
765     {
766         /* Retrieve all registered ***. */
767         vlc_value_t val;
768         int i;
769         char * psz_value;
770
771         if ( var_Get( (vlc_object_t *)p_aout, psz_variable, &val ) < 0 )
772         {
773             vlc_object_release( (vlc_object_t *)p_aout );
774             return VLC_EGENERIC;
775         }
776         psz_value = val.psz_string;
777
778         if ( var_Change( (vlc_object_t *)p_aout, psz_variable,
779                          VLC_VAR_GETLIST, &val ) < 0 )
780         {
781             free( psz_value );
782             vlc_object_release( (vlc_object_t *)p_aout );
783             return VLC_EGENERIC;
784         }
785
786         printf( "+----[ %s ]\n", psz_name );
787         for ( i = 0; i < val.p_list->i_count; i++ )
788         {
789             if ( !strcmp( psz_value, val.p_list->p_values[i].psz_string ) )
790                 printf( "| %s *\n", val.p_list->p_values[i].psz_string );
791             else
792                 printf( "| %s\n", val.p_list->p_values[i].psz_string );
793         }
794         var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_FREELIST,
795                     &val );
796         printf( "+----[ end of %s ]\n", psz_name );
797
798         free( psz_value );
799         i_error = VLC_SUCCESS;
800     }
801     else
802     {
803         vlc_value_t val;
804         val.psz_string = newval.psz_string;
805
806         i_error = var_Set( (vlc_object_t *)p_aout, psz_variable, val );
807     }
808     vlc_object_release( (vlc_object_t *)p_aout );
809
810     return i_error;
811 }