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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * entry.c : Callbacks for module entry point
  3.  *****************************************************************************
  4.  * Copyright (C) 2007 the VideoLAN team
  5.  * Copyright © 2007-2008 Rémi Denis-Courmont
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation; either version 2 of the License, or
  10.  * (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  20.  *****************************************************************************/
  21. #ifdef HAVE_CONFIG_H
  22. # include "config.h"
  23. #endif
  24. #include <vlc_common.h>
  25. #include <vlc_plugin.h>
  26. #include <assert.h>
  27. #include <stdarg.h>
  28. #ifdef ENABLE_NLS
  29. # include <libintl.h>
  30. #endif
  31. #include "modules/modules.h"
  32. #include "config/configuration.h"
  33. #include "libvlc.h"
  34. static const char *mdgettext (const char *domain, const char *msg)
  35. {
  36.     assert (msg);
  37. #ifdef ENABLE_NLS
  38.     if (*msg) /* Do not translate ""! */
  39.         return dgettext (domain, msg);
  40. #endif
  41.     return msg;
  42. }
  43. static void vlc_module_destruct (gc_object_t *obj)
  44. {
  45.     module_t *module = vlc_priv (obj, module_t);
  46.     vlc_mutex_destroy (&module->lock);
  47.     free (module->psz_object_name);
  48.     free (module);
  49. }
  50. static const char default_name[] = "unnamed";
  51. module_t *vlc_module_create (vlc_object_t *obj)
  52. {
  53.     module_t *module = malloc (sizeof (*module));
  54.     if (module == NULL)
  55.         return NULL;
  56.     module->psz_object_name = strdup( default_name );
  57.     module->next = NULL;
  58.     module->submodule = NULL;
  59.     module->parent = NULL;
  60.     module->submodule_count = 0;
  61.     vlc_gc_init (module, vlc_module_destruct);
  62.     vlc_mutex_init (&module->lock);
  63.     module->psz_shortname = NULL;
  64.     module->psz_longname = (char*)default_name;
  65.     module->psz_help = NULL;
  66.     for (unsigned i = 0; i < MODULE_SHORTCUT_MAX; i++)
  67.         module->pp_shortcuts[i] = NULL;
  68.     module->psz_capability = (char*)"";
  69.     module->i_score = 1;
  70.     module->i_cpu = 0;
  71.     module->b_unloadable = true;
  72.     module->b_reentrant = true;
  73.     module->b_submodule = false;
  74.     module->pf_activate = NULL;
  75.     module->pf_deactivate = NULL;
  76.     module->p_config = NULL;
  77.     module->confsize = 0;
  78.     module->i_config_items = 0;
  79.     module->i_bool_items = 0;
  80.     /*module->handle = garbage */
  81.     module->psz_filename = NULL;
  82.     module->b_builtin = false;
  83.     module->b_loaded = false;
  84.     (void)obj;
  85.     return module;
  86. }
  87. static void vlc_submodule_destruct (gc_object_t *obj)
  88. {
  89.     module_t *module = vlc_priv (obj, module_t);
  90.     free (module->psz_object_name);
  91.     free (module);
  92. }
  93. module_t *vlc_submodule_create (module_t *module)
  94. {
  95.     assert (module != NULL);
  96.     module_t *submodule = calloc( 1, sizeof(*submodule) );
  97.     if( !submodule )
  98.         return NULL;
  99.     vlc_gc_init (submodule, vlc_submodule_destruct);
  100.     submodule->next = module->submodule;
  101.     submodule->parent = module;
  102.     module->submodule = submodule;
  103.     module->submodule_count++;
  104.     /* Muahahaha! Heritage! Polymorphism! Ugliness!! */
  105.     submodule->pp_shortcuts[0] = module->pp_shortcuts[0]; /* object name */
  106.     for (unsigned i = 1; i < MODULE_SHORTCUT_MAX; i++)
  107.         submodule->pp_shortcuts[i] = NULL;
  108.     submodule->psz_object_name = strdup( module->psz_object_name );
  109.     submodule->psz_shortname = module->psz_shortname;
  110.     submodule->psz_longname = module->psz_longname;
  111.     submodule->psz_capability = module->psz_capability;
  112.     submodule->i_score = module->i_score;
  113.     submodule->i_cpu = module->i_cpu;
  114.     submodule->b_submodule = true;
  115.     return submodule;
  116. }
  117. static module_config_t *vlc_config_create (module_t *module, int type)
  118. {
  119.     unsigned confsize = module->confsize;
  120.     module_config_t *tab = module->p_config;
  121.     if ((confsize & 0xf) == 0)
  122.     {
  123.         tab = realloc (tab, (confsize + 17) * sizeof (*tab));
  124.         if (tab == NULL)
  125.             return NULL;
  126.         module->p_config = tab;
  127.     }
  128.     memset (tab + confsize, 0, sizeof (tab[confsize]));
  129.     tab[confsize].i_type = type;
  130.     tab[confsize].p_lock = &module->lock;
  131.     if (type & CONFIG_ITEM)
  132.     {
  133.         module->i_config_items++;
  134.         if (type == CONFIG_ITEM_BOOL)
  135.             module->i_bool_items++;
  136.     }
  137.     module->confsize++;
  138.     return tab + confsize;
  139. }
  140. int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
  141. {
  142.     va_list ap;
  143.     int ret = 0;
  144.     va_start (ap, propid);
  145.     switch (propid)
  146.     {
  147.         case VLC_SUBMODULE_CREATE:
  148.         {
  149.             module_t **pp = va_arg (ap, module_t **);
  150.             *pp = vlc_submodule_create (module);
  151.             if (*pp == NULL)
  152.                 ret = -1;
  153.             break;
  154.         }
  155.         case VLC_CONFIG_CREATE:
  156.         {
  157.             int type = va_arg (ap, int);
  158.             module_config_t **pp = va_arg (ap, module_config_t **);
  159.             *pp = vlc_config_create (module, type);
  160.             if (*pp == NULL)
  161.                 ret = -1;
  162.             break;
  163.         }
  164.         case VLC_MODULE_CPU_REQUIREMENT:
  165.             assert (!module->b_submodule);
  166.             module->i_cpu |= va_arg (ap, int);
  167.             break;
  168.         case VLC_MODULE_SHORTCUT:
  169.         {
  170.             unsigned i;
  171.             for (i = 0; module->pp_shortcuts[i] != NULL; i++);
  172.                 if (i >= (MODULE_SHORTCUT_MAX - 1))
  173.                     break;
  174.             module->pp_shortcuts[i] = va_arg (ap, char *);
  175.             break;
  176.         }
  177.         case VLC_MODULE_CAPABILITY:
  178.             module->psz_capability = va_arg (ap, char *);
  179.             break;
  180.         case VLC_MODULE_SCORE:
  181.             module->i_score = va_arg (ap, int);
  182.             break;
  183.         case VLC_MODULE_CB_OPEN:
  184.             module->pf_activate = va_arg (ap, int (*) (vlc_object_t *));
  185.             break;
  186.         case VLC_MODULE_CB_CLOSE:
  187.             module->pf_deactivate = va_arg (ap, void (*) (vlc_object_t *));
  188.             break;
  189.         case VLC_MODULE_NO_UNLOAD:
  190.             module->b_unloadable = false;
  191.             break;
  192.         case VLC_MODULE_NAME:
  193.         {
  194.             const char *value = va_arg (ap, const char *);
  195.             free( module->psz_object_name );
  196.             module->psz_object_name = strdup( value );
  197.             module->pp_shortcuts[0] = (char*)value; /* dooh! */
  198.             if (module->psz_longname == default_name)
  199.                 module->psz_longname = (char*)value; /* dooh! */
  200.             break;
  201.         }
  202.         case VLC_MODULE_SHORTNAME:
  203.         {
  204.             const char *domain = va_arg (ap, const char *);
  205.             if (domain == NULL)
  206.                 domain = PACKAGE;
  207.             module->psz_shortname = mdgettext (domain, va_arg (ap, char *));
  208.             break;
  209.         }
  210.         case VLC_MODULE_DESCRIPTION:
  211.         {
  212.             const char *domain = va_arg (ap, const char *);
  213.             if (domain == NULL)
  214.                 domain = PACKAGE;
  215.             module->psz_longname = mdgettext (domain, va_arg (ap, char *));
  216.             break;
  217.         }
  218.         case VLC_MODULE_HELP:
  219.         {
  220.             const char *domain = va_arg (ap, const char *);
  221.             if (domain == NULL)
  222.                 domain = PACKAGE;
  223.             module->psz_help = mdgettext (domain, va_arg (ap, char *));
  224.             break;
  225.         }
  226.         case VLC_CONFIG_NAME:
  227.         {
  228.             const char *name = va_arg (ap, const char *);
  229.             vlc_callback_t cb = va_arg (ap, vlc_callback_t);
  230.             assert (name != NULL);
  231.             item->psz_name = strdup (name);
  232.             item->pf_callback = cb;
  233.             break;
  234.         }
  235.         case VLC_CONFIG_VALUE:
  236.         {
  237.             if (IsConfigIntegerType (item->i_type))
  238.             {
  239.                 item->orig.i = item->saved.i =
  240.                 item->value.i = va_arg (ap, int);
  241.             }
  242.             else
  243.             if (IsConfigFloatType (item->i_type))
  244.             {
  245.                 item->orig.f = item->saved.f =
  246.                 item->value.f = va_arg (ap, double);
  247.             }
  248.             else
  249.             if (IsConfigStringType (item->i_type))
  250.             {
  251.                 const char *value = va_arg (ap, const char *);
  252.                 item->value.psz = value ? strdup (value) : NULL;
  253.                 item->orig.psz = value ? strdup (value) : NULL;
  254.                 item->saved.psz = value ? strdup (value) : NULL;
  255.             }
  256.             break;
  257.         }
  258.         case VLC_CONFIG_RANGE:
  259.         {
  260.             if (IsConfigIntegerType (item->i_type)
  261.              || item->i_type == CONFIG_ITEM_MODULE_LIST_CAT
  262.              || item->i_type == CONFIG_ITEM_MODULE_CAT)
  263.             {
  264.                 item->min.i = va_arg (ap, int);
  265.                 item->max.i = va_arg (ap, int);
  266.             }
  267.             else
  268.             if (IsConfigFloatType (item->i_type))
  269.             {
  270.                 item->min.f = va_arg (ap, double);
  271.                 item->max.f = va_arg (ap, double);
  272.             }
  273.             break;
  274.         }
  275.         case VLC_CONFIG_ADVANCED:
  276.             item->b_advanced = true;
  277.             break;
  278.         case VLC_CONFIG_VOLATILE:
  279.             item->b_unsaveable = true;
  280.             break;
  281.         case VLC_CONFIG_PERSISTENT:
  282.             item->b_autosave = true;
  283.             break;
  284.         case VLC_CONFIG_RESTART:
  285.             item->b_restart = true;
  286.             break;
  287.         case VLC_CONFIG_PRIVATE:
  288.             item->b_internal = true;
  289.             break;
  290.         case VLC_CONFIG_REMOVED:
  291.             item->b_removed = true;
  292.             break;
  293.         case VLC_CONFIG_CAPABILITY:
  294.         {
  295.             const char *cap = va_arg (ap, const char *);
  296.             item->psz_type = cap ? strdup (cap) : NULL;
  297.             break;
  298.         }
  299.         case VLC_CONFIG_SHORTCUT:
  300.             item->i_short = va_arg (ap, int);
  301.             break;
  302.         case VLC_CONFIG_OLDNAME:
  303.         {
  304.             const char *oldname = va_arg (ap, const char *);
  305.             item->psz_oldname = oldname ? strdup (oldname) : NULL;
  306.             break;
  307.         }
  308.         case VLC_CONFIG_SAFE:
  309.             item->b_safe = true;
  310.             break;
  311.         case VLC_CONFIG_DESC:
  312.         {
  313.             const char *domain = va_arg (ap, const char *);
  314.             const char *text = va_arg (ap, const char *);
  315.             const char *longtext = va_arg (ap, const char *);
  316.             if (domain == NULL)
  317.                 domain = PACKAGE;
  318.             item->psz_text = text ? strdup (mdgettext (domain, text)) : NULL;
  319.             item->psz_longtext =
  320.                 longtext ? strdup (mdgettext (domain, longtext)) : NULL;
  321.             break;
  322.         }
  323.         case VLC_CONFIG_LIST:
  324.         {
  325.             const char *domain = va_arg (ap, const char *);
  326.             size_t len = va_arg (ap, size_t);
  327.             /* Copy values */
  328.             if (IsConfigIntegerType (item->i_type))
  329.             {
  330.                 const int *src = va_arg (ap, const int *);
  331.                 int *dst = malloc (sizeof (int) * (len + 1));
  332.                 if (dst != NULL)
  333.                 {
  334.                     memcpy (dst, src, sizeof (int) * len);
  335.                     dst[len] = 0;
  336.                 }
  337.                 item->pi_list = dst;
  338.             }
  339.             else
  340.             if (IsConfigStringType (item->i_type))
  341.             {
  342.                 const char *const *src = va_arg (ap, const char *const *);
  343.                 char **dst = malloc (sizeof (char *) * (len + 1));
  344.                 if (dst != NULL)
  345.                 {
  346.                     for (size_t i = 0; i < len; i++)
  347.                         dst[i] = src[i] ? strdup (src[i]) : NULL;
  348.                     dst[len] = NULL;
  349.                 }
  350.                 item->ppsz_list = dst;
  351.             }
  352.             else
  353.                 break;
  354.             /* Copy textual descriptions */
  355.             if (domain == NULL)
  356.                 domain = PACKAGE;
  357.             const char *const *text = va_arg (ap, const char *const *);
  358.             if (text != NULL)
  359.             {
  360.                 char **dtext = malloc (sizeof (char *) * (len + 1));
  361.                 if( dtext != NULL )
  362.                 {
  363.                     for (size_t i = 0; i < len; i++)
  364.                         dtext[i] = text[i] ?
  365.                                         strdup (mdgettext( domain, text[i] )) :
  366.                                         NULL;
  367.                     dtext[len] = NULL;
  368.                 }
  369.                 item->ppsz_list_text = dtext;
  370.             }
  371.             else
  372.                 item->ppsz_list_text = NULL;
  373.             item->i_list = len;
  374.             item->pf_update_list = va_arg (ap, vlc_callback_t);
  375.             break;
  376.         }
  377.         case VLC_CONFIG_ADD_ACTION:
  378.         {
  379.             const char *domain = va_arg (ap, const char *);
  380.             vlc_callback_t cb = va_arg (ap, vlc_callback_t), *tabcb;
  381.             const char *name = va_arg (ap, const char *);
  382.             char **tabtext;
  383.             tabcb = realloc (item->ppf_action,
  384.                              (item->i_action + 2) * sizeof (cb));
  385.             if (tabcb == NULL)
  386.                 break;
  387.             item->ppf_action = tabcb;
  388.             tabcb[item->i_action] = cb;
  389.             tabcb[item->i_action + 1] = NULL;
  390.             tabtext = realloc (item->ppsz_action_text,
  391.                                (item->i_action + 2) * sizeof (name));
  392.             if (tabtext == NULL)
  393.                 break;
  394.             item->ppsz_action_text = tabtext;
  395.             if (domain == NULL)
  396.                 domain = PACKAGE;
  397.             if (name)
  398.                 tabtext[item->i_action] = strdup (mdgettext (domain, name));
  399.             else
  400.                 tabtext[item->i_action] = NULL;
  401.             tabtext[item->i_action + 1] = NULL;
  402.             item->i_action++;
  403.             break;
  404.         }
  405.         default:
  406.             fprintf (stderr, "LibVLC: unknown module property %dn", propid);
  407.             fprintf (stderr, "LibVLC: too old to use this module?n");
  408.             ret = -1;
  409.             break;
  410.     }
  411.     va_end (ap);
  412.     return ret;
  413. }