/src/vlc/include/vlc_extensions.h
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * vlc_extensions.h: Extensions (meta data, web information, ...) |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2009-2010 VideoLAN and authors |
5 | | * |
6 | | * Authors: Jean-Philippe André < jpeg # videolan.org > |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify it |
9 | | * under the terms of the GNU Lesser General Public License as published by |
10 | | * the Free Software Foundation; either version 2.1 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public License |
19 | | * along with this program; if not, write to the Free Software Foundation, |
20 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
21 | | *****************************************************************************/ |
22 | | |
23 | | #ifndef VLC_EXTENSIONS_H |
24 | | #define VLC_EXTENSIONS_H |
25 | | |
26 | | #include "vlc_common.h" |
27 | | #include "vlc_threads.h" |
28 | | #include "vlc_arrays.h" |
29 | | |
30 | | /* Structures */ |
31 | | typedef struct extensions_manager_sys_t extensions_manager_sys_t; |
32 | | typedef struct extensions_manager_t extensions_manager_t; |
33 | | struct vlc_player_t; |
34 | | struct vlc_logger; |
35 | | |
36 | | /** Extension descriptor: name, title, author, ... */ |
37 | | typedef struct extension_t { |
38 | | void *p_sys; /**< Reserved for the manager module */ |
39 | | |
40 | | /** |
41 | | * The LibVLC logger to use for the extension. |
42 | | */ |
43 | | struct vlc_logger *logger; |
44 | | |
45 | | /* Below, (ro) means read-only for the GUI */ |
46 | | char *psz_name; /**< Real name of the extension (ro) */ |
47 | | |
48 | | char *psz_title; /**< Display title (ro) */ |
49 | | char *psz_author; /**< Author of the extension (ro) */ |
50 | | char *psz_version; /**< Version (ro) */ |
51 | | char *psz_url; /**< A URL to the official page (ro) */ |
52 | | char *psz_description; /**< Full description (ro) */ |
53 | | char *psz_shortdescription; /**< Short description (eg. 1 line) (ro) */ |
54 | | char *p_icondata; /**< Embedded data for the icon (ro) */ |
55 | | int i_icondata_size; /**< Size of that data */ |
56 | | } extension_t; |
57 | | |
58 | | struct vlc_extensions_manager_operations { |
59 | | int (*activate)(extensions_manager_t*, extension_t *); |
60 | | int (*deactivate)(extensions_manager_t *, extension_t *); |
61 | | bool (*is_activated)(extensions_manager_t *, extension_t *); |
62 | | bool (*has_menu)(extensions_manager_t *, extension_t *); |
63 | | int (*get_menu)(extensions_manager_t *, extension_t *, char ***, uint16_t **); |
64 | | bool (*trigger_only)(extensions_manager_t *, extension_t *); |
65 | | int (*trigger)(extensions_manager_t *, extension_t *); |
66 | | int (*trigger_menu)(extensions_manager_t *, extension_t *, int); |
67 | | int (*set_input)(extensions_manager_t *, extension_t *, input_item_t *); |
68 | | int (*playing_changed)(extensions_manager_t *, extension_t *, int); |
69 | | int (*meta_changed)(extensions_manager_t *, extension_t *); |
70 | | }; |
71 | | |
72 | | /** Extensions manager object */ |
73 | | struct extensions_manager_t |
74 | | { |
75 | | struct vlc_object_t obj; |
76 | | |
77 | | module_t *p_module; /**< Extensions manager module */ |
78 | | void *p_sys; /**< Reserved for the module */ |
79 | | struct vlc_player_t *player; |
80 | | |
81 | | DECL_ARRAY(extension_t*) extensions; /**< Array of extension descriptors */ |
82 | | vlc_mutex_t lock; /**< A lock for the extensions array */ |
83 | | |
84 | | /** Control, see extension_Control |
85 | | * |
86 | | * Legacy way of implementing callbacks. |
87 | | * \ref vlc_extensions_manager_operations should be preferred. |
88 | | */ |
89 | | int (*pf_control)(extensions_manager_t*, int, extension_t *, va_list); |
90 | | |
91 | | /** |
92 | | * Implementation of the extension manager operations. |
93 | | * |
94 | | * If NULL all operations will be redirected to \ref extensions_manager_t.pf_control |
95 | | */ |
96 | | const struct vlc_extensions_manager_operations *ops; |
97 | | }; |
98 | | |
99 | | /* Control commands */ |
100 | | enum |
101 | | { |
102 | | /* Control extensions */ |
103 | | EXTENSION_ACTIVATE, /**< arg1: extension_t* */ |
104 | | EXTENSION_DEACTIVATE, /**< arg1: extension_t* */ |
105 | | EXTENSION_IS_ACTIVATED, /**< arg1: extension_t*, arg2: bool* */ |
106 | | EXTENSION_HAS_MENU, /**< arg1: extension_t* */ |
107 | | EXTENSION_GET_MENU, /**< arg1: extension_t*, arg2: char***, arg3: uint16_t** */ |
108 | | EXTENSION_TRIGGER_ONLY, /**< arg1: extension_t*, arg2: bool* */ |
109 | | EXTENSION_TRIGGER, /**< arg1: extension_t* */ |
110 | | EXTENSION_TRIGGER_MENU, /**< arg1: extension_t*, int (uint16_t) */ |
111 | | EXTENSION_SET_INPUT, /**< arg1: extension_t*, arg2 (input_item_t*) */ |
112 | | EXTENSION_PLAYING_CHANGED, /**< arg1: extension_t*, arg2 int( playing status ) */ |
113 | | EXTENSION_META_CHANGED, /**< arg1: extension_t*, arg2 (input_item_t*) */ |
114 | | }; |
115 | | |
116 | | VLC_API int vlc_extension_VaControl( extensions_manager_t *p_mgr, |
117 | | int i_control, |
118 | | extension_t *ext, |
119 | | va_list args ); |
120 | | |
121 | | /** |
122 | | * Control function for extensions. |
123 | | * Every GUI -> extension command will go through this function. |
124 | | **/ |
125 | | static inline int extension_Control( extensions_manager_t *p_mgr, |
126 | | int i_control, |
127 | | extension_t *ext, ... ) |
128 | 0 | { |
129 | 0 | va_list args; |
130 | 0 | va_start(args, ext); |
131 | 0 | int i_ret = vlc_extension_VaControl(p_mgr, i_control, ext, args); |
132 | 0 | va_end( args ); |
133 | 0 | return i_ret; |
134 | 0 | } |
135 | | |
136 | | /** |
137 | | * Helper for extension_HasMenu, extension_IsActivated... |
138 | | * Do not use. |
139 | | **/ |
140 | | static inline bool |
141 | | vlc_extension_GetBool( extensions_manager_t *p_mgr, extension_t *p_ext, |
142 | | int i_flag, bool b_default ) |
143 | 0 | { |
144 | 0 | bool b = b_default; |
145 | 0 | int i_ret = extension_Control( p_mgr, i_flag, p_ext, &b ); |
146 | 0 | if( i_ret != VLC_SUCCESS ) |
147 | 0 | return b_default; |
148 | 0 | else |
149 | 0 | return b; |
150 | 0 | } |
151 | | |
152 | | /** Activate or trigger an extension */ |
153 | | #define extension_Activate( mgr, ext ) \ |
154 | | extension_Control( mgr, EXTENSION_ACTIVATE, ext ) |
155 | | |
156 | | /** Trigger the extension. Attention: NOT multithreaded! */ |
157 | | #define extension_Trigger( mgr, ext ) \ |
158 | | extension_Control( mgr, EXTENSION_TRIGGER, ext ) |
159 | | |
160 | | /** Deactivate an extension */ |
161 | | #define extension_Deactivate( mgr, ext ) \ |
162 | | extension_Control( mgr, EXTENSION_DEACTIVATE, ext ) |
163 | | |
164 | | /** Is this extension activated? */ |
165 | | #define extension_IsActivated( mgr, ext ) \ |
166 | | vlc_extension_GetBool( mgr, ext, EXTENSION_IS_ACTIVATED, false ) |
167 | | |
168 | | /** Does this extension have a sub-menu? */ |
169 | | #define extension_HasMenu( mgr, ext ) \ |
170 | | vlc_extension_GetBool( mgr, ext, EXTENSION_HAS_MENU, false ) |
171 | | |
172 | | /** Get this extension's sub-menu */ |
173 | | static inline int extension_GetMenu( extensions_manager_t *p_mgr, |
174 | | extension_t *p_ext, |
175 | | char ***pppsz, |
176 | | uint16_t **ppi ) |
177 | 0 | { |
178 | 0 | return extension_Control( p_mgr, EXTENSION_GET_MENU, p_ext, pppsz, ppi ); |
179 | 0 | } |
180 | | |
181 | | /** Trigger an entry of the extension menu */ |
182 | | static inline int extension_TriggerMenu( extensions_manager_t *p_mgr, |
183 | | extension_t *p_ext, |
184 | | uint16_t i ) |
185 | 0 | { |
186 | 0 | return extension_Control( p_mgr, EXTENSION_TRIGGER_MENU, p_ext, i ); |
187 | 0 | } |
188 | | |
189 | | /** Trigger an entry of the extension menu */ |
190 | | /* TODO: use player */ |
191 | | static inline int extension_SetInput( extensions_manager_t *p_mgr, |
192 | | extension_t *p_ext, input_item_t *p_item ) |
193 | 0 | { |
194 | 0 | return extension_Control( p_mgr, EXTENSION_SET_INPUT, p_ext, p_item ); |
195 | 0 | } |
196 | | |
197 | | static inline int extension_PlayingChanged( extensions_manager_t *p_mgr, |
198 | | extension_t *p_ext, |
199 | | int state ) |
200 | 0 | { |
201 | 0 | return extension_Control( p_mgr, EXTENSION_PLAYING_CHANGED, p_ext, state ); |
202 | 0 | } |
203 | | |
204 | | static inline int extension_MetaChanged( extensions_manager_t *p_mgr, |
205 | | extension_t *p_ext ) |
206 | 0 | { |
207 | 0 | return extension_Control( p_mgr, EXTENSION_META_CHANGED, p_ext ); |
208 | 0 | } |
209 | | |
210 | | /** Can this extension only be triggered but not activated? |
211 | | Not compatible with HasMenu */ |
212 | | #define extension_TriggerOnly( mgr, ext ) \ |
213 | | vlc_extension_GetBool( mgr, ext, EXTENSION_TRIGGER_ONLY, false ) |
214 | | |
215 | | |
216 | | /***************************************************************************** |
217 | | * Extension dialogs |
218 | | *****************************************************************************/ |
219 | | |
220 | | typedef struct extension_dialog_t extension_dialog_t; |
221 | | typedef struct extension_widget_t extension_widget_t; |
222 | | |
223 | | /// User interface event types |
224 | | typedef enum |
225 | | { |
226 | | EXTENSION_EVENT_CLICK, ///< Click on a widget: data = widget |
227 | | EXTENSION_EVENT_CLOSE, ///< Close the dialog: no data |
228 | | // EXTENSION_EVENT_SELECTION_CHANGED, |
229 | | // EXTENSION_EVENT_TEXT_CHANGED, |
230 | | } extension_dialog_event_e; |
231 | | |
232 | | /// Command to pass to the extension dialog owner |
233 | | typedef struct |
234 | | { |
235 | | extension_dialog_t *p_dlg; ///< Destination dialog |
236 | | extension_dialog_event_e event; ///< Event, @see extension_dialog_event_e |
237 | | void *p_data; ///< Opaque data to send |
238 | | } extension_dialog_command_t; |
239 | | |
240 | | |
241 | | /// Dialog descriptor for extensions |
242 | | struct extension_dialog_t |
243 | | { |
244 | | vlc_object_t *p_object; ///< Owner object (callback on "dialog-event") |
245 | | |
246 | | char *psz_title; ///< Title for the Dialog (in TitleBar) |
247 | | int i_width; ///< Width hint in pixels (may be discarded) |
248 | | int i_height; ///< Height hint in pixels (may be discarded) |
249 | | |
250 | | DECL_ARRAY(extension_widget_t*) widgets; ///< Widgets owned by the dialog |
251 | | |
252 | | bool b_hide; ///< Hide this dialog (!b_hide shows) |
253 | | bool b_kill; ///< Kill this dialog |
254 | | |
255 | | void *p_sys; ///< Dialog private pointer |
256 | | void *p_sys_intf; ///< GUI private pointer |
257 | | vlc_mutex_t lock; ///< Dialog mutex |
258 | | vlc_cond_t cond; ///< Signaled == UI is done working on the dialog |
259 | | }; |
260 | | |
261 | | /** Send a command to an Extension dialog |
262 | | * @param p_dialog The dialog |
263 | | * @param event @see extension_dialog_event_e for a list of possible events |
264 | | * @param data Optional opaque data, @see extension_dialog_event_e |
265 | | * @return VLC error code |
266 | | **/ |
267 | | static inline int extension_DialogCommand( extension_dialog_t* p_dialog, |
268 | | extension_dialog_event_e event, |
269 | | void *data ) |
270 | 0 | { |
271 | 0 | extension_dialog_command_t command; |
272 | 0 | command.p_dlg = p_dialog; |
273 | 0 | command.event = event; |
274 | 0 | command.p_data = data; |
275 | 0 | var_SetAddress( p_dialog->p_object, "dialog-event", &command ); |
276 | 0 | return VLC_SUCCESS; |
277 | 0 | } |
278 | | |
279 | | /** Close the dialog |
280 | | * @param dlg The dialog |
281 | | **/ |
282 | | #define extension_DialogClosed( dlg ) \ |
283 | | extension_DialogCommand( dlg, EXTENSION_EVENT_CLOSE, NULL ) |
284 | | |
285 | | /** Forward a click on a widget |
286 | | * @param dlg The dialog |
287 | | * @param wdg The widget (button, ...) |
288 | | **/ |
289 | | #define extension_WidgetClicked( dlg, wdg ) \ |
290 | | extension_DialogCommand( dlg, EXTENSION_EVENT_CLICK, wdg ) |
291 | | |
292 | | /// Widget types |
293 | | typedef enum |
294 | | { |
295 | | EXTENSION_WIDGET_LABEL, ///< Text label |
296 | | EXTENSION_WIDGET_BUTTON, ///< Clickable button |
297 | | EXTENSION_WIDGET_IMAGE, ///< Image label (psz_text is local URI) |
298 | | EXTENSION_WIDGET_HTML, ///< HTML or rich text area (non editable) |
299 | | EXTENSION_WIDGET_TEXT_FIELD, ///< Editable text line for user input |
300 | | EXTENSION_WIDGET_PASSWORD, ///< Editable password input (******) |
301 | | EXTENSION_WIDGET_DROPDOWN, ///< Drop-down box |
302 | | EXTENSION_WIDGET_LIST, ///< Vertical list box (of strings) |
303 | | EXTENSION_WIDGET_CHECK_BOX, ///< Checkable box with label |
304 | | EXTENSION_WIDGET_SPIN_ICON, ///< A "loading..." spinning icon |
305 | | } extension_widget_type_e; |
306 | | |
307 | | /// Widget descriptor for extensions |
308 | | struct extension_widget_t |
309 | | { |
310 | | /* All widgets */ |
311 | | extension_widget_type_e type; ///< Type of the widget |
312 | | char *psz_text; ///< Text. May be NULL or modified by the UI |
313 | | |
314 | | /* Drop-down & List widgets */ |
315 | | struct extension_widget_value_t { |
316 | | int i_id; ///< Identifier for the extension module |
317 | | ///< (weird behavior may occur if not unique) |
318 | | char *psz_text; ///< String value |
319 | | bool b_selected; ///< True if this item is selected |
320 | | struct extension_widget_value_t *p_next; ///< Next value or NULL |
321 | | } *p_values; ///< Chained list of values (Drop-down/List) |
322 | | |
323 | | /* Check-box */ |
324 | | bool b_checked; ///< Is this entry checked |
325 | | |
326 | | /* Layout */ |
327 | | int i_row; ///< Row in the grid |
328 | | int i_column; ///< Column in the grid |
329 | | int i_horiz_span; ///< Horizontal size of the object |
330 | | int i_vert_span; ///< Vertical size of the object |
331 | | int i_width; ///< Width hint |
332 | | int i_height; ///< Height hint |
333 | | bool b_hide; ///< Hide this widget (make it invisible) |
334 | | |
335 | | /* Spinning icon */ |
336 | | int i_spin_loops; ///< Number of loops to play (-1 = infinite, |
337 | | ///< 0 = stop animation) |
338 | | |
339 | | /* Orders */ |
340 | | bool b_kill; ///< Destroy this widget |
341 | | bool b_update; ///< Update this widget |
342 | | |
343 | | /* Misc */ |
344 | | void *p_sys; ///< Reserved for the extension manager |
345 | | void *p_sys_intf; ///< Reserved for the UI, but: |
346 | | ///< NULL means the UI has destroyed the widget |
347 | | ///< or has not created it yet |
348 | | extension_dialog_t *p_dialog; ///< Parent dialog |
349 | | }; |
350 | | |
351 | | #endif /* VLC_EXTENSIONS_H */ |