dialog.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:8k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * dialog.c: User dialog functions
  3.  *****************************************************************************
  4.  * Copyright © 2009 Rémi Denis-Courmont
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  19.  *****************************************************************************/
  20. /**
  21.  * file dialog.c
  22.  * User dialogs core
  23.  */
  24. #ifdef HAVE_CONFIG_H
  25. # include "config.h"
  26. #endif
  27. #include <stdarg.h>
  28. #include <vlc_common.h>
  29. #include <vlc_dialog.h>
  30. #include <assert.h>
  31. #include "libvlc.h"
  32. static vlc_mutex_t provider_lock = VLC_STATIC_MUTEX;
  33. #undef dialog_Register
  34. /**
  35.  * Registers an object as the dialog provider.
  36.  * It is assumed that the appropriate variable callbacks are already
  37.  * registered.
  38.  */
  39. int dialog_Register (vlc_object_t *obj)
  40. {
  41.     libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
  42.     int ret = VLC_EGENERIC;
  43.     vlc_mutex_lock (&provider_lock);
  44.     if (priv->p_dialog_provider == NULL)
  45.     {   /* Since the object is responsible for unregistering itself before
  46.          * it terminates, at reference is not needed. */
  47.         priv->p_dialog_provider = obj;
  48.         ret = VLC_SUCCESS;
  49.     }
  50.     vlc_mutex_unlock (&provider_lock);
  51.     return ret;
  52. }
  53. #undef dialog_Unregister
  54. /**
  55.  * Unregisters the dialog provider.
  56.  * Note that unless you have unregistered the callbacks already, the provider
  57.  * might still be in use by other threads. Also, you need to cancel all
  58.  * pending dialogs yourself.
  59.  */
  60. int dialog_Unregister (vlc_object_t *obj)
  61. {
  62.     libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
  63.     int ret = VLC_EGENERIC;
  64.     vlc_mutex_lock (&provider_lock);
  65.     if (priv->p_dialog_provider == obj)
  66.     {
  67.         priv->p_dialog_provider = NULL;
  68.         ret = VLC_SUCCESS;
  69.     }
  70.     vlc_mutex_unlock (&provider_lock);
  71.     return ret;
  72. }
  73. static vlc_object_t *dialog_GetProvider (vlc_object_t *obj)
  74. {
  75.     libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
  76.     vlc_object_t *provider;
  77.     vlc_mutex_lock (&provider_lock);
  78.     if ((provider = priv->p_dialog_provider) != NULL)
  79.         vlc_object_hold (provider);
  80.     vlc_mutex_unlock (&provider_lock);
  81.     return provider;
  82. }
  83. /**
  84.  * Sends an error message through the user interface (if any).
  85.  * @param obj the VLC object emitting the error
  86.  * @param modal whether to wait for user to acknowledge the error
  87.  *              before returning control to the caller
  88.  * @param title title of the error dialog
  89.  * @param fmt format string for the error message
  90.  * @param ap parameters list for the formatted error message
  91.  */
  92. void dialog_VFatal (vlc_object_t *obj, bool modal, const char *title,
  93.                     const char *fmt, va_list ap)
  94. {
  95.     char *text;
  96.     if (obj->i_flags & OBJECT_FLAGS_NOINTERACT)
  97.         return;
  98.     vlc_object_t *provider = dialog_GetProvider (obj);
  99.     if (provider == NULL)
  100.     {
  101.         msg_Err (obj, "%s", title);
  102.         msg_GenericVa (obj, VLC_MSG_ERR, MODULE_STRING, fmt, ap);
  103.         return;
  104.     }
  105.     if (vasprintf (&text, fmt, ap) != -1)
  106.     {
  107.         dialog_fatal_t dialog = { title, text, };
  108.         var_SetAddress (provider,
  109.                         modal ? "dialog-critical" : "dialog-error", &dialog);
  110.         free (text);
  111.     }
  112.     vlc_object_release (provider);
  113. }
  114. #undef dialog_Login
  115. /**
  116.  * Requests a username and password through the user interface.
  117.  * @param obj the VLC object requesting credential informations
  118.  * @param username a pointer to the specified username [OUT]
  119.  * @param password a pointer to the specified password [OUT]
  120.  * @param title title for the dialog
  121.  * @param text format string for the message in the dialog
  122.  * @return Nothing. If a user name resp. a password was specified,
  123.  * it will be returned as a heap-allocated character array
  124.  * into the username resp password pointer. Those must be freed with free().
  125.  * Otherwise *username resp *password will be NULL.
  126.  */
  127. void dialog_Login (vlc_object_t *obj, char **username, char **password,
  128.                    const char *title, const char *fmt, ...)
  129. {
  130.     assert ((username != NULL) && (password != NULL));
  131.     *username = *password = NULL;
  132.     if (obj->i_flags & OBJECT_FLAGS_NOINTERACT)
  133.         return;
  134.     vlc_object_t *provider = dialog_GetProvider (obj);
  135.     if (provider == NULL)
  136.         return;
  137.     char *text;
  138.     va_list ap;
  139.     va_start (ap, fmt);
  140.     if (vasprintf (&text, fmt, ap) != -1)
  141.     {
  142.         dialog_login_t dialog = { title, text, username, password, };
  143.         var_SetAddress (provider, "dialog-login", &dialog);
  144.         free (text);
  145.     }
  146.     va_end (ap);
  147.     vlc_object_release (provider);
  148. }
  149. #undef dialog_Question
  150. /**
  151.  * Asks a total (Yes/No/Cancel) question through the user interface.
  152.  * @param obj VLC object emitting the question
  153.  * @param title dialog box title
  154.  * @param text dialog box text
  155.  * @param yes first choice/button text
  156.  * @param no second choice/button text
  157.  * @param cancel third answer/button text, or NULL if no third option
  158.  * @return 0 if the user could not answer the question (e.g. there is no UI),
  159.  * 1, 2 resp. 3 if the user pressed the first, second resp. third button.
  160.  */
  161. int dialog_Question (vlc_object_t *obj, const char *title, const char *text,
  162.                      const char *yes, const char *no, const char *cancel)
  163. {
  164.     if (obj->i_flags & OBJECT_FLAGS_NOINTERACT)
  165.         return 0;
  166.     vlc_object_t *provider = dialog_GetProvider (obj);
  167.     if (provider == NULL)
  168.         return 0;
  169.     dialog_question_t dialog = { title, text, yes, no, cancel, 0, };
  170.     var_SetAddress (provider, "dialog-question", &dialog);
  171.     vlc_object_release (provider);
  172.     return dialog.answer;
  173. }
  174. #undef dialog_ProgressCreate
  175. /**
  176.  * Creates a progress bar dialog.
  177.  */
  178. dialog_progress_bar_t *
  179. dialog_ProgressCreate (vlc_object_t *obj, const char *title,
  180.                        const char *message, const char *cancel)
  181. {
  182.     if (obj->i_flags & OBJECT_FLAGS_NOINTERACT)
  183.         return NULL;
  184.     vlc_object_t *provider = dialog_GetProvider (obj);
  185.     if (provider == NULL)
  186.         return NULL;
  187.     dialog_progress_bar_t *dialog = malloc (sizeof (*dialog));
  188.     if (dialog != NULL)
  189.     {
  190.         dialog->title = title;
  191.         dialog->message = message;
  192.         dialog->cancel = cancel;
  193.         var_SetAddress (provider, "dialog-progress-bar", dialog);
  194. #ifndef NDEBUG
  195.         dialog->title = dialog->message = dialog->cancel = NULL;
  196. #endif
  197.         assert (dialog->pf_update);
  198.         assert (dialog->pf_check);
  199.         assert (dialog->pf_destroy);
  200.     }
  201.     /* FIXME: This could conceivably crash if the dialog provider is destroyed
  202.      * before the dialog user. Holding the provider does not help, as it only
  203.      * protects object variable operations. For instance, it does not prevent
  204.      * unloading of the interface plugin. In the short term, the only solution
  205.      * is to not use progress dialog after deinitialization of the interfaces.
  206.      */
  207.     vlc_object_release (provider);
  208.     return dialog;
  209. }
  210. void dialog_ProgressDestroy (dialog_progress_bar_t *dialog)
  211. {
  212.     assert (dialog);
  213.     dialog->pf_destroy (dialog->p_sys);
  214.     free (dialog);
  215. }
  216. void dialog_ProgressSet (dialog_progress_bar_t *dialog, const char *text,
  217.                          float value)
  218. {
  219.     assert (dialog);
  220.     dialog->pf_update (dialog->p_sys, text, value);
  221. }
  222. bool dialog_ProgressCancelled (dialog_progress_bar_t *dialog)
  223. {
  224.     assert (dialog);
  225.     return dialog->pf_check (dialog->p_sys);
  226. }