[vlc-devel] [PATCH] libvlc: add dialog API
Thomas Guillem
thomas at gllm.fr
Mon Feb 1 19:02:42 CET 2016
---
include/vlc/libvlc_dialog.h | 223 ++++++++++++++++++++++++++++++++++++++++++++
lib/Makefile.am | 2 +
lib/dialog.c | 161 ++++++++++++++++++++++++++++++++
lib/libvlc.sym | 6 ++
lib/libvlc_internal.h | 6 ++
5 files changed, 398 insertions(+)
create mode 100644 include/vlc/libvlc_dialog.h
create mode 100644 lib/dialog.c
diff --git a/include/vlc/libvlc_dialog.h b/include/vlc/libvlc_dialog.h
new file mode 100644
index 0000000..589f1f1
--- /dev/null
+++ b/include/vlc/libvlc_dialog.h
@@ -0,0 +1,223 @@
+/*****************************************************************************
+ * libvlc_dialog.h: libvlc dialog API
+ *****************************************************************************
+ * Copyright © 2016 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef LIBVLC_DIALOG_H
+#define LIBVLC_DIALOG_H 1
+
+#include <stdbool.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct libvlc_dialog_id libvlc_dialog_id;
+
+/**
+ * @defgroup libvlc_dialog LibVLC dialog
+ * @ingroup libvlc
+ * @{
+ * @file
+ * LibVLC dialog external API
+ */
+
+typedef enum libvlc_dialog_question_type
+{
+ LIBVLC_DIALOG_QUESTION_NORMAL,
+ LIBVLC_DIALOG_QUESTION_WARNING,
+ LIBVLC_DIALOG_QUESTION_CRITICAL,
+} libvlc_dialog_question_type;
+
+typedef enum libvlc_dialog_type
+{
+ LIBVLC_DIALOG_ERROR,
+ LIBVLC_DIALOG_LOGIN,
+ LIBVLC_DIALOG_QUESTION,
+ LIBVLC_DIALOG_PROGRESS,
+} libvlc_dialog_type;
+
+/** Dialog to be displayed */
+typedef struct libvlc_dialog
+{
+ libvlc_dialog_type i_type;
+ /** title of the dialog */
+ const char *psz_title;
+ /** text of the dialog */
+ const char *psz_text;
+
+ union
+ {
+ /** if i_type == LIBVLC_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 == LIBVLC_DIALOG_QUESTION */
+ struct
+ {
+ /** question type (or severity) of the dialog */
+ libvlc_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 == LIBVLC_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;
+} libvlc_dialog;
+
+/**
+ * Dialog callbacks to be implemented
+ *
+ * pf_display and pf_cancel are mandatory.
+ */
+typedef struct libvlc_dialog_cbs
+{
+ /**
+ * Called when a new dialog needs to be displayed
+ *
+ * You can interact with the dialog by calling libvlc_dialog_post_login()
+ * for LIBVLC_DIALOG_LOGIN type, libvlc_dialog_post_action() for
+ * LIBVLC_DIALOG_QUESTION type or libvlc_dialog_dimiss() in order to cancel
+ * the dialog.
+ *
+ * @param p_id id used to interact with the dialog, can be null (for the
+ * LIBVLC_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)(libvlc_dialog_id *p_id, libvlc_dialog *p_dialog,
+ void *p_data);
+ /**
+ * Called when a displayed dialog needs to be cancelled
+ *
+ * The implementation must call libvlc_dialog_dismiss() to really release
+ * the dialog.
+ *
+ * @param p_id id of the dialog
+ * @param p_data opaque pointer for the callback
+ */
+ void (*pf_cancel)(libvlc_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)(libvlc_dialog_id *p_id, float f_position,
+ const char *psz_text, void *p_data);
+} libvlc_dialog_cbs;
+
+/**
+ * Register callbacks to handle VLC dialogs
+ *
+ * @version LibVLC 3.0.0 and later.
+ *
+ * @param p_cbs a pointer to callbacks, or NULL to unregister callbacks.
+ * @param p_data opaque pointer for the callback
+ */
+LIBVLC_API void
+libvlc_dialog_set_callbacks(libvlc_instance_t *p_instance,
+ const libvlc_dialog_cbs *p_cbs, void *p_data);
+
+/**
+ * Associate an opaque pointer with the dialog id
+ *
+ * @version LibVLC 3.0.0 and later.
+ */
+LIBVLC_API void
+libvlc_dialog_set_context(libvlc_dialog_id *p_id, void *p_context);
+
+/**
+ * Return the opaque pointer associated with the dialog id
+ *
+ * @version LibVLC 3.0.0 and later.
+ */
+LIBVLC_API void *
+libvlc_dialog_get_context(libvlc_dialog_id *p_id);
+
+/**
+ * Post a login answer
+ *
+ * After this call, p_id won't be valid anymore
+ *
+ * @version LibVLC 3.0.0 and later.
+ *
+ * @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 0 on success, or -1 on error
+ */
+LIBVLC_API int
+libvlc_dialog_post_login(libvlc_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
+ *
+ * @version LibVLC 3.0.0 and later.
+ *
+ * @param p_id id of the dialog
+ * @param i_action 1 for action1, 2 for action2
+ * @return 0 on success, or -1 on error
+ */
+LIBVLC_API int
+libvlc_dialog_post_action(libvlc_dialog_id *p_id, int i_action);
+
+/**
+ * Dismiss a dialog
+ *
+ * After this call, p_id won't be valid anymore
+ *
+ * @version LibVLC 3.0.0 and later.
+ *
+ * @param p_id id of the dialog
+ * @return 0 on success, or -1 on error
+ */
+LIBVLC_API int
+libvlc_dialog_dismiss(libvlc_dialog_id *p_id);
+
+/** @} */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* LIBVLC_DIALOG_H */
diff --git a/lib/Makefile.am b/lib/Makefile.am
index a32260d..a4f87d0 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -11,6 +11,7 @@ CLEANFILES = $(BUILT_SOURCES) $(pkgconfig_DATA)
pkginclude_HEADERS = \
../include/vlc/deprecated.h \
../include/vlc/libvlc.h \
+ ../include/vlc/libvlc_dialog.h \
../include/vlc/libvlc_events.h \
../include/vlc/libvlc_media.h \
../include/vlc/libvlc_media_discoverer.h \
@@ -36,6 +37,7 @@ libvlc_la_SOURCES = \
media_list_internal.h \
media_player_internal.h \
core.c \
+ dialog.c \
error.c \
log.c \
playlist.c \
diff --git a/lib/dialog.c b/lib/dialog.c
new file mode 100644
index 0000000..62b6f3a
--- /dev/null
+++ b/lib/dialog.c
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ * dialog.c: libvlc dialog API
+ *****************************************************************************
+ * Copyright © 2016 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include <vlc/libvlc.h>
+#include <vlc/libvlc_dialog.h>
+
+#include <vlc_common.h>
+#include <vlc_dialog.h>
+
+#include "libvlc_internal.h"
+
+static libvlc_dialog_question_type
+vlc_to_libvlc_dialog_question_type(vlc_dialog_question_type i_type)
+{
+ switch (i_type)
+ {
+ case VLC_DIALOG_QUESTION_NORMAL: return LIBVLC_DIALOG_QUESTION_NORMAL;
+ case VLC_DIALOG_QUESTION_WARNING: return LIBVLC_DIALOG_QUESTION_WARNING;
+ case VLC_DIALOG_QUESTION_CRITICAL: return LIBVLC_DIALOG_QUESTION_CRITICAL;
+ default: vlc_assert_unreachable();
+ }
+}
+
+static bool
+display_cb(vlc_dialog_id *p_id, vlc_dialog *p_dialog, void *p_data)
+{
+ libvlc_instance_t *p_instance = p_data;
+
+ libvlc_dialog ldialog;
+ ldialog.psz_title = p_dialog->psz_title;
+ ldialog.psz_text = p_dialog->psz_text;
+ switch (p_dialog->i_type)
+ {
+ case VLC_DIALOG_ERROR:
+ ldialog.i_type = LIBVLC_DIALOG_ERROR;
+ break;
+ case VLC_DIALOG_LOGIN:
+ ldialog.i_type = LIBVLC_DIALOG_LOGIN;
+ ldialog.u.login.psz_default_username =
+ p_dialog->u.login.psz_default_username;
+ ldialog.u.login.b_ask_store = p_dialog->u.login.b_ask_store;
+ break;
+ case VLC_DIALOG_QUESTION:
+ ldialog.i_type = LIBVLC_DIALOG_QUESTION;
+ ldialog.u.question.i_type =
+ vlc_to_libvlc_dialog_question_type(p_dialog->u.question.i_type);
+ ldialog.u.question.psz_cancel = p_dialog->u.question.psz_cancel;
+ ldialog.u.question.psz_action1 = p_dialog->u.question.psz_action1;
+ ldialog.u.question.psz_action2 = p_dialog->u.question.psz_action2;
+ break;
+ case VLC_DIALOG_PROGRESS:
+ ldialog.i_type = LIBVLC_DIALOG_PROGRESS;
+ ldialog.u.progress.b_indeterminate =
+ p_dialog->u.progress.b_indeterminate;
+ ldialog.u.progress.f_position = p_dialog->u.progress.f_position;
+ ldialog.u.progress.psz_cancel = p_dialog->u.progress.psz_cancel;
+ break;
+ default:
+ vlc_assert_unreachable();
+ }
+ return p_instance->dialog.cbs.pf_display((libvlc_dialog_id *)p_id,
+ &ldialog,
+ p_instance->dialog.data);
+}
+
+static void cancel_cb(vlc_dialog_id *p_id, void *p_data)
+{
+ libvlc_instance_t *p_instance = p_data;
+ p_instance->dialog.cbs.pf_cancel((libvlc_dialog_id *)p_id,
+ p_instance->dialog.data);
+}
+
+static void
+update_progress_cb(vlc_dialog_id *p_id, float f_position, const char *psz_text,
+ void *p_data)
+{
+ libvlc_instance_t *p_instance = p_data;
+ p_instance->dialog.cbs.pf_update_progress((libvlc_dialog_id *) p_id,
+ f_position, psz_text,
+ p_instance->dialog.data);
+}
+
+static const vlc_dialog_cbs dialog_cbs = {
+ .pf_display = display_cb,
+ .pf_cancel = cancel_cb,
+ .pf_update_progress = update_progress_cb,
+};
+
+void
+libvlc_dialog_set_callbacks(libvlc_instance_t *p_instance,
+ const libvlc_dialog_cbs *p_cbs, void *p_data)
+{
+ libvlc_int_t *p_libvlc = p_instance->p_libvlc_int;
+
+ vlc_mutex_lock(&p_instance->instance_lock);
+ p_instance->dialog.cbs = *p_cbs;
+ p_instance->dialog.data = p_data;
+ if (p_cbs != NULL)
+ vlc_dialog_provider_set_callbacks(p_libvlc, &dialog_cbs, p_instance);
+ else
+ vlc_dialog_provider_set_callbacks(p_libvlc, NULL, NULL);
+ vlc_mutex_unlock(&p_instance->instance_lock);
+}
+
+void
+libvlc_dialog_set_context(libvlc_dialog_id *p_id, void *p_context)
+{
+ vlc_dialog_id_set_context((vlc_dialog_id *)p_id, p_context);
+}
+
+void *
+libvlc_dialog_get_context(libvlc_dialog_id *p_id)
+{
+ return vlc_dialog_id_get_context((vlc_dialog_id *)p_id);
+}
+
+int
+libvlc_dialog_post_login(libvlc_dialog_id *p_id, const char *psz_username,
+ const char *psz_password, bool b_store)
+{
+ int i_ret = vlc_dialog_id_post_login((vlc_dialog_id *)p_id, psz_username,
+ psz_password, b_store);
+ return i_ret == VLC_SUCCESS ? 0 : -1;
+}
+
+int
+libvlc_dialog_post_action(libvlc_dialog_id *p_id, int i_action)
+{
+ int i_ret = vlc_dialog_id_post_action((vlc_dialog_id *)p_id, i_action);
+ return i_ret == VLC_SUCCESS ? 0 : -1;
+}
+
+int
+libvlc_dialog_dismiss(libvlc_dialog_id *p_id)
+{
+ int i_ret = vlc_dialog_id_dismiss((vlc_dialog_id *)p_id);
+ return i_ret == VLC_SUCCESS ? 0 : -1;
+}
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 49207db..3ca9f18 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -46,6 +46,12 @@ libvlc_audio_set_callbacks
libvlc_audio_set_volume_callback
libvlc_chapter_descriptions_release
libvlc_clock
+libvlc_dialog_dismiss
+libvlc_dialog_get_context
+libvlc_dialog_post_action
+libvlc_dialog_post_login
+libvlc_dialog_set_callbacks
+libvlc_dialog_set_context
libvlc_event_attach
libvlc_event_detach
libvlc_event_type_name
diff --git a/lib/libvlc_internal.h b/lib/libvlc_internal.h
index b37b749..ac853b6 100644
--- a/lib/libvlc_internal.h
+++ b/lib/libvlc_internal.h
@@ -31,6 +31,7 @@
#include <vlc/libvlc_structures.h>
#include <vlc/libvlc.h>
+#include <vlc/libvlc_dialog.h>
#include <vlc/libvlc_media.h>
#include <vlc/libvlc_events.h>
@@ -78,6 +79,11 @@ struct libvlc_instance_t
void (*cb) (void *, int, const libvlc_log_t *, const char *, va_list);
void *data;
} log;
+ struct
+ {
+ libvlc_dialog_cbs cbs;
+ void *data;
+ } dialog;
};
--
2.7.0.rc3
More information about the vlc-devel
mailing list