[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