asx: remove useless test
[vlc.git] / src / interface / dialog.c
blob459c41602b52da87a4c15e77320ba142dfecb955
1 /*****************************************************************************
2 * dialog.c: User dialog functions
3 *****************************************************************************
4 * Copyright © 2009 Rémi Denis-Courmont
5 * Copyright © 2016 VLC authors and VideoLAN
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20 *****************************************************************************/
22 /** @ingroup vlc_dialog */
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
27 #include <stdarg.h>
29 #include <vlc_common.h>
30 #include <vlc_dialog.h>
31 #include <vlc_interrupt.h>
32 #include <vlc_extensions.h>
33 #include <assert.h>
34 #include "libvlc.h"
36 struct vlc_dialog_provider
38 vlc_mutex_t lock;
39 vlc_array_t dialog_array;
40 vlc_dialog_cbs cbs;
41 void * p_cbs_data;
43 vlc_dialog_ext_update_cb pf_ext_update;
44 void * p_ext_data;
47 enum dialog_type
49 VLC_DIALOG_ERROR,
50 VLC_DIALOG_LOGIN,
51 VLC_DIALOG_QUESTION,
52 VLC_DIALOG_PROGRESS,
55 struct dialog_answer
57 enum dialog_type i_type;
58 union
60 struct
62 char *psz_username;
63 char *psz_password;
64 bool b_store;
65 } login;
66 struct
68 int i_action;
69 } question;
70 } u;
73 struct dialog
75 enum dialog_type i_type;
76 const char *psz_title;
77 const char *psz_text;
79 union
81 struct
83 const char *psz_default_username;
84 bool b_ask_store;
85 } login;
86 struct
88 vlc_dialog_question_type i_type;
89 const char *psz_cancel;
90 const char *psz_action1;
91 const char *psz_action2;
92 } question;
93 struct
95 bool b_indeterminate;
96 float f_position;
97 const char *psz_cancel;
98 } progress;
99 } u;
102 struct vlc_dialog_id
104 vlc_mutex_t lock;
105 vlc_cond_t wait;
106 enum dialog_type i_type;
107 void * p_context;
108 int i_refcount;
109 bool b_cancelled;
110 bool b_answered;
111 bool b_progress_indeterminate;
112 char * psz_progress_text;
113 struct dialog_answer answer;
116 struct dialog_i11e_context
118 vlc_dialog_provider * p_provider;
119 vlc_dialog_id * p_id;
122 static inline vlc_dialog_provider *
123 get_dialog_provider(vlc_object_t *p_obj, bool b_check_interact)
125 if (b_check_interact && p_obj->obj.flags & OBJECT_FLAGS_NOINTERACT)
126 return NULL;
128 vlc_dialog_provider *p_provider =
129 libvlc_priv(p_obj->obj.libvlc)->p_dialog_provider;
130 assert(p_provider != NULL);
131 return p_provider;
134 static void
135 dialog_id_release(vlc_dialog_id *p_id)
137 if (p_id->answer.i_type == VLC_DIALOG_LOGIN)
139 free(p_id->answer.u.login.psz_username);
140 free(p_id->answer.u.login.psz_password);
142 free(p_id->psz_progress_text);
143 vlc_mutex_destroy(&p_id->lock);
144 vlc_cond_destroy(&p_id->wait);
145 free(p_id);
149 libvlc_InternalDialogInit(libvlc_int_t *p_libvlc)
151 assert(p_libvlc != NULL);
152 vlc_dialog_provider *p_provider = malloc(sizeof(*p_provider));
153 if (p_provider == NULL)
154 return VLC_EGENERIC;
156 vlc_mutex_init(&p_provider->lock);
157 vlc_array_init(&p_provider->dialog_array);
159 memset(&p_provider->cbs, 0, sizeof(p_provider->cbs));
160 p_provider->p_cbs_data = NULL;
162 p_provider->pf_ext_update = NULL;
163 p_provider->p_ext_data = NULL;
164 libvlc_priv(p_libvlc)->p_dialog_provider = p_provider;
166 return VLC_SUCCESS;
169 static void
170 dialog_cancel_locked(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id)
172 vlc_mutex_lock(&p_id->lock);
173 if (p_id->b_cancelled || p_id->b_answered)
175 vlc_mutex_unlock(&p_id->lock);
176 return;
178 p_id->b_cancelled = true;
179 vlc_mutex_unlock(&p_id->lock);
181 p_provider->cbs.pf_cancel(p_provider->p_cbs_data, p_id);
184 static vlc_dialog_id *
185 dialog_add_locked(vlc_dialog_provider *p_provider, enum dialog_type i_type)
187 vlc_dialog_id *p_id = calloc(1, sizeof(*p_id));
189 if (p_id == NULL)
190 return NULL;
192 if(vlc_array_append(&p_provider->dialog_array, p_id))
194 free(p_id);
195 return NULL;
198 vlc_mutex_init(&p_id->lock);
199 vlc_cond_init(&p_id->wait);
201 p_id->i_type = i_type;
202 p_id->i_refcount = 2; /* provider and callbacks */
204 return p_id;
207 static void
208 dialog_remove_locked(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id)
210 ssize_t i_idx = vlc_array_index_of_item(&p_provider->dialog_array, p_id);
211 assert(i_idx >= 0);
212 vlc_array_remove(&p_provider->dialog_array, i_idx);
214 vlc_mutex_lock(&p_id->lock);
215 p_id->i_refcount--;
216 if (p_id->i_refcount == 0)
218 vlc_mutex_unlock(&p_id->lock);
219 dialog_id_release(p_id);
221 else
222 vlc_mutex_unlock(&p_id->lock);
225 static void
226 dialog_clear_all_locked(vlc_dialog_provider *p_provider)
228 for (size_t i = 0; i < vlc_array_count(&p_provider->dialog_array); ++i)
230 vlc_dialog_id *p_id =
231 vlc_array_item_at_index(&p_provider->dialog_array, i);
232 dialog_cancel_locked(p_provider, p_id);
236 void
237 libvlc_InternalDialogClean(libvlc_int_t *p_libvlc)
239 assert(p_libvlc != NULL);
240 vlc_dialog_provider *p_provider = libvlc_priv(p_libvlc)->p_dialog_provider;
242 if (p_provider == NULL)
243 return;
244 vlc_mutex_lock(&p_provider->lock);
245 dialog_clear_all_locked(p_provider);
246 vlc_mutex_unlock(&p_provider->lock);
248 vlc_mutex_destroy(&p_provider->lock);
249 free(p_provider);
250 libvlc_priv(p_libvlc)->p_dialog_provider = NULL;
253 #undef vlc_dialog_provider_set_callbacks
254 void
255 vlc_dialog_provider_set_callbacks(vlc_object_t *p_obj,
256 const vlc_dialog_cbs *p_cbs, void *p_data)
258 assert(p_obj != NULL);
259 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, false);
261 vlc_mutex_lock(&p_provider->lock);
262 dialog_clear_all_locked(p_provider);
264 if (p_cbs == NULL)
266 memset(&p_provider->cbs, 0, sizeof(p_provider->cbs));
267 p_provider->p_cbs_data = NULL;
269 else
271 p_provider->cbs = *p_cbs;
272 p_provider->p_cbs_data = p_data;
274 vlc_mutex_unlock(&p_provider->lock);
277 static void
278 dialog_wait_interrupted(void *p_data)
280 struct dialog_i11e_context *p_context = p_data;
281 vlc_dialog_provider *p_provider = p_context->p_provider;
282 vlc_dialog_id *p_id = p_context->p_id;
284 vlc_mutex_lock(&p_provider->lock);
285 dialog_cancel_locked(p_provider, p_id);
286 vlc_mutex_unlock(&p_provider->lock);
288 vlc_mutex_lock(&p_id->lock);
289 vlc_cond_signal(&p_id->wait);
290 vlc_mutex_unlock(&p_id->lock);
293 static int
294 dialog_wait(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id,
295 enum dialog_type i_type, struct dialog_answer *p_answer)
297 struct dialog_i11e_context context = {
298 .p_provider = p_provider,
299 .p_id = p_id,
301 vlc_interrupt_register(dialog_wait_interrupted, &context);
303 vlc_mutex_lock(&p_id->lock);
304 /* Wait for the dialog to be dismissed, interrupted or answered */
305 while (!p_id->b_cancelled && !p_id->b_answered)
306 vlc_cond_wait(&p_id->wait, &p_id->lock);
308 int i_ret;
309 if (p_id->b_cancelled)
310 i_ret = 0;
311 else if (p_id->answer.i_type != i_type)
312 i_ret = VLC_EGENERIC;
313 else
315 i_ret = 1;
316 memcpy(p_answer, &p_id->answer, sizeof(p_id->answer));
317 memset(&p_id->answer, 0, sizeof(p_id->answer));
320 vlc_mutex_unlock(&p_id->lock);
321 vlc_interrupt_unregister();
323 vlc_mutex_lock(&p_provider->lock);
324 dialog_remove_locked(p_provider, p_id);
325 vlc_mutex_unlock(&p_provider->lock);
326 return i_ret;
329 static int
330 dialog_display_error_va(vlc_dialog_provider *p_provider, const char *psz_title,
331 const char *psz_fmt, va_list ap)
333 vlc_mutex_lock(&p_provider->lock);
334 if (p_provider->cbs.pf_display_error == NULL)
336 vlc_mutex_unlock(&p_provider->lock);
337 return VLC_EGENERIC;
340 char *psz_text;
341 if (vasprintf(&psz_text, psz_fmt, ap) == -1)
343 vlc_mutex_unlock(&p_provider->lock);
344 return VLC_ENOMEM;
347 p_provider->cbs.pf_display_error(p_provider->p_cbs_data, psz_title, psz_text);
348 free(psz_text);
349 vlc_mutex_unlock(&p_provider->lock);
351 return VLC_SUCCESS;
355 vlc_dialog_display_error_va(vlc_object_t *p_obj, const char *psz_title,
356 const char *psz_fmt, va_list ap)
358 assert(p_obj != NULL && psz_title != NULL && psz_fmt != NULL);
359 int i_ret;
360 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, true);
362 if (p_provider != NULL)
363 i_ret = dialog_display_error_va(p_provider, psz_title, psz_fmt, ap);
364 else
365 i_ret = VLC_EGENERIC;
367 if (i_ret != VLC_SUCCESS)
369 msg_Err(p_obj, "%s", psz_title);
370 msg_GenericVa(p_obj, VLC_MSG_ERR, psz_fmt, ap);
372 return i_ret;
376 #undef vlc_dialog_display_error
378 vlc_dialog_display_error(vlc_object_t *p_obj, const char *psz_title,
379 const char *psz_fmt, ...)
381 assert(psz_fmt != NULL);
382 va_list ap;
383 va_start(ap, psz_fmt);
384 int i_ret = vlc_dialog_display_error_va(p_obj, psz_title, psz_fmt, ap);
385 va_end(ap);
386 return i_ret;
389 static int
390 dialog_display_login_va(vlc_dialog_provider *p_provider, vlc_dialog_id **pp_id,
391 const char *psz_default_username, bool b_ask_store,
392 const char *psz_title, const char *psz_fmt, va_list ap)
394 vlc_mutex_lock(&p_provider->lock);
395 if (p_provider->cbs.pf_display_login == NULL
396 || p_provider->cbs.pf_cancel == NULL)
398 vlc_mutex_unlock(&p_provider->lock);
399 return VLC_EGENERIC;
402 char *psz_text;
403 if (vasprintf(&psz_text, psz_fmt, ap) == -1)
405 vlc_mutex_unlock(&p_provider->lock);
406 return VLC_ENOMEM;
409 vlc_dialog_id *p_id = dialog_add_locked(p_provider, VLC_DIALOG_LOGIN);
410 if (p_id == NULL)
412 free(psz_text);
413 vlc_mutex_unlock(&p_provider->lock);
414 return VLC_ENOMEM;
416 p_provider->cbs.pf_display_login(p_provider->p_cbs_data, p_id, psz_title,
417 psz_text, psz_default_username, b_ask_store);
418 free(psz_text);
419 vlc_mutex_unlock(&p_provider->lock);
420 *pp_id = p_id;
422 return VLC_SUCCESS;
426 vlc_dialog_wait_login_va(vlc_object_t *p_obj, char **ppsz_username,
427 char **ppsz_password, bool *p_store,
428 const char *psz_default_username,
429 const char *psz_title, const char *psz_fmt, va_list ap)
431 assert(p_obj != NULL && ppsz_username != NULL && ppsz_password != NULL
432 && psz_fmt != NULL && psz_title != NULL);
434 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, true);
435 if (p_provider == NULL)
436 return VLC_EGENERIC;
438 vlc_dialog_id *p_id;
439 int i_ret = dialog_display_login_va(p_provider, &p_id, psz_default_username,
440 p_store != NULL, psz_title, psz_fmt, ap);
441 if (i_ret < 0 || p_id == NULL)
442 return i_ret;
444 struct dialog_answer answer;
445 i_ret = dialog_wait(p_provider, p_id, VLC_DIALOG_LOGIN, &answer);
446 if (i_ret <= 0)
447 return i_ret;
449 *ppsz_username = answer.u.login.psz_username;
450 *ppsz_password = answer.u.login.psz_password;
451 if (p_store != NULL)
452 *p_store = answer.u.login.b_store;
454 return 1;
457 #undef vlc_dialog_wait_login
459 vlc_dialog_wait_login(vlc_object_t *p_obj, char **ppsz_username,
460 char **ppsz_password, bool *p_store,
461 const char *psz_default_username, const char *psz_title,
462 const char *psz_fmt, ...)
464 assert(psz_fmt != NULL);
465 va_list ap;
466 va_start(ap, psz_fmt);
467 int i_ret = vlc_dialog_wait_login_va(p_obj, ppsz_username, ppsz_password,
468 p_store,psz_default_username,
469 psz_title, psz_fmt, ap);
470 va_end(ap);
471 return i_ret;
474 static int
475 dialog_display_question_va(vlc_dialog_provider *p_provider, vlc_dialog_id **pp_id,
476 vlc_dialog_question_type i_type,
477 const char *psz_cancel, const char *psz_action1,
478 const char *psz_action2, const char *psz_title,
479 const char *psz_fmt, va_list ap)
481 vlc_mutex_lock(&p_provider->lock);
482 if (p_provider->cbs.pf_display_question == NULL
483 || p_provider->cbs.pf_cancel == NULL)
485 vlc_mutex_unlock(&p_provider->lock);
486 return VLC_EGENERIC;
489 char *psz_text;
490 if (vasprintf(&psz_text, psz_fmt, ap) == -1)
492 vlc_mutex_unlock(&p_provider->lock);
493 return VLC_ENOMEM;
496 vlc_dialog_id *p_id = dialog_add_locked(p_provider, VLC_DIALOG_QUESTION);
497 if (p_id == NULL)
499 free(psz_text);
500 vlc_mutex_unlock(&p_provider->lock);
501 return VLC_ENOMEM;
503 p_provider->cbs.pf_display_question(p_provider->p_cbs_data, p_id, psz_title,
504 psz_text, i_type, psz_cancel, psz_action1,
505 psz_action2);
506 free(psz_text);
507 vlc_mutex_unlock(&p_provider->lock);
508 *pp_id = p_id;
510 return VLC_SUCCESS;
514 vlc_dialog_wait_question_va(vlc_object_t *p_obj,
515 vlc_dialog_question_type i_type,
516 const char *psz_cancel, const char *psz_action1,
517 const char *psz_action2, const char *psz_title,
518 const char *psz_fmt, va_list ap)
520 assert(p_obj != NULL && psz_fmt != NULL && psz_title != NULL
521 && psz_cancel != NULL);
523 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, true);
524 if (p_provider == NULL)
525 return VLC_EGENERIC;
527 vlc_dialog_id *p_id;
528 int i_ret = dialog_display_question_va(p_provider, &p_id, i_type,
529 psz_cancel, psz_action1,
530 psz_action2, psz_title, psz_fmt, ap);
531 if (i_ret < 0 || p_id == NULL)
532 return i_ret;
534 struct dialog_answer answer;
535 i_ret = dialog_wait(p_provider, p_id, VLC_DIALOG_QUESTION, &answer);
536 if (i_ret <= 0)
537 return i_ret;
539 if (answer.u.question.i_action != 1 && answer.u.question.i_action != 2)
540 return VLC_EGENERIC;
542 return answer.u.question.i_action;
545 #undef vlc_dialog_wait_question
547 vlc_dialog_wait_question(vlc_object_t *p_obj,
548 vlc_dialog_question_type i_type,
549 const char *psz_cancel, const char *psz_action1,
550 const char *psz_action2, const char *psz_title,
551 const char *psz_fmt, ...)
553 assert(psz_fmt != NULL);
554 va_list ap;
555 va_start(ap, psz_fmt);
556 int i_ret = vlc_dialog_wait_question_va(p_obj, i_type, psz_cancel,
557 psz_action1, psz_action2, psz_title,
558 psz_fmt, ap);
559 va_end(ap);
560 return i_ret;
563 static int
564 display_progress_va(vlc_dialog_provider *p_provider, vlc_dialog_id **pp_id,
565 bool b_indeterminate, float f_position,
566 const char *psz_cancel, const char *psz_title,
567 const char *psz_fmt, va_list ap)
569 vlc_mutex_lock(&p_provider->lock);
570 if (p_provider->cbs.pf_display_progress == NULL
571 || p_provider->cbs.pf_update_progress == NULL
572 || p_provider->cbs.pf_cancel == NULL)
574 vlc_mutex_unlock(&p_provider->lock);
575 return VLC_EGENERIC;
578 char *psz_text;
579 if (vasprintf(&psz_text, psz_fmt, ap) == -1)
581 vlc_mutex_unlock(&p_provider->lock);
582 return VLC_ENOMEM;
585 vlc_dialog_id *p_id = dialog_add_locked(p_provider, VLC_DIALOG_PROGRESS);
586 if (p_id == NULL)
588 free(psz_text);
589 vlc_mutex_unlock(&p_provider->lock);
590 return VLC_ENOMEM;
592 p_id->b_progress_indeterminate = b_indeterminate;
593 p_id->psz_progress_text = psz_text;
594 p_provider->cbs.pf_display_progress(p_provider->p_cbs_data, p_id, psz_title,
595 psz_text, b_indeterminate, f_position,
596 psz_cancel);
597 vlc_mutex_unlock(&p_provider->lock);
598 *pp_id = p_id;
600 return VLC_SUCCESS;
603 vlc_dialog_id *
604 vlc_dialog_display_progress_va(vlc_object_t *p_obj, bool b_indeterminate,
605 float f_position, const char *psz_cancel,
606 const char *psz_title, const char *psz_fmt,
607 va_list ap)
609 assert(p_obj != NULL && psz_title != NULL && psz_fmt != NULL);
611 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, true);
612 if (p_provider == NULL)
613 return NULL;
614 vlc_dialog_id *p_id;
615 int i_ret = display_progress_va(p_provider, &p_id, b_indeterminate,
616 f_position, psz_cancel, psz_title, psz_fmt,
617 ap);
618 return i_ret == VLC_SUCCESS ? p_id : NULL;
621 #undef vlc_dialog_display_progress
622 vlc_dialog_id *
623 vlc_dialog_display_progress(vlc_object_t *p_obj, bool b_indeterminate,
624 float f_position, const char *psz_cancel,
625 const char *psz_title, const char *psz_fmt, ...)
627 assert(psz_fmt != NULL);
628 va_list ap;
629 va_start(ap, psz_fmt);
630 vlc_dialog_id *p_id =
631 vlc_dialog_display_progress_va(p_obj, b_indeterminate, f_position,
632 psz_cancel, psz_title, psz_fmt, ap);
633 va_end(ap);
634 return p_id;
637 static int
638 dialog_update_progress(vlc_object_t *p_obj, vlc_dialog_id *p_id, float f_value,
639 char *psz_text)
641 assert(p_obj != NULL && p_id != NULL);
642 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, false);
644 vlc_mutex_lock(&p_provider->lock);
645 if (p_provider->cbs.pf_update_progress == NULL ||
646 vlc_dialog_is_cancelled(p_obj, p_id))
648 vlc_mutex_unlock(&p_provider->lock);
649 free(psz_text);
650 return VLC_EGENERIC;
653 if (p_id->b_progress_indeterminate)
654 f_value = 0.0f;
656 if (psz_text != NULL)
658 free(p_id->psz_progress_text);
659 p_id->psz_progress_text = psz_text;
661 p_provider->cbs.pf_update_progress(p_provider->p_cbs_data, p_id, f_value,
662 p_id->psz_progress_text);
664 vlc_mutex_unlock(&p_provider->lock);
665 return VLC_SUCCESS;
668 #undef vlc_dialog_update_progress
670 vlc_dialog_update_progress(vlc_object_t *p_obj, vlc_dialog_id *p_id,
671 float f_value)
673 return dialog_update_progress(p_obj, p_id, f_value, NULL);
677 vlc_dialog_update_progress_text_va(vlc_object_t *p_obj, vlc_dialog_id *p_id,
678 float f_value, const char *psz_fmt,
679 va_list ap)
681 assert(psz_fmt != NULL);
683 char *psz_text;
684 if (vasprintf(&psz_text, psz_fmt, ap) == -1)
685 return VLC_ENOMEM;
686 return dialog_update_progress(p_obj, p_id, f_value, psz_text);
689 #undef vlc_dialog_update_progress_text
691 vlc_dialog_update_progress_text(vlc_object_t *p_obj, vlc_dialog_id *p_id,
692 float f_value, const char *psz_fmt, ...)
694 assert(psz_fmt != NULL);
695 va_list ap;
696 va_start(ap, psz_fmt);
697 int i_ret = vlc_dialog_update_progress_text_va(p_obj, p_id, f_value,
698 psz_fmt, ap);
699 va_end(ap);
700 return i_ret;
703 #undef vlc_dialog_release
704 void
705 vlc_dialog_release(vlc_object_t *p_obj, vlc_dialog_id *p_id)
707 assert(p_obj != NULL && p_id != NULL);
708 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, false);
710 vlc_mutex_lock(&p_provider->lock);
711 dialog_cancel_locked(p_provider, p_id);
712 dialog_remove_locked(p_provider, p_id);
713 vlc_mutex_unlock(&p_provider->lock);
716 #undef vlc_dialog_is_cancelled
717 bool
718 vlc_dialog_is_cancelled(vlc_object_t *p_obj, vlc_dialog_id *p_id)
720 (void) p_obj;
721 assert(p_id != NULL);
723 vlc_mutex_lock(&p_id->lock);
724 bool b_cancelled = p_id->b_cancelled;
725 vlc_mutex_unlock(&p_id->lock);
726 return b_cancelled;
729 void
730 vlc_dialog_id_set_context(vlc_dialog_id *p_id, void *p_context)
732 vlc_mutex_lock(&p_id->lock);
733 p_id->p_context = p_context;
734 vlc_mutex_unlock(&p_id->lock);
737 void *
738 vlc_dialog_id_get_context(vlc_dialog_id *p_id)
740 assert(p_id != NULL);
741 vlc_mutex_lock(&p_id->lock);
742 void *p_context = p_id->p_context;
743 vlc_mutex_unlock(&p_id->lock);
744 return p_context;
747 static int
748 dialog_id_post(vlc_dialog_id *p_id, struct dialog_answer *p_answer)
750 vlc_mutex_lock(&p_id->lock);
751 if (p_answer == NULL)
753 p_id->b_cancelled = true;
755 else
757 p_id->answer = *p_answer;
758 p_id->b_answered = true;
760 p_id->i_refcount--;
761 if (p_id->i_refcount > 0)
763 vlc_cond_signal(&p_id->wait);
764 vlc_mutex_unlock(&p_id->lock);
766 else
768 vlc_mutex_unlock(&p_id->lock);
769 dialog_id_release(p_id);
771 return VLC_SUCCESS;
775 vlc_dialog_id_post_login(vlc_dialog_id *p_id, const char *psz_username,
776 const char *psz_password, bool b_store)
778 assert(p_id != NULL && psz_username != NULL && psz_password != NULL);
780 struct dialog_answer answer = {
781 .i_type = VLC_DIALOG_LOGIN,
782 .u.login = {
783 .b_store = b_store,
784 .psz_username = strdup(psz_username),
785 .psz_password = strdup(psz_password),
788 if (answer.u.login.psz_username == NULL
789 || answer.u.login.psz_password == NULL)
791 free(answer.u.login.psz_username);
792 free(answer.u.login.psz_password);
793 dialog_id_post(p_id, NULL);
794 return VLC_ENOMEM;
797 return dialog_id_post(p_id, &answer);
801 vlc_dialog_id_post_action(vlc_dialog_id *p_id, int i_action)
803 assert(p_id != NULL);
805 struct dialog_answer answer = {
806 .i_type = VLC_DIALOG_QUESTION,
807 .u.question = { .i_action = i_action },
810 return dialog_id_post(p_id, &answer);
814 vlc_dialog_id_dismiss(vlc_dialog_id *p_id)
816 return dialog_id_post(p_id, NULL);
819 #undef vlc_dialog_provider_set_ext_callback
820 void
821 vlc_dialog_provider_set_ext_callback(vlc_object_t *p_obj,
822 vlc_dialog_ext_update_cb pf_update,
823 void *p_data)
825 assert(p_obj != NULL);
826 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, false);
828 vlc_mutex_lock(&p_provider->lock);
830 p_provider->pf_ext_update = pf_update;
831 p_provider->p_ext_data = p_data;
833 vlc_mutex_unlock(&p_provider->lock);
836 #undef vlc_ext_dialog_update
838 vlc_ext_dialog_update(vlc_object_t *p_obj, extension_dialog_t *p_ext_dialog)
840 assert(p_obj != NULL);
841 vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, false);
843 vlc_mutex_lock(&p_provider->lock);
844 if (p_provider->pf_ext_update == NULL)
846 vlc_mutex_unlock(&p_provider->lock);
847 return VLC_EGENERIC;
849 p_provider->pf_ext_update(p_ext_dialog, p_provider->p_ext_data);
850 vlc_mutex_unlock(&p_provider->lock);
851 return VLC_SUCCESS;