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