1 /*
2   gtkui_api.h -- API of the DeaDBeeF GTK UI plugin
3   http://deadbeef.sourceforge.net
4 
5   Copyright (C) 2009-2013 Alexey Yakovenko
6 
7   This software is provided 'as-is', without any express or implied
8   warranty.  In no event will the authors be held liable for any damages
9   arising from the use of this software.
10 
11   Permission is granted to anyone to use this software for any purpose,
12   including commercial applications, and to alter it and redistribute it
13   freely, subject to the following restrictions:
14 
15   1. The origin of this software must not be misrepresented; you must not
16      claim that you wrote the original software. If you use this software
17      in a product, an acknowledgment in the product documentation would be
18      appreciated but is not required.
19   2. Altered source versions must be plainly marked as such, and must not be
20      misrepresented as being the original software.
21   3. This notice may not be removed or altered from any source distribution.
22 
23   Note: DeaDBeeF player itself uses different license
24 */
25 #ifndef __GTKUI_API_H
26 #define __GTKUI_API_H
27 
28 // gtkui.version_major=2 corresponds to deadbeef 0.6
29 // this is the version which has added design mode.
30 // it's guaranteed that the API will remain backwards compatible
31 // in minor releases (2.x)
32 
33 // gtkui plugin id has been changed to gtkui_1, to avoid loading broken plugins.
34 // please DON'T simply patch your plugin to load gtkui_1 instead of gtkui.
35 // for information, about how to port your plugin to the new API correctly,
36 // and to learn more about design mode programming,
37 // please visit the following page:
38 // http://github.com/Alexey-Yakovenko/deadbeef/wiki/Porting-GUI-plugins-to-deadbeef-from-0.5.x-to-0.6.0
39 
40 #if GTK_CHECK_VERSION(3,0,0)
41 #define DDB_GTKUI_PLUGIN_ID "gtkui3_1"
42 #else
43 #define DDB_GTKUI_PLUGIN_ID "gtkui_1"
44 #endif
45 
46 #define DDB_GTKUI_API_VERSION_MAJOR 2
47 #define DDB_GTKUI_API_VERSION_MINOR 2
48 
49 #define DDB_GTKUI_DEPRECATED(x)
50 
51 #ifdef __GNUC__
52 // avoid including glibc headers, this is not very portable
53 #if defined __GNUC__ && defined __GNUC_MINOR__
54 # define __GNUC_PREREQ(maj, min) \
55 	((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
56 #else
57 # define __GNUC_PREREQ(maj, min) 0
58 #endif
59 #undef DDB_GTKUI_DEPRECATED
60 #if __GNUC_PREREQ(4,5)
61 #define DDB_GTKUI_DEPRECATED(x) __attribute__ ((deprecated(x)))
62 #else
63 #define DDB_GTKUI_DEPRECATED(x) __attribute__ ((deprecated))
64 #endif
65 #endif
66 
67 #ifndef DDB_GTKUI_API_LEVEL
68 #define DDB_GTKUI_API_LEVEL (DDB_GTKUI_API_VERSION_MAJOR * 100 + DB_API_VERSION_MINOR)
69 #endif
70 
71 #if (DDB_WARN_DEPRECATED && DDB_GTKUI_API_LEVEL >= 202)
72 #define DEPRECATED_202 DDB_GTKUI_DEPRECATED("since GTKUI API 2.2")
73 #else
74 #define DEPRECATED_202
75 #endif
76 
77 #if (DDB_GTKUI_API_LEVEL >= 201)
78 // added in API 2.1 (deadbeef-0.6.2)
79 #define DDB_GTKUI_CONF_LAYOUT "gtkui.layout.0.6.2"
80 #endif
81 
82 // this flag tells that the widget should be added to h/vboxes with expand=FALSE
83 #define DDB_GTKUI_WIDGET_FLAG_NON_EXPANDABLE 0x00000001
84 
85 // widget config string must look like that:
86 // type key1=value1 key2=value2... { child widgets }
87 //
88 // the default widget loader will ignore all key-value pairs,
89 // so it's your custom loader's responsibility to handle them
90 // you can find out how to write custom loaders in gtkui sources,
91 // look e.g. for the "w_splitter_load"
92 
93 typedef struct ddb_gtkui_widget_s {
94     const char *type;
95 
96     struct ddb_gtkui_widget_s *parent;
97 
98     GtkWidget *widget;
99 
100     uint32_t flags;
101 
102     // all the functions here are overloads, so they are not mandatory
103     // they can be implemented to add custom code to normal widget code
104     // they can be NULL if you don't need them, or you can set them to
105     // standard functions (more below)
106 
107     // this function will be called after the widget is visible and needs to
108     // [re]initialize itself
109     // e.g. splitter widget sets the grip position in the init
110     void (*init) (struct ddb_gtkui_widget_s *container);
111 
112     // save your custom parameters in the string using strncat
113     // for example, if you need to write width and height:
114     // strncat (s, "100 200", sz);
115     void (*save) (struct ddb_gtkui_widget_s *w, char *s, int sz);
116 
117     // this is to read custom widget parameters, e.g. width and height;
118     // you will be passed a string looking like "100 200 {"
119     // you will need to read params, and return the new pointer, normally it
120     // should be pointing to the "{"
121     //
122     // type string is necessary for backwards compatibility, so that load
123     // function knows which type it's loading
124     const char *(*load) (struct ddb_gtkui_widget_s *w, const char *type, const char *s);
125 
126     // custom destructor code
127     void (*destroy) (struct ddb_gtkui_widget_s *w);
128 
129     // custom append code
130     // if left NULL, appending will not be supported
131     // you should use standard w_container_add if your widget is derived from
132     // GTK_CONTAINER
133     void (*append) (struct ddb_gtkui_widget_s *container, struct ddb_gtkui_widget_s *child);
134 
135     // custom remove code
136     // you should use w_container_remove if your widget is derived from
137     // GTK_CONTAINER
138     void (*remove) (struct ddb_gtkui_widget_s *container, struct ddb_gtkui_widget_s *child);
139 
140     // custom replace code
141     // default replace will call remove;destroy;append
142     // but you can override if you need smarter behaviour
143     // look at the splitter and tabs implementation for more details
144     void (*replace) (struct ddb_gtkui_widget_s *container, struct ddb_gtkui_widget_s *child, struct ddb_gtkui_widget_s *newchild);
145 
146     // return the container widget of a composite widget
147     // e.g. HBox is contained in EventBox, this function should return the HBox
148     // the default implementation will always return the toplevel widget
149     GtkWidget * (*get_container) (struct ddb_gtkui_widget_s *w);
150 
151     // implement this if you want to handle deadbeef broadcast messages/events
152     int (*message) (struct ddb_gtkui_widget_s *w, uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2);
153 
154     // this will be called to setup the menu widget in design mode
155     void (*initmenu) (struct ddb_gtkui_widget_s *w, GtkWidget *menu);
156 
157     // this will be called to setup the child menu widget in design mode
158     // for example, to add "expand"/"fill" options for hbox/vbox children
159     void (*initchildmenu) (struct ddb_gtkui_widget_s *w, GtkWidget *menu);
160 
161     // you shouldn't touch this list normally, the system takes care of it
162     struct ddb_gtkui_widget_s *children;
163     struct ddb_gtkui_widget_s *next; // points to next widget in the same container
164 } ddb_gtkui_widget_t;
165 
166 
167 // flags for passing to w_reg_widget
168 
169 // tell the widget manager, that this widget can only have single instance
170 #define DDB_WF_SINGLE_INSTANCE 0x00000001
171 
172 typedef struct {
173     DB_gui_t gui;
174 
175     // returns main window ptr
176     GtkWidget * (*get_mainwin) (void);
177 
178     // register new widget type;
179     // type strings are passed at the end of argument list terminated with NULL
180     // for example:
181     // w_reg_widget("My Visualization", 0, my_viz_create, "my_viz_ng", "my_viz", NULL);
182     // this call will register new type "my_viz_ng", with support for another
183     // "my_viz" type string
184     void (*w_reg_widget) (const char *title, uint32_t flags, ddb_gtkui_widget_t *(*create_func) (void), ...);
185 
186     // unregister existing widget type
187     void (*w_unreg_widget) (const char *type);
188 
189     // this must be called from your <widget>_create for design mode support
190     void (*w_override_signals) (GtkWidget *w, gpointer user_data);
191 
192     // returns 1 if a widget of specified type is registered
193     int (*w_is_registered) (const char *type);
194 
195     // returns the toplevel widget
196     ddb_gtkui_widget_t * (*w_get_rootwidget) (void);
197 
198     // enter/exit design mode
199     void (*w_set_design_mode) (int active);
200 
201     // check whether we are in design mode
202     int (*w_get_design_mode) (void);
203 
204     // create a widget of specified type
205     ddb_gtkui_widget_t * (*w_create) (const char *type);
206 
207     // destroy the widget
208     void (*w_destroy) (ddb_gtkui_widget_t *w);
209 
210     // append the widget to the container
211     void (*w_append) (ddb_gtkui_widget_t *cont, ddb_gtkui_widget_t *child);
212 
213     // replace existing child widget in the container with another widget
214     void (*w_replace) (ddb_gtkui_widget_t *w, ddb_gtkui_widget_t *from, ddb_gtkui_widget_t *to);
215 
216     // remove the widget from its container
217     void (*w_remove) (ddb_gtkui_widget_t *cont, ddb_gtkui_widget_t *child);
218 
219     // return the container widget of a composite widget
220     // e.g. HBox is contained in EventBox, this function should return the HBox
221     // the default implementation will always return the toplevel widget
222     GtkWidget * (*w_get_container) (ddb_gtkui_widget_t *w);
223 
224     // function to create the standard playlist context menu (the same as
225     // appears when right-clicked on playlist tab)
226     GtkWidget* (*create_pltmenu) (int plt_idx);
227 
228     // return a cover art pixbuf, if available.
229     // if not available, the requested cover will be loaded asyncronously.
230     // the callback will be called when the requested cover is available,
231     // in which case you will need to call the get_cover_art_pixbuf again from
232     // the callback.
233     // get_cover_art_pixbuf is deprecated in API 2.2.
234     // in new code, use get_cover_art_primary to get the large single cover art image,
235     // and get_cover_art_thumb to get one of many smaller cover art images.
236     GdkPixbuf *(*get_cover_art_pixbuf) (const char *uri, const char *artist, const char *album, int size, void (*callback)(void *user_data), void *user_data) DEPRECATED_202;
237 
238     // get_default_cover_pixbuf returns the default cover art image
239     GdkPixbuf *(*cover_get_default_pixbuf) (void);
240 
241 #if (DDB_GTKUI_API_LEVEL >= 202)
242     // added in API 2.2 (deadbeef-0.7)
243     GdkPixbuf *(*get_cover_art_primary) (const char *uri, const char *artist, const char *album, int size, void (*callback)(void *user_data), void *user_data);
244     GdkPixbuf *(*get_cover_art_thumb) (const char *uri, const char *artist, const char *album, int size, void (*callback)(void *user_data), void *user_data);
245     // adds a hook to be called before the main loop starts running, but after
246     // the window was created.
247     void (*add_window_init_hook) (void (*callback) (void *userdata), void *userdata);
248 #endif
249 } ddb_gtkui_t;
250 
251 #endif
252