]> git.sesse.net Git - vlc/blob - src/interface/interaction.c
Very beginning of the interaction framework (Refs:#27)
[vlc] / src / interface / interaction.c
1 /*****************************************************************************
2  * interaction.c: User interaction functions
3  *****************************************************************************
4  * Copyright (C) 1998-2004 VideoLAN
5  * $Id: interface.c 10147 2005-03-05 17:18:30Z gbazin $
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@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 /**
25  *   \file
26  *   This file contains functions related to user interaction management
27  */
28
29
30 /*****************************************************************************
31  * Preamble
32  *****************************************************************************/
33 #include <stdlib.h>                                      /* free(), strtol() */
34 #include <stdio.h>                                                   /* FILE */
35 #include <string.h>                                            /* strerror() */
36
37 #include <vlc/vlc.h>
38 #include <vlc/input.h>
39
40 #include "vlc_interaction.h"
41 #include "vlc_interface.h"
42 #include "vlc_playlist.h"
43
44 static void intf_InteractionInit( playlist_t *p_playlist );
45 static int intf_WaitAnswer( intf_thread_t *p_intf, interaction_dialog_t *p_interact );
46 static int intf_Send( intf_thread_t *p_intf, interaction_dialog_t *p_interact );
47
48 /**
49  * Send an interaction element to the user
50  *
51  * \param p_this the calling vlc_object_t
52  * \param p_interact the interaction element
53  * \return VLC_SUCCESS or an error code
54  */
55 int  __intf_Interact( vlc_object_t *p_this, interaction_dialog_t *
56                                     p_interact )
57 {
58     vlc_list_t  *p_list;
59     int          i_index;
60     intf_thread_t *p_chosen_intf;
61
62
63     /* Search a suitable intf */
64     p_list = vlc_list_find( p_this, VLC_OBJECT_INTF, FIND_ANYWHERE );
65     if( !p_list )
66     {
67         msg_Err( p_this, "Unable to create module list" );
68         return VLC_FALSE;
69     }
70
71     p_chosen_intf = NULL;
72     for( i_index = 0; i_index < p_list->i_count; i_index ++ )
73     {
74         intf_thread_t *p_intf = (intf_thread_t *)
75                                         p_list->p_values[i_index].p_object;
76         if( p_intf->pf_interact != NULL )
77         {
78             p_chosen_intf = p_intf;
79             break;
80         }
81     }
82     if( !p_chosen_intf )
83     {
84         msg_Dbg( p_this, "No interface suitable for interaction" );
85         return VLC_FALSE;
86     }
87     msg_Dbg( p_this, "found an interface for interaction" );
88
89     /* Find id, if we don't already have one */
90     if( p_interact->i_id == 0 )
91     {
92         p_interact->i_id = ++p_chosen_intf->i_last_id;
93     }
94
95     if( p_interact->i_type == INTERACT_ASK )
96     {
97         return intf_WaitAnswer( p_chosen_intf, p_interact );
98     }
99     else
100     {
101         return intf_Send( p_chosen_intf, p_interact );
102     }
103 }
104
105 int intf_WaitAnswer( intf_thread_t *p_intf, interaction_dialog_t *p_interact )
106 {
107     // TODO: Add to queue, wait for answer
108     return VLC_SUCCESS;
109 }
110
111 int intf_Send( intf_thread_t *p_intf, interaction_dialog_t *p_interact )
112 {
113     // TODO: Add to queue, return
114     return VLC_SUCCESS;
115 }
116
117 // The playlist manages the user interaction to avoid creating another thread
118 void intf_InteractionManage( playlist_t *p_playlist )
119 {
120     if( p_playlist->p_interaction == NULL )
121     {
122         intf_InteractionInit( p_playlist );
123     }
124
125     vlc_mutex_lock( &p_playlist->p_interaction->object_lock );
126
127     /* Todo:
128      *    - Walk the queue
129      *    - If blocking
130      *       - If have answer, signal what is waiting (vlc_cond ? dangerous in case of pb ?)
131      *         And then, if not reusable, destroy
132      *    - If have update, send update
133      */
134
135     vlc_mutex_unlock( &p_playlist->p_interaction->object_lock );
136 }
137
138 static void intf_InteractionInit( playlist_t *p_playlist )
139 {
140     interaction_t *p_interaction;
141     p_interaction = vlc_object_create( VLC_OBJECT( p_playlist ), sizeof( interaction_t ) );
142     if( !p_interaction )
143     {
144         msg_Err( p_playlist,"out of memory" );
145         return;
146     }
147
148     p_interaction->i_dialogs = 0;
149     p_interaction->pp_dialogs = NULL;
150 }
151
152 /** Helper function to build a progress bar */
153 interaction_dialog_t *__intf_ProgressBuild( vlc_object_t *p_this,
154                                           const char *psz_text )
155 {
156     interaction_dialog_t *p_new = (interaction_dialog_t *)malloc(
157                                         sizeof( interaction_dialog_t ) );
158
159
160     return p_new;
161 }
162
163 #define INTERACT_INIT( new )                                            \
164         interaction_dialog_t *new = (interaction_dialog_t*)malloc(          \
165                                         sizeof( interaction_dialog_t ) ); \
166         new->i_widgets = 0;                                             \
167         new->pp_widgets = NULL;                                         \
168         new->psz_title = NULL;                                          \
169         new->psz_description = NULL;                                    \
170         new->i_id = 0;
171
172 #define INTERACT_FREE( new )                                            \
173         if( new->psz_title ) free( new->psz_title );                    \
174         if( new->psz_description ) free( new->psz_description );
175
176 /** Helper function to send a fatal message */
177 void intf_UserFatal( vlc_object_t *p_this, const char *psz_title,
178                      const char *psz_format, ... )
179 {
180     va_list args;
181
182     INTERACT_INIT( p_new );
183     p_new->i_type = INTERACT_FATAL;
184     p_new->psz_title = strdup( psz_title );
185
186     va_start( args, psz_format );
187     vasprintf( &p_new->psz_description, psz_format, args );
188     va_end( args );
189
190     intf_Interact( p_this, p_new );
191
192     INTERACT_FREE( p_new );
193 }