| 51 | | static void InteractionInit( playlist_t *p_playlist ); |
|---|
| 52 | | static interaction_t * InteractionGet( vlc_object_t *p_this ); |
|---|
| 53 | | static void InteractionSearchInterface( interaction_t * |
|---|
| 54 | | p_interaction ); |
|---|
| 55 | | static interaction_dialog_t *DialogGetById( interaction_t* , int ); |
|---|
| 56 | | static void DialogDestroy( interaction_dialog_t *p_dialog ); |
|---|
| 57 | | static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog ); |
|---|
| 58 | | |
|---|
| 59 | | /** |
|---|
| 60 | | * Destroy the interaction system |
|---|
| 61 | | * |
|---|
| 62 | | * \param The interaction object to destroy |
|---|
| | 45 | static interaction_t * InteractionInit( libvlc_int_t * ); |
|---|
| | 46 | static interaction_t * InteractionGet( vlc_object_t * ); |
|---|
| | 47 | static void InteractionSearchInterface( interaction_t * ); |
|---|
| | 48 | static void InteractionLoop( vlc_object_t * ); |
|---|
| | 49 | static void InteractionManage( interaction_t * ); |
|---|
| | 50 | |
|---|
| | 51 | static interaction_dialog_t *DialogGetById( interaction_t* , int ); |
|---|
| | 52 | static void DialogDestroy( interaction_dialog_t * ); |
|---|
| | 53 | static int DialogSend( vlc_object_t *, interaction_dialog_t * ); |
|---|
| | 54 | |
|---|
| | 55 | #define DIALOG_INIT( type ) \ |
|---|
| | 56 | DECMALLOC_ERR( p_new, interaction_dialog_t ); \ |
|---|
| | 57 | memset( p_new, 0, sizeof( interaction_dialog_t ) ); \ |
|---|
| | 58 | p_new->b_cancelled = VLC_FALSE; \ |
|---|
| | 59 | p_new->i_status = NEW_DIALOG; \ |
|---|
| | 60 | p_new->i_flags = 0; \ |
|---|
| | 61 | p_new->i_type = INTERACT_DIALOG_##type; \ |
|---|
| | 62 | p_new->psz_returned[0] = NULL; \ |
|---|
| | 63 | p_new->psz_returned[1] = NULL |
|---|
| | 64 | |
|---|
| | 65 | #define FORMAT_DESC \ |
|---|
| | 66 | va_start( args, psz_format ); \ |
|---|
| | 67 | if( vasprintf( &p_new->psz_description, psz_format, args ) == -1 ) \ |
|---|
| | 68 | return VLC_EGENERIC; \ |
|---|
| | 69 | va_end( args ) |
|---|
| | 70 | |
|---|
| | 71 | /** |
|---|
| | 72 | * Send an error message, both in a blocking and non-blocking way |
|---|
| | 73 | * |
|---|
| | 74 | * \param p_this Parent vlc_object |
|---|
| | 75 | * \param b_blocking Is this dialog blocking or not? |
|---|
| | 76 | * \param psz_title Title for the dialog |
|---|
| | 77 | * \param psz_format The message to display |
|---|
| | 78 | * \return VLC_SUCCESS or VLC_EGENERIC |
|---|
| | 79 | */ |
|---|
| | 80 | int __intf_UserFatal( vlc_object_t *p_this, vlc_bool_t b_blocking, |
|---|
| | 81 | const char *psz_title, |
|---|
| | 82 | const char *psz_format, ... ) |
|---|
| | 83 | { |
|---|
| | 84 | va_list args; |
|---|
| | 85 | DIALOG_INIT( ONEWAY ); |
|---|
| | 86 | |
|---|
| | 87 | p_new->psz_title = strdup( psz_title ); |
|---|
| | 88 | FORMAT_DESC; |
|---|
| | 89 | |
|---|
| | 90 | if( b_blocking ) |
|---|
| | 91 | p_new->i_flags = DIALOG_BLOCKING_ERROR; |
|---|
| | 92 | else |
|---|
| | 93 | p_new->i_flags = DIALOG_NONBLOCKING_ERROR; |
|---|
| | 94 | |
|---|
| | 95 | return DialogSend( p_this, p_new ); |
|---|
| | 96 | } |
|---|
| | 97 | |
|---|
| | 98 | /** |
|---|
| | 99 | * Helper function to send a warning, which is always shown non-blocking |
|---|
| | 100 | * |
|---|
| | 101 | * \param p_this Parent vlc_object |
|---|
| | 102 | * \param psz_title Title for the dialog |
|---|
| | 103 | * \param psz_format The message to display |
|---|
| | 104 | * \return VLC_SUCCESS or VLC_EGENERIC |
|---|
| | 105 | */ |
|---|
| | 106 | int __intf_UserWarn( vlc_object_t *p_this, |
|---|
| | 107 | const char *psz_title, |
|---|
| | 108 | const char *psz_format, ... ) |
|---|
| | 109 | { |
|---|
| | 110 | va_list args; |
|---|
| | 111 | DIALOG_INIT( ONEWAY ); |
|---|
| | 112 | |
|---|
| | 113 | p_new->psz_title = strdup( psz_title ); |
|---|
| | 114 | FORMAT_DESC; |
|---|
| | 115 | |
|---|
| | 116 | p_new->i_flags = DIALOG_WARNING; |
|---|
| | 117 | |
|---|
| | 118 | return DialogSend( p_this, p_new ); |
|---|
| | 119 | } |
|---|
| | 120 | |
|---|
| | 121 | /** |
|---|
| | 122 | * Helper function to ask a yes-no-cancel question |
|---|
| | 123 | * |
|---|
| | 124 | * \param p_this Parent vlc_object |
|---|
| | 125 | * \param psz_title Title for the dialog |
|---|
| | 126 | * \param psz_description A description |
|---|
| | 127 | * \param psz_default caption for the default button |
|---|
| | 128 | * \param psz_alternate caption for the alternate button |
|---|
| | 129 | * \param psz_other caption for the optional 3rd button (== cancel) |
|---|
| | 130 | * \return Clicked button code |
|---|
| | 131 | */ |
|---|
| | 132 | int __intf_UserYesNo( vlc_object_t *p_this, |
|---|
| | 133 | const char *psz_title, |
|---|
| | 134 | const char *psz_description, |
|---|
| | 135 | const char *psz_default, |
|---|
| | 136 | const char *psz_alternate, |
|---|
| | 137 | const char *psz_other ) |
|---|
| | 138 | { |
|---|
| | 139 | DIALOG_INIT( TWOWAY ); |
|---|
| | 140 | |
|---|
| | 141 | p_new->psz_title = strdup( psz_title ); |
|---|
| | 142 | p_new->psz_description = strdup( psz_description ); |
|---|
| | 143 | p_new->i_flags = DIALOG_YES_NO_CANCEL; |
|---|
| | 144 | p_new->psz_default_button = strdup( psz_default ); |
|---|
| | 145 | p_new->psz_alternate_button = strdup( psz_alternate ); |
|---|
| | 146 | if( psz_other ) |
|---|
| | 147 | p_new->psz_other_button = strdup( psz_other ); |
|---|
| | 148 | |
|---|
| | 149 | return DialogSend( p_this, p_new ); |
|---|
| | 150 | } |
|---|
| | 151 | |
|---|
| | 152 | /** |
|---|
| | 153 | * Helper function to create a dialogue showing a progress-bar with some info |
|---|
| | 154 | * |
|---|
| | 155 | * \param p_this Parent vlc_object |
|---|
| | 156 | * \param psz_title Title for the dialog (NULL implies main intf ) |
|---|
| | 157 | * \param psz_status Current status |
|---|
| | 158 | * \param f_position Current position (0.0->100.0) |
|---|
| | 159 | * \param i_timeToGo Time (in sec) to go until process is finished |
|---|
| | 160 | * \return Dialog id, to give to UserProgressUpdate |
|---|
| | 161 | */ |
|---|
| | 162 | int __intf_Progress( vlc_object_t *p_this, const char *psz_title, |
|---|
| | 163 | const char *psz_status, float f_pos, int i_time ) |
|---|
| | 164 | { |
|---|
| | 165 | DIALOG_INIT( ONEWAY ); |
|---|
| | 166 | p_new->psz_description = strdup( psz_status ); |
|---|
| | 167 | p_new->val.f_float = f_pos; |
|---|
| | 168 | p_new->i_timeToGo = i_time; |
|---|
| | 169 | p_new->psz_alternate_button = strdup( _( "Cancel" ) ); |
|---|
| | 170 | |
|---|
| | 171 | if( psz_title ) |
|---|
| | 172 | { |
|---|
| | 173 | p_new->psz_title = strdup( psz_title ); |
|---|
| | 174 | p_new->i_flags = DIALOG_USER_PROGRESS; |
|---|
| | 175 | } |
|---|
| | 176 | else |
|---|
| | 177 | p_new->i_flags = DIALOG_INTF_PROGRESS; |
|---|
| | 178 | |
|---|
| | 179 | DialogSend( p_this, p_new ); |
|---|
| | 180 | return p_new->i_id; |
|---|
| | 181 | } |
|---|
| | 182 | |
|---|
| | 183 | /** |
|---|
| | 184 | * Update a progress bar in a dialogue |
|---|
| | 185 | * |
|---|
| | 186 | * \param p_this Parent vlc_object |
|---|
| | 187 | * \param i_id Identifier of the dialog |
|---|
| | 188 | * \param psz_status New status |
|---|
| | 189 | * \param f_position New position (0.0->100.0) |
|---|
| | 190 | * \param i_timeToGo Time (in sec) to go until process is finished |
|---|
| | 191 | * \return nothing |
|---|
| | 192 | */ |
|---|
| | 193 | void __intf_ProgressUpdate( vlc_object_t *p_this, int i_id, |
|---|
| | 194 | const char *psz_status, float f_pos, int i_time ) |
|---|
| | 195 | { |
|---|
| | 196 | interaction_t *p_interaction = InteractionGet( p_this ); |
|---|
| | 197 | interaction_dialog_t *p_dialog; |
|---|
| | 198 | |
|---|
| | 199 | if( !p_interaction ) return; |
|---|
| | 200 | |
|---|
| | 201 | vlc_object_lock( p_interaction ); |
|---|
| | 202 | p_dialog = DialogGetById( p_interaction, i_id ); |
|---|
| | 203 | |
|---|
| | 204 | if( !p_dialog ) |
|---|
| | 205 | { |
|---|
| | 206 | vlc_object_unlock( p_interaction ); |
|---|
| | 207 | vlc_object_release( p_interaction ); |
|---|
| | 208 | return; |
|---|
| | 209 | } |
|---|
| | 210 | |
|---|
| | 211 | free( p_dialog->psz_description ); |
|---|
| | 212 | p_dialog->psz_description = strdup( psz_status ); |
|---|
| | 213 | |
|---|
| | 214 | p_dialog->val.f_float = f_pos; |
|---|
| | 215 | p_dialog->i_timeToGo = i_time; |
|---|
| | 216 | |
|---|
| | 217 | p_dialog->i_status = UPDATED_DIALOG; |
|---|
| | 218 | |
|---|
| | 219 | vlc_object_signal_unlocked( p_interaction ); |
|---|
| | 220 | vlc_object_unlock( p_interaction ); |
|---|
| | 221 | vlc_object_release( p_interaction ); |
|---|
| | 222 | } |
|---|
| | 223 | |
|---|
| | 224 | /** |
|---|
| | 225 | * Helper function to communicate dialogue cancellations between the |
|---|
| | 226 | * interface module and the caller |
|---|
| | 227 | * |
|---|
| | 228 | * \param p_this Parent vlc_object |
|---|
| | 229 | * \param i_id Identifier of the dialogue |
|---|
| | 230 | * \return Either true or false |
|---|
| | 231 | */ |
|---|
| | 232 | vlc_bool_t __intf_UserProgressIsCancelled( vlc_object_t *p_this, int i_id ) |
|---|
| | 233 | { |
|---|
| | 234 | interaction_t *p_interaction = InteractionGet( p_this ); |
|---|
| | 235 | interaction_dialog_t *p_dialog; |
|---|
| | 236 | vlc_bool_t b_cancel; |
|---|
| | 237 | |
|---|
| | 238 | if( !p_interaction ) return VLC_TRUE; |
|---|
| | 239 | |
|---|
| | 240 | vlc_object_lock( p_interaction ); |
|---|
| | 241 | p_dialog = DialogGetById( p_interaction, i_id ); |
|---|
| | 242 | if( !p_dialog ) |
|---|
| | 243 | { |
|---|
| | 244 | vlc_object_unlock( p_interaction ) ; |
|---|
| | 245 | vlc_object_release( p_interaction ); |
|---|
| | 246 | return VLC_TRUE; |
|---|
| | 247 | } |
|---|
| | 248 | |
|---|
| | 249 | b_cancel = p_dialog->b_cancelled; |
|---|
| | 250 | vlc_object_unlock( p_interaction ); |
|---|
| | 251 | vlc_object_release( p_interaction ); |
|---|
| | 252 | return b_cancel; |
|---|
| | 253 | } |
|---|
| | 254 | |
|---|
| | 255 | /** |
|---|
| | 256 | * Helper function to make a login/password dialogue |
|---|
| | 257 | * |
|---|
| | 258 | * \param p_this Parent vlc_object |
|---|
| | 259 | * \param psz_title Title for the dialog |
|---|
| | 260 | * \param psz_description A description |
|---|
| | 261 | * \param ppsz_login Returned login |
|---|
| | 262 | * \param ppsz_password Returned password |
|---|
| | 263 | * \return Clicked button code |
|---|
| | 264 | */ |
|---|
| | 265 | int __intf_UserLoginPassword( vlc_object_t *p_this, |
|---|
| | 266 | const char *psz_title, |
|---|
| | 267 | const char *psz_description, |
|---|
| | 268 | char **ppsz_login, |
|---|
| | 269 | char **ppsz_password ) |
|---|
| | 270 | { |
|---|
| | 271 | int i_ret; |
|---|
| | 272 | DIALOG_INIT( TWOWAY ); |
|---|
| | 273 | p_new->i_type = INTERACT_DIALOG_TWOWAY; |
|---|
| | 274 | p_new->psz_title = strdup( psz_title ); |
|---|
| | 275 | p_new->psz_description = strdup( psz_description ); |
|---|
| | 276 | p_new->psz_default_button = strdup( _("Ok" ) ); |
|---|
| | 277 | p_new->psz_alternate_button = strdup( _("Cancel" ) ); |
|---|
| | 278 | |
|---|
| | 279 | p_new->i_flags = DIALOG_LOGIN_PW_OK_CANCEL; |
|---|
| | 280 | |
|---|
| | 281 | i_ret = DialogSend( p_this, p_new ); |
|---|
| | 282 | |
|---|
| | 283 | if( i_ret != DIALOG_CANCELLED && i_ret != VLC_EGENERIC ) |
|---|
| | 284 | { |
|---|
| | 285 | *ppsz_login = p_new->psz_returned[0]? |
|---|
| | 286 | strdup( p_new->psz_returned[0] ) : NULL; |
|---|
| | 287 | *ppsz_password = p_new->psz_returned[1]? |
|---|
| | 288 | strdup( p_new->psz_returned[1] ) : NULL; |
|---|
| | 289 | } |
|---|
| | 290 | return i_ret; |
|---|
| | 291 | } |
|---|
| | 292 | |
|---|
| | 293 | /** |
|---|
| | 294 | * Helper function to make a dialogue asking the user for !password string |
|---|
| | 295 | * |
|---|
| | 296 | * \param p_this Parent vlc_object |
|---|
| | 297 | * \param psz_title Title for the dialog |
|---|
| | 298 | * \param psz_description A description |
|---|
| | 299 | * \param ppsz_usersString Returned login |
|---|
| | 300 | * \return Clicked button code |
|---|
| | 301 | */ |
|---|
| | 302 | int __intf_UserStringInput( vlc_object_t *p_this, |
|---|
| | 303 | const char *psz_title, |
|---|
| | 304 | const char *psz_description, |
|---|
| | 305 | char **ppsz_usersString ) |
|---|
| | 306 | { |
|---|
| | 307 | int i_ret; |
|---|
| | 308 | DIALOG_INIT( TWOWAY ); |
|---|
| | 309 | p_new->i_type = INTERACT_DIALOG_TWOWAY; |
|---|
| | 310 | p_new->psz_title = strdup( psz_title ); |
|---|
| | 311 | p_new->psz_description = strdup( psz_description ); |
|---|
| | 312 | |
|---|
| | 313 | p_new->i_flags = DIALOG_PSZ_INPUT_OK_CANCEL; |
|---|
| | 314 | |
|---|
| | 315 | i_ret = DialogSend( p_this, p_new ); |
|---|
| | 316 | |
|---|
| | 317 | if( i_ret != DIALOG_CANCELLED ) |
|---|
| | 318 | { |
|---|
| | 319 | *ppsz_usersString = p_new->psz_returned[0]? |
|---|
| | 320 | strdup( p_new->psz_returned[0] ) : NULL; |
|---|
| | 321 | } |
|---|
| | 322 | return i_ret; |
|---|
| | 323 | } |
|---|
| | 324 | |
|---|
| | 325 | /** |
|---|
| | 326 | * Hide an interaction dialog |
|---|
| | 327 | * |
|---|
| | 328 | * \param p_this the parent vlc object |
|---|
| | 329 | * \param i_id the id of the item to hide |
|---|
| 65 | | void intf_InteractionDestroy( interaction_t *p_interaction ) |
|---|
| | 332 | void __intf_UserHide( vlc_object_t *p_this, int i_id ) |
|---|
| | 333 | { |
|---|
| | 334 | interaction_t *p_interaction = InteractionGet( p_this ); |
|---|
| | 335 | interaction_dialog_t *p_dialog; |
|---|
| | 336 | |
|---|
| | 337 | if( !p_interaction ) return; |
|---|
| | 338 | |
|---|
| | 339 | vlc_object_lock( p_interaction ); |
|---|
| | 340 | p_dialog = DialogGetById( p_interaction, i_id ); |
|---|
| | 341 | |
|---|
| | 342 | if( p_dialog ) |
|---|
| | 343 | p_dialog->i_status = ANSWERED_DIALOG; |
|---|
| | 344 | |
|---|
| | 345 | vlc_object_unlock( p_interaction ); |
|---|
| | 346 | vlc_object_release( p_interaction ); |
|---|
| | 347 | } |
|---|
| | 348 | |
|---|
| | 349 | /********************************************************************** |
|---|
| | 350 | * The following functions are local |
|---|
| | 351 | **********************************************************************/ |
|---|
| | 352 | |
|---|
| | 353 | /* Get the interaction object. Create it if needed */ |
|---|
| | 354 | static interaction_t * InteractionGet( vlc_object_t *p_this ) |
|---|
| | 355 | { |
|---|
| | 356 | interaction_t *p_interaction = |
|---|
| | 357 | vlc_object_find( p_this, VLC_OBJECT_INTERACTION, FIND_ANYWHERE ); |
|---|
| | 358 | |
|---|
| | 359 | if( !p_interaction ) |
|---|
| | 360 | p_interaction = InteractionInit( p_this->p_libvlc ); |
|---|
| | 361 | |
|---|
| | 362 | return p_interaction; |
|---|
| | 363 | } |
|---|
| | 364 | |
|---|
| | 365 | /* Create the interaction object in the given playlist object */ |
|---|
| | 366 | static interaction_t * InteractionInit( libvlc_int_t *p_libvlc ) |
|---|
| | 367 | { |
|---|
| | 368 | interaction_t *p_interaction = |
|---|
| | 369 | vlc_object_create( p_libvlc, VLC_OBJECT_INTERACTION ); |
|---|
| | 370 | |
|---|
| | 371 | if( p_interaction ) |
|---|
| | 372 | { |
|---|
| | 373 | vlc_object_attach( p_interaction, p_libvlc ); |
|---|
| | 374 | |
|---|
| | 375 | p_interaction->i_dialogs = 0; |
|---|
| | 376 | p_interaction->pp_dialogs = NULL; |
|---|
| | 377 | p_interaction->p_intf = NULL; |
|---|
| | 378 | p_interaction->i_last_id = 0; |
|---|
| | 379 | |
|---|
| | 380 | if( vlc_thread_create( p_interaction, "Interaction control", |
|---|
| | 381 | InteractionLoop, VLC_THREAD_PRIORITY_LOW, |
|---|
| | 382 | VLC_FALSE ) ) |
|---|
| | 383 | { |
|---|
| | 384 | msg_Err( p_interaction, "Interaction control thread creation failed" |
|---|
| | 385 | ", interaction will not be displayed" ); |
|---|
| | 386 | vlc_object_detach( p_interaction ); |
|---|
| | 387 | vlc_object_release( p_interaction ); |
|---|
| | 388 | p_interaction = NULL; |
|---|
| | 389 | } |
|---|
| | 390 | else |
|---|
| | 391 | vlc_object_yield( p_interaction ); |
|---|
| | 392 | } |
|---|
| | 393 | |
|---|
| | 394 | return p_interaction; |
|---|
| | 395 | } |
|---|
| | 396 | |
|---|
| | 397 | /* Look for an interface suitable for interaction */ |
|---|
| | 398 | static void InteractionSearchInterface( interaction_t *p_interaction ) |
|---|
| | 399 | { |
|---|
| | 400 | vlc_list_t *p_list; |
|---|
| | 401 | int i_index; |
|---|
| | 402 | |
|---|
| | 403 | p_interaction->p_intf = NULL; |
|---|
| | 404 | |
|---|
| | 405 | p_list = vlc_list_find( p_interaction, VLC_OBJECT_INTF, FIND_ANYWHERE ); |
|---|
| | 406 | if( !p_list ) |
|---|
| | 407 | { |
|---|
| | 408 | msg_Err( p_interaction, "unable to create module list" ); |
|---|
| | 409 | return; |
|---|
| | 410 | } |
|---|
| | 411 | |
|---|
| | 412 | for( i_index = 0; i_index < p_list->i_count; i_index ++ ) |
|---|
| | 413 | { |
|---|
| | 414 | intf_thread_t *p_intf = (intf_thread_t *) |
|---|
| | 415 | p_list->p_values[i_index].p_object; |
|---|
| | 416 | if( p_intf->b_interaction ) |
|---|
| | 417 | { |
|---|
| | 418 | p_interaction->p_intf = p_intf; |
|---|
| | 419 | break; |
|---|
| | 420 | } |
|---|
| | 421 | } |
|---|
| | 422 | vlc_list_release ( p_list ); |
|---|
| | 423 | } |
|---|
| | 424 | |
|---|
| | 425 | /* Find an interaction dialog by its id */ |
|---|
| | 426 | static interaction_dialog_t *DialogGetById( interaction_t *p_interaction, |
|---|
| | 427 | int i_id ) |
|---|
| 68 | | // Remove all dialogs - Interfaces must be able to clean up their data |
|---|
| | 430 | for( i = 0 ; i< p_interaction->i_dialogs; i++ ) |
|---|
| | 431 | { |
|---|
| | 432 | if( p_interaction->pp_dialogs[i]->i_id == i_id ) |
|---|
| | 433 | return p_interaction->pp_dialogs[i]; |
|---|
| | 434 | } |
|---|
| | 435 | return NULL; |
|---|
| | 436 | } |
|---|
| | 437 | |
|---|
| | 438 | /* Destroy a dialog */ |
|---|
| | 439 | static void DialogDestroy( interaction_dialog_t *p_dialog ) |
|---|
| | 440 | { |
|---|
| | 441 | free( p_dialog->psz_title ); |
|---|
| | 442 | free( p_dialog->psz_description ); |
|---|
| | 443 | free( p_dialog->psz_default_button ); |
|---|
| | 444 | free( p_dialog->psz_alternate_button ); |
|---|
| | 445 | free( p_dialog->psz_other_button ); |
|---|
| | 446 | free( p_dialog ); |
|---|
| | 447 | } |
|---|
| | 448 | |
|---|
| | 449 | /* Ask for the dialog to be sent to the user. Wait for answer |
|---|
| | 450 | * if required */ |
|---|
| | 451 | static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog ) |
|---|
| | 452 | { |
|---|
| | 453 | interaction_t *p_interaction = InteractionGet( p_this ); |
|---|
| | 454 | |
|---|
| | 455 | /* Get an id, if we don't already have one */ |
|---|
| | 456 | if( p_dialog->i_id == 0 ) |
|---|
| | 457 | p_dialog->i_id = ++p_interaction->i_last_id; |
|---|
| | 458 | |
|---|
| | 459 | if( p_this->i_flags & OBJECT_FLAGS_NOINTERACT ) return VLC_EGENERIC; |
|---|
| | 460 | |
|---|
| | 461 | if( config_GetInt( p_this, "interact" ) || |
|---|
| | 462 | p_dialog->i_flags & DIALOG_BLOCKING_ERROR || |
|---|
| | 463 | p_dialog->i_flags & DIALOG_NONBLOCKING_ERROR ) |
|---|
| | 464 | { |
|---|
| | 465 | vlc_bool_t b_found = VLC_FALSE; |
|---|
| | 466 | int i; |
|---|
| | 467 | p_dialog->p_interaction = p_interaction; |
|---|
| | 468 | p_dialog->p_parent = p_this; |
|---|
| | 469 | |
|---|
| | 470 | /* Check if we have already added this dialog */ |
|---|
| | 471 | vlc_object_lock( p_interaction ); |
|---|
| | 472 | for( i = 0 ; i< p_interaction->i_dialogs; i++ ) |
|---|
| | 473 | { |
|---|
| | 474 | if( p_interaction->pp_dialogs[i]->i_id == p_dialog->i_id ) |
|---|
| | 475 | b_found = VLC_TRUE; |
|---|
| | 476 | } |
|---|
| | 477 | /* Add it to the queue, the main loop will send the orders to the |
|---|
| | 478 | * interface */ |
|---|
| | 479 | if( ! b_found ) |
|---|
| | 480 | { |
|---|
| | 481 | INSERT_ELEM( p_interaction->pp_dialogs, |
|---|
| | 482 | p_interaction->i_dialogs, |
|---|
| | 483 | p_interaction->i_dialogs, |
|---|
| | 484 | p_dialog ); |
|---|
| | 485 | } |
|---|
| | 486 | else |
|---|
| | 487 | p_dialog->i_status = UPDATED_DIALOG; |
|---|
| | 488 | |
|---|
| | 489 | if( p_dialog->i_type == INTERACT_DIALOG_TWOWAY ) /* Wait for answer */ |
|---|
| | 490 | { |
|---|
| | 491 | vlc_object_signal_unlocked( p_interaction ); |
|---|
| | 492 | while( p_dialog->i_status != ANSWERED_DIALOG && |
|---|
| | 493 | p_dialog->i_status != HIDING_DIALOG && |
|---|
| | 494 | p_dialog->i_status != HIDDEN_DIALOG && |
|---|
| | 495 | !p_dialog->p_parent->b_die ) |
|---|
| | 496 | { |
|---|
| | 497 | vlc_object_unlock( p_interaction ); |
|---|
| | 498 | msleep( 100000 ); |
|---|
| | 499 | vlc_object_lock( p_interaction ); |
|---|
| | 500 | } |
|---|
| | 501 | if( p_dialog->p_parent->b_die ) |
|---|
| | 502 | { |
|---|
| | 503 | p_dialog->i_return = DIALOG_CANCELLED; |
|---|
| | 504 | p_dialog->i_status = ANSWERED_DIALOG; |
|---|
| | 505 | } |
|---|
| | 506 | p_dialog->i_flags |= DIALOG_GOT_ANSWER; |
|---|
| | 507 | vlc_object_signal_unlocked( p_interaction ); |
|---|
| | 508 | vlc_object_unlock( p_interaction ); |
|---|
| | 509 | vlc_object_release( p_interaction ); |
|---|
| | 510 | return p_dialog->i_return; |
|---|
| | 511 | } |
|---|
| | 512 | else |
|---|
| | 513 | { |
|---|
| | 514 | /* Pretend we already retrieved the "answer" */ |
|---|
| | 515 | p_dialog->i_flags |= DIALOG_GOT_ANSWER; |
|---|
| | 516 | vlc_object_signal_unlocked( p_interaction ); |
|---|
| | 517 | vlc_object_unlock( p_interaction ); |
|---|
| | 518 | vlc_object_release( p_interaction ); |
|---|
| | 519 | return VLC_SUCCESS; |
|---|
| | 520 | } |
|---|
| | 521 | } |
|---|
| | 522 | else |
|---|
| | 523 | { |
|---|
| | 524 | vlc_object_release( p_interaction ); |
|---|
| | 525 | return VLC_EGENERIC; |
|---|
| | 526 | } |
|---|
| | 527 | } |
|---|
| | 528 | |
|---|
| | 529 | static void InteractionLoop( vlc_object_t *p_this ) |
|---|
| | 530 | { |
|---|
| | 531 | int i; |
|---|
| | 532 | interaction_t *p_interaction = (interaction_t*) p_this; |
|---|
| | 533 | |
|---|
| | 534 | while( !p_this->b_die ) |
|---|
| | 535 | { |
|---|
| | 536 | vlc_object_lock( p_this ); |
|---|
| | 537 | if( vlc_object_wait( p_this ) ) |
|---|
| | 538 | { |
|---|
| | 539 | vlc_object_unlock( p_this ); |
|---|
| | 540 | break; |
|---|
| | 541 | } |
|---|
| | 542 | InteractionManage( p_interaction ); |
|---|
| | 543 | vlc_object_unlock( p_this ); |
|---|
| | 544 | } |
|---|
| | 545 | |
|---|
| | 546 | /* Remove all dialogs - Interfaces must be able to clean up their data */ |
|---|
| 163 | | } |
|---|
| 164 | | |
|---|
| 165 | | vlc_mutex_unlock( &p_playlist->p_interaction->object_lock ); |
|---|
| 166 | | } |
|---|
| 167 | | |
|---|
| 168 | | #define DIALOG_INIT( type ) \ |
|---|
| 169 | | DECMALLOC_ERR( p_new, interaction_dialog_t ); \ |
|---|
| 170 | | memset( p_new, 0, sizeof( interaction_dialog_t ) ); \ |
|---|
| 171 | | p_new->b_cancelled = VLC_FALSE; \ |
|---|
| 172 | | p_new->i_status = NEW_DIALOG; \ |
|---|
| 173 | | p_new->i_flags = 0; \ |
|---|
| 174 | | p_new->i_type = INTERACT_DIALOG_##type; \ |
|---|
| 175 | | p_new->psz_returned[0] = NULL; \ |
|---|
| 176 | | p_new->psz_returned[1] = NULL; |
|---|
| 177 | | |
|---|
| 178 | | #define FORMAT_DESC \ |
|---|
| 179 | | va_start( args, psz_format ); \ |
|---|
| 180 | | vasprintf( &p_new->psz_description, psz_format, args ); \ |
|---|
| 181 | | va_end( args ); |
|---|
| 182 | | |
|---|
| 183 | | /** |
|---|
| 184 | | * Send an error message, both in a blocking and non-blocking way |
|---|
| 185 | | * |
|---|
| 186 | | * \param p_this Parent vlc_object |
|---|
| 187 | | * \param b_blocking Is this dialog blocking or not? |
|---|
| 188 | | * \param psz_title Title for the dialog |
|---|
| 189 | | * \param psz_format The message to display |
|---|
| 190 | | * \return VLC_SUCCESS or VLC_EGENERIC |
|---|
| 191 | | */ |
|---|
| 192 | | int __intf_UserFatal( vlc_object_t *p_this, vlc_bool_t b_blocking, |
|---|
| 193 | | const char *psz_title, |
|---|
| 194 | | const char *psz_format, ... ) |
|---|
| 195 | | { |
|---|
| 196 | | va_list args; |
|---|
| 197 | | DIALOG_INIT( ONEWAY ); |
|---|
| 198 | | |
|---|
| 199 | | p_new->psz_title = strdup( psz_title ); |
|---|
| 200 | | FORMAT_DESC; |
|---|
| 201 | | |
|---|
| 202 | | if( b_blocking ) |
|---|
| 203 | | p_new->i_flags = DIALOG_BLOCKING_ERROR; |
|---|
| 204 | | else |
|---|
| 205 | | p_new->i_flags = DIALOG_NONBLOCKING_ERROR; |
|---|
| 206 | | |
|---|
| 207 | | return DialogSend( p_this, p_new ); |
|---|
| 208 | | } |
|---|
| 209 | | |
|---|
| 210 | | /** |
|---|
| 211 | | * Helper function to send a warning, which is always shown non-blocking |
|---|
| 212 | | * |
|---|
| 213 | | * \param p_this Parent vlc_object |
|---|
| 214 | | * \param psz_title Title for the dialog |
|---|
| 215 | | * \param psz_format The message to display |
|---|
| 216 | | * \return VLC_SUCCESS or VLC_EGENERIC |
|---|
| 217 | | */ |
|---|
| 218 | | int __intf_UserWarn( vlc_object_t *p_this, |
|---|
| 219 | | const char *psz_title, |
|---|
| 220 | | const char *psz_format, ... ) |
|---|
| 221 | | { |
|---|
| 222 | | va_list args; |
|---|
| 223 | | DIALOG_INIT( ONEWAY ); |
|---|
| 224 | | |
|---|
| 225 | | p_new->psz_title = strdup( psz_title ); |
|---|
| 226 | | FORMAT_DESC |
|---|
| 227 | | |
|---|
| 228 | | p_new->i_flags = DIALOG_WARNING; |
|---|
| 229 | | |
|---|
| 230 | | return DialogSend( p_this, p_new ); |
|---|
| 231 | | } |
|---|
| 232 | | |
|---|
| 233 | | /** |
|---|
| 234 | | * Helper function to ask a yes-no-cancel question |
|---|
| 235 | | * |
|---|
| 236 | | * \param p_this Parent vlc_object |
|---|
| 237 | | * \param psz_title Title for the dialog |
|---|
| 238 | | * \param psz_description A description |
|---|
| 239 | | * \param psz_default caption for the default button |
|---|
| 240 | | * \param psz_alternate caption for the alternate button |
|---|
| 241 | | * \param psz_other caption for the optional 3rd button (== cancel) |
|---|
| 242 | | * \return Clicked button code |
|---|
| 243 | | */ |
|---|
| 244 | | int __intf_UserYesNo( vlc_object_t *p_this, |
|---|
| 245 | | const char *psz_title, |
|---|
| 246 | | const char *psz_description, |
|---|
| 247 | | const char *psz_default, |
|---|
| 248 | | const char *psz_alternate, |
|---|
| 249 | | const char *psz_other ) |
|---|
| 250 | | { |
|---|
| 251 | | DIALOG_INIT( TWOWAY ); |
|---|
| 252 | | |
|---|
| 253 | | p_new->psz_title = strdup( psz_title ); |
|---|
| 254 | | p_new->psz_description = strdup( psz_description ); |
|---|
| 255 | | p_new->i_flags = DIALOG_YES_NO_CANCEL; |
|---|
| 256 | | p_new->psz_default_button = strdup( psz_default ); |
|---|
| 257 | | p_new->psz_alternate_button = strdup( psz_alternate ); |
|---|
| 258 | | if( psz_other ) |
|---|
| 259 | | p_new->psz_other_button = strdup( psz_other ); |
|---|
| 260 | | |
|---|
| 261 | | return DialogSend( p_this, p_new ); |
|---|
| 262 | | } |
|---|
| 263 | | |
|---|
| 264 | | /** |
|---|
| 265 | | * Helper function to create a dialogue showing a progress-bar with some info |
|---|
| 266 | | * |
|---|
| 267 | | * \param p_this Parent vlc_object |
|---|
| 268 | | * \param psz_title Title for the dialog (NULL implies main intf ) |
|---|
| 269 | | * \param psz_status Current status |
|---|
| 270 | | * \param f_position Current position (0.0->100.0) |
|---|
| 271 | | * \param i_timeToGo Time (in sec) to go until process is finished |
|---|
| 272 | | * \return Dialog id, to give to UserProgressUpdate |
|---|
| 273 | | */ |
|---|
| 274 | | int __intf_Progress( vlc_object_t *p_this, const char *psz_title, |
|---|
| 275 | | const char *psz_status, float f_pos, int i_time ) |
|---|
| 276 | | { |
|---|
| 277 | | DIALOG_INIT( ONEWAY ); |
|---|
| 278 | | p_new->psz_description = strdup( psz_status ); |
|---|
| 279 | | p_new->val.f_float = f_pos; |
|---|
| 280 | | p_new->i_timeToGo = i_time; |
|---|
| 281 | | p_new->psz_alternate_button = strdup( _( "Cancel" ) ); |
|---|
| 282 | | |
|---|
| 283 | | if( psz_title ) |
|---|
| 284 | | { |
|---|
| 285 | | p_new->psz_title = strdup( psz_title ); |
|---|
| 286 | | p_new->i_flags = DIALOG_USER_PROGRESS; |
|---|
| 287 | | } |
|---|
| 288 | | else |
|---|
| 289 | | p_new->i_flags = DIALOG_INTF_PROGRESS; |
|---|
| 290 | | |
|---|
| 291 | | DialogSend( p_this, p_new ); |
|---|
| 292 | | return p_new->i_id; |
|---|
| 293 | | } |
|---|
| 294 | | |
|---|
| 295 | | /** |
|---|
| 296 | | * Update a progress bar in a dialogue |
|---|
| 297 | | * |
|---|
| 298 | | * \param p_this Parent vlc_object |
|---|
| 299 | | * \param i_id Identifier of the dialog |
|---|
| 300 | | * \param psz_status New status |
|---|
| 301 | | * \param f_position New position (0.0->100.0) |
|---|
| 302 | | * \param i_timeToGo Time (in sec) to go until process is finished |
|---|
| 303 | | * \return nothing |
|---|
| 304 | | */ |
|---|
| 305 | | void __intf_ProgressUpdate( vlc_object_t *p_this, int i_id, |
|---|
| 306 | | const char *psz_status, float f_pos, int i_time ) |
|---|
| 307 | | { |
|---|
| 308 | | interaction_t *p_interaction = InteractionGet( p_this ); |
|---|
| 309 | | interaction_dialog_t *p_dialog; |
|---|
| 310 | | |
|---|
| 311 | | if( !p_interaction ) return; |
|---|
| 312 | | |
|---|
| 313 | | vlc_mutex_lock( &p_interaction->object_lock ); |
|---|
| 314 | | p_dialog = DialogGetById( p_interaction, i_id ); |
|---|
| 315 | | |
|---|
| 316 | | if( !p_dialog ) |
|---|
| 317 | | { |
|---|
| 318 | | vlc_mutex_unlock( &p_interaction->object_lock ) ; |
|---|
| 319 | | return; |
|---|
| 320 | | } |
|---|
| 321 | | |
|---|
| 322 | | free( p_dialog->psz_description ); |
|---|
| 323 | | p_dialog->psz_description = strdup( psz_status ); |
|---|
| 324 | | |
|---|
| 325 | | p_dialog->val.f_float = f_pos; |
|---|
| 326 | | p_dialog->i_timeToGo = i_time; |
|---|
| 327 | | |
|---|
| 328 | | p_dialog->i_status = UPDATED_DIALOG; |
|---|
| 329 | | vlc_mutex_unlock( &p_interaction->object_lock) ; |
|---|
| 330 | | |
|---|
| 331 | | playlist_Signal( pl_Get( p_this ) ); |
|---|
| 332 | | } |
|---|
| 333 | | |
|---|
| 334 | | /** |
|---|
| 335 | | * Helper function to communicate dialogue cancellations between the |
|---|
| 336 | | * interface module and the caller |
|---|
| 337 | | * |
|---|
| 338 | | * \param p_this Parent vlc_object |
|---|
| 339 | | * \param i_id Identifier of the dialogue |
|---|
| 340 | | * \return Either true or false |
|---|
| 341 | | */ |
|---|
| 342 | | vlc_bool_t __intf_UserProgressIsCancelled( vlc_object_t *p_this, int i_id ) |
|---|
| 343 | | { |
|---|
| 344 | | interaction_t *p_interaction = InteractionGet( p_this ); |
|---|
| 345 | | interaction_dialog_t *p_dialog; |
|---|
| 346 | | vlc_bool_t b_cancel; |
|---|
| 347 | | |
|---|
| 348 | | if( !p_interaction ) return VLC_TRUE; |
|---|
| 349 | | |
|---|
| 350 | | vlc_mutex_lock( &p_interaction->object_lock ); |
|---|
| 351 | | p_dialog = DialogGetById( p_interaction, i_id ); |
|---|
| 352 | | if( !p_dialog ) |
|---|
| 353 | | { |
|---|
| 354 | | vlc_mutex_unlock( &p_interaction->object_lock ) ; |
|---|
| 355 | | return VLC_TRUE; |
|---|
| 356 | | } |
|---|
| 357 | | |
|---|
| 358 | | b_cancel = p_dialog->b_cancelled; |
|---|
| 359 | | vlc_mutex_unlock( &p_interaction->object_lock ); |
|---|
| 360 | | return b_cancel; |
|---|
| 361 | | } |
|---|
| 362 | | |
|---|
| 363 | | /** |
|---|
| 364 | | * Helper function to make a login/password dialogue |
|---|
| 365 | | * |
|---|
| 366 | | * \param p_this Parent vlc_object |
|---|
| 367 | | * \param psz_title Title for the dialog |
|---|
| 368 | | * \param psz_description A description |
|---|
| 369 | | * \param ppsz_login Returned login |
|---|
| 370 | | * \param ppsz_password Returned password |
|---|
| 371 | | * \return Clicked button code |
|---|
| 372 | | */ |
|---|
| 373 | | int __intf_UserLoginPassword( vlc_object_t *p_this, |
|---|
| 374 | | const char *psz_title, |
|---|
| 375 | | const char *psz_description, |
|---|
| 376 | | char **ppsz_login, |
|---|
| 377 | | char **ppsz_password ) |
|---|
| 378 | | { |
|---|
| 379 | | int i_ret; |
|---|
| 380 | | DIALOG_INIT( TWOWAY ); |
|---|
| 381 | | p_new->i_type = INTERACT_DIALOG_TWOWAY; |
|---|
| 382 | | p_new->psz_title = strdup( psz_title ); |
|---|
| 383 | | p_new->psz_description = strdup( psz_description ); |
|---|
| 384 | | p_new->psz_default_button = strdup( _("Ok" ) ); |
|---|
| 385 | | p_new->psz_alternate_button = strdup( _("Cancel" ) ); |
|---|
| 386 | | |
|---|
| 387 | | p_new->i_flags = DIALOG_LOGIN_PW_OK_CANCEL; |
|---|
| 388 | | |
|---|
| 389 | | i_ret = DialogSend( p_this, p_new ); |
|---|
| 390 | | |
|---|
| 391 | | if( i_ret != DIALOG_CANCELLED && i_ret != VLC_EGENERIC ) |
|---|
| 392 | | { |
|---|
| 393 | | *ppsz_login = p_new->psz_returned[0]? |
|---|
| 394 | | strdup( p_new->psz_returned[0] ) : NULL; |
|---|
| 395 | | *ppsz_password = p_new->psz_returned[1]? |
|---|
| 396 | | strdup( p_new->psz_returned[1] ) : NULL; |
|---|
| 397 | | } |
|---|
| 398 | | return i_ret; |
|---|
| 399 | | } |
|---|
| 400 | | |
|---|
| 401 | | /** |
|---|
| 402 | | * Helper function to make a dialogue asking the user for !password string |
|---|
| 403 | | * |
|---|
| 404 | | * \param p_this Parent vlc_object |
|---|
| 405 | | * \param psz_title Title for the dialog |
|---|
| 406 | | * \param psz_description A description |
|---|
| 407 | | * \param ppsz_usersString Returned login |
|---|
| 408 | | * \return Clicked button code |
|---|
| 409 | | */ |
|---|
| 410 | | int __intf_UserStringInput( vlc_object_t *p_this, |
|---|
| 411 | | const char *psz_title, |
|---|
| 412 | | const char *psz_description, |
|---|
| 413 | | char **ppsz_usersString ) |
|---|
| 414 | | { |
|---|
| 415 | | int i_ret; |
|---|
| 416 | | DIALOG_INIT( TWOWAY ); |
|---|
| 417 | | p_new->i_type = INTERACT_DIALOG_TWOWAY; |
|---|
| 418 | | p_new->psz_title = strdup( psz_title ); |
|---|
| 419 | | p_new->psz_description = strdup( psz_description ); |
|---|
| 420 | | |
|---|
| 421 | | p_new->i_flags = DIALOG_PSZ_INPUT_OK_CANCEL; |
|---|
| 422 | | |
|---|
| 423 | | i_ret = DialogSend( p_this, p_new ); |
|---|
| 424 | | |
|---|
| 425 | | if( i_ret != DIALOG_CANCELLED ) |
|---|
| 426 | | { |
|---|
| 427 | | *ppsz_usersString = p_new->psz_returned[0]? |
|---|
| 428 | | strdup( p_new->psz_returned[0] ) : NULL; |
|---|
| 429 | | } |
|---|
| 430 | | return i_ret; |
|---|
| 431 | | } |
|---|
| 432 | | |
|---|
| 433 | | /** |
|---|
| 434 | | * Hide an interaction dialog |
|---|
| 435 | | * |
|---|
| 436 | | * \param p_this the parent vlc object |
|---|
| 437 | | * \param i_id the id of the item to hide |
|---|
| 438 | | * \return nothing |
|---|
| 439 | | */ |
|---|
| 440 | | void __intf_UserHide( vlc_object_t *p_this, int i_id ) |
|---|
| 441 | | { |
|---|
| 442 | | interaction_t *p_interaction = InteractionGet( p_this ); |
|---|
| 443 | | interaction_dialog_t *p_dialog; |
|---|
| 444 | | |
|---|
| 445 | | if( !p_interaction ) return; |
|---|
| 446 | | |
|---|
| 447 | | vlc_mutex_lock( &p_interaction->object_lock ); |
|---|
| 448 | | p_dialog = DialogGetById( p_interaction, i_id ); |
|---|
| 449 | | |
|---|
| 450 | | if( !p_dialog ) |
|---|
| 451 | | { |
|---|
| 452 | | vlc_mutex_unlock( &p_interaction->object_lock ); |
|---|
| 453 | | return; |
|---|
| 454 | | } |
|---|
| 455 | | |
|---|
| 456 | | p_dialog->i_status = ANSWERED_DIALOG; |
|---|
| 457 | | vlc_mutex_unlock( &p_interaction->object_lock ); |
|---|
| 458 | | } |
|---|
| 459 | | |
|---|
| 460 | | /********************************************************************** |
|---|
| 461 | | * The following functions are local |
|---|
| 462 | | **********************************************************************/ |
|---|
| 463 | | |
|---|
| 464 | | /* Get the interaction object. Create it if needed */ |
|---|
| 465 | | static interaction_t * InteractionGet( vlc_object_t *p_this ) |
|---|
| 466 | | { |
|---|
| 467 | | interaction_t *p_interaction; |
|---|
| 468 | | playlist_t *p_playlist = pl_Yield( p_this ); |
|---|
| 469 | | |
|---|
| 470 | | PL_LOCK; |
|---|
| 471 | | if( p_playlist->p_interaction == NULL ) |
|---|
| 472 | | InteractionInit( p_playlist ); |
|---|
| 473 | | |
|---|
| 474 | | p_interaction = p_playlist->p_interaction; |
|---|
| 475 | | PL_UNLOCK; |
|---|
| 476 | | |
|---|
| 477 | | pl_Release( p_this ); |
|---|
| 478 | | return p_interaction; |
|---|
| 479 | | } |
|---|
| 480 | | |
|---|
| 481 | | /* Create the interaction object in the given playlist object */ |
|---|
| 482 | | static void InteractionInit( playlist_t *p_playlist ) |
|---|
| 483 | | { |
|---|
| 484 | | interaction_t *p_interaction = vlc_object_create( VLC_OBJECT( p_playlist ), |
|---|
| 485 | | sizeof( interaction_t ) ); |
|---|
| 486 | | if( !p_interaction ) |
|---|
| 487 | | { |
|---|
| 488 | | msg_Err( p_playlist,"out of memory" ); |
|---|
| 489 | | return; |
|---|
| 490 | | } |
|---|
| 491 | | |
|---|
| 492 | | p_interaction->psz_object_name = "interaction"; |
|---|
| 493 | | p_interaction->i_dialogs = 0; |
|---|
| 494 | | p_interaction->pp_dialogs = NULL; |
|---|
| 495 | | p_interaction->p_intf = NULL; |
|---|
| 496 | | p_interaction->i_last_id = 0; |
|---|
| 497 | | |
|---|
| 498 | | vlc_mutex_init( p_interaction , &p_interaction->object_lock ); |
|---|
| 499 | | p_playlist->p_interaction = p_interaction; |
|---|
| 500 | | } |
|---|
| 501 | | |
|---|
| 502 | | /* Look for an interface suitable for interaction */ |
|---|
| 503 | | static void InteractionSearchInterface( interaction_t *p_interaction ) |
|---|
| 504 | | { |
|---|
| 505 | | vlc_list_t *p_list; |
|---|
| 506 | | int i_index; |
|---|
| 507 | | |
|---|
| 508 | | p_interaction->p_intf = NULL; |
|---|
| 509 | | |
|---|
| 510 | | p_list = vlc_list_find( p_interaction, VLC_OBJECT_INTF, FIND_ANYWHERE ); |
|---|
| 511 | | if( !p_list ) |
|---|
| 512 | | { |
|---|
| 513 | | msg_Err( p_interaction, "unable to create module list" ); |
|---|
| 514 | | return; |
|---|
| 515 | | } |
|---|
| 516 | | |
|---|
| 517 | | for( i_index = 0; i_index < p_list->i_count; i_index ++ ) |
|---|
| 518 | | { |
|---|
| 519 | | intf_thread_t *p_intf = (intf_thread_t *) |
|---|
| 520 | | p_list->p_values[i_index].p_object; |
|---|
| 521 | | if( p_intf->b_interaction ) |
|---|
| 522 | | { |
|---|
| 523 | | p_interaction->p_intf = p_intf; |
|---|
| 524 | | break; |
|---|
| 525 | | } |
|---|
| 526 | | } |
|---|
| 527 | | vlc_list_release ( p_list ); |
|---|
| 528 | | } |
|---|
| 529 | | |
|---|
| 530 | | /* Find an interaction dialog by its id */ |
|---|
| 531 | | static interaction_dialog_t *DialogGetById( interaction_t *p_interaction, |
|---|
| 532 | | int i_id ) |
|---|
| 533 | | { |
|---|
| 534 | | int i; |
|---|
| 535 | | for( i = 0 ; i< p_interaction->i_dialogs; i++ ) |
|---|
| 536 | | { |
|---|
| 537 | | if( p_interaction->pp_dialogs[i]->i_id == i_id ) |
|---|
| 538 | | return p_interaction->pp_dialogs[i]; |
|---|
| 539 | | } |
|---|
| 540 | | return NULL; |
|---|
| 541 | | } |
|---|
| 542 | | |
|---|
| 543 | | /* Destroy a dialog */ |
|---|
| 544 | | static void DialogDestroy( interaction_dialog_t *p_dialog ) |
|---|
| 545 | | { |
|---|
| 546 | | free( p_dialog->psz_title ); |
|---|
| 547 | | free( p_dialog->psz_description ); |
|---|
| 548 | | free( p_dialog->psz_default_button ); |
|---|
| 549 | | free( p_dialog->psz_alternate_button ); |
|---|
| 550 | | free( p_dialog->psz_other_button ); |
|---|
| 551 | | free( p_dialog ); |
|---|
| 552 | | } |
|---|
| 553 | | |
|---|
| 554 | | /* Ask for the dialog to be sent to the user. Wait for answer |
|---|
| 555 | | * if required */ |
|---|
| 556 | | static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog ) |
|---|
| 557 | | { |
|---|
| 558 | | interaction_t *p_interaction = InteractionGet( p_this ); |
|---|
| 559 | | |
|---|
| 560 | | /* Get an id, if we don't already have one */ |
|---|
| 561 | | if( p_dialog->i_id == 0 ) |
|---|
| 562 | | p_dialog->i_id = ++p_interaction->i_last_id; |
|---|
| 563 | | |
|---|
| 564 | | if( p_this->i_flags & OBJECT_FLAGS_NOINTERACT ) return VLC_EGENERIC; |
|---|
| 565 | | |
|---|
| 566 | | if( config_GetInt( p_this, "interact" ) || |
|---|
| 567 | | p_dialog->i_flags & DIALOG_BLOCKING_ERROR || |
|---|
| 568 | | p_dialog->i_flags & DIALOG_NONBLOCKING_ERROR ) |
|---|
| 569 | | { |
|---|