]> git.sesse.net Git - vlc/blob - include/vlc_extensions.h
Extensions: fix extensions manager's locking scheme
[vlc] / 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
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 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 General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, 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 */
36 typedef struct extension_t {
37     char *psz_title;          /**< Display title (ro) */
38     char *psz_name;           /**< Real name of the extension (ro) */
39     extension_sys_t *p_sys;   /**< Reserved for the manager module */
40 } extension_t;
41
42 /** Extensions manager object */
43 struct extensions_manager_t
44 {
45     VLC_COMMON_MEMBERS
46
47     module_t *p_module;                /**< Extensions manager module */
48     extensions_manager_sys_t *p_sys;   /**< Reserved for the module */
49
50     DECL_ARRAY(extension_t*) extensions; /**< Array of extension descriptors */
51     vlc_mutex_t lock;                  /**< A lock for the extensions array */
52
53     /** Control, see extension_Control */
54     int ( *pf_control ) ( extensions_manager_t*, int, va_list );
55 };
56
57 /* Control commands */
58 enum
59 {
60     /* Control extensions */
61     EXTENSION_ACTIVATE,       /**< arg1: extension_t* */
62     EXTENSION_DEACTIVATE,     /**< arg1: extension_t* */
63     EXTENSION_IS_ACTIVATED,   /**< arg1: extension_t*, arg2: bool* */
64     EXTENSION_HAS_MENU,       /**< arg1: extension_t* */
65     EXTENSION_GET_MENU,       /**< arg1: extension_t*, arg2: char***, arg3: uint16_t** */
66     EXTENSION_TRIGGER_ONLY,   /**< arg1: extension_t*, arg2: bool* */
67     EXTENSION_TRIGGER,        /**< arg1: extension_t* */
68     EXTENSION_TRIGGER_MENU,   /**< arg1: extension_t*, int (uint16_t) */
69 };
70
71 /**
72  * Control function for extensions.
73  * Every GUI -> extension command will go through this function.
74  **/
75 static inline int extension_Control( extensions_manager_t *p_mgr,
76                                      int i_control, ... )
77 {
78     va_list args;
79     va_start( args, i_control );
80     int i_ret = p_mgr->pf_control( p_mgr, i_control, args );
81     va_end( args );
82     return i_ret;
83 }
84
85 /**
86  * Helper for extension_HasMenu, extension_IsActivated...
87  * Do not use.
88  **/
89 static inline bool __extension_GetBool( extensions_manager_t *p_mgr,
90                                         extension_t *p_ext,
91                                         int i_flag,
92                                         bool b_default )
93 {
94     bool b = b_default;
95     int i_ret = extension_Control( p_mgr, i_flag, p_ext, &b );
96     if( i_ret != VLC_SUCCESS )
97         return b_default;
98     else
99         return b;
100 }
101
102 /** Activate or trigger an extension */
103 #define extension_Activate( mgr, ext ) \
104         extension_Control( mgr, EXTENSION_ACTIVATE, ext )
105
106 /** Trigger the extension. Attention: NOT multithreaded! */
107 #define extension_Trigger( mgr, ext ) \
108         extension_Control( mgr, EXTENSION_TRIGGER, ext )
109
110 /** Deactivate an extension */
111 #define extension_Deactivate( mgr, ext ) \
112         extension_Control( mgr, EXTENSION_DEACTIVATE, ext )
113
114 /** Is this extension activated? */
115 #define extension_IsActivated( mgr, ext ) \
116         __extension_GetBool( mgr, ext, EXTENSION_IS_ACTIVATED, false )
117
118 /** Does this extension have a sub-menu? */
119 #define extension_HasMenu( mgr, ext ) \
120         __extension_GetBool( mgr, ext, EXTENSION_HAS_MENU, false )
121
122 /** Get this extension's sub-menu */
123 static inline int extension_GetMenu( extensions_manager_t *p_mgr,
124                                      extension_t *p_ext,
125                                      char ***pppsz,
126                                      uint16_t **ppi )
127 {
128     return extension_Control( p_mgr, EXTENSION_GET_MENU, p_ext, pppsz, ppi );
129 }
130
131 /** Trigger an entry of the extension menu */
132 static inline int extension_TriggerMenu( extensions_manager_t *p_mgr,
133                                          extension_t *p_ext,
134                                          uint16_t i )
135 {
136     return extension_Control( p_mgr, EXTENSION_TRIGGER_MENU, p_ext, i );
137 }
138
139 /** Can this extension only be triggered but not activated?
140     Not compatible with HasMenu */
141 #define extension_TriggerOnly( mgr, ext ) \
142         __extension_GetBool( mgr, ext, EXTENSION_TRIGGER_ONLY, false )
143
144
145 /*****************************************************************************
146  * Extension dialogs
147  *****************************************************************************/
148
149 typedef struct extension_dialog_t extension_dialog_t;
150 typedef struct extension_widget_t extension_widget_t;
151
152 /// User interface event types
153 typedef enum
154 {
155     EXTENSION_EVENT_CLICK,       ///< Click on a widget: data = widget
156     EXTENSION_EVENT_CLOSE,       ///< Close the dialog: no data
157     // EXTENSION_EVENT_SELECTION_CHANGED,
158     // EXTENSION_EVENT_TEXT_CHANGED,
159 } extension_dialog_event_e;
160
161 /// Command to pass to the extension dialog owner
162 typedef struct
163 {
164     extension_dialog_t *p_dlg;      ///< Destination dialog
165     extension_dialog_event_e event; ///< Event, @see extension_dialog_event_e
166     void *p_data;                   ///< Opaque data to send
167 } extension_dialog_command_t;
168
169
170 /// Dialog descriptor for extensions
171 struct extension_dialog_t
172 {
173     vlc_object_t *p_object;      ///< Owner object (callback on "dialog-event")
174
175     char *psz_title;             ///< Title for the Dialog (in TitleBar)
176     int i_width;                 ///< Width hint in pixels (may be discarded)
177     int i_height;                ///< Height hint in pixels (may be discarded)
178
179     DECL_ARRAY(extension_widget_t*) widgets; ///< Widgets owned by the dialog
180
181     bool b_hide;                 ///< Hide this dialog (!b_hide shows)
182     bool b_kill;                 ///< Kill this dialog
183
184     void *p_sys;                 ///< Dialog private pointer
185     void *p_sys_intf;            ///< GUI private pointer
186     vlc_mutex_t lock;            ///< Dialog mutex
187     vlc_cond_t cond;             ///< Signaled == UI is done working on the dialog
188 };
189
190 /** Send a command to an Extension dialog
191  * @param p_dialog The dialog
192  * @param event @see extension_dialog_event_e for a list of possible events
193  * @param data Optional opaque data,  @see extension_dialog_event_e
194  * @return VLC error code
195  **/
196 static inline int extension_DialogCommand( extension_dialog_t* p_dialog,
197                                            extension_dialog_event_e event,
198                                            void *data )
199 {
200     extension_dialog_command_t command;
201     command.p_dlg = p_dialog;
202     command.event = event;
203     command.p_data = data;
204     var_SetAddress( p_dialog->p_object, "dialog-event", &command );
205     return VLC_SUCCESS;
206 }
207
208 /** Close the dialog
209  * @param dlg The dialog
210  **/
211 #define extension_DialogClosed( dlg ) \
212         extension_DialogCommand( dlg, EXTENSION_EVENT_CLOSE, NULL )
213
214 /** Forward a click on a widget
215  * @param dlg The dialog
216  * @param wdg The widget (button, ...)
217  **/
218 #define extension_WidgetClicked( dlg, wdg ) \
219         extension_DialogCommand( dlg, EXTENSION_EVENT_CLICK, wdg )
220
221 /// Widget types
222 typedef enum
223 {
224     EXTENSION_WIDGET_LABEL,      ///< Non editable text label
225     EXTENSION_WIDGET_BUTTON,     ///< Clickable button
226     EXTENSION_WIDGET_IMAGE,      ///< Image label (psz_text is local URI)
227     EXTENSION_WIDGET_HTML,       ///< HTML or rich text area (non editable)
228     EXTENSION_WIDGET_TEXT_FIELD, ///< Editable text line for user input
229     EXTENSION_WIDGET_PASSWORD,   ///< Editable password input (******)
230     EXTENSION_WIDGET_DROPDOWN,   ///< Drop-down box
231     EXTENSION_WIDGET_LIST,       ///< Vertical list box (of strings)
232     EXTENSION_WIDGET_CHECK_BOX,  ///< Checkable box with label
233 } extension_widget_type_e;
234
235 /// Widget descriptor for extensions
236 struct extension_widget_t
237 {
238     /* All widgets */
239     extension_widget_type_e type; ///< Type of the widget
240     char *psz_text;               ///< Text. May be NULL or modified by the UI
241
242     /* Drop-down & List widgets */
243     struct extension_widget_value_t {
244         int i_id;          ///< Identifier for the extension module
245                            // (weird behavior may occur if not unique)
246         char *psz_text;    ///< String value
247         bool b_selected;   ///< True if this item is selected
248         struct extension_widget_value_t *p_next; ///< Next value or NULL
249     } *p_values;                  ///< Chained list of values (Drop-down/List)
250
251     /* Check-box */
252     bool b_checked;               ///< Is this entry checked
253
254     /* Layout */
255     int i_row;                    ///< Row in the grid
256     int i_column;                 ///< Column in the grid
257     int i_horiz_span;             ///< Horizontal size of the object
258     int i_vert_span;              ///< Vertical size of the object
259     int i_width;                  ///< Width hint
260     int i_height;                 ///< Height hint
261     bool b_hide;                  ///< Hide this widget (make it invisible)
262
263     /* Orders */
264     bool b_kill;                  ///< Destroy this widget
265     bool b_update;                ///< Update this widget
266
267     /* Misc */
268     void *p_sys;                  ///< Reserved for the extension manager
269     void *p_sys_intf;             ///< Reserved for the UI, but:
270                                   // NULL means the UI has destroyed the widget
271                                   // or has not created it yet
272     extension_dialog_t *p_dialog; ///< Parent dialog
273 };
274
275 VLC_EXPORT(int, dialog_ExtensionUpdate, (vlc_object_t*, extension_dialog_t *));
276 #define dialog_ExtensionUpdate(o, d) dialog_ExtensionUpdate(VLC_OBJECT(o), d)
277
278 #endif /* VLC_EXTENSIONS_H */
279