1 /*
2  * This file is part of mpv.
3  *
4  * mpv is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * mpv is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #pragma once
19 
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <stdbool.h>
23 
24 #include "common/common.h"
25 #include "common/global.h"
26 #include "common/msg.h"
27 #include "common/msg_control.h"
28 #include "m_config_core.h"
29 #include "misc/bstr.h"
30 #include "misc/dispatch.h"
31 #include "options/m_option.h"
32 #include "osdep/atomic.h"
33 
34 // m_config provides an API to manipulate the config variables in MPlayer.
35 // It makes use of the Options API to provide a context stack that
36 // allows saving and later restoring the state of all variables.
37 
38 typedef struct m_profile m_profile_t;
39 struct m_option;
40 struct m_option_type;
41 struct m_sub_options;
42 struct m_obj_desc;
43 struct m_obj_settings;
44 struct mp_log;
45 struct mp_dispatch_queue;
46 
47 // Config option
48 struct m_config_option {
49     bool is_set_from_cmdline : 1;   // Set by user from command line
50     bool is_set_from_config : 1;    // Set by a config file
51     bool is_set_locally : 1;        // Has a backup entry
52     bool warning_was_printed : 1;
53     int32_t opt_id;                 // For some m_config APIs
54     const char *name;               // Full name (ie option-subopt)
55     const struct m_option *opt;     // Option description
56     void *data;                     // Raw value of the option
57 };
58 
59 // Config object
60 /** \ingroup Config */
61 typedef struct m_config {
62     struct mp_log *log;
63     struct mpv_global *global; // can be NULL
64 
65     // Registered options.
66     struct m_config_option *opts; // all options, even suboptions
67     int num_opts;
68 
69     // List of defined profiles.
70     struct m_profile *profiles;
71     // Depth when recursively including profiles.
72     int profile_depth;
73     // Temporary during profile application.
74     struct m_opt_backup **profile_backup_tmp;
75     int profile_backup_flags;
76 
77     struct m_opt_backup *backup_opts;
78     struct m_opt_backup *watch_later_backup_opts;
79 
80     bool use_profiles;
81     bool is_toplevel;
82     int (*includefunc)(void *ctx, char *filename, int flags);
83     void *includefunc_ctx;
84 
85     // Notification after an option was successfully written to.
86     // Uses flags as set in UPDATE_OPTS_MASK.
87     // self_update==true means the update was caused by a call to
88     // m_config_notify_change_opt_ptr(). If false, it's caused either by
89     // m_config_set_option_*() (and similar) calls or external updates.
90     void (*option_change_callback)(void *ctx, struct m_config_option *co,
91                                    int flags, bool self_update);
92     void *option_change_callback_ctx;
93 
94     // For the command line parser
95     int recursion_depth;
96 
97     void *optstruct; // struct mpopts or other
98 
99     // Private. Non-NULL if data was allocated. m_config_option.data uses it.
100     // API users call m_config_set_update_dispatch_queue() to get async updates.
101     struct m_config_cache *cache;
102 
103     // Private. Thread-safe shadow memory; only set for the main m_config.
104     struct m_config_shadow *shadow;
105 } m_config_t;
106 
107 // Create a new config object.
108 //  talloc_ctx: talloc parent context for the m_config allocation
109 //  root: description of all options
110 // Note that the m_config object will keep pointers to root and log.
111 struct m_config *m_config_new(void *talloc_ctx, struct mp_log *log,
112                               const struct m_sub_options *root);
113 
114 // Create a m_config for the given desc. This is for --af/--vf, which have
115 // different sub-options for every filter (represented by separate desc
116 // structs).
117 // args is an array of key/value pairs (args=[k0, v0, k1, v1, ..., NULL]).
118 // name/defaults is only needed for the legacy af-defaults/vf-defaults options.
119 struct m_config *m_config_from_obj_desc_and_args(void *ta_parent,
120     struct mp_log *log, struct mpv_global *global, struct m_obj_desc *desc,
121     const char *name, struct m_obj_settings *defaults, char **args);
122 
123 // Like m_config_from_obj_desc_and_args(), but don't allocate option the
124 // struct, i.e. m_config.optstruct==NULL. This is used by the sub-option
125 // parser (--af/--vf, to a lesser degree --ao/--vo) to check sub-option names
126 // and types.
127 struct m_config *m_config_from_obj_desc_noalloc(void *talloc_ctx,
128                                                 struct mp_log *log,
129                                                 struct m_obj_desc *desc);
130 
131 // Make sure the option is backed up. If it's already backed up, do nothing.
132 // All backed up options can be restored with m_config_restore_backups().
133 void m_config_backup_opt(struct m_config *config, const char *opt);
134 
135 // Call m_config_backup_opt() on all options.
136 void m_config_backup_all_opts(struct m_config *config);
137 
138 // Backup options on startup so that quit-watch-later can compare the current
139 // values to their backups, and save them only if they have been changed.
140 void m_config_backup_watch_later_opts(struct m_config *config);
141 
142 // Restore all options backed up with m_config_backup_opt(), and delete the
143 // backups afterwards.
144 void m_config_restore_backups(struct m_config *config);
145 
146 // Whether opt_name is different from its initial value.
147 bool m_config_watch_later_backup_opt_changed(struct m_config *config,
148                                              char *opt_name);
149 
150 enum {
151     M_SETOPT_PRE_PARSE_ONLY = 1,    // Silently ignore non-M_OPT_PRE_PARSE opt.
152     M_SETOPT_CHECK_ONLY = 2,        // Don't set, just check name/value
153     M_SETOPT_FROM_CONFIG_FILE = 4,  // Reject M_OPT_NOCFG opt. (print error)
154     M_SETOPT_FROM_CMDLINE = 8,      // Mark as set by command line
155     M_SETOPT_BACKUP = 16,           // Call m_config_backup_opt() before
156     M_SETOPT_PRESERVE_CMDLINE = 32, // Don't set if already marked as FROM_CMDLINE
157     M_SETOPT_NO_PRE_PARSE = 128,    // Reject M_OPT_PREPARSE options
158     M_SETOPT_NO_OVERWRITE = 256,    // Skip options marked with FROM_*
159 };
160 
161 // Set the named option to the given string. This is for command line and config
162 // file use only.
163 // flags: combination of M_SETOPT_* flags (0 for normal operation)
164 // Returns >= 0 on success, otherwise see OptionParserReturn.
165 int m_config_set_option_cli(struct m_config *config, struct bstr name,
166                             struct bstr param, int flags);
167 
168 // Similar to m_config_set_option_cli(), but set as data in its native format.
169 // This takes care of some details like sending change notifications.
170 // The type data points to is as in: co->opt
171 int m_config_set_option_raw(struct m_config *config, struct m_config_option *co,
172                             void *data, int flags);
173 
174 void m_config_mark_co_flags(struct m_config_option *co, int flags);
175 
176 // Convert the mpv_node to raw option data, then call m_config_set_option_raw().
177 struct mpv_node;
178 int m_config_set_option_node(struct m_config *config, bstr name,
179                              struct mpv_node *data, int flags);
180 
181 // Return option descriptor. You shouldn't use this.
182 struct m_config_option *m_config_get_co(const struct m_config *config,
183                                         struct bstr name);
184 // Same as above, but does not resolve aliases or trigger warning messages.
185 struct m_config_option *m_config_get_co_raw(const struct m_config *config,
186                                             struct bstr name);
187 
188 // Special uses only. Look away.
189 int m_config_get_co_count(struct m_config *config);
190 struct m_config_option *m_config_get_co_index(struct m_config *config, int index);
191 const void *m_config_get_co_default(const struct m_config *config,
192                                     struct m_config_option *co);
193 
194 // Return the n-th option by position. n==0 is the first option. If there are
195 // less than (n + 1) options, return NULL.
196 const char *m_config_get_positional_option(const struct m_config *config, int n);
197 
198 // Return a hint to the option parser whether a parameter is/may be required.
199 // The option may still accept empty/non-empty parameters independent from
200 // this, and this function is useful only for handling ambiguous options like
201 // flags (e.g. "--a" is ok, "--a=yes" is also ok).
202 // Returns: error code (<0), or number of expected params (0, 1)
203 int m_config_option_requires_param(struct m_config *config, bstr name);
204 
205 // Notify m_config_cache users that the option has (probably) changed its value.
206 // This will force a self-notification back to config->option_change_callback.
207 void m_config_notify_change_opt_ptr(struct m_config *config, void *ptr);
208 
209 // Exactly like m_config_notify_change_opt_ptr(), but the option change callback
210 // (config->option_change_callback()) is invoked with self_update=false, if at all.
211 void m_config_notify_change_opt_ptr_notify(struct m_config *config, void *ptr);
212 
213 // Return all (visible) option names as NULL terminated string list.
214 char **m_config_list_options(void *ta_parent, const struct m_config *config);
215 
216 void m_config_print_option_list(const struct m_config *config, const char *name);
217 
218 
219 /*  Find the profile with the given name.
220  *  \param config The config object.
221  *  \param arg The profile's name.
222  *  \return The profile object or NULL.
223  */
224 struct m_profile *m_config_get_profile0(const struct m_config *config,
225                                         char *name);
226 struct m_profile *m_config_get_profile(const struct m_config *config, bstr name);
227 
228 // Apply and clear the default profile - it's the only profile that new config
229 // files do not simply append to (for configfile parser).
230 void m_config_finish_default_profile(struct m_config *config, int flags);
231 
232 /*  Get the profile with the given name, creating it if necessary.
233  *  \param config The config object.
234  *  \param arg The profile's name.
235  *  \return The profile object.
236  */
237 struct m_profile *m_config_add_profile(struct m_config *config, char *name);
238 
239 /*  Add an option to a profile.
240  *  Used by the config file parser when defining a profile.
241  *
242  *  \param config The config object.
243  *  \param p The profile object.
244  *  \param name The option's name.
245  *  \param val The option's value.
246  */
247 int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
248                                 bstr name, bstr val);
249 
250 /*  Enables profile usage
251  *  Used by the config file parser when loading a profile.
252  *
253  *  \param config The config object.
254  *  \param p The profile object.
255  *  \param flags M_SETOPT_* bits
256  * Returns error code (<0) or 0 on success
257  */
258 int m_config_set_profile(struct m_config *config, char *name, int flags);
259 
260 // Attempt to "unset" a profile if possible.
261 int m_config_restore_profile(struct m_config *config, char *name);
262 
263 struct mpv_node m_config_get_profiles(struct m_config *config);
264 
265 // Run async option updates here. This will call option_change_callback() on it.
266 void m_config_set_update_dispatch_queue(struct m_config *config,
267                                         struct mp_dispatch_queue *dispatch);
268