X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finterface%2Fdialog.c;h=fd3568c33f3148c30e7e1b2a765ab4465f6a5cd6;hb=4d85871d1b29265a6cc5744677f0f0bb9bfac20f;hp=6cce299fce7158855875d1435c0db3c08f0dbd26;hpb=a21347d0362b56ee14b1d63634648c3cae5028da;p=vlc diff --git a/src/interface/dialog.c b/src/interface/dialog.c index 6cce299fce..fd3568c33f 100644 --- a/src/interface/dialog.c +++ b/src/interface/dialog.c @@ -31,6 +31,7 @@ #include #include +#include #include #include "libvlc.h" @@ -92,9 +93,17 @@ static vlc_object_t *dialog_GetProvider (vlc_object_t *obj) return provider; } -static -void dialog_FatalVa (vlc_object_t *obj, const char *title, - const char *fmt, va_list ap) +/** + * Sends an error message through the user interface (if any). + * @param obj the VLC object emitting the error + * @param modal whether to wait for user to acknowledge the error + * before returning control to the caller + * @param title title of the error dialog + * @param fmt format string for the error message + * @param ap parameters list for the formatted error message + */ +void dialog_VFatal (vlc_object_t *obj, bool modal, const char *title, + const char *fmt, va_list ap) { char *text; @@ -109,24 +118,165 @@ void dialog_FatalVa (vlc_object_t *obj, const char *title, return; } - if (vasprintf (&text, fmt, ap) == -1) - return; - - dialog_fatal_t dialog = { title, text, }; - var_SetAddress (provider, "dialog-fatal", &dialog); - free (text); + if (vasprintf (&text, fmt, ap) != -1) + { + dialog_fatal_t dialog = { title, text, }; + var_SetAddress (provider, + modal ? "dialog-critical" : "dialog-error", &dialog); + free (text); + } + vlc_object_release (provider); } -#undef dialog_Fatal +#undef dialog_Login /** - * Notify the user of some fatal error. - * This is a fire and forget function. + * Requests a username and password through the user interface. + * @param obj the VLC object requesting credential information + * @param username a pointer to the specified username [OUT] + * @param password a pointer to the specified password [OUT] + * @param title title for the dialog + * @param text format string for the message in the dialog + * @return Nothing. If a user name resp. a password was specified, + * it will be returned as a heap-allocated character array + * into the username resp password pointer. Those must be freed with free(). + * Otherwise *username resp *password will be NULL. */ -void dialog_Fatal (vlc_object_t *obj, const char *title, const char *fmt, ...) +void dialog_Login (vlc_object_t *obj, char **username, char **password, + const char *title, const char *fmt, ...) { + assert ((username != NULL) && (password != NULL)); + + *username = *password = NULL; + if (obj->i_flags & OBJECT_FLAGS_NOINTERACT) + return; + + vlc_object_t *provider = dialog_GetProvider (obj); + if (provider == NULL) + return; + + char *text; va_list ap; va_start (ap, fmt); - dialog_FatalVa (obj, title, fmt, ap); + if (vasprintf (&text, fmt, ap) != -1) + { + dialog_login_t dialog = { title, text, username, password, }; + var_SetAddress (provider, "dialog-login", &dialog); + free (text); + } va_end (ap); + vlc_object_release (provider); +} + + +#undef dialog_Question +/** + * Asks a total (Yes/No/Cancel) question through the user interface. + * @param obj VLC object emitting the question + * @param title dialog box title + * @param text dialog box text + * @param yes first choice/button text + * @param no second choice/button text + * @param cancel third answer/button text, or NULL if no third option + * @return 0 if the user could not answer the question (e.g. there is no UI), + * 1, 2 resp. 3 if the user pressed the first, second resp. third button. + */ +int dialog_Question (vlc_object_t *obj, const char *title, const char *text, + const char *yes, const char *no, const char *cancel) +{ + if (obj->i_flags & OBJECT_FLAGS_NOINTERACT) + return 0; + + vlc_object_t *provider = dialog_GetProvider (obj); + if (provider == NULL) + return 0; + + dialog_question_t dialog = { title, text, yes, no, cancel, 0, }; + var_SetAddress (provider, "dialog-question", &dialog); + vlc_object_release (provider); + return dialog.answer; +} + +#undef dialog_ProgressCreate +/** + * Creates a progress bar dialog. + */ +dialog_progress_bar_t * +dialog_ProgressCreate (vlc_object_t *obj, const char *title, + const char *message, const char *cancel) +{ + if (obj->i_flags & OBJECT_FLAGS_NOINTERACT) + return NULL; + + vlc_object_t *provider = dialog_GetProvider (obj); + if (provider == NULL) + return NULL; + + dialog_progress_bar_t *dialog = malloc (sizeof (*dialog)); + if (dialog != NULL) + { + dialog->title = title; + dialog->message = message; + dialog->cancel = cancel; + var_SetAddress (provider, "dialog-progress-bar", dialog); +#ifndef NDEBUG + dialog->title = dialog->message = dialog->cancel = NULL; +#endif + assert (dialog->pf_update); + assert (dialog->pf_check); + assert (dialog->pf_destroy); + } + + /* FIXME: This could conceivably crash if the dialog provider is destroyed + * before the dialog user. Holding the provider does not help, as it only + * protects object variable operations. For instance, it does not prevent + * unloading of the interface plugin. In the short term, the only solution + * is to not use progress dialog after deinitialization of the interfaces. + */ + vlc_object_release (provider); + return dialog; +} + +void dialog_ProgressDestroy (dialog_progress_bar_t *dialog) +{ + assert (dialog); + + dialog->pf_destroy (dialog->p_sys); + free (dialog); +} + +void dialog_ProgressSet (dialog_progress_bar_t *dialog, const char *text, + float value) +{ + assert (dialog); + + dialog->pf_update (dialog->p_sys, text, value); +} + +bool dialog_ProgressCancelled (dialog_progress_bar_t *dialog) +{ + assert (dialog); + + return dialog->pf_check (dialog->p_sys); +} + +#undef dialog_ExtensionUpdate +int dialog_ExtensionUpdate (vlc_object_t *obj, extension_dialog_t *dialog) +{ + assert (obj); + assert (dialog); + + vlc_object_t *dp = dialog_GetProvider(obj); + if (!dp) + { + msg_Warn (obj, "Dialog provider is not set, can't update dialog '%s'", + dialog->psz_title); + return VLC_EGENERIC; + } + + // Signaling the dialog provider + int ret = var_SetAddress (dp, "dialog-extension", dialog); + + vlc_object_release (dp); + return ret; }