[vlc-devel] [RFC PATCH 2/5] dialog: rework API
Thomas Guillem
thomas at gllm.fr
Fri Jan 29 12:06:28 CET 2016
New version: fix comment typos, simplify pf_cancel callback
This reworks the vlc dialog api:
- dialog_Question is replaced by vlc_dialog_wait_question
- dialog_Login is replaced by vlc_dialog_wait_login
- dialog_Progress is replace by vlc_dialog_display_progress
- dialog_Fatal is replaced by vlc_dialog_display_error
- dialog_FatalWait is replaced by vlc_dialog_wait_question with i_type ==
VLC_DIALOG_QUESTION_CRITICAL and without action1/action2
- All dialogs (except vlc_dialog_display_error that returns immediatly) are
interruptible via vlc_interrupt.
- Nothing prevents to have more than one dialog type displayed at a time.
---
include/vlc_dialog.h | 446 +++++++++---
include/vlc_objects.h | 2 +
modules/access/dvb/scan.c | 43 +-
modules/access_output/file.c | 12 +-
modules/codec/libass.c | 18 +-
modules/demux/avi/avi.c | 48 +-
modules/gui/qt4/dialogs/external.cpp | 401 ++++++----
modules/gui/qt4/dialogs/external.hpp | 126 +++-
modules/lua/extension.c | 57 +-
modules/lua/extension.h | 2 +-
modules/lua/extension_thread.c | 6 +-
modules/misc/gnutls.c | 28 +-
modules/misc/securetransport.c | 10 +-
modules/text_renderer/freetype/fonts/fontconfig.c | 22 +-
src/interface/dialog.c | 844 +++++++++++++++++-----
src/libvlc.c | 11 +
src/libvlc.h | 4 +-
src/libvlccore.sym | 31 +-
src/misc/keystore.c | 37 +-
src/misc/update.c | 58 +-
test/modules/misc/tls.c | 33 +-
21 files changed, 1605 insertions(+), 634 deletions(-)
diff --git a/include/vlc_dialog.h b/include/vlc_dialog.h
index 27eacd8..4dd13ba 100644
--- a/include/vlc_dialog.h
+++ b/include/vlc_dialog.h
@@ -18,119 +18,389 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+/**
+ * @file
+ * This file declares VLC dialog API
+ */
+
#ifndef VLC_DIALOG_H_
#define VLC_DIALOG_H_
# include <stdarg.h>
+typedef struct vlc_dialog_provider vlc_dialog_provider;
+typedef struct vlc_dialog_id vlc_dialog_id;
+
+
+/* Called from src/libvlc.c */
+vlc_dialog_provider *
+vlc_dialog_provider_new(void);
+
+/* Called from src/libvlc.c */
+void
+vlc_dialog_provider_release(vlc_dialog_provider *p_provider);
+
/**
- * \ingroup interaction
+ * @defgroup vlc_dialog VLC dialog API
+ * @{
+ * @defgroup vlc_dialog_api API to interract with the user
* @{
- * \file vlc_dialog.h
- * User interaction dialog APIs
*/
/**
- * A fatal error dialog.
- * No response expected from the user.
+ * Dialog question type, see vlc_dialog_wait_question()
*/
-typedef struct dialog_fatal_t
+typedef enum vlc_dialog_question_type
{
- const char *title;
- const char *message;
-} dialog_fatal_t;
+ VLC_DIALOG_QUESTION_NORMAL,
+ VLC_DIALOG_QUESTION_WARNING,
+ VLC_DIALOG_QUESTION_CRITICAL,
+} vlc_dialog_question_type;
-VLC_API void dialog_VFatal(vlc_object_t *, bool, const char *, const char *, va_list);
+/**
+ * Sends an error message
+ *
+ * This function returns immediately
+ *
+ * @param p_obj the VLC object emitting the error
+ * @param psz_title title of the error dialog
+ * @param psz_fmt format string for the error message
+ * @return VLC_SUCCESS on success, or a VLC error code on error
+ */
+VLC_API int
+vlc_dialog_display_error(vlc_object_t *p_obj, const char *psz_title,
+ const char *psz_fmt, ...) VLC_FORMAT(3,4);
+#define vlc_dialog_display_error(a, b, c, ...) \
+ vlc_dialog_display_error(VLC_OBJECT(a), b, c, ##__VA_ARGS__)
-static inline VLC_FORMAT(3, 4)
-void dialog_Fatal (vlc_object_t *obj, const char *title, const char *fmt, ...)
-{
- va_list ap;
+/**
+ * Sends an error message
+ *
+ * Equivalent to vlc_dialog_display_error() expect that it's called with a
+ * va_list.
+ */
+VLC_API int
+vlc_dialog_display_error_va(vlc_object_t *p_obj, const char *psz_title,
+ const char *psz_fmt, va_list ap);
+/* TODO s/dialog_Fatal/vlc_dialog_display_error/g if accepted */
+#define dialog_Fatal vlc_dialog_display_error
- va_start (ap, fmt);
- dialog_VFatal(obj, false, title, fmt, ap);
- va_end (ap);
-}
-#define dialog_Fatal(o, t, ...) \
- dialog_Fatal(VLC_OBJECT(o), t, __VA_ARGS__)
+/**
+ * Requests an user name and a password
+ *
+ * This function waits until the user dismisses the dialog or responds. It's
+ * interruptible via vlc_interrupt. In that case, vlc_dialog_cbs.pf_cancel()
+ * will be invoked. If p_store is not NULL, the user will be asked to store the
+ * password or not.
+ *
+ * @param p_obj the VLC object emitting the dialog
+ * @param ppsz_username a pointer to the user name provided by the user, it
+ * must be freed with free() on success
+ * @param ppsz_password a pointer to the password provided by the user, it must
+ * be freed with free() on success
+ * @param p_store a pointer to the store answer provided by the user (optional)
+ * @param psz_title title of the login dialog
+ * @param psz_fmt format string for the login message
+ * @return < 0 on error, 0 if the user cancelled it, and 1 if ppsz_username and
+ * ppsz_password are valid.
+ */
+VLC_API int
+vlc_dialog_wait_login(vlc_object_t *p_obj, char **ppsz_username,
+ char **ppsz_password, bool *p_store,
+ const char *psz_default_username,
+ const char *psz_title, const char *psz_fmt, ...)
+ VLC_FORMAT(7,8);
+#define vlc_dialog_wait_login(a, b, c, d, e, f, g, ...) \
+ vlc_dialog_wait_login(VLC_OBJECT(a), b, c, d, e, f, g, ##__VA_ARGS__)
-static inline VLC_FORMAT(3, 4)
-void dialog_FatalWait (vlc_object_t *obj, const char *title,
- const char *fmt, ...){
- va_list ap;
+/**
+ * Requests an user name and a password
+ *
+ * Equivalent to vlc_dialog_wait_login() expect that it's called with a
+ * va_list.
+ */
+VLC_API int
+vlc_dialog_wait_login_va(vlc_object_t *p_obj, char **ppsz_username,
+ char **ppsz_password, bool *p_store,
+ const char *psz_default_username,
+ const char *psz_title, const char *psz_fmt, va_list ap);
- va_start (ap, fmt);
- dialog_VFatal(obj, true, title, fmt, ap);
- va_end (ap);
-}
-#define dialog_FatalWait(o, t, ...) \
- dialog_FatalWait(VLC_OBJECT(o), t, __VA_ARGS__)
+/**
+ * Asks a total (Yes/No/Cancel) question
+ *
+ * This function waits until the user dismisses the dialog or responds. It's
+ * interruptible via vlc_interrupt. In that case, vlc_dialog_cbs.pf_cancel()
+ * will be invoked. The psz_cancel is mandatory since this dialog is always
+ * cancellable by the user.
+ *
+ * @param p_obj the VLC object emitting the dialog
+ * @param i_type question type (severity of the question)
+ * @param psz_cancel text of the cancel button
+ * @param psz_action1 first choice/button text (optional)
+ * @param psz_action2 second choice/button text (optional)
+ * @param psz_title title of the question dialog
+ * @param psz_fmt format string for the question message
+ * @return < 0 on error, 0 if the user cancelled it, 1 on action1, 2 on action2
+ */
+VLC_API int
+vlc_dialog_wait_question(vlc_object_t *p_obj,
+ vlc_dialog_question_type i_type,
+ const char *psz_cancel, const char *psz_action1,
+ const char *psz_action2, const char *psz_title,
+ const char *psz_fmt, ...) VLC_FORMAT(7,8);
+#define vlc_dialog_wait_question(a, b, c, d, e, f, g, ...) \
+ vlc_dialog_wait_question(VLC_OBJECT(a), b, c, d, e, f, g, ##__VA_ARGS__)
/**
- * A login dialog.
+ * Asks a total (Yes/No/Cancel) question
+ *
+ * Equivalent to vlc_dialog_wait_question() expect that it's called with a
+ * va_list.
*/
-typedef struct dialog_login_t
-{
- const char *title;
- const char *message;
- const char *default_username;
- char **username;
- char **password;
- /* if store is NULL, password can't be stored (there is no keystore) */
- bool *store;
-} dialog_login_t;
+VLC_API int
+vlc_dialog_wait_question_va(vlc_object_t *p_obj,
+ vlc_dialog_question_type i_type,
+ const char *psz_cancel, const char *psz_action1,
+ const char *psz_action2, const char *psz_title,
+ const char *psz_fmt, va_list ap);
+
+/**
+ * Display a progress dialog
+ *
+ * This function returns immediately
+ *
+ * @param p_obj the VLC object emitting the dialog
+ * @param b_indeterminate true if the progress dialog is indeterminate
+ * @param f_position initial position of the progress bar (between 0.0 and 1.0)
+ * @param psz_cancel text of the cancel button, if NULL the dialog is not
+ * cancellable (optional)
+ * @param psz_title title of the progress dialog
+ * @param psz_fmt format string for the progress message
+ * @return a valid vlc_dialog_id on success, must be released with
+ * vlc_dialog_id_release()
+ */
+VLC_API vlc_dialog_id *
+vlc_dialog_display_progress(vlc_object_t *p_obj, bool b_indeterminate,
+ float f_position, const char *psz_cancel,
+ const char *psz_title, const char *psz_fmt, ...)
+ VLC_FORMAT(6,7);
+#define vlc_dialog_display_progress(a, b, c, d, e, f, ...) \
+ vlc_dialog_display_progress(VLC_OBJECT(a), b, c, d, e, f, ##__VA_ARGS__)
-VLC_API void dialog_Login(vlc_object_t *, const char *, char **, char **, bool *, const char *, const char *, ...) VLC_FORMAT (7, 8);
-#define dialog_Login(o, u, p, s, t, v, w, ...) \
- dialog_Login(VLC_OBJECT(o), u, p, s, t, v, w, __VA_ARGS__)
+/**
+ * Display a progress dialog
+ *
+ * Equivalent to vlc_dialog_display_progress() expect that it's called with a
+ * va_list.
+ */
+VLC_API vlc_dialog_id *
+vlc_dialog_display_progress_va(vlc_object_t *p_obj, bool b_indeterminate,
+ float f_position, const char *psz_cancel,
+ const char *psz_title, const char *psz_fmt,
+ va_list ap);
-VLC_API void dialog_vaLogin(vlc_object_t *, const char *, char **, char **, bool *, const char *, const char *, va_list args);
-#define dialog_vaLogin(o, u, p, s, t, v, w, x) \
- dialog_vaLogin(VLC_OBJECT(o), u, p, s, t, v, w, x)
+/**
+ * Update the position of the progress dialog
+ *
+ * @param f_position position of the progress bar (between 0.0 and 1.0)
+ * @return VLC_SUCCESS on success, or a VLC error code on error
+ */
+VLC_API int
+vlc_dialog_id_update_progress(vlc_dialog_id *p_id, float f_position);
+/**
+ * Update the position and the message of the progress dialog
+ *
+ * @param f_position position of the progress bar (between 0.0 and 1.0)
+ * @param psz_fmt format string for the progress message
+ * @return VLC_SUCCESS on success, or a VLC error code on error
+ */
+VLC_API int
+vlc_dialog_id_update_progress_text(vlc_dialog_id *p_id, float f_position,
+ const char *psz_fmt, ...);
/**
- * A question dialog.
+ * Update the position and the message of the progress dialog
+ *
+ * Equivalent to vlc_dialog_id_update_progress_text() expect that it's called
+ * with a va_list.
*/
-typedef struct dialog_question_t
+VLC_API int
+vlc_dialog_id_update_progress_text_va(vlc_dialog_id *p_id, float f_position,
+ const char *psz_fmt, va_list ap);
+
+/**
+ * Release the dialog id returned by vlc_dialog_display_progress(), causes the
+ * vlc_dialog_cbs.pf_cancel() callback to be invoked.
+ */
+VLC_API void
+vlc_dialog_id_release(vlc_dialog_id *p_id);
+
+/**
+ * Return true if the dialog id is cancelled
+ */
+VLC_API bool
+vlc_dialog_id_is_cancelled(vlc_dialog_id *p_id);
+
+/**
+ * @}
+ * @defgroup vlc_dialog_implementation Implemented by GUI modules or libvlc
+ * @{
+ */
+
+typedef enum vlc_dialog_type
+{
+ VLC_DIALOG_ERROR,
+ VLC_DIALOG_LOGIN,
+ VLC_DIALOG_QUESTION,
+ VLC_DIALOG_PROGRESS,
+} vlc_dialog_type;
+
+/** Dialog to be displayed */
+typedef struct vlc_dialog
{
- const char *title;
- const char *message;
- const char *yes;
- const char *no;
- const char *cancel;
- int answer;
-} dialog_question_t;
-
-VLC_API int dialog_Question(vlc_object_t *, const char *, const char *,
- const char *, const char *, const char *, ...)
-VLC_FORMAT(3, 7);
-#define dialog_Question(o, t, m, y, n, ...) \
- dialog_Question(VLC_OBJECT(o), t, m, y, n, __VA_ARGS__)
-
-typedef struct dialog_progress_bar_t
-{ /* Request-time parameters */
- const char *title;
- const char *message;
- const char *cancel;
- /* Permanent parameters */
- void (*pf_update) (void *, const char *, float);
- bool (*pf_check) (void *);
- void (*pf_destroy) (void *);
- void *p_sys;
-} dialog_progress_bar_t;
-
-VLC_API dialog_progress_bar_t * dialog_ProgressCreate(vlc_object_t *, const char *, const char *, const char *) VLC_USED;
-#define dialog_ProgressCreate(o, t, m, c) \
- dialog_ProgressCreate(VLC_OBJECT(o), t, m, c)
-VLC_API void dialog_ProgressDestroy(dialog_progress_bar_t *);
-VLC_API void dialog_ProgressSet(dialog_progress_bar_t *, const char *, float);
-VLC_API bool dialog_ProgressCancelled(dialog_progress_bar_t *);
-
-VLC_API int dialog_Register(vlc_object_t *);
-VLC_API int dialog_Unregister(vlc_object_t *);
-#define dialog_Register(o) dialog_Register(VLC_OBJECT(o))
-#define dialog_Unregister(o) dialog_Unregister(VLC_OBJECT(o))
-
-/** @} */
+ vlc_dialog_type i_type;
+ /** title of the dialog */
+ const char *psz_title;
+ /** text of the dialog */
+ const char *psz_text;
+
+ union
+ {
+ /** if i_type == VLC_DIALOG_LOGIN */
+ struct
+ {
+ /** default user name that should be set on the user form */
+ const char *psz_default_username;
+ /** if true, ask the user if he wants to save the credentials */
+ bool b_ask_store;
+ } login;
+ /** if i_type == VLC_DIALOG_QUESTION */
+ struct
+ {
+ /** question type (or severity) of the dialog */
+ vlc_dialog_question_type i_type;
+ /** text of the cancel button */
+ const char *psz_cancel;
+ /** text of the first button (optional) */
+ const char *psz_action1;
+ /** text of the second button (optional) */
+ const char *psz_action2;
+ } question;
+ /** if i_type == VLC_DIALOG_PROGRESS */
+ struct
+ {
+ /** true if the progress dialog is indeterminate */
+ bool b_indeterminate;
+ /** initial position of the progress bar (between 0.0 and 1.0) */
+ float f_position;
+ /** text of the cancel button, if NULL the dialog is not
+ * cancellable (optional) */
+ const char *psz_cancel;
+ } progress;
+ } u;
+} vlc_dialog;
+
+/**
+ * Dialog callbacks to be implemented
+ *
+ * pf_display and pf_cancel are mandatory.
+ */
+typedef struct vlc_dialog_cbs
+{
+ /**
+ * Called when a new dialog needs to be displayed
+ *
+ * @param p_id id used to interact with the dialog, can be null (for the
+ * VLC_DIALOG_ERROR case)
+ * @param p_dialog all informations that need to be displayed
+ * @param p_data opaque pointer for the callback
+ * @return true if the dialog is handled by the callback, false otherwise
+ */
+ bool (*pf_display)(vlc_dialog_id *p_id, vlc_dialog *p_dialog, void *p_data);
+ /**
+ * Called when a displayed dialog needs to be cancelled
+ *
+ * The implementation must call vlc_dialog_id_dismiss() to really release
+ * the dialog.
+ *
+ * @param p_id id of the dialog
+ * @param p_data opaque pointer for the callback
+ */
+ void (*pf_cancel)(vlc_dialog_id *p_id, void *p_data);
+ /**
+ * Called when a progress dialog needs to be updated (optional)
+ *
+ * @param p_id id of the dialog
+ * @param f_position osition of the progress bar (between 0.0 and 1.0)
+ * @param psz_text new text of the progress dialog
+ * @param p_data opaque pointer for the callback
+ */
+ void (*pf_update_progress)(vlc_dialog_id *p_id, float f_position,
+ const char *psz_text, void *p_data);
+} vlc_dialog_cbs;
+
+/**
+ * Register callbacks for the VLC dialog
+ *
+ * @param p_cbs a pointer to callbacks, or NULL to unregister callbacks.
+ * @param p_data opaque pointer for the callback
+ */
+VLC_API void
+vlc_dialog_provider_set_callbacks(vlc_object_t *p_obj,
+ vlc_dialog_cbs *p_cbs, void *p_data);
+#define vlc_dialog_provider_set_callbacks(a, b, c) \
+ vlc_dialog_provider_set_callbacks(VLC_OBJECT(a), b, c)
+
+/**
+ * Associate an opaque pointer with the dialog id
+ */
+VLC_API void
+vlc_dialog_id_set_context(vlc_dialog_id *p_id, void *p_context);
+
+/**
+ * Return the opaque pointer associated with the dialog id
+ */
+VLC_API void *
+vlc_dialog_id_get_context(vlc_dialog_id *p_id);
+
+/**
+ * Post a login answer
+ *
+ * After this call, p_id won't be valid anymore
+ *
+ * @param p_id id of the dialog
+ * @param psz_username valid and non empty string
+ * @param psz_password valid string (can be empty)
+ * @param b_store if true, store the credentials
+ * @return VLC_SUCCESS on success, or a VLC error code on error
+ */
+VLC_API int
+vlc_dialog_id_post_login(vlc_dialog_id *p_id, const char *psz_username,
+ const char *psz_password, bool b_store);
+
+/**
+ * Post a question answer
+ *
+ * After this call, p_id won't be valid anymore
+ *
+ * @param p_id id of the dialog
+ * @param i_action 1 or action1, 2 for action2
+ * @return VLC_SUCCESS on success, or a VLC error code on error
+ */
+VLC_API int
+vlc_dialog_id_post_action(vlc_dialog_id *p_id, int i_action);
+
+/**
+ * Dismiss a dialog
+ *
+ * After this call, p_id won't be valid anymore
+ *
+ * @param p_id id of the dialog
+ * @return VLC_SUCCESS on success, or a VLC error code on error
+ */
+VLC_API int
+vlc_dialog_id_dismiss(vlc_dialog_id *p_id);
+
+/** @} @} */
#endif
diff --git a/include/vlc_objects.h b/include/vlc_objects.h
index 598313e..12f754a 100644
--- a/include/vlc_objects.h
+++ b/include/vlc_objects.h
@@ -41,6 +41,8 @@ struct vlc_object_t
VLC_COMMON_MEMBERS
};
+typedef struct vlc_dialog_provider vlc_dialog_provider;
+
/*****************************************************************************
* Prototypes
*****************************************************************************/
diff --git a/modules/access/dvb/scan.c b/modules/access/dvb/scan.c
index f12d015..c6b7894 100644
--- a/modules/access/dvb/scan.c
+++ b/modules/access/dvb/scan.c
@@ -87,7 +87,7 @@ typedef struct
struct scan_t
{
vlc_object_t *p_obj;
- struct dialog_progress_bar_t *p_dialog;
+ vlc_dialog_id *p_dialog_id;
uint64_t i_index;
scan_parameter_t parameter;
int64_t i_time_start;
@@ -212,7 +212,7 @@ scan_t *scan_New( vlc_object_t *p_obj, const scan_parameter_t *p_parameter )
p_scan->p_obj = VLC_OBJECT(p_obj);
p_scan->i_index = 0;
- p_scan->p_dialog = NULL;
+ p_scan->p_dialog_id = NULL;
TAB_INIT( p_scan->i_service, p_scan->pp_service );
p_scan->parameter = *p_parameter;
p_scan->i_time_start = mdate();
@@ -222,8 +222,8 @@ scan_t *scan_New( vlc_object_t *p_obj, const scan_parameter_t *p_parameter )
void scan_Destroy( scan_t *p_scan )
{
- if( p_scan->p_dialog != NULL )
- dialog_ProgressDestroy( p_scan->p_dialog );
+ if( p_scan->p_dialog_id != NULL )
+ vlc_dialog_id_release( p_scan->p_dialog_id );
for( int i = 0; i < p_scan->i_service; i++ )
scan_service_Delete( p_scan->pp_service[i] );
@@ -647,7 +647,6 @@ int scan_Next( scan_t *p_scan, scan_configuration_t *p_cfg )
if( i_ret )
return i_ret;
- char *psz_text;
int i_service = 0;
for( int i = 0; i < p_scan->i_service; i++ )
@@ -658,18 +657,28 @@ int scan_Next( scan_t *p_scan, scan_configuration_t *p_cfg )
const mtime_t i_eta = f_position > 0.005 ? (mdate() - p_scan->i_time_start) * ( 1.0 / f_position - 1.0 ) : -1;
char psz_eta[MSTRTIME_MAX_SIZE];
+ const char *psz_fmt = _("%.1f MHz (%d services)\n~%s remaining");
- if( asprintf( &psz_text, _("%.1f MHz (%d services)\n~%s remaining"),
- (double)p_cfg->i_frequency / 1000000, i_service, secstotimestr( psz_eta, i_eta/1000000 ) ) >= 0 )
+ if( i_eta >= 0 )
+ msg_Info( p_scan->p_obj, "Scan ETA %s | %f", secstotimestr( psz_eta, i_eta/1000000 ), f_position * 100 );
+
+ if( p_scan->p_dialog_id == NULL )
{
- if( i_eta >= 0 )
- msg_Info( p_scan->p_obj, "Scan ETA %s | %f", secstotimestr( psz_eta, i_eta/1000000 ), f_position * 100 );
-
- if( p_scan->p_dialog == NULL )
- p_scan->p_dialog = dialog_ProgressCreate( p_scan->p_obj, _("Scanning DVB"), psz_text, _("Cancel") );
- if( p_scan->p_dialog != NULL )
- dialog_ProgressSet( p_scan->p_dialog, psz_text, f_position );
- free( psz_text );
+ p_scan->p_dialog_id =
+ vlc_dialog_display_progress( p_scan->p_obj, false,
+ f_position, _("Cancel"),
+ _("Scanning DVB"), psz_fmt,
+ (double)p_cfg->i_frequency / 1000000,
+ i_service,
+ secstotimestr( psz_eta, i_eta/1000000 ) );
+ }
+ else
+ {
+ vlc_dialog_id_update_progress_text( p_scan->p_dialog_id,
+ f_position, psz_fmt,
+ (double)p_cfg->i_frequency / 1000000,
+ i_service,
+ secstotimestr( psz_eta, i_eta/1000000 ) );
}
p_scan->i_index++;
@@ -678,7 +687,9 @@ int scan_Next( scan_t *p_scan, scan_configuration_t *p_cfg )
bool scan_IsCancelled( scan_t *p_scan )
{
- return p_scan->p_dialog && dialog_ProgressCancelled( p_scan->p_dialog );
+ if( p_scan->p_dialog_id == NULL )
+ return false;
+ return vlc_dialog_id_is_cancelled( p_scan->p_dialog_id );
}
static scan_service_t *ScanFindService( scan_t *p_scan, int i_service_start, int i_program )
diff --git a/modules/access_output/file.c b/modules/access_output/file.c
index 2e61e32..34a0329 100644
--- a/modules/access_output/file.c
+++ b/modules/access_output/file.c
@@ -318,12 +318,12 @@ static int Open( vlc_object_t *p_this )
break;
flags &= ~O_EXCL;
}
- while (dialog_Question (p_access, path,
- _("The output file already exists. "
- "If recording continues, the file will be "
- "overridden and its content will be lost."),
- _("Keep existing file"),
- _("Overwrite"), NULL) == 2);
+ while (vlc_dialog_wait_question (p_access, VLC_DIALOG_QUESTION_NORMAL,
+ _("Keep existing file"),
+ _("Overwrite"), NULL, path,
+ _("The output file already exists. "
+ "If recording continues, the file will be "
+ "overridden and its content will be lost.")) == 1);
free (buf);
if (fd == -1)
return VLC_EGENERIC;
diff --git a/modules/codec/libass.c b/modules/codec/libass.c
index 77240e7..920148a 100644
--- a/modules/codec/libass.c
+++ b/modules/codec/libass.c
@@ -225,19 +225,17 @@ static int Create( vlc_object_t *p_this )
#ifdef HAVE_FONTCONFIG
#if defined(_WIN32)
- dialog_progress_bar_t *p_dialog =
- dialog_ProgressCreate( p_dec,
- _("Building font cache"),
- _( "Please wait while your font cache is rebuilt.\n"
- "This should take less than a minute." ), NULL );
+ int i_ret =
+ vlc_dialog_display_progress( p_dec, true, 0.0, NULL,
+ _("Building font cache"),
+ _( "Please wait while your font cache is rebuilt.\n"
+ "This should take less than a minute." ) );
+ unsigned int i_dialog_id = i_ret > 0 ? i_ret : 0;
#endif
ass_set_fonts( p_renderer, psz_font, psz_family, 1, NULL, 1 ); // setup default font/family
#if defined(_WIN32)
- if( p_dialog )
- {
- dialog_ProgressSet( p_dialog, NULL, 1.0 );
- dialog_ProgressDestroy( p_dialog );
- }
+ if( i_dialog_id != 0 )
+ vlc_dialog_cancel( p_dec, i_dialog_id );
#endif
#else
ass_set_fonts( p_renderer, psz_font, psz_family, 1, NULL, 1 );
diff --git a/modules/demux/avi/avi.c b/modules/demux/avi/avi.c
index 425748a..fd41f03 100644
--- a/modules/demux/avi/avi.c
+++ b/modules/demux/avi/avi.c
@@ -753,22 +753,28 @@ aviindex:
}
if( i_do_index == 0 )
{
- switch( dialog_Question( p_demux, _("Broken or missing AVI Index") ,
- _( "Because this AVI file index is broken or missing, "
- "seeking will not work correctly.\n"
- "VLC won't repair your file but can temporary fix this "
- "problem by building an index in memory.\n"
- "This step might take a long time on a large file.\n"
- "What do you want to do?" ),
- _( "Build index then play" ), _( "Play as is" ), _( "Do not play") ) )
+ const char *psz_msg = _(
+ "Because this AVI file index is broken or missing, "
+ "seeking will not work correctly.\n"
+ "VLC won't repair your file but can temporary fix this "
+ "problem by building an index in memory.\n"
+ "This step might take a long time on a large file.\n"
+ "What do you want to do?");
+ switch( vlc_dialog_wait_question( p_demux,
+ VLC_DIALOG_QUESTION_NORMAL,
+ _("Do not play"),
+ _("Build index then play"),
+ _("Play as is"),
+ _("Broken or missing AVI Index"),
+ "%s", psz_msg ) )
{
+ case 0:
+ b_aborted = true;
+ goto error;
case 1:
b_index = true;
msg_Dbg( p_demux, "Fixing AVI index" );
goto aviindex;
- case 3:
- b_aborted = true;
- goto error;
}
}
else
@@ -2609,7 +2615,7 @@ static void AVI_IndexCreate( demux_t *p_demux )
off_t i_movi_end;
mtime_t i_dialog_update;
- dialog_progress_bar_t *p_dialog = NULL;
+ vlc_dialog_id *p_dialog_id = NULL;
p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0);
p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
@@ -2633,23 +2639,27 @@ static void AVI_IndexCreate( demux_t *p_demux )
/* Only show dialog if AVI is > 10MB */
i_dialog_update = mdate();
if( stream_Size( p_demux->s ) > 10000000 )
- p_dialog = dialog_ProgressCreate( p_demux, _("Fixing AVI Index..."),
- NULL, _("Cancel") );
+ {
+ p_dialog_id =
+ vlc_dialog_display_progress( p_demux, false, 0.0, _("Cancel"),
+ _("Broken or missing AVI Index"),
+ _("Fixing AVI Index...") );
+ }
for( ;; )
{
avi_packet_t pk;
/* Don't update/check dialog too often */
- if( p_dialog && mdate() - i_dialog_update > 100000 )
+ if( p_dialog_id != NULL && mdate() - i_dialog_update > 100000 )
{
- if( dialog_ProgressCancelled( p_dialog ) )
+ if( vlc_dialog_id_is_cancelled( p_dialog_id ) )
break;
double f_current = stream_Tell( p_demux->s );
double f_size = stream_Size( p_demux->s );
double f_pos = f_current / f_size;
- dialog_ProgressSet( p_dialog, NULL, f_pos );
+ vlc_dialog_id_update_progress( p_dialog_id, f_pos );
i_dialog_update = mdate();
}
@@ -2714,8 +2724,8 @@ static void AVI_IndexCreate( demux_t *p_demux )
}
print_stat:
- if( p_dialog != NULL )
- dialog_ProgressDestroy( p_dialog );
+ if( p_dialog_id != NULL )
+ vlc_dialog_id_release( p_dialog_id );
for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
{
diff --git a/modules/gui/qt4/dialogs/external.cpp b/modules/gui/qt4/dialogs/external.cpp
index 9c7ebfd..85d3912 100644
--- a/modules/gui/qt4/dialogs/external.cpp
+++ b/modules/gui/qt4/dialogs/external.cpp
@@ -23,96 +23,171 @@
# include <config.h>
#endif
-//#include "qt4.hpp"
#include "external.hpp"
#include "errors.hpp"
-#include <vlc_dialog.h>
-#include <QDialog>
+#include <assert.h>
+
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QProgressDialog>
-#include <QMutex>
#include <QPushButton>
-#include <QTimer>
DialogHandler::DialogHandler (intf_thread_t *p_intf, QObject *_parent)
- : QObject( _parent ), p_intf (p_intf),
- critical (VLC_OBJECT(p_intf), "dialog-critical"),
- login (VLC_OBJECT(p_intf), "dialog-login"),
- question (VLC_OBJECT(p_intf), "dialog-question"),
- progressBar (VLC_OBJECT(p_intf), "dialog-progress-bar")
+ : QObject( _parent ), p_intf (p_intf)
+{
+ vlc_dialog_cbs cbs = {
+ displayCb,
+ cancelCb,
+ updateProgressCb
+ };
+ vlc_dialog_provider_set_callbacks(p_intf, &cbs, this);
+
+ CONNECT(this, errorDisplayed(const QString &, const QString &),
+ this, displayError(const QString &, const QString &));
+
+ CONNECT(this, loginDisplayed(vlc_dialog_id *, const QString &,
+ const QString &, const QString &, bool),
+ this, displayLogin(vlc_dialog_id *, const QString &, const QString &,
+ const QString &, bool));
+
+ CONNECT(this, questionDisplayed(vlc_dialog_id *, const QString &,
+ const QString &, int, const QString &,
+ const QString &, const QString &),
+ this, displayQuestion(vlc_dialog_id *, const QString &, const QString &,
+ int, const QString &, const QString &,
+ const QString &));
+
+ CONNECT(this, progressDisplayed(vlc_dialog_id *, const QString &, const QString &,
+ bool, float, const QString &),
+ this, displayProgress(vlc_dialog_id *, const QString &, const QString &,
+ bool, float, const QString &));
+
+ CONNECT(this, cancelled(vlc_dialog_id *), this, cancel(vlc_dialog_id *));
+
+ CONNECT(this, progressUpdated(vlc_dialog_id *, float, const QString &),
+ this, updateProgress(vlc_dialog_id *, float, const QString &));
+}
+
+DialogHandler::~DialogHandler()
{
- var_Create (p_intf, "dialog-error", VLC_VAR_ADDRESS);
- var_AddCallback (p_intf, "dialog-error", error, this);
- connect (this, SIGNAL(error(const QString &, const QString &)),
- SLOT(displayError(const QString &, const QString &)));
-
- critical.addCallback(this, SLOT(displayCritical(void *)),
- Qt::BlockingQueuedConnection);
- login.addCallback(this, SLOT(requestLogin(void *)),
- Qt::BlockingQueuedConnection);
- question.addCallback(this, SLOT(requestAnswer(void *)),
- Qt::BlockingQueuedConnection);
- progressBar.addCallback(this, SLOT(startProgressBar(void *)),
- Qt::BlockingQueuedConnection);
-
- dialog_Register (p_intf);
+ vlc_dialog_provider_set_callbacks(p_intf, NULL, NULL);
}
-DialogHandler::~DialogHandler (void)
+bool DialogHandler::displayCb(vlc_dialog_id *p_id, vlc_dialog *p_dialog,
+ void *p_data)
{
- dialog_Unregister (p_intf);
+ DialogHandler *self = static_cast<DialogHandler *>(p_data);
+ const QString title = qfu(p_dialog->psz_title);
+ const QString text = qfu(p_dialog->psz_text);
- var_DelCallback (p_intf, "dialog-error", error, this);
- var_Destroy (p_intf, "dialog-error");
+ switch (p_dialog->i_type)
+ {
+ case VLC_DIALOG_ERROR:
+ emit self->errorDisplayed(title, text);
+ break;
+ case VLC_DIALOG_LOGIN:
+ {
+ assert(p_id != NULL);
+ const QString defaultUsername =
+ p_dialog->u.login.psz_default_username != NULL ?
+ qfu(p_dialog->u.login.psz_default_username) : QString();
+
+ emit self->loginDisplayed(p_id, title, text, defaultUsername,
+ p_dialog->u.login.b_ask_store);
+ break;
+ }
+ case VLC_DIALOG_QUESTION:
+ {
+ assert(p_id != NULL);
+ const QString cancel = qfu(p_dialog->u.question.psz_cancel);
+ const QString action1 = p_dialog->u.question.psz_action1 != NULL ?
+ qfu(p_dialog->u.question.psz_action1) : QString();
+ const QString action2 = p_dialog->u.question.psz_action2 != NULL ?
+ qfu(p_dialog->u.question.psz_action2) : QString();
+
+ emit self->questionDisplayed(p_id, title, text,
+ p_dialog->u.question.i_type,
+ cancel, action1, action2);
+ break;
+ }
+ case VLC_DIALOG_PROGRESS:
+ {
+ assert(p_id != NULL);
+ const QString cancel = p_dialog->u.progress.psz_cancel != NULL ?
+ qfu(p_dialog->u.progress.psz_cancel) : QString();
+ emit self->progressDisplayed(p_id, title, text,
+ p_dialog->u.progress.b_indeterminate,
+ p_dialog->u.progress.f_position, cancel);
+ break;
+ }
+ }
+ return true;
}
-int DialogHandler::error (vlc_object_t *obj, const char *,
- vlc_value_t, vlc_value_t value, void *data)
+void DialogHandler::cancelCb(vlc_dialog_id *p_id, void *p_data)
{
- const dialog_fatal_t *dialog = (const dialog_fatal_t *)value.p_address;
- DialogHandler *self = static_cast<DialogHandler *>(data);
+ DialogHandler *self = static_cast<DialogHandler *>(p_data);
+ emit self->cancelled(p_id);
+}
- if (var_InheritBool (obj, "qt-error-dialogs"))
- emit self->error (qfu(dialog->title), qfu(dialog->message));
- return VLC_SUCCESS;
+void DialogHandler::updateProgressCb(vlc_dialog_id *p_id, float f_value,
+ const char *psz_text, void *p_data)
+{
+ DialogHandler *self = static_cast<DialogHandler *>(p_data);
+ emit self->progressUpdated(p_id, f_value, qfu(psz_text));
}
-void DialogHandler::displayError (const QString& title, const QString& message)
+void DialogHandler::cancel(vlc_dialog_id *p_id)
{
- ErrorsDialog::getInstance (p_intf)->addError(title, message);
+ DialogWrapper *p_wrapper =
+ static_cast<DialogWrapper *>(vlc_dialog_id_get_context(p_id));
+ if (p_wrapper != NULL)
+ p_wrapper->finish(QDialog::Rejected);
}
-void DialogHandler::displayCritical (void *value)
+void DialogHandler::updateProgress(vlc_dialog_id *p_id, float f_value,
+ const QString &text)
{
- const dialog_fatal_t *dialog = (const dialog_fatal_t *)value;
+ DialogWrapper *p_wrapper =
+ static_cast<DialogWrapper *>(vlc_dialog_id_get_context(p_id));
- QMessageBox::critical (NULL, qfu(dialog->title), qfu(dialog->message),
- QMessageBox::Ok);
+ ProgressDialogWrapper *p_progress_wrapper
+ = dynamic_cast<ProgressDialogWrapper *>(p_wrapper);
+
+ if (p_progress_wrapper != NULL)
+ p_progress_wrapper->updateProgress(f_value, text);
}
-void DialogHandler::requestLogin (void *value)
+void DialogHandler::displayError(const QString &title, const QString &text)
{
- dialog_login_t *data = (dialog_login_t *)value;
- QDialog *dialog = new QDialog;
+ ErrorsDialog::getInstance (p_intf)->addError(title, text);
+}
+
+void DialogHandler::displayLogin(vlc_dialog_id *p_id, const QString &title,
+ const QString &text,
+ const QString &defaultUsername,
+ bool b_ask_store)
+{
+ QDialog *dialog = new QDialog();
QLayout *layout = new QVBoxLayout (dialog);
- dialog->setWindowTitle (qfu(data->title));
+ dialog->setWindowTitle (title);
dialog->setWindowRole ("vlc-login");
+ dialog->setModal(true);
layout->setMargin (2);
/* Username and password fields */
QWidget *panel = new QWidget (dialog);
QGridLayout *grid = new QGridLayout;
- grid->addWidget (new QLabel (qfu(data->message)), 0, 0, 1, 2);
+ grid->addWidget (new QLabel (text), 0, 0, 1, 2);
QLineEdit *userLine = new QLineEdit;
- if (data->default_username != NULL)
- userLine->setText(qtr(data->default_username));
+ if (!defaultUsername.isEmpty())
+ userLine->setText(defaultUsername);
grid->addWidget (new QLabel (qtr("Username")), 1, 0);
grid->addWidget (userLine, 1, 1);
@@ -122,7 +197,7 @@ void DialogHandler::requestLogin (void *value)
grid->addWidget (passLine, 2, 1);
QCheckBox *checkbox = NULL;
- if (data->store != NULL)
+ if (b_ask_store)
{
checkbox = new QCheckBox;
checkbox->setChecked (getSettings()->value ("store_password", true).toBool ());
@@ -134,7 +209,7 @@ void DialogHandler::requestLogin (void *value)
layout->addWidget (panel);
/* focus on passLine if the username is already set */
- if (data->default_username != NULL)
+ if (!defaultUsername.isEmpty())
passLine->setFocus();
/* OK, Cancel buttons */
@@ -148,126 +223,172 @@ void DialogHandler::requestLogin (void *value)
CONNECT( buttonBox, rejected(), dialog, reject() );
layout->addWidget (buttonBox);
- /* Run the dialog */
dialog->setLayout (layout);
+ vlc_dialog_id_set_context(p_id,
+ new LoginDialogWrapper(this, p_intf, p_id, dialog, userLine, passLine,
+ checkbox));
+ dialog->show();
+}
- if (dialog->exec ())
+void
+DialogHandler::displayQuestion(vlc_dialog_id *p_id, const QString &title,
+ const QString &text, int i_type,
+ const QString &cancel, const QString &action1,
+ const QString &action2)
+{
+ enum QMessageBox::Icon icon;
+ switch (i_type)
{
- *data->username = strdup (qtu(userLine->text ()));
- *data->password = strdup (qtu(passLine->text ()));
- if (data->store != NULL)
- {
- *data->store = checkbox->isChecked ();
- getSettings()->setValue ("store_password", *data->store);
- }
+ case VLC_DIALOG_QUESTION_WARNING:
+ icon = QMessageBox::Warning;
+ break;
+ case VLC_DIALOG_QUESTION_CRITICAL:
+ icon = QMessageBox::Critical;
+ break;
+ default:
+ case VLC_DIALOG_QUESTION_NORMAL:
+ icon = action1.isEmpty() && action2.isEmpty() ?
+ QMessageBox::Information : QMessageBox::Question;
+ break;
}
+ QMessageBox *box = new QMessageBox (icon, title, text);
+ box->addButton ("&" + cancel, QMessageBox::RejectRole);
+ box->setModal(true);
+ QAbstractButton *action1Button = NULL;
+ if (!action1.isEmpty())
+ action1Button = box->addButton("&" + action1, QMessageBox::AcceptRole);
+ QAbstractButton *action2Button = NULL;
+ if (!action2.isEmpty())
+ action2Button = box->addButton("&" + action2, QMessageBox::AcceptRole);
+
+ vlc_dialog_id_set_context(p_id,
+ new QuestionDialogWrapper(this, p_intf, p_id, box, action1Button,
+ action2Button));
+ box->show();
+}
+
+void DialogHandler::displayProgress(vlc_dialog_id *p_id, const QString &title,
+ const QString &text, bool b_indeterminate,
+ float f_position, const QString &cancel)
+{
+ QProgressDialog *progress =
+ new QProgressDialog(text, cancel.isEmpty() ? QString() : "&" + cancel,
+ 0, b_indeterminate ? 0 : 1000);
+ progress->setWindowTitle(title);
+ if (!cancel.isEmpty())
+ progress->setModal(true);
else
{
- *data->username = *data->password = NULL;
- if (data->store != NULL)
- *data->store = false;
+ /* not cancellable: remove close button */
+ progress->setWindowFlags(Qt::Window | Qt::WindowTitleHint |
+ Qt::CustomizeWindowHint);
}
+ progress->setWindowRole ("vlc-progress");
+ progress->setValue(b_indeterminate ? 0 : f_position * 1000);
- delete dialog;
+ vlc_dialog_id_set_context(p_id,
+ new ProgressDialogWrapper(this, p_intf, p_id, progress, b_indeterminate));
+
+ progress->show();
}
-void DialogHandler::requestAnswer (void *value)
+DialogWrapper::DialogWrapper(DialogHandler *p_handler, intf_thread_t *p_intf,
+ vlc_dialog_id *p_id, QDialog *p_dialog)
+ : QObject()
+ , p_handler(p_handler)
+ , p_intf(p_intf)
+ , p_id(p_id)
+ , p_dialog(p_dialog)
{
- dialog_question_t *data = (dialog_question_t *)value;
-
- QMessageBox *box = new QMessageBox (QMessageBox::Question,
- qfu(data->title), qfu(data->message));
- QAbstractButton *yes = (data->yes != NULL)
- ? box->addButton ("&" + qfu(data->yes), QMessageBox::YesRole) : NULL;
- QAbstractButton *no = (data->no != NULL)
- ? box->addButton ("&" + qfu(data->no), QMessageBox::NoRole) : NULL;
- if (data->cancel != NULL)
- box->addButton ("&" + qfu(data->cancel), QMessageBox::RejectRole);
-
- box->exec ();
-
- int answer;
- if (box->clickedButton () == yes)
- answer = 1;
- else
- if (box->clickedButton () == no)
- answer = 2;
- else
- answer = 3;
-
- delete box;
- data->answer = answer;
+ CONNECT(p_dialog, finished(int), this, finish(int));
}
-
-QVLCProgressDialog::QVLCProgressDialog (DialogHandler *parent,
- struct dialog_progress_bar_t *data)
- : QProgressDialog (qfu(data->message),
- data->cancel ? ("&" + qfu(data->cancel)) : 0, 0, 1000),
- handler (parent),
- cancelled (false)
+DialogWrapper::~DialogWrapper()
{
- if (data->cancel)
- setWindowModality (Qt::ApplicationModal);
- if (data->title != NULL)
- setWindowTitle (qfu(data->title));
-
- setWindowRole ("vlc-progress");
- setValue( 0 );
-
- connect (this, SIGNAL(progressed(int)), SLOT(setValue(int)));
- connect (this, SIGNAL(described(const QString&)),
- SLOT(setLabelText(const QString&)));
- connect (this, SIGNAL(canceled(void)), SLOT(saveCancel(void)));
- connect (this, SIGNAL(released(void)), SLOT(deleteLater(void)));
-
- data->pf_update = update;
- data->pf_check = check;
- data->pf_destroy = destroy;
- data->p_sys = this;
+ p_dialog->hide();
+ delete p_dialog;
}
-void QVLCProgressDialog::update (void *priv, const char *text, float value)
+void DialogWrapper::finish(int result)
{
- QVLCProgressDialog *self = static_cast<QVLCProgressDialog *>(priv);
-
- if (text != NULL)
- emit self->described (qfu(text));
- emit self->progressed ((int)(value * 1000.));
+ if (result == QDialog::Rejected && p_id != NULL)
+ {
+ vlc_dialog_id_dismiss(p_id);
+ p_id = NULL;
+ }
+ deleteLater();
}
-static QMutex cancel_mutex;
-
-bool QVLCProgressDialog::check (void *priv)
+LoginDialogWrapper::LoginDialogWrapper(DialogHandler *p_handler,
+ intf_thread_t *p_intf, vlc_dialog_id *p_id,
+ QDialog *p_dialog, QLineEdit *userLine,
+ QLineEdit *passLine, QCheckBox *checkbox)
+ : DialogWrapper(p_handler, p_intf, p_id, p_dialog)
+ , userLine(userLine)
+ , passLine(passLine)
+ , checkbox(checkbox)
{
- QVLCProgressDialog *self = static_cast<QVLCProgressDialog *>(priv);
- QMutexLocker locker (&cancel_mutex);
- return self->cancelled;
+ CONNECT(p_dialog, accepted(), this, accept());
}
-void QVLCProgressDialog::destroy (void *priv)
+void LoginDialogWrapper::accept()
{
- QVLCProgressDialog *self = static_cast<QVLCProgressDialog *>(priv);
-
- emit self->released ();
+ if (p_id != NULL)
+ {
+ vlc_dialog_id_post_login(p_id, qtu(userLine->text ()),
+ qtu(passLine->text ()),
+ checkbox != NULL ? checkbox->isChecked () : false);
+ p_id = NULL;
+ if (checkbox != NULL)
+ getSettings()->setValue ("store_password", checkbox->isChecked ());
+ }
}
-void QVLCProgressDialog::saveCancel (void)
+QuestionDialogWrapper::QuestionDialogWrapper(DialogHandler *p_handler,
+ intf_thread_t *p_intf,
+ vlc_dialog_id *p_id,
+ QMessageBox *p_box,
+ QAbstractButton *action1,
+ QAbstractButton *action2)
+ : DialogWrapper(p_handler, p_intf, p_id, p_box)
+ , action1(action1)
+ , action2(action2)
{
- QMutexLocker locker (&cancel_mutex);
- cancelled = true;
+ CONNECT(p_box, buttonClicked(QAbstractButton *),
+ this, buttonClicked(QAbstractButton *));
}
-void DialogHandler::startProgressBar (void *value)
+void QuestionDialogWrapper::buttonClicked(QAbstractButton *button)
{
- dialog_progress_bar_t *data = (dialog_progress_bar_t *)value;
- QWidget *dlg = new QVLCProgressDialog (this, data);
+ if (p_id != NULL)
+ {
+ if (button == action1)
+ vlc_dialog_id_post_action(p_id, 1);
+ else if (button == action2)
+ vlc_dialog_id_post_action(p_id, 2);
+ else
+ vlc_dialog_id_dismiss(p_id);
+ p_id = NULL;
+ }
+}
- QTimer::singleShot( 1500, dlg, SLOT( show() ) );
-// dlg->show ();
+ProgressDialogWrapper::ProgressDialogWrapper(DialogHandler *p_handler,
+ intf_thread_t *p_intf,
+ vlc_dialog_id *p_id,
+ QProgressDialog *p_progress,
+ bool b_indeterminate)
+ : DialogWrapper(p_handler, p_intf, p_id, p_progress)
+ , b_indeterminate(b_indeterminate)
+{
+ CONNECT(p_progress, canceled(void), this, finish(void));
}
-void DialogHandler::stopProgressBar (QWidget *dlg)
+void ProgressDialogWrapper::updateProgress(float f_position, const QString &text)
{
- delete dlg;
+ if (!b_indeterminate)
+ {
+ QProgressDialog *progress = static_cast<QProgressDialog *>(p_dialog);
+ progress->setLabelText(text);
+ progress->setValue(f_position * 1000);
+ }
}
diff --git a/modules/gui/qt4/dialogs/external.hpp b/modules/gui/qt4/dialogs/external.hpp
index 1a8fe68..f955f08 100644
--- a/modules/gui/qt4/dialogs/external.hpp
+++ b/modules/gui/qt4/dialogs/external.hpp
@@ -26,65 +26,125 @@
#endif
#include <QObject>
+#include <QDialog>
+#include <QMap>
#include <vlc_common.h>
+#include <vlc_dialog.h>
#include "adapters/variables.hpp"
struct intf_thread_t;
class QProgressDialog;
+class DialogWrapper;
class DialogHandler : public QObject
{
Q_OBJECT
- friend class QVLCProgressDialog;
-
public:
DialogHandler (intf_thread_t *, QObject *parent);
- virtual ~DialogHandler (void);
+ virtual ~DialogHandler();
+ void removeDialogId(vlc_dialog_id *p_id);
-private:
- intf_thread_t *p_intf;
- static int error (vlc_object_t *, const char *, vlc_value_t, vlc_value_t,
- void *);
- QVLCPointer critical;
- QVLCPointer login;
- QVLCPointer question;
- QVLCPointer progressBar;
signals:
- void error (const QString&, const QString&);
+ void errorDisplayed(const QString &title, const QString &text);
+ void loginDisplayed(vlc_dialog_id *p_id, const QString &title,
+ const QString &text, const QString &defaultUsername,
+ bool b_ask_store);
+ void questionDisplayed(vlc_dialog_id *p_id, const QString &title,
+ const QString &text, int i_type,
+ const QString &cancel, const QString &action1,
+ const QString &action2);
+ void progressDisplayed(vlc_dialog_id *p_id, const QString &title,
+ const QString &text, bool b_indeterminate,
+ float f_position, const QString &cancel);
+ void cancelled(vlc_dialog_id *p_id);
+ void progressUpdated(vlc_dialog_id *p_id, float f_value, const QString &text);
private slots:
- void displayError (const QString&, const QString&);
- void displayCritical (void *);
- void requestLogin (void *);
- void requestAnswer (void *);
- void startProgressBar (void *);
- void stopProgressBar (QWidget *);
+ void displayError(const QString &title, const QString &text);
+ void displayLogin(vlc_dialog_id *p_id, const QString &title,
+ const QString &text, const QString &defaultUsername,
+ bool b_ask_store);
+ void displayQuestion(vlc_dialog_id *p_id, const QString &title,
+ const QString &text, int i_type,
+ const QString &cancel, const QString &action1,
+ const QString &action2);
+ void displayProgress(vlc_dialog_id *p_id, const QString &title,
+ const QString &text, bool b_indeterminate,
+ float f_position, const QString &cancel);
+ void cancel(vlc_dialog_id *p_id);
+ void updateProgress(vlc_dialog_id *p_id, float f_value, const QString &text);
+
+private:
+ intf_thread_t *p_intf;
+
+ static bool displayCb(vlc_dialog_id *, vlc_dialog *, void *);
+ static void cancelCb(vlc_dialog_id *, void *);
+ static void updateProgressCb(vlc_dialog_id *, float, const char *, void *);
};
-/* Put here instead of .cpp because of MOC */
-#include <QProgressDialog>
+class DialogWrapper : public QObject
+{
+ Q_OBJECT
+
+ friend class DialogHandler;
+public:
+ DialogWrapper(DialogHandler *p_handler, intf_thread_t *p_intf,
+ vlc_dialog_id *p_id, QDialog *p_dialog);
+ virtual ~DialogWrapper();
+protected slots:
+ virtual void finish(int result = QDialog::Rejected);
+protected:
+ DialogHandler *p_handler;
+ intf_thread_t *p_intf;
+ vlc_dialog_id *p_id;
+ QDialog *p_dialog;
+};
-class QVLCProgressDialog : public QProgressDialog
+class QLineEdit;
+class QCheckBox;
+class LoginDialogWrapper : public DialogWrapper
{
Q_OBJECT
public:
- QVLCProgressDialog (DialogHandler *parent,
- struct dialog_progress_bar_t *);
+ LoginDialogWrapper(DialogHandler *p_handler, intf_thread_t *p_intf,
+ vlc_dialog_id *p_id, QDialog *p_dialog,
+ QLineEdit *userLine, QLineEdit *passLine,
+ QCheckBox *checkbox);
+private slots:
+ virtual void accept();
private:
- DialogHandler *handler;
- bool cancelled;
+ QLineEdit *userLine;
+ QLineEdit *passLine;
+ QCheckBox *checkbox;
+};
- static void update (void *, const char *, float);
- static bool check (void *);
- static void destroy (void *);
+class QAbstractButton;
+class QMessageBox;
+class QuestionDialogWrapper : public DialogWrapper
+{
+ Q_OBJECT
+public:
+ QuestionDialogWrapper(DialogHandler *p_handler, intf_thread_t *p_intf,
+ vlc_dialog_id *p_id, QMessageBox *p_box,
+ QAbstractButton *action1, QAbstractButton *action2);
private slots:
- void saveCancel (void);
+ virtual void buttonClicked(QAbstractButton *);
+private:
+ QAbstractButton *action1;
+ QAbstractButton *action2;
+};
-signals:
- void progressed (int);
- void described (const QString&);
- void released (void);
+class ProgressDialogWrapper : public DialogWrapper
+{
+ Q_OBJECT
+public:
+ ProgressDialogWrapper(DialogHandler *p_handler, intf_thread_t *p_intf,
+ vlc_dialog_id *p_id, QProgressDialog *p_progress,
+ bool b_indeterminate);
+ void updateProgress(float f_position, const QString &text);
+private:
+ bool b_indeterminate;
};
#endif
diff --git a/modules/lua/extension.c b/modules/lua/extension.c
index 9546e4c..da75e40 100644
--- a/modules/lua/extension.c
+++ b/modules/lua/extension.c
@@ -964,10 +964,10 @@ int lua_ExecuteFunctionVa( extensions_manager_t *p_mgr, extension_t *p_ext,
// Reset watch timer and timestamp
vlc_mutex_lock( &p_ext->p_sys->command_lock );
- if( p_ext->p_sys->progress )
+ if( p_ext->p_sys->p_progress_id != NULL )
{
- dialog_ProgressDestroy( p_ext->p_sys->progress );
- p_ext->p_sys->progress = NULL;
+ vlc_dialog_id_release( p_ext->p_sys->p_progress_id );
+ p_ext->p_sys->p_progress_id = NULL;
}
vlc_timer_schedule( p_ext->p_sys->timer, false, 0, 0 );
vlc_mutex_unlock( &p_ext->p_sys->command_lock );
@@ -1021,10 +1021,10 @@ int lua_ExtensionTriggerMenu( extensions_manager_t *p_mgr,
// Reset watch timer and timestamp
vlc_mutex_lock( &p_ext->p_sys->command_lock );
- if( p_ext->p_sys->progress )
+ if( p_ext->p_sys->p_progress_id != NULL )
{
- dialog_ProgressDestroy( p_ext->p_sys->progress );
- p_ext->p_sys->progress = NULL;
+ vlc_dialog_id_release( p_ext->p_sys->p_progress_id );
+ p_ext->p_sys->p_progress_id = NULL;
}
vlc_timer_schedule( p_ext->p_sys->timer, false, 0, 0 );
vlc_mutex_unlock( &p_ext->p_sys->command_lock );
@@ -1106,10 +1106,10 @@ int vlclua_extension_keep_alive( lua_State *L )
extension_t *p_ext = vlclua_extension_get( L );
vlc_mutex_lock( &p_ext->p_sys->command_lock );
- if( p_ext->p_sys->progress )
+ if( p_ext->p_sys->p_progress_id != NULL )
{
- dialog_ProgressDestroy( p_ext->p_sys->progress );
- p_ext->p_sys->progress = NULL;
+ vlc_dialog_id_release( p_ext->p_sys->p_progress_id );
+ p_ext->p_sys->p_progress_id = NULL;
}
vlc_timer_schedule( p_ext->p_sys->timer, false, WATCH_TIMER_PERIOD, 0 );
vlc_mutex_unlock( &p_ext->p_sys->command_lock );
@@ -1211,14 +1211,6 @@ static void WatchTimerCallback( void *data )
extension_t *p_ext = data;
extensions_manager_t *p_mgr = p_ext->p_sys->p_mgr;
- char *message;
- if( asprintf( &message, _( "Extension '%s' does not respond.\n"
- "Do you want to kill it now? " ),
- p_ext->psz_title ) == -1 )
- {
- return;
- }
-
vlc_mutex_lock( &p_ext->p_sys->command_lock );
for( struct command_t *cmd = p_ext->p_sys->command;
@@ -1226,30 +1218,39 @@ static void WatchTimerCallback( void *data )
cmd = cmd->next )
if( cmd->i_command == CMD_DEACTIVATE )
{ /* We have a pending Deactivate command... */
- if( p_ext->p_sys->progress )
+ if( p_ext->p_sys->p_progress_id != NULL )
{
- dialog_ProgressDestroy( p_ext->p_sys->progress );
- p_ext->p_sys->progress = NULL;
+ vlc_dialog_id_release( p_ext->p_sys->p_progress_id );
+ p_ext->p_sys->p_progress_id = NULL;
}
vlc_mutex_unlock( &p_ext->p_sys->command_lock );
KillExtension( p_mgr, p_ext );
return;
}
- if( !p_ext->p_sys->progress )
+ if( p_ext->p_sys->p_progress_id == NULL )
{
- p_ext->p_sys->progress =
- dialog_ProgressCreate( p_mgr, _( "Extension not responding!" ),
- message,
- _( "Yes" ) );
+ p_ext->p_sys->p_progress_id =
+ vlc_dialog_display_progress( p_mgr, true, 0.0,
+ _( "Yes" ),
+ _( "Extension not responding!" ),
+ _( "Extension '%s' does not respond.\n"
+ "Do you want to kill it now? " ),
+ p_ext->psz_title );
+ if( p_ext->p_sys->p_progress_id == NULL )
+ {
+ vlc_mutex_unlock( &p_ext->p_sys->command_lock );
+ KillExtension( p_mgr, p_ext );
+ return;
+ }
vlc_timer_schedule( p_ext->p_sys->timer, false, 100000, 0 );
}
else
{
- if( dialog_ProgressCancelled( p_ext->p_sys->progress ) )
+ if( vlc_dialog_id_is_cancelled( p_ext->p_sys->p_progress_id ) )
{
- dialog_ProgressDestroy( p_ext->p_sys->progress );
- p_ext->p_sys->progress = NULL;
+ vlc_dialog_id_release( p_ext->p_sys->p_progress_id );
+ p_ext->p_sys->p_progress_id = NULL;
vlc_mutex_unlock( &p_ext->p_sys->command_lock );
KillExtension( p_mgr, p_ext );
return;
diff --git a/modules/lua/extension.h b/modules/lua/extension.h
index 69f1705..1626334 100644
--- a/modules/lua/extension.h
+++ b/modules/lua/extension.h
@@ -91,7 +91,7 @@ struct extension_sys_t
} *command;
// The two following booleans are protected by command_lock
- dialog_progress_bar_t *progress;
+ vlc_dialog_id *p_progress_id;
vlc_timer_t timer; ///< This timer makes sure Lua never gets stuck >5s
bool b_exiting;
diff --git a/modules/lua/extension_thread.c b/modules/lua/extension_thread.c
index 17d4276..61e88e7 100644
--- a/modules/lua/extension_thread.c
+++ b/modules/lua/extension_thread.c
@@ -149,11 +149,11 @@ int Deactivate( extensions_manager_t *p_mgr, extension_t *p_ext )
return VLC_EGENERIC;
}
- if( p_ext->p_sys->progress )
+ if( p_ext->p_sys->p_progress_id != NULL )
{
// Extension is stuck, kill it now
- dialog_ProgressDestroy( p_ext->p_sys->progress );
- p_ext->p_sys->progress = NULL;
+ vlc_dialog_id_release( p_ext->p_sys->p_progress_id );
+ p_ext->p_sys->p_progress_id = NULL;
vlc_mutex_unlock( &p_ext->p_sys->command_lock );
KillExtension( p_mgr, p_ext );
return VLC_SUCCESS;
diff --git a/modules/misc/gnutls.c b/modules/misc/gnutls.c
index 43ef396..692f901 100644
--- a/modules/misc/gnutls.c
+++ b/modules/misc/gnutls.c
@@ -490,13 +490,13 @@ error:
goto error;
}
- if (dialog_Question(creds, _("Insecure site"),
- _("You attempted to reach %s. %s\n"
- "This problem may be stem from an attempt to breach your security, "
- "compromise your privacy, or a configuration error.\n\n"
- "If in doubt, abort now.\n"),
- _("Abort"), _("View certificate"), NULL,
- vlc_gettext(msg), host) != 2)
+ if (vlc_dialog_wait_question(creds, VLC_DIALOG_QUESTION_NORMAL,
+ _("Abort"), _("View certificate"), NULL,
+ _("Insecure site"),
+ _("You attempted to reach %s. %s\n"
+ "This problem may be stem from an attempt to breach your security, "
+ "compromise your privacy, or a configuration error.\n\n"
+ "If in doubt, abort now.\n"), host, vlc_gettext(msg)) != 1)
goto error;
gnutls_x509_crt_t cert;
@@ -511,20 +511,20 @@ error:
}
gnutls_x509_crt_deinit (cert);
- val = dialog_Question(creds, _("Insecure site"),
- _("This is the certificate presented by %s:\n%s\n\n"
- "If in doubt, abort now.\n"),
- _("Abort"), _("Accept 24 hours"),
- _("Accept permanently"), host, desc.data);
+ val = vlc_dialog_wait_question(creds, VLC_DIALOG_QUESTION_NORMAL,
+ _("Abort"), _("Accept 24 hours"), _("Accept permanently"),
+ _("Insecure site"),
+ _("This is the certificate presented by %s:\n%s\n\n"
+ "If in doubt, abort now.\n"), host, desc.data);
gnutls_free (desc.data);
time_t expiry = 0;
switch (val)
{
- case 2:
+ case 1:
time (&expiry);
expiry += 24 * 60 * 60;
- case 3:
+ case 2:
val = gnutls_store_pubkey (NULL, NULL, host, service,
GNUTLS_CRT_X509, datum, expiry, 0);
if (val)
diff --git a/modules/misc/securetransport.c b/modules/misc/securetransport.c
index a313ce2..8e9afc4 100644
--- a/modules/misc/securetransport.c
+++ b/modules/misc/securetransport.c
@@ -330,10 +330,12 @@ static int st_validateServerCertificate (vlc_tls_t *session, const char *hostnam
"This problem may be caused by a configuration error "
"or an attempt to breach your security or your privacy.\n\n"
"If in doubt, abort now.\n");
- int answer = dialog_Question(session->obj, _("Insecure site"), vlc_gettext (msg),
- _("Abort"), _("Accept certificate temporarily"), NULL, hostname);
-
- if (answer == 2) {
+ int answer = vlc_dialog_wait_question(session->obj,
+ VLC_DIALOG_QUESTION_NORMAL, _("Abort"),
+ _("Accept certificate temporarily"),
+ NULL, _("Insecure site"),
+ vlc_gettext (msg), hostname);
+ if (answer == 1) {
msg_Warn(session->obj, "Proceeding despite of failed certificate validation");
/* save leaf certificate in whitelist */
diff --git a/modules/text_renderer/freetype/fonts/fontconfig.c b/modules/text_renderer/freetype/fonts/fontconfig.c
index 2c1e5f0..1165b34 100644
--- a/modules/text_renderer/freetype/fonts/fontconfig.c
+++ b/modules/text_renderer/freetype/fonts/fontconfig.c
@@ -54,26 +54,24 @@ int FontConfig_Prepare( filter_t *p_filter )
#endif
#if defined( _WIN32 )
+ int i_ret;
+ unsigned int i_dialog_id = 0;
dialog_progress_bar_t *p_dialog = NULL;
FcConfig *fcConfig = FcInitLoadConfig();
- p_dialog = dialog_ProgressCreate( p_filter,
- _("Building font cache"),
- _("Please wait while your font cache is rebuilt.\n"
- "This should take less than a few minutes."), NULL );
+ i_ret =
+ vlc_dialog_display_progress( p_filter, true, 0.0, NULL,
+ _("Building font cache"),
+ _("Please wait while your font cache is rebuilt.\n"
+ "This should take less than a few minutes.") );
-/* if( p_dialog )
- dialog_ProgressSet( p_dialog, NULL, 0.5 ); */
+ i_dialog_id = i_ret > 0 ? i_ret : 0;
if( FcConfigBuildFonts( fcConfig ) == FcFalse )
return VLC_ENOMEM;
- if( p_dialog )
- {
-// dialog_ProgressSet( p_dialog, NULL, 1.0 );
- dialog_ProgressDestroy( p_dialog );
- p_dialog = NULL;
- }
+ if( i_dialog_id != 0 )
+ vlc_dialog_cancel( p_filter, i_dialog_id );
#endif
t2 = mdate();
msg_Dbg( p_filter, "Took %ld microseconds", (long)((t2 - t1)) );
diff --git a/src/interface/dialog.c b/src/interface/dialog.c
index 94450db..6681f39 100644
--- a/src/interface/dialog.c
+++ b/src/interface/dialog.c
@@ -27,277 +27,741 @@
# include "config.h"
#endif
-#include <stdarg.h>
-
#include <vlc_common.h>
#include <vlc_dialog.h>
+#include <vlc_interrupt.h>
#include <vlc_extensions.h>
#include <assert.h>
#include "libvlc.h"
-static vlc_mutex_t provider_lock = VLC_STATIC_MUTEX;
+struct vlc_dialog_provider
+{
+ vlc_mutex_t lock;
+ vlc_array_t dialog_array;
+ vlc_dialog_cbs cbs;
+ void * p_cbs_data;
+};
-#undef dialog_Register
-/**
- * Registers an object as the dialog provider.
- * It is assumed that the appropriate variable callbacks are already
- * registered.
- */
-int dialog_Register (vlc_object_t *obj)
+struct dialog_answer
+{
+ vlc_dialog_type i_type;
+ union
+ {
+ struct
+ {
+ char *psz_username;
+ char *psz_password;
+ bool b_store;
+ } login;
+ struct
+ {
+ int i_action;
+ } question;
+ } u;
+};
+
+struct vlc_dialog_id
{
- libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
- int ret = VLC_EGENERIC;
+ vlc_mutex_t lock;
+ vlc_cond_t wait;
+ vlc_dialog_type i_type;
+ vlc_dialog_provider * p_provider;
+ void * p_context;
+ int i_refcount;
+ bool b_cancelled;
+ bool b_answered;
+ bool b_progress_indeterminate;
+ char * psz_progress_text;
+ struct dialog_answer answer;
+};
+
+static inline vlc_dialog_provider *
+get_dialog_provider(vlc_object_t *p_obj, bool b_check_interact)
+{
+ if (b_check_interact && p_obj->i_flags & OBJECT_FLAGS_NOINTERACT)
+ return NULL;
+ return libvlc_priv(p_obj->p_libvlc)->p_dialog_provider;
+}
- vlc_mutex_lock (&provider_lock);
- if (priv->p_dialog_provider == NULL)
- { /* Since the object is responsible for unregistering itself before
- * it terminates, at reference is not needed. */
- priv->p_dialog_provider = obj;
- ret = VLC_SUCCESS;
+static void
+dialog_id_release(vlc_dialog_id *p_id)
+{
+ if (p_id->answer.i_type == VLC_DIALOG_LOGIN)
+ {
+ free(p_id->answer.u.login.psz_username);
+ free(p_id->answer.u.login.psz_password);
}
- vlc_mutex_unlock (&provider_lock);
- return ret;
+ free(p_id->psz_progress_text);
+ vlc_mutex_destroy(&p_id->lock);
+ vlc_cond_destroy(&p_id->wait);
+ free(p_id);
}
-#undef dialog_Unregister
-/**
- * Unregisters the dialog provider.
- * Note that unless you have unregistered the callbacks already, the provider
- * might still be in use by other threads. Also, you need to cancel all
- * pending dialogs yourself.
- */
-int dialog_Unregister (vlc_object_t *obj)
+#undef dialog_ExtensionUpdate
+int dialog_ExtensionUpdate (vlc_object_t *obj, extension_dialog_t *dialog)
{
- libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
- int ret = VLC_EGENERIC;
+ assert (obj);
+ assert (dialog);
- vlc_mutex_lock (&provider_lock);
- if (priv->p_dialog_provider == obj)
+ vlc_object_t *dp = NULL;//dialog_GetProvider(obj);
+ if (!dp)
{
- priv->p_dialog_provider = NULL;
- ret = VLC_SUCCESS;
+ msg_Warn (obj, "Dialog provider is not set, can't update dialog '%s'",
+ dialog->psz_title);
+ return VLC_EGENERIC;
}
- vlc_mutex_unlock (&provider_lock);
+
+ // Signaling the dialog provider
+ int ret = var_SetAddress (dp, "dialog-extension", dialog);
+
+ vlc_object_release (dp);
return ret;
}
-static vlc_object_t *dialog_GetProvider (vlc_object_t *obj)
+vlc_dialog_provider *
+vlc_dialog_provider_new(void)
{
- libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
- vlc_object_t *provider;
+ vlc_dialog_provider *p_provider = malloc(sizeof(*p_provider));
+ if( p_provider == NULL )
+ return NULL;
+
+ vlc_mutex_init(&p_provider->lock);
+ vlc_array_init(&p_provider->dialog_array);
+
+ memset(&p_provider->cbs, 0, sizeof(p_provider->cbs));
+ p_provider->p_cbs_data = NULL;
- vlc_mutex_lock (&provider_lock);
- if ((provider = priv->p_dialog_provider) != NULL)
- vlc_object_hold (provider);
- vlc_mutex_unlock (&provider_lock);
- return provider;
+ return p_provider;
}
-/**
- * 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)
+static int
+dialog_get_idx_locked(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id)
{
- char *text;
+ for (int i = 0; i < vlc_array_count(&p_provider->dialog_array); ++i)
+ {
+ if (p_id == vlc_array_item_at_index(&p_provider->dialog_array, i))
+ return i;
+ }
+ return -1;
+}
- if (obj->i_flags & OBJECT_FLAGS_NOINTERACT)
+static void
+dialog_cancel_locked(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id)
+{
+ vlc_mutex_lock(&p_id->lock);
+ if (p_id->b_cancelled || p_id->b_answered)
+ {
+ vlc_mutex_unlock(&p_id->lock);
return;
+ }
+ p_id->b_cancelled = true;
+ vlc_mutex_unlock(&p_id->lock);
+
+ p_provider->cbs.pf_cancel(p_id, p_provider->p_cbs_data);
+}
+
+static void
+dialog_remove_locked(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id,
+ bool b_force_release)
+{
+ int i_array_idx = dialog_get_idx_locked(p_provider, p_id);
+ assert(i_array_idx >= 0);
- vlc_object_t *provider = dialog_GetProvider (obj);
- if (provider == NULL)
+ vlc_array_remove(&p_provider->dialog_array, i_array_idx);
+
+ vlc_mutex_lock(&p_id->lock);
+ p_id->i_refcount--;
+ if (p_id->i_refcount == 0 || b_force_release)
{
- msg_Err (obj, "%s", title);
- msg_GenericVa (obj, VLC_MSG_ERR, fmt, ap);
- return;
+ vlc_mutex_unlock(&p_id->lock);
+ dialog_id_release(p_id);
}
+ else
+ vlc_mutex_unlock(&p_id->lock);
+}
- if (vasprintf (&text, fmt, ap) != -1)
+static void
+dialog_clear_all_locked(vlc_dialog_provider *p_provider)
+{
+ for (int i = 0; i < vlc_array_count(&p_provider->dialog_array); ++i)
{
- dialog_fatal_t dialog = { title, text, };
- var_SetAddress (provider,
- modal ? "dialog-critical" : "dialog-error", &dialog);
- free (text);
+ vlc_dialog_id *p_id =
+ vlc_array_item_at_index(&p_provider->dialog_array, i);
+ dialog_cancel_locked(p_provider, p_id);
}
- vlc_object_release (provider);
+ vlc_array_clear(&p_provider->dialog_array);
}
-#undef dialog_vaLogin
-void dialog_vaLogin (vlc_object_t *obj, const char *default_username,
- char **username, char **password, bool *store,
- const char *title, const char *fmt, va_list ap)
+void
+vlc_dialog_provider_release(vlc_dialog_provider *p_provider)
{
- assert ((username != NULL) && (password != NULL));
+ assert(p_provider != NULL);
- *username = *password = NULL;
- if (obj->i_flags & OBJECT_FLAGS_NOINTERACT)
- return;
+ vlc_mutex_lock(&p_provider->lock);
+ dialog_clear_all_locked(p_provider);
+ vlc_mutex_unlock(&p_provider->lock);
- vlc_object_t *provider = dialog_GetProvider (obj);
- if (provider == NULL)
- return;
+ vlc_mutex_destroy(&p_provider->lock);
+ free(p_provider);
+}
+
+#undef vlc_dialog_provider_set_callbacks
+void
+vlc_dialog_provider_set_callbacks(vlc_object_t *p_obj,
+ vlc_dialog_cbs *p_cbs, void *p_data)
+{
+ assert(p_obj != NULL);
+ vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, false);
+ assert(p_provider != NULL);
- char *text;
+ vlc_mutex_lock(&p_provider->lock);
+ dialog_clear_all_locked(p_provider);
- if (vasprintf (&text, fmt, ap) != -1)
+ if (p_cbs == NULL)
+ {
+ memset(&p_provider->cbs, 0, sizeof(p_provider->cbs));
+ p_provider->p_cbs_data = NULL;
+ }
+ else
{
- dialog_login_t dialog = { title, text, default_username, username,
- password, store };
- var_SetAddress (provider, "dialog-login", &dialog);
- free (text);
+ assert(p_cbs->pf_display != NULL && p_cbs->pf_cancel != NULL);
+ p_provider->cbs = *p_cbs;
+ p_provider->p_cbs_data = p_data;
}
- vlc_object_release (provider);
+ vlc_mutex_unlock(&p_provider->lock);
}
-#undef dialog_Login
-/**
- * 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 fmt 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_Login (vlc_object_t *obj, const char *default_username,
- char **username, char **password,
- bool *store, const char *title, const char *fmt, ...)
+static void
+dialog_wait_interrupted(void *p_data)
+{
+ vlc_dialog_id *p_id = p_data;
+ vlc_dialog_provider *p_provider = p_id->p_provider;
+
+ vlc_mutex_lock(&p_provider->lock);
+ dialog_cancel_locked(p_provider, p_id);
+ vlc_mutex_unlock(&p_provider->lock);
+
+ vlc_mutex_lock(&p_id->lock);
+ vlc_cond_signal(&p_id->wait);
+ vlc_mutex_unlock(&p_id->lock);
+}
+
+static int
+dialog_wait(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id,
+ vlc_dialog_type i_type, struct dialog_answer *p_answer)
+{
+ vlc_interrupt_register(dialog_wait_interrupted, p_id);
+
+ vlc_mutex_lock(&p_id->lock);
+ /* Wait for the dialog to be dismissed, interrupted or answered */
+ while (!p_id->b_cancelled && !p_id->b_answered)
+ vlc_cond_wait(&p_id->wait, &p_id->lock);
+
+ int i_ret;
+ if (p_id->b_cancelled)
+ i_ret = 0;
+ else if (p_id->answer.i_type != i_type)
+ i_ret = VLC_EGENERIC;
+ else
+ {
+ i_ret = 1;
+ memcpy(p_answer, &p_id->answer, sizeof(p_id->answer));
+ memset(&p_id->answer, 0, sizeof(p_id->answer));
+ }
+
+ vlc_mutex_unlock(&p_id->lock);
+ vlc_interrupt_unregister();
+
+ vlc_mutex_lock(&p_provider->lock);
+ dialog_remove_locked(p_provider, p_id, false);
+ vlc_mutex_unlock(&p_provider->lock);
+ return i_ret;
+}
+
+static int
+dialog_display(vlc_dialog_provider *p_provider, vlc_dialog_id **pp_id,
+ vlc_dialog *p_dialog)
+{
+ vlc_dialog_id *p_id = NULL;
+
+ vlc_mutex_lock(&p_provider->lock);
+ if (p_provider->cbs.pf_display == NULL)
+ {
+ vlc_mutex_unlock(&p_provider->lock);
+ return VLC_EGENERIC;
+ }
+
+ if (pp_id != NULL)
+ {
+ p_id = calloc(1, sizeof(*p_id));
+ vlc_mutex_init(&p_id->lock);
+ vlc_cond_init(&p_id->wait);
+ if (p_id == NULL)
+ {
+ vlc_mutex_unlock(&p_provider->lock);
+ return VLC_ENOMEM;
+ }
+
+ p_id->p_provider = p_provider;
+ p_id->i_type = p_dialog->i_type;
+ p_id->i_refcount = 2; /* provider and callbacks */
+
+ vlc_array_append(&p_provider->dialog_array, p_id);
+ }
+
+ if (!p_provider->cbs.pf_display(p_id, p_dialog, p_provider->p_cbs_data)
+ && p_id != NULL)
+ {
+ dialog_remove_locked(p_provider, p_id, true);
+ p_id = NULL;
+ }
+ if (pp_id != NULL)
+ *pp_id = p_id;
+
+ vlc_mutex_unlock(&p_provider->lock);
+
+ return VLC_SUCCESS;
+}
+
+static int
+dialog_display_error_va(vlc_dialog_provider *p_provider, const char *psz_title,
+ const char *psz_fmt, va_list ap)
{
+ char *psz_text;
+ if (vasprintf(&psz_text, psz_fmt, ap) == -1)
+ return VLC_ENOMEM;
+
+ vlc_dialog dialog = {
+ .i_type = VLC_DIALOG_ERROR,
+ .psz_title = psz_title,
+ .psz_text = psz_text,
+ };
+
+ int i_ret = dialog_display(p_provider, NULL, &dialog);
+ free(psz_text);
+ return i_ret;
+}
+
+int
+vlc_dialog_display_error_va(vlc_object_t *p_obj, const char *psz_title,
+ const char *psz_fmt, va_list ap)
+{
+ assert(p_obj != NULL && psz_title != NULL && psz_fmt != NULL);
+ vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, true);
+ if (p_provider == NULL)
+ return VLC_EGENERIC;
+
+ return dialog_display_error_va(p_provider, psz_title, psz_fmt, ap);
+}
+
+
+#undef vlc_dialog_display_error
+int
+vlc_dialog_display_error(vlc_object_t *p_obj, const char *psz_title,
+ const char *psz_fmt, ...)
+{
+ assert(psz_fmt != NULL);
va_list ap;
- va_start (ap, fmt);
- dialog_vaLogin (obj, default_username, username, password, store,
- title, fmt, ap);
- va_end (ap);
+ va_start(ap, psz_fmt);
+ int i_ret = vlc_dialog_display_error_va(p_obj, psz_title, psz_fmt, ap);
+ va_end(ap);
+ return i_ret;
}
-#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 fmt format string for the 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 *fmt,
- const char *yes, const char *no, const char *cancel, ...)
+static int
+dialog_display_login_va(vlc_dialog_provider *p_provider, vlc_dialog_id **pp_id,
+ const char *psz_default_username, bool b_ask_store,
+ const char *psz_title, const char *psz_fmt, va_list ap)
{
- if (obj->i_flags & OBJECT_FLAGS_NOINTERACT)
- return 0;
+ char *psz_text;
+ if (vasprintf(&psz_text, psz_fmt, ap) == -1)
+ return VLC_ENOMEM;
+
+ vlc_dialog dialog = {
+ .i_type = VLC_DIALOG_LOGIN,
+ .psz_title = psz_title,
+ .psz_text = psz_text,
+ .u.login = {
+ .psz_default_username = psz_default_username,
+ .b_ask_store = b_ask_store,
+ }
+ };
+
+ int i_ret = dialog_display(p_provider, pp_id, &dialog);
+ free(psz_text);
+ return i_ret;
+}
+
+int
+vlc_dialog_wait_login_va(vlc_object_t *p_obj, char **ppsz_username,
+ char **ppsz_password, bool *p_store,
+ const char *psz_default_username,
+ const char *psz_title, const char *psz_fmt, va_list ap)
+{
+ assert(p_obj != NULL && ppsz_username != NULL && ppsz_password != NULL
+ && psz_fmt != NULL && psz_title != NULL);
+
+ vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, true);
+ if (p_provider == NULL)
+ return VLC_EGENERIC;
+
+ vlc_dialog_id *p_id;
+ int i_ret = dialog_display_login_va(p_provider, &p_id, psz_default_username,
+ p_store != NULL, psz_title, psz_fmt, ap);
+ if (i_ret < 0 || p_id == NULL)
+ return i_ret;
+
+ struct dialog_answer answer;
+ i_ret = dialog_wait(p_provider, p_id, VLC_DIALOG_LOGIN, &answer);
+ if (i_ret <= 0)
+ return i_ret;
+
+ *ppsz_username = answer.u.login.psz_username;
+ *ppsz_password = answer.u.login.psz_password;
+ if (p_store != NULL)
+ *p_store = answer.u.login.b_store;
+
+ return 1;
+}
+
+#undef vlc_dialog_wait_login
+int
+vlc_dialog_wait_login(vlc_object_t *p_obj, char **ppsz_username,
+ char **ppsz_password, bool *p_store,
+ const char *psz_default_username, const char *psz_title,
+ const char *psz_fmt, ...)
+{
+ assert(psz_fmt != NULL);
+ va_list ap;
+ va_start(ap, psz_fmt);
+ int i_ret = vlc_dialog_wait_login_va(p_obj, ppsz_username, ppsz_password,
+ p_store,psz_default_username,
+ psz_title, psz_fmt, ap);
+ va_end(ap);
+ return i_ret;
+}
+
+static int
+dialog_display_question_va(vlc_dialog_provider *p_provider, vlc_dialog_id **pp_id,
+ vlc_dialog_question_type i_type,
+ const char *psz_cancel, const char *psz_action1,
+ const char *psz_action2, const char *psz_title,
+ const char *psz_fmt, va_list ap)
+{
+ char *psz_text;
+ if (vasprintf(&psz_text, psz_fmt, ap) == -1)
+ return VLC_ENOMEM;
+
+ vlc_dialog dialog = {
+ .i_type = VLC_DIALOG_QUESTION,
+ .psz_title = psz_title,
+ .psz_text = psz_text,
+ .u.question = {
+ .i_type = i_type,
+ .psz_cancel = psz_cancel,
+ .psz_action1 = psz_action1,
+ .psz_action2 = psz_action2,
+ }
+ };
+
+ int i_ret = dialog_display(p_provider, pp_id, &dialog);
+ free(psz_text);
+ return i_ret;
+}
+
+int
+vlc_dialog_wait_question_va(vlc_object_t *p_obj,
+ vlc_dialog_question_type i_type,
+ const char *psz_cancel, const char *psz_action1,
+ const char *psz_action2, const char *psz_title,
+ const char *psz_fmt, va_list ap)
+{
+ assert(p_obj != NULL && psz_fmt != NULL && psz_title != NULL
+ && psz_cancel != NULL);
+
+ vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, true);
+ if (p_provider == NULL)
+ return VLC_EGENERIC;
+
+ vlc_dialog_id *p_id;
+ int i_ret = dialog_display_question_va(p_provider, &p_id, i_type,
+ psz_cancel, psz_action1,
+ psz_action2, psz_title, psz_fmt, ap);
+ if (i_ret < 0 || p_id == NULL)
+ return i_ret;
+
+ struct dialog_answer answer;
+ i_ret = dialog_wait(p_provider, p_id, VLC_DIALOG_QUESTION, &answer);
+ if (i_ret <= 0)
+ return i_ret;
- vlc_object_t *provider = dialog_GetProvider (obj);
- if (provider == NULL)
- return 0;
+ if (answer.u.question.i_action != 1 && answer.u.question.i_action != 2)
+ return VLC_EGENERIC;
+
+ return answer.u.question.i_action;
+}
- char *text;
+#undef vlc_dialog_wait_question
+int
+vlc_dialog_wait_question(vlc_object_t *p_obj,
+ vlc_dialog_question_type i_type,
+ const char *psz_cancel, const char *psz_action1,
+ const char *psz_action2, const char *psz_title,
+ const char *psz_fmt, ...)
+{
+ assert(psz_fmt != NULL);
va_list ap;
- int answer = 0;
+ va_start(ap, psz_fmt);
+ int i_ret = vlc_dialog_wait_question_va(p_obj, i_type, psz_cancel,
+ psz_action1, psz_action2, psz_title,
+ psz_fmt, ap);
+ va_end(ap);
+ return i_ret;
+}
- va_start (ap, cancel);
- if (vasprintf (&text, fmt, ap) != -1)
+static int
+display_progress_va(vlc_dialog_provider *p_provider, vlc_dialog_id **pp_id,
+ bool b_indeterminate, float f_position,
+ const char *psz_cancel, const char *psz_title,
+ const char *psz_fmt, va_list ap)
+{
+ char *psz_text;
+ if (vasprintf(&psz_text, psz_fmt, ap) == -1)
+ return VLC_ENOMEM;
+
+ vlc_dialog dialog = {
+ .i_type = VLC_DIALOG_PROGRESS,
+ .psz_title = psz_title,
+ .psz_text = psz_text,
+ .u.progress = {
+ .b_indeterminate = b_indeterminate,
+ .f_position = f_position,
+ .psz_cancel = psz_cancel,
+ }
+ };
+
+ int i_ret = dialog_display(p_provider, pp_id, &dialog);
+ if (i_ret == VLC_SUCCESS && *pp_id != NULL)
{
- dialog_question_t dialog = { title, text, yes, no, cancel, 0, };
- var_SetAddress (provider, "dialog-question", &dialog);
- answer = dialog.answer;
- free (text);
+ vlc_dialog_id *p_id = *pp_id;
+ vlc_mutex_lock(&p_provider->lock);
+ p_id->b_progress_indeterminate = b_indeterminate;
+ p_id->psz_progress_text = psz_text;
+ psz_text = NULL;
+ vlc_mutex_unlock(&p_provider->lock);
}
- va_end (ap);
- vlc_object_release (provider);
- return answer;
+ free(psz_text);
+ return i_ret;
}
-#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)
+vlc_dialog_id *
+vlc_dialog_display_progress_va(vlc_object_t *p_obj, bool b_indeterminate,
+ float f_position, const char *psz_cancel,
+ const char *psz_title, const char *psz_fmt,
+ va_list ap)
{
- if (obj->i_flags & OBJECT_FLAGS_NOINTERACT)
- return NULL;
+ assert(p_obj != NULL && psz_title != NULL && psz_fmt != NULL);
- vlc_object_t *provider = dialog_GetProvider (obj);
- if (provider == NULL)
+ vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, true);
+ if (p_provider == NULL)
return NULL;
+ vlc_dialog_id *p_id;
+ int i_ret = display_progress_va(p_provider, &p_id, b_indeterminate,
+ f_position, psz_cancel, psz_title, psz_fmt,
+ ap);
+ return i_ret == VLC_SUCCESS ? p_id : NULL;
+}
- dialog_progress_bar_t *dialog = malloc (sizeof (*dialog));
- if (dialog != NULL)
+#undef vlc_dialog_display_progress
+vlc_dialog_id *
+vlc_dialog_display_progress(vlc_object_t *p_obj, bool b_indeterminate,
+ float f_position, const char *psz_cancel,
+ const char *psz_title, const char *psz_fmt, ...)
+{
+ assert(psz_fmt != NULL);
+ va_list ap;
+ va_start(ap, psz_fmt);
+ vlc_dialog_id *p_id =
+ vlc_dialog_display_progress_va(p_obj, b_indeterminate, f_position,
+ psz_cancel, psz_title, psz_fmt, ap);
+ va_end(ap);
+ return p_id;
+}
+
+static int
+dialog_id_update_progress(vlc_dialog_id *p_id, float f_value, char *psz_text)
+{
+ assert(p_id != NULL);
+ vlc_dialog_provider *p_provider = p_id->p_provider;
+ assert(p_provider != NULL);
+
+ vlc_mutex_lock(&p_provider->lock);
+ if (p_provider->cbs.pf_update_progress == 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);
+ vlc_mutex_unlock(&p_provider->lock);
+ free(psz_text);
+ return VLC_EGENERIC;
+ }
+
+ if (p_id->b_progress_indeterminate)
+ {
+ vlc_mutex_unlock(&p_provider->lock);
+ free(psz_text);
+ return VLC_EGENERIC;
+ }
+ if (psz_text != NULL)
+ {
+ free(p_id->psz_progress_text);
+ p_id->psz_progress_text = psz_text;
}
+ p_provider->cbs.pf_update_progress(p_id, f_value, p_id->psz_progress_text,
+ p_provider->p_cbs_data);
- /* 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;
+ vlc_mutex_unlock(&p_provider->lock);
+ return VLC_SUCCESS;
}
-void dialog_ProgressDestroy (dialog_progress_bar_t *dialog)
+int
+vlc_dialog_id_update_progress(vlc_dialog_id *p_id, float f_value)
{
- assert (dialog);
+ assert(p_id!= NULL);
- dialog->pf_destroy (dialog->p_sys);
- free (dialog);
+ return dialog_id_update_progress(p_id, f_value, NULL);
}
-void dialog_ProgressSet (dialog_progress_bar_t *dialog, const char *text,
- float value)
+int
+vlc_dialog_id_update_progress_text_va(vlc_dialog_id *p_id, float f_value,
+ const char *psz_fmt, va_list ap)
{
- assert (dialog);
+ assert(p_id != NULL);
- dialog->pf_update (dialog->p_sys, text, value);
+ char *psz_text;
+ if (vasprintf(&psz_text, psz_fmt, ap) == -1)
+ return VLC_ENOMEM;
+ return dialog_id_update_progress(p_id, f_value, psz_text);
}
-bool dialog_ProgressCancelled (dialog_progress_bar_t *dialog)
+int
+vlc_dialog_id_update_progress_text(vlc_dialog_id *p_id, float f_value,
+ const char *psz_fmt, ...)
{
- assert (dialog);
+ assert(psz_fmt != NULL);
+ va_list ap;
+ va_start(ap, psz_fmt);
+ int i_ret = vlc_dialog_id_update_progress_text_va(p_id, f_value, psz_fmt, ap);
+ va_end(ap);
+ return i_ret;
+}
- return dialog->pf_check (dialog->p_sys);
+void
+vlc_dialog_id_release(vlc_dialog_id *p_id)
+{
+ assert(p_id != NULL);
+ vlc_dialog_provider *p_provider = p_id->p_provider;
+ assert(p_provider != NULL);
+
+ vlc_mutex_lock(&p_provider->lock);
+ dialog_cancel_locked(p_provider, p_id);
+ dialog_remove_locked(p_provider, p_id, false);
+ vlc_mutex_unlock(&p_provider->lock);
}
-#undef dialog_ExtensionUpdate
-int dialog_ExtensionUpdate (vlc_object_t *obj, extension_dialog_t *dialog)
+bool
+vlc_dialog_id_is_cancelled(vlc_dialog_id *p_id)
{
- assert (obj);
- assert (dialog);
+ assert(p_id != NULL);
- vlc_object_t *dp = dialog_GetProvider(obj);
- if (!dp)
+ vlc_mutex_lock(&p_id->lock);
+ bool b_cancelled = p_id->b_cancelled;
+ vlc_mutex_unlock(&p_id->lock);
+ return b_cancelled;
+}
+
+void
+vlc_dialog_id_set_context(vlc_dialog_id *p_id, void *p_context)
+{
+ vlc_mutex_lock(&p_id->lock);
+ p_id->p_context = p_context;
+ vlc_mutex_unlock(&p_id->lock);
+}
+
+void *
+vlc_dialog_id_get_context(vlc_dialog_id *p_id)
+{
+ vlc_mutex_lock(&p_id->lock);
+ void *p_context = p_id->p_context;
+ vlc_mutex_unlock(&p_id->lock);
+ return p_context;
+}
+
+static int
+dialog_id_post(vlc_dialog_id *p_id, struct dialog_answer *p_answer)
+{
+ vlc_mutex_lock(&p_id->lock);
+ if (p_answer == NULL)
{
- msg_Warn (obj, "Dialog provider is not set, can't update dialog '%s'",
- dialog->psz_title);
- return VLC_EGENERIC;
+ p_id->b_cancelled = true;
+ }
+ else
+ {
+ p_id->answer = *p_answer;
+ p_id->b_answered = true;
+ }
+ p_id->i_refcount--;
+ if (p_id->i_refcount > 0)
+ {
+ vlc_cond_signal(&p_id->wait);
+ vlc_mutex_unlock(&p_id->lock);
+ }
+ else
+ {
+ vlc_mutex_unlock(&p_id->lock);
+ dialog_id_release(p_id);
}
+ return VLC_SUCCESS;
+}
- // Signaling the dialog provider
- int ret = var_SetAddress (dp, "dialog-extension", dialog);
+int
+vlc_dialog_id_post_login(vlc_dialog_id *p_id, const char *psz_username,
+ const char *psz_password, bool b_store)
+{
+ assert(p_id != NULL && psz_username != NULL && psz_password != NULL);
+
+ struct dialog_answer answer = {
+ .i_type = VLC_DIALOG_LOGIN,
+ .u.login = {
+ .b_store = b_store,
+ .psz_username = strdup(psz_username),
+ .psz_password = strdup(psz_password),
+ },
+ };
+ if (answer.u.login.psz_username == NULL
+ || answer.u.login.psz_password == NULL)
+ {
+ free(answer.u.login.psz_username);
+ free(answer.u.login.psz_password);
+ dialog_id_post(p_id, NULL);
+ return VLC_ENOMEM;
+ }
- vlc_object_release (dp);
- return ret;
+ return dialog_id_post(p_id, &answer);
+}
+
+int
+vlc_dialog_id_post_action(vlc_dialog_id *p_id, int i_action)
+{
+ assert(p_id != NULL);
+
+ struct dialog_answer answer = {
+ .i_type = VLC_DIALOG_QUESTION,
+ .u.question = { .i_action = i_action },
+ };
+
+ return dialog_id_post(p_id, &answer);
+}
+
+int
+vlc_dialog_id_dismiss(vlc_dialog_id *p_id)
+{
+ return dialog_id_post(p_id, NULL);
}
diff --git a/src/libvlc.c b/src/libvlc.c
index a7d9a69..964e586 100644
--- a/src/libvlc.c
+++ b/src/libvlc.c
@@ -61,6 +61,7 @@
#include <vlc_interface.h>
#include <vlc_charset.h>
+#include <vlc_dialog.h>
#include <vlc_fs.h>
#include <vlc_cpu.h>
#include <vlc_url.h>
@@ -235,6 +236,14 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
}
#endif
+ priv->p_dialog_provider = vlc_dialog_provider_new();
+ if( priv->p_dialog_provider == NULL )
+ {
+ vlc_LogDeinit (p_libvlc);
+ module_EndBank (true);
+ return VLC_ENOMEM;
+ }
+
/* FIXME: could be replaced by using Unix sockets */
#ifdef HAVE_DBUS
@@ -503,6 +512,8 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
libvlc_Quit( p_libvlc );
intf_DestroyAll( p_libvlc );
+ vlc_dialog_provider_release( priv->p_dialog_provider );
+
#ifdef ENABLE_VLM
/* Destroy VLM if created in libvlc_InternalInit */
if( priv->p_vlm )
diff --git a/src/libvlc.h b/src/libvlc.h
index e18ee37..d198581 100644
--- a/src/libvlc.h
+++ b/src/libvlc.h
@@ -138,6 +138,8 @@ module_t *module_find_by_shortcut (const char *psz_shortcut);
/**
* Private LibVLC instance data.
*/
+typedef struct vlc_dialog_provider vlc_dialog_provider;
+
typedef struct libvlc_priv_t
{
libvlc_int_t public_data;
@@ -148,7 +150,7 @@ typedef struct libvlc_priv_t
/* Singleton objects */
vlc_logger_t *logger;
vlm_t *p_vlm; ///< the VLM singleton (or NULL)
- vlc_object_t *p_dialog_provider; ///< dialog provider
+ vlc_dialog_provider *p_dialog_provider; ///< dialog provider
struct playlist_t *playlist; ///< Playlist for interfaces
struct playlist_preparser_t *parser; ///< Input item meta data handler
struct vlc_actions *actions; ///< Hotkeys handler
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 62ef785..d36d6ed 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -95,16 +95,6 @@ demux_New
demux_vaControl
demux_vaControlHelper
dialog_ExtensionUpdate
-dialog_Login
-dialog_vaLogin
-dialog_ProgressCancelled
-dialog_ProgressCreate
-dialog_ProgressDestroy
-dialog_ProgressSet
-dialog_Question
-dialog_Register
-dialog_Unregister
-dialog_VFatal
EndMD5
es_format_Clean
es_format_Copy
@@ -526,6 +516,27 @@ vlc_credential_init
vlc_credential_clean
vlc_credential_get
vlc_credential_store
+vlc_dialog_display_error
+vlc_dialog_display_error_va
+vlc_dialog_display_progress
+vlc_dialog_display_progress_va
+vlc_dialog_id_dismiss
+vlc_dialog_id_get_context
+vlc_dialog_id_is_cancelled
+vlc_dialog_id_post_action
+vlc_dialog_id_post_login
+vlc_dialog_id_release
+vlc_dialog_id_set_context
+vlc_dialog_id_update_progress
+vlc_dialog_id_update_progress_text
+vlc_dialog_id_update_progress_text_va
+vlc_dialog_provider_new
+vlc_dialog_provider_release
+vlc_dialog_provider_set_callbacks
+vlc_dialog_wait_login
+vlc_dialog_wait_login_va
+vlc_dialog_wait_question
+vlc_dialog_wait_question_va
vlc_sem_init
vlc_sem_destroy
vlc_sem_post
diff --git a/src/misc/keystore.c b/src/misc/keystore.c
index 62c7603..638fab5 100644
--- a/src/misc/keystore.c
+++ b/src/misc/keystore.c
@@ -395,37 +395,38 @@ vlc_credential_get(vlc_credential *p_credential, vlc_object_t *p_parent,
return false;
char *psz_dialog_username = NULL;
char *psz_dialog_password = NULL;
-
va_list ap;
va_start(ap, psz_dialog_fmt);
- dialog_vaLogin(p_parent, p_credential->psz_username,
- &psz_dialog_username, &psz_dialog_password,
- p_credential->p_keystore ? &p_credential->b_store : NULL,
- psz_dialog_title, psz_dialog_fmt, ap);
+ bool *p_store = p_credential->p_keystore != NULL ?
+ &p_credential->b_store : NULL;
+ int i_ret =
+ vlc_dialog_wait_login_va(p_parent,
+ &psz_dialog_username,
+ &psz_dialog_password, p_store,
+ p_credential->psz_username,
+ psz_dialog_title, psz_dialog_fmt, ap);
va_end(ap);
- /* Free previous dialog strings after dialog_vaLogin call since
- * p_credential->psz_username (default username) can be a pointer
- * to p_credential->psz_dialog_username */
+ /* Free previous dialog strings after vlc_dialog_wait_login_va call
+ * since p_credential->psz_username (default username) can be a
+ * pointer to p_credential->psz_dialog_username */
free(p_credential->psz_dialog_username);
free(p_credential->psz_dialog_password);
p_credential->psz_dialog_username = psz_dialog_username;
p_credential->psz_dialog_password = psz_dialog_password;
- if (p_credential->psz_dialog_username
- && p_credential->psz_dialog_password)
- {
- p_credential->psz_username = p_credential->psz_dialog_username;
- p_credential->psz_password = p_credential->psz_dialog_password;
-
- if (protocol_is_smb(p_url))
- smb_split_domain(p_credential);
- }
- else
+ if (i_ret != 1)
{
p_credential->psz_username = p_credential->psz_password = NULL;
return false;
}
+
+ p_credential->psz_username = p_credential->psz_dialog_username;
+ p_credential->psz_password = p_credential->psz_dialog_password;
+
+ if (protocol_is_smb(p_url))
+ smb_split_domain(p_credential);
+
break;
}
}
diff --git a/src/misc/update.c b/src/misc/update.c
index 1d7f765..a5f14e1 100644
--- a/src/misc/update.c
+++ b/src/misc/update.c
@@ -88,6 +88,10 @@
# define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status" UPDATE_OS_SUFFIX
#endif
+#define dialog_FatalWait( p_obj, psz_title, psz_fmt, ... ) \
+ vlc_dialog_wait_question( p_obj, VLC_DIALOG_QUESTION_CRITICAL, "OK", NULL, \
+ NULL, psz_title, psz_fmt, ##__VA_ARGS__ );
+
/*****************************************************************************
* Update_t functions
*****************************************************************************/
@@ -525,11 +529,11 @@ void update_Download( update_t *p_update, const char *psz_destdir )
static void* update_DownloadReal( void *obj )
{
update_download_thread_t *p_udt = (update_download_thread_t *)obj;
- dialog_progress_bar_t *p_progress = NULL;
+ int i_ret;
+ unsigned int i_dialog_id = 0;
uint64_t l_size;
uint64_t l_downloaded = 0;
float f_progress;
- char *psz_status;
char *psz_downloaded = NULL;
char *psz_size = NULL;
char *psz_destfile = NULL;
@@ -589,20 +593,21 @@ static void* update_DownloadReal( void *obj )
msg_Dbg( p_udt, "Downloading Stream '%s'", p_update->release.psz_url );
psz_size = size_str( l_size );
- if( asprintf( &psz_status, _("%s\nDownloading... %s/%s %.1f%% done"),
- p_update->release.psz_url, "0.0", psz_size, 0.0 ) == -1 )
- goto end;
- p_progress = dialog_ProgressCreate( p_udt, _( "Downloading..."),
- psz_status, _("Cancel") );
+ i_ret =
+ vlc_dialog_display_progress( p_udt, false, 0.0, _("Cancel"),
+ ( "Downloading..."),
+ _("%s\nDownloading... %s/%s %.1f%% done"),
+ p_update->release.psz_url, "0.0", psz_size,
+ 0.0 );
- free( psz_status );
- if( p_progress == NULL )
+ if( i_ret <= 0 )
goto end;
+ i_dialog_id = i_ret;
while( !atomic_load( &p_udt->aborted ) &&
( i_read = stream_Read( p_stream, p_buffer, 1 << 10 ) ) &&
- !dialog_ProgressCancelled( p_progress ) )
+ !vlc_dialog_cancelled( p_udt, i_dialog_id ) )
{
if( fwrite( p_buffer, i_read, 1, p_file ) < 1 )
{
@@ -614,13 +619,11 @@ static void* update_DownloadReal( void *obj )
psz_downloaded = size_str( l_downloaded );
f_progress = (float)l_downloaded/(float)l_size;
- if( asprintf( &psz_status, _( "%s\nDownloading... %s/%s - %.1f%% done" ),
- p_update->release.psz_url, psz_downloaded, psz_size,
- f_progress*100 ) != -1 )
- {
- dialog_ProgressSet( p_progress, psz_status, f_progress );
- free( psz_status );
- }
+ vlc_dialog_update_progress_text( p_udt, i_dialog_id, f_pos,
+ "%s\nDownloading... %s/%s - %.1f%% done",
+ p_update->release.psz_url,
+ psz_downloaded, psz_size,
+ f_progress*100 );
free( psz_downloaded );
}
@@ -629,10 +632,10 @@ static void* update_DownloadReal( void *obj )
p_file = NULL;
if( !atomic_load( &p_udt->aborted ) &&
- !dialog_ProgressCancelled( p_progress ) )
+ !vlc_dialog_cancelled( p_udt, i_dialog_id ) )
{
- dialog_ProgressDestroy( p_progress );
- p_progress = NULL;
+ vlc_dialog_cancel( p_udt, i_dialog_id );
+ i_dialog_id = 0;
}
else
{
@@ -719,10 +722,13 @@ static void* update_DownloadReal( void *obj )
free( p_hash );
#ifdef _WIN32
- int answer = dialog_Question( p_udt, _("Update VLC media player"),
- _("The new version was successfully downloaded. Do you want to close VLC and install it now?"),
- _("Install"), _("Cancel"), NULL);
-
+ static const char *psz_msg =
+ _("The new version was successfully downloaded."
+ "Do you want to close VLC and install it now?");
+ int answer = vlc_dialog_wait_question( p_udt, VLC_DIALOG_QUESTION_NORMAL,
+ _("Cancel"), _("Install"), NULL,
+ _("Update VLC media player"),
+ psz_msg );
if(answer == 1)
{
wchar_t psz_wdestfile[MAX_PATH];
@@ -733,8 +739,8 @@ static void* update_DownloadReal( void *obj )
}
#endif
end:
- if( p_progress )
- dialog_ProgressDestroy( p_progress );
+ if( i_dialog_id != 0 )
+ vlc_dialog_cancel( p_udt, i_dialog_id );
if( p_stream )
stream_Delete( p_stream );
if( p_file )
diff --git a/test/modules/misc/tls.c b/test/modules/misc/tls.c
index d7f4a2c..6f12b56 100644
--- a/test/modules/misc/tls.c
+++ b/test/modules/misc/tls.c
@@ -47,18 +47,19 @@ static int tlspair(int fds[2])
return vlc_socketpair(PF_LOCAL, SOCK_STREAM, 0, fds, true);
}
-static int question_callback(vlc_object_t *obj, const char *varname,
- vlc_value_t old, vlc_value_t cur, void *data)
+static bool dialog_display_cb(vlc_dialog_id *id, vlc_dialog *dialog, void *data)
{
- dialog_question_t *q = cur.p_address;
+ if (dialog->i_type != VLC_DIALOG_QUESTION)
+ return false;
int *value = data;
+ vlc_dialog_id_post_action(id, *value);
+ return true;
+}
- q->answer = *value;
-
- assert(obj == VLC_OBJECT(obj->p_libvlc));
- assert(!strcmp(varname, "dialog-question"));
- (void) old;
- return VLC_SUCCESS;
+static void dialog_cancel_cb(vlc_dialog_id *id, void *data)
+{
+ (void)data;
+ vlc_dialog_id_dismiss(id);
}
static libvlc_instance_t *vlc;
@@ -172,9 +173,12 @@ int main(void)
client_creds = vlc_tls_ClientCreate(obj);
assert(client_creds != NULL);
- var_Create(obj, "dialog-question", VLC_VAR_ADDRESS);
- var_AddCallback(obj, "dialog-question", question_callback, &answer);
- dialog_Register(obj);
+ vlc_dialog_cbs cbs = {
+ dialog_display_cb,
+ dialog_cancel_cb,
+ NULL,
+ };
+ vlc_dialog_provider_set_callbacks(obj, &cbs, &answer);
vlc_thread_t th;
vlc_tls_t *tls;
@@ -188,7 +192,7 @@ int main(void)
assert(val == -1);
/* Accept unknown certificate */
- answer = 2;
+ answer = 1;
val = securepair(&th, &tls, alpnv, &alp);
assert(val == 0);
assert(alp != NULL);
@@ -269,8 +273,7 @@ int main(void)
vlc_tls_Close(tls);
vlc_join(th, NULL);
- dialog_Unregister(obj);
- var_DelCallback(obj, "dialog-question", question_callback, &answer);
+ vlc_dialog_provider_set_callbacks(obj, NULL, NULL);
vlc_tls_Delete(client_creds);
vlc_tls_Delete(server_creds);
libvlc_release(vlc);
--
2.7.0.rc3
More information about the vlc-devel
mailing list