]> git.sesse.net Git - vlc/blob - src/input/control.c
* src/input/control.c: added INPUT_ADD_INFO/INPUT_SET_NAME to input_Control().
[vlc] / src / input / control.c
1 /*****************************************************************************
2  * control.c
3  *****************************************************************************
4  * Copyright (C) 1999-2004 VideoLAN
5  * $Id: stream.c 7041 2004-03-11 16:48:27Z gbazin $
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
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 #include <stdlib.h>
25 #include <vlc/vlc.h>
26 #include <vlc/input.h>
27
28 #include "vlc_playlist.h"
29
30 #include "ninput.h"
31 #include "../../modules/demux/util/sub.h"
32
33 struct input_thread_sys_t
34 {
35     /* subtitles */
36     int              i_sub;
37     subtitle_demux_t **sub;
38     int64_t          i_stop_time;
39 };
40
41 /****************************************************************************
42  * input_Control
43  ****************************************************************************/
44 /**
45  * Control function for inputs.
46  * \param p_input input handle
47  * \param i_query query type
48  * \return VLC_SUCESS if ok
49  */
50 int input_Control( input_thread_t *p_input, int i_query, ...  )
51 {
52     va_list args;
53     int     i_result;
54
55     va_start( args, i_query );
56     i_result = input_vaControl( p_input, i_query, args );
57     va_end( args );
58
59     return i_result;
60 }
61
62 int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
63 {
64     int     i_ret;
65     seekpoint_t *p_bkmk, ***ppp_bkmk;
66     int i_bkmk, *pi_bkmk;
67     int i, *pi;
68     vlc_value_t val, text;
69     char *psz_option, *psz_value;
70
71     vlc_mutex_lock( &p_input->stream.stream_lock );
72     switch( i_query )
73     {
74         case INPUT_ADD_OPTION:
75         {
76             psz_option = (char *)va_arg( args, char * );
77             psz_value = (char *)va_arg( args, char * );
78             i_ret = VLC_EGENERIC;
79
80             vlc_mutex_lock( &p_input->p_item->lock );
81             vlc_mutex_unlock( &p_input->p_item->lock );
82
83             i_ret = VLC_SUCCESS;
84             break;
85         }
86
87         case INPUT_SET_NAME:
88         {
89             char *psz_name = (char *)va_arg( args, char * );
90             i_ret = VLC_EGENERIC;
91             if( !psz_name ) break;
92             vlc_mutex_lock( &p_input->p_item->lock );
93             if( p_input->p_item->psz_name ) free( p_input->p_item->psz_name );
94             p_input->p_item->psz_name = strdup( psz_name );
95             vlc_mutex_unlock( &p_input->p_item->lock );
96             i_ret = VLC_SUCCESS;
97
98             /* Notify playlist */
99             {
100                 vlc_value_t val;
101                 playlist_t *p_playlist =
102                 (playlist_t *)vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
103                                                FIND_PARENT );
104                 if( p_playlist )
105                 {
106                     val.i_int = p_playlist->i_index;
107                     var_Set( p_playlist, "item-change", val );
108                     vlc_object_release( p_playlist );
109                 }
110             }
111             break;
112         }
113
114         case INPUT_ADD_INFO:
115         {
116             char *psz_cat = (char *)va_arg( args, char * );
117             char *psz_name = (char *)va_arg( args, char * );
118             char *psz_format = (char *)va_arg( args, char * );
119
120             info_category_t *p_cat;
121             info_t *p_info;
122             int i;
123
124             i_ret = VLC_EGENERIC;
125
126             vlc_mutex_lock( &p_input->p_item->lock );
127             for( i = 0; i < p_input->p_item->i_categories; i++ )
128             {
129                 if( !strcmp( p_input->p_item->pp_categories[i]->psz_name,
130                              psz_cat ) )
131                     break;
132             }
133
134             if( i == p_input->p_item->i_categories )
135             {
136                 p_cat = malloc( sizeof( info_category_t ) );
137                 if( !p_cat ) break;
138                 p_cat->psz_name = strdup( psz_cat );
139                 p_cat->i_infos = 0;
140                 p_cat->pp_infos = NULL;
141                 INSERT_ELEM( p_input->p_item->pp_categories,
142                              p_input->p_item->i_categories,
143                              p_input->p_item->i_categories, p_cat );
144             }
145
146             p_cat = p_input->p_item->pp_categories[i];
147
148             for( i = 0; i < p_cat->i_infos; i++ )
149             {
150                 if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
151                 {
152                     if( p_cat->pp_infos[i]->psz_value )
153                         free( p_cat->pp_infos[i]->psz_value );
154                     break;
155                 }
156             }
157
158             if( i == p_cat->i_infos )
159             {
160                 p_info = malloc( sizeof( info_t ) );
161                 if( !p_info ) break;
162                 INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos,
163                              p_cat->i_infos, p_info );
164                 p_info->psz_name = strdup( psz_name );
165             }
166
167             p_info = p_cat->pp_infos[i];
168             vasprintf( &p_info->psz_value, psz_format, args );
169
170             vlc_mutex_unlock( &p_input->p_item->lock );
171
172             i_ret = VLC_SUCCESS;
173
174             /* Notify playlist */
175             {
176                 vlc_value_t val;
177                 playlist_t *p_playlist =
178                 (playlist_t *)vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
179                                                FIND_PARENT );
180                 if( p_playlist )
181                 {
182                     val.i_int = p_playlist->i_index;
183                     var_Set( p_playlist, "item-change", val );
184                     vlc_object_release( p_playlist );
185                 }
186             }
187         }
188         break;
189
190         case INPUT_ADD_BOOKMARK:
191             p_bkmk = (seekpoint_t *)va_arg( args, seekpoint_t * );
192             p_bkmk = vlc_seekpoint_Duplicate( p_bkmk );
193             if( !p_bkmk->psz_name )
194             {
195                  asprintf( &p_bkmk->psz_name, _("Bookmark %i"),
196                            p_input->i_bookmarks );
197             }
198             TAB_APPEND( p_input->i_bookmarks, p_input->pp_bookmarks, p_bkmk );
199
200             /* Reflect the changes on the object var */
201             var_Change( p_input, "bookmark", VLC_VAR_CLEARCHOICES, 0, 0 );
202             {
203                 int i;
204                 for( i = 0; i < p_input->i_bookmarks; i++ )
205                 {
206                     val.i_int = i;
207                     text.psz_string = p_input->pp_bookmarks[i]->psz_name;
208                     var_Change( p_input, "bookmark", VLC_VAR_ADDCHOICE,
209                                 &val, &text );
210                 }
211             }
212
213             i_ret = VLC_SUCCESS;
214             break;
215
216         case INPUT_DEL_BOOKMARK:
217             i_bkmk = (int)va_arg( args, int );
218             if( i_bkmk < p_input->i_bookmarks )
219             {
220                 int i;
221                 p_bkmk = p_input->pp_bookmarks[i_bkmk];
222                 TAB_REMOVE( p_input->i_bookmarks, p_input->pp_bookmarks,
223                             p_bkmk );
224                 vlc_seekpoint_Delete( p_bkmk );
225
226                 /* Reflect the changes on the object var */
227                 var_Change( p_input, "bookmark", VLC_VAR_CLEARCHOICES, 0, 0 );
228                 for( i = 0; i < p_input->i_bookmarks; i++ )
229                 {
230                     val.i_int = i;
231                     text.psz_string = p_input->pp_bookmarks[i]->psz_name;
232                     var_Change( p_input, "bookmark", VLC_VAR_ADDCHOICE,
233                                 &val, &text );
234                 }
235                 i_ret = VLC_SUCCESS;
236             }
237             else i_ret = VLC_EGENERIC;
238             break;
239
240         case INPUT_GET_BOOKMARKS:
241             ppp_bkmk = (seekpoint_t ***)va_arg( args, seekpoint_t *** );
242             pi_bkmk = (int *)va_arg( args, int * );
243             if( p_input->i_bookmarks )
244             {
245                 int i;
246
247                 *pi_bkmk = p_input->i_bookmarks;
248                 *ppp_bkmk = malloc( sizeof(seekpoint_t *) *
249                               p_input->i_bookmarks );
250                 for( i = 0; i < p_input->i_bookmarks; i++ )
251                 {
252                     (*ppp_bkmk)[i] =
253                         vlc_seekpoint_Duplicate(p_input->pp_bookmarks[i]);
254                 }
255                 i_ret = VLC_SUCCESS;
256             }
257             else
258             {
259                 *ppp_bkmk = NULL;
260                 *pi_bkmk = 0;
261                 i_ret = VLC_EGENERIC;
262             }
263             break;
264
265         case INPUT_CLEAR_BOOKMARKS:
266             if( p_input->i_bookmarks )
267             {
268                 int i;
269
270                 for( i = p_input->i_bookmarks - 1; i >= 0; i-- )
271                 {
272                     p_bkmk = p_input->pp_bookmarks[i];
273                     TAB_REMOVE( p_input->i_bookmarks, p_input->pp_bookmarks,
274                                 p_bkmk );
275                     vlc_seekpoint_Delete( p_bkmk );
276                 }
277                 var_Change( p_input, "bookmark", VLC_VAR_CLEARCHOICES, 0, 0 );
278             }
279             i_ret = VLC_SUCCESS;
280             break;
281
282         case INPUT_SET_BOOKMARK:
283             i_bkmk = (int)va_arg( args, int );
284             if( i_bkmk >= 0 && i_bkmk < p_input->i_bookmarks )
285             {
286                 vlc_value_t pos;
287                 vlc_mutex_unlock( &p_input->stream.stream_lock );
288                 if( p_input->pp_bookmarks[i_bkmk]->i_byte_offset ||
289                     ( !p_input->pp_bookmarks[i_bkmk]->i_byte_offset &&
290                       !p_input->pp_bookmarks[i_bkmk]->i_time_offset ) )
291                 {
292                     pos.f_float = p_input->pp_bookmarks[i_bkmk]->i_byte_offset/
293                         (double)p_input->stream.p_selected_area->i_size;
294                     i_ret = var_Set( p_input, "position", pos );
295                 }
296                 else if( p_input->pp_bookmarks[i_bkmk]->i_time_offset )
297                 {
298                     pos.i_time = p_input->pp_bookmarks[i_bkmk]->i_time_offset;
299                     i_ret = var_Set( p_input, "time", pos );
300                 }
301                 vlc_mutex_lock( &p_input->stream.stream_lock );
302             }
303             else
304             {
305                 i_ret = VLC_EGENERIC;
306             }
307             break;
308
309         case INPUT_GET_SUBDELAY:
310             pi = (int*)va_arg( args, int *);
311             /* We work on the first subtitle */
312             if( p_input->p_sys != NULL )
313             {
314                 if( p_input->p_sys->i_sub > 0 )
315                 {
316                     i_ret = var_Get( (vlc_object_t *)p_input->p_sys->sub[0],
317                                       "sub-delay", &val );
318                     *pi = val.i_int;
319                 }
320                 else
321                 {
322                     msg_Dbg( p_input,"no subtitle track");
323                     i_ret = VLC_EGENERIC;
324                 }
325             }
326             else
327             {
328                 i_ret = VLC_EGENERIC;
329             }
330             break;
331
332         case INPUT_SET_SUBDELAY:
333             i = (int)va_arg( args, int );
334             /* We work on the first subtitle */
335             if( p_input->p_sys )
336             {
337                 if( p_input->p_sys->i_sub > 0 )
338                 {
339                     val.i_int = i;
340                     i_ret = var_Set( (vlc_object_t *)p_input->p_sys->sub[0],
341                                       "sub-delay", val );
342                 }
343                 else
344                 {
345                     msg_Dbg( p_input,"no subtitle track");
346                     i_ret = VLC_EGENERIC;
347                 }
348             }
349             else
350             {
351                 i_ret = VLC_EGENERIC;
352             }
353             break;
354
355         default:
356             msg_Err( p_input, "unknown query in input_vaControl" );
357             i_ret = VLC_EGENERIC;
358             break;
359     }
360     vlc_mutex_unlock( &p_input->stream.stream_lock );
361
362     return i_ret;
363 }