1 /*
2   deadbeef.h -- plugin API of the DeaDBeeF audio player
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 
24 
25 #ifndef __DEADBEEF_H
26 #define __DEADBEEF_H
27 
28 #include <stdint.h>
29 #include <time.h>
30 #include <stdio.h>
31 #include <dirent.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 // every plugin must define the following entry-point:
38 // extern "C" DB_plugin_t* $MODULENAME_load (DB_functions_t *api);
39 // where $MODULENAME is a name of module
40 // e.g. if your plugin is called "myplugin.so", $MODULENAME is "myplugin"
41 // this function should return pointer to DB_plugin_t structure
42 // that is enough for both static and dynamic modules
43 
44 // backwards compatibility is supported since API version 1.0
45 // that means that the plugins which use the API 1.0 will work without recompiling until API 2.0.
46 //
47 // increments in the major version number mean that there are API breaks, and
48 // plugins must be recompiled to be compatible.
49 //
50 // add DDB_REQUIRE_API_VERSION(x,y) macro when you define the plugin structure
51 // like this:
52 // static DB_decoder_t plugin = {
53 //   DDB_REQUIRE_API_VERSION(1,0)
54 //  ............
55 // }
56 // this is required for versioning
57 // if you don't do it -- no version checking will be done (useful for debugging/development)
58 //
59 // please DON'T release plugins without version requirement
60 //
61 // to ensure compatibility, use the following before including deadbeef.h:
62 // #define DDB_API_LEVEL x
63 // where x is the minor API version number.
64 // that way, you'll get errors or warnings when using incompatible stuff.
65 //
66 // if you also want to get the deprecation warnings, use the following:
67 // #define DDB_WARN_DEPRECATED 1
68 //
69 // NOTE: deprecation doesn't mean the API is going to be removed, it just means
70 // that there's a better replacement in the newer deadbeef versions.
71 
72 // api version history:
73 // 1.9 -- deadbeef-0.7.2
74 // 1.8 -- deadbeef-0.7.0
75 // 1.7 -- deadbeef-0.6.2
76 // 1.6 -- deadbeef-0.6.1
77 // 1.5 -- deadbeef-0.6
78 // 1.4 -- deadbeef-0.5.5
79 // 1.3 -- deadbeef-0.5.3
80 // 1.2 -- deadbeef-0.5.2
81 // 1.1 -- deadbeef-0.5.1
82 //   adds pass_through method to dsp plugins for optimization purposes
83 // 1.0 -- deadbeef-0.5.0
84 // 0.10 -- deadbeef-0.4.4-portable-r1 (note: 0.4.4 uses api v0.9)
85 // 0.9 -- deadbeef-0.4.3-portable-build3
86 // 0.8 -- deadbeef-0.4.2
87 // 0.7 -- deabdeef-0.4.0
88 // 0.6 -- deadbeef-0.3.3
89 // 0.5 -- deadbeef-0.3.2
90 // 0.4 -- deadbeef-0.3.0
91 // 0.3 -- deadbeef-0.2.3.2
92 // 0.2 -- deadbeef-0.2.3
93 // 0.1 -- deadbeef-0.2.0
94 
95 #define DB_API_VERSION_MAJOR 1
96 #define DB_API_VERSION_MINOR 9
97 
98 #define DDB_DEPRECATED(x)
99 
100 #ifdef __GNUC__
101 // avoid including glibc headers, this is not very portable
102 #if defined __GNUC__ && defined __GNUC_MINOR__
103 # define __GNUC_PREREQ(maj, min) \
104 	((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
105 #else
106 # define __GNUC_PREREQ(maj, min) 0
107 #endif
108 #undef DDB_DEPRECATED
109 #if __GNUC_PREREQ(4,5)
110 #define DDB_DEPRECATED(x) __attribute__ ((deprecated(x)))
111 #else
112 #define DDB_DEPRECATED(x) __attribute__ ((deprecated))
113 #endif
114 #endif
115 
116 #ifndef DDB_API_LEVEL
117 #define DDB_API_LEVEL DB_API_VERSION_MINOR
118 #endif
119 
120 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 9)
121 #define DEPRECATED_19 DDB_DEPRECATED("since deadbeef API 1.9")
122 #else
123 #define DEPRECATED_19
124 #endif
125 
126 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 8)
127 #define DEPRECATED_18 DDB_DEPRECATED("since deadbeef API 1.8")
128 #else
129 #define DEPRECATED_18
130 #endif
131 
132 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 7)
133 #define DEPRECATED_17 DDB_DEPRECATED("since deadbeef API 1.7")
134 #else
135 #define DEPRECATED_17
136 #endif
137 
138 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 6)
139 #define DEPRECATED_16 DDB_DEPRECATED("since deadbeef API 1.6")
140 #else
141 #define DEPRECATED_16
142 #endif
143 
144 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 5)
145 #define DEPRECATED_15 DDB_DEPRECATED("since deadbeef API 1.5")
146 #else
147 #define DEPRECATED_15
148 #endif
149 
150 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 4)
151 #define DEPRECATED_14 DDB_DEPRECATED("since deadbeef API 1.4")
152 #else
153 #define DEPRECATED_14
154 #endif
155 
156 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 3)
157 #define DEPRECATED_13 DDB_DEPRECATED("since deadbeef API 1.3")
158 #else
159 #define DEPRECATED_13
160 #endif
161 
162 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 2)
163 #define DEPRECATED_12 DDB_DEPRECATED("since deadbeef API 1.2")
164 #else
165 #define DEPRECATED_12
166 #endif
167 
168 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 1)
169 #define DEPRECATED_11 DDB_DEPRECATED("since deadbeef API 1.1")
170 #else
171 #define DEPRECATED_11
172 #endif
173 
174 #if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 0)
175 #define DEPRECATED DDB_DEPRECATED
176 #else
177 #define DEPRECATED
178 #endif
179 
180 #define DDB_PLUGIN_SET_API_VERSION\
181     .plugin.api_vmajor = DB_API_VERSION_MAJOR,\
182     .plugin.api_vminor = DB_API_VERSION_MINOR,
183 
184 // backwards compat macro
185 #define DB_PLUGIN_SET_API_VERSION DDB_PLUGIN_SET_API_VERSION
186 
187 #define PLUG_TEST_COMPAT(plug,x,y) ((plug)->version_major == (x) && (plug)->version_minor >= (y))
188 
189 #define DDB_REQUIRE_API_VERSION(x,y)\
190     .plugin.api_vmajor = x,\
191     .plugin.api_vminor = y,
192 
193 ////////////////////////////
194 // default values for some common config variables should go here
195 
196 // network.ctmapping : content-type to plugin mapping
197 #define DDB_DEFAULT_CTMAPPING "audio/mpeg {stdmpg ffmpeg} audio/x-mpeg {stdmpg ffmpeg} application/ogg {stdogg ffmpeg} audio/ogg {stdogg ffmpeg} audio/aac {aac ffmpeg} audio/aacp {aac ffmpeg} audio/x-m4a {aac ffmpeg} audio/wma {wma ffmpeg}"
198 
199 ////////////////////////////
200 // playlist structures
201 
202 // that's a good candidate for redesign
203 // short explanation: PL_MAIN and PL_SEARCH are used as "iter" argument in
204 // playlist functions, to reference main or search playlist, respectively
205 #define PL_MAIN 0
206 #define PL_SEARCH 1
207 
208 enum {
209     DDB_IS_SUBTRACK = (1<<0), // file is not single-track, might have metainfo in external file
210     DDB_IS_READONLY = (1<<1), // check this flag to block tag writing (e.g. in iso.wv)
211     DDB_HAS_EMBEDDED_CUESHEET = (1<<2),
212 
213     DDB_TAG_ID3V1 = (1<<8),
214     DDB_TAG_ID3V22 = (1<<9),
215     DDB_TAG_ID3V23 = (1<<10),
216     DDB_TAG_ID3V24 = (1<<11),
217     DDB_TAG_APEV2 = (1<<12),
218     DDB_TAG_VORBISCOMMENTS = (1<<13),
219     DDB_TAG_CUESHEET = (1<<14),
220     DDB_TAG_ICY = (1<<15),
221     DDB_TAG_ITUNES = (1<<16),
222 
223     DDB_TAG_MASK = 0x000fff00
224 };
225 
226 // playlist item
227 // these are "public" fields, available to plugins
228 typedef struct DB_playItem_s {
229     int startsample; // start sample of track, or -1 for auto
230     int endsample; // end sample of track, or -1 for auto
231     int shufflerating; // sort order for shuffle mode
232 } ddb_playItem_t;
233 
234 typedef ddb_playItem_t DB_playItem_t;
235 
236 typedef struct {
237 } ddb_playlist_t;
238 
239 typedef struct DB_metaInfo_s {
240     struct DB_metaInfo_s *next;
241     const char *key;
242     const char *value;
243 } DB_metaInfo_t;
244 
245 // FIXME: that needs to be in separate plugin
246 
247 #define JUNK_STRIP_ID3V2 1
248 #define JUNK_STRIP_APEV2 2
249 #define JUNK_STRIP_ID3V1 4
250 #define JUNK_WRITE_ID3V2 8
251 #define JUNK_WRITE_APEV2 16
252 #define JUNK_WRITE_ID3V1 32
253 
254 typedef struct DB_id3v2_frame_s {
255     struct DB_id3v2_frame_s *next;
256     char id[5];
257     uint32_t size;
258     uint8_t flags[2];
259     uint8_t data[0];
260 } DB_id3v2_frame_t;
261 
262 typedef struct DB_id3v2_tag_s {
263     uint8_t version[2];
264     uint8_t flags;
265     DB_id3v2_frame_t *frames;
266 } DB_id3v2_tag_t;
267 
268 typedef struct DB_apev2_frame_s {
269     struct DB_apev2_frame_s *next;
270     uint32_t flags;
271     char key[256];
272     uint32_t size; // size of data
273     uint8_t data[0];
274 } DB_apev2_frame_t;
275 
276 typedef struct DB_apev2_tag_s {
277     uint32_t version;
278     uint32_t flags;
279     DB_apev2_frame_t *frames;
280 } DB_apev2_tag_t;
281 
282 // plugin types
283 enum {
284     DB_PLUGIN_DECODER = 1,
285     DB_PLUGIN_OUTPUT  = 2,
286     DB_PLUGIN_DSP     = 3,
287     DB_PLUGIN_MISC    = 4,
288     DB_PLUGIN_VFS     = 5,
289     DB_PLUGIN_PLAYLIST = 6,
290     DB_PLUGIN_GUI = 7,
291 };
292 
293 // output plugin states
294 enum output_state_t {
295     OUTPUT_STATE_STOPPED = 0,
296     OUTPUT_STATE_PLAYING = 1,
297     OUTPUT_STATE_PAUSED = 2,
298 };
299 
300 // playback order
301 enum playback_order_t {
302     PLAYBACK_ORDER_LINEAR = 0,
303     PLAYBACK_ORDER_SHUFFLE_TRACKS = 1,
304     PLAYBACK_ORDER_RANDOM = 2,
305     PLAYBACK_ORDER_SHUFFLE_ALBUMS = 3,
306 };
307 
308 // playback modes
309 enum playback_mode_t {
310     PLAYBACK_MODE_LOOP_ALL = 0, // loop playlist
311     PLAYBACK_MODE_NOLOOP = 1, // don't loop
312     PLAYBACK_MODE_LOOP_SINGLE = 2, // loop single track
313 };
314 
315 #if (DDB_API_LEVEL >= 8)
316 // playlist change info, used in the DB_EV_PLAYLISTCHANGED p1 argument
317 enum ddb_playlist_change_t {
318     DDB_PLAYLIST_CHANGE_CONTENT, // this is the most generic one, will work for the cases when p1 was omitted (0)
319     DDB_PLAYLIST_CHANGE_CREATED,
320     DDB_PLAYLIST_CHANGE_DELETED,
321     DDB_PLAYLIST_CHANGE_POSITION,
322     DDB_PLAYLIST_CHANGE_TITLE,
323     DDB_PLAYLIST_CHANGE_SELECTION,
324     DDB_PLAYLIST_CHANGE_SEARCHRESULT,
325     DDB_PLAYLIST_CHANGE_PLAYQUEUE,
326 };
327 #endif
328 
329 typedef struct {
330     int event;
331     int size;
332 } ddb_event_t;
333 
334 typedef struct {
335     ddb_event_t ev;
336     DB_playItem_t *track;
337     float playtime; // for SONGFINISHED event -- for how many seconds track was playing
338     time_t started_timestamp; // time when "track" started playing
339 } ddb_event_track_t;
340 
341 typedef struct {
342     ddb_event_t ev;
343     DB_playItem_t *from;
344     DB_playItem_t *to;
345     float playtime; // for SONGCHANGED event -- for how many seconds prev track was playing
346     time_t started_timestamp; // time when "from" started playing
347 } ddb_event_trackchange_t;
348 
349 typedef struct {
350     ddb_event_t ev;
351     int state;
352 } ddb_event_state_t;
353 
354 typedef struct {
355     ddb_event_t ev;
356     DB_playItem_t *track;
357     float playpos;
358 } ddb_event_playpos_t;
359 
360 typedef struct DB_conf_item_s {
361     char *key;
362     char *value;
363     struct DB_conf_item_s *next;
364 } DB_conf_item_t;
365 
366 // event callback type
367 typedef int (*DB_callback_t)(ddb_event_t *, uintptr_t data);
368 
369 // events
370 enum {
371     DB_EV_NEXT = 1, // switch to next track
372     DB_EV_PREV = 2, // switch to prev track
373     DB_EV_PLAY_CURRENT = 3, // play current track (will start/unpause if stopped or paused)
374     DB_EV_PLAY_NUM = 4, // play track nr. p1
375     DB_EV_STOP = 5, // stop current track
376     DB_EV_PAUSE = 6, // pause playback
377     DB_EV_PLAY_RANDOM = 7, // play random track
378     DB_EV_TERMINATE = 8, // must be sent to player thread to terminate
379     DB_EV_PLAYLIST_REFRESH = 9, // [DEPRECATED IN API LEVEL 8, use DB_EV_PLAYLISTCHANGED instead] save and redraw current playlist
380     DB_EV_REINIT_SOUND = 10, // reinitialize sound output with current output_plugin config value
381     DB_EV_CONFIGCHANGED = 11, // one or more config options were changed
382     DB_EV_TOGGLE_PAUSE = 12,
383     DB_EV_ACTIVATED = 13, // will be fired every time player is activated
384     DB_EV_PAUSED = 14, // player was paused or unpaused
385 
386     DB_EV_PLAYLISTCHANGED = 15, // playlist contents were changed (e.g. metadata in any track)
387     // DB_EV_PLAYLISTCHANGED NOTE: it's usually sent on LARGE changes,
388     // when multiple tracks are affected, while for single tracks
389     // the DB_EV_TRACKINFOCHANGED is preferred
390     // added in API level 8:
391     // p1 is one of ddb_playlist_change_t enum values, detailing what exactly has been changed.
392 
393     DB_EV_VOLUMECHANGED = 16, // volume was changed
394     DB_EV_OUTPUTCHANGED = 17, // sound output plugin changed
395     DB_EV_PLAYLISTSWITCHED = 18, // playlist switch occured
396     DB_EV_SEEK = 19, // seek current track to position p1 (ms)
397     DB_EV_ACTIONSCHANGED = 20, // plugin actions were changed, e.g. for reinitializing gui
398     DB_EV_DSPCHAINCHANGED = 21, // emitted when any parameter of the main dsp chain has been changed
399 
400     // since 1.5
401 #if (DDB_API_LEVEL >= 5)
402     DB_EV_SELCHANGED = 22, // selection changed in playlist p1 iter p2, ctx should be a pointer to playlist viewer instance, which caused the change, or NULL
403     DB_EV_PLUGINSLOADED = 23, // after all plugins have been loaded and connected
404 #endif
405 
406 #if (DDB_API_LEVEL >= 8)
407     DB_EV_FOCUS_SELECTION = 24, // tell playlist viewer to focus on selection
408 #endif
409 
410     // -----------------
411     // structured events
412 
413     DB_EV_FIRST = 1000,
414     DB_EV_SONGCHANGED = 1000, // current song changed from one to another, ctx=ddb_event_trackchange_t
415     DB_EV_SONGSTARTED = 1001, // song started playing, ctx=ddb_event_track_t
416     DB_EV_SONGFINISHED = 1002, // song finished playing, ctx=ddb_event_track_t
417 
418     DB_EV_TRACKINFOCHANGED = 1004, // trackinfo was changed (included medatata, playback status, playqueue state, etc), ctx=ddb_event_track_t
419     // DB_EV_TRACKINFOCHANGED NOTE: when multiple tracks change, DB_EV_PLAYLISTCHANGED may be sent instead,
420     // for speed reasons, so always handle both events.
421 
422     DB_EV_SEEKED = 1005, // seek happened, ctx=ddb_event_playpos_t
423 
424     // since 1.5
425 #if (DDB_API_LEVEL >= 5)
426     // NOTE: this is not a structured event, but too late to fix, needs to stay here for backwards compat
427     DB_EV_TRACKFOCUSCURRENT = 1006, // user wants to highlight/find the current playing track
428 #endif
429 
430     DB_EV_MAX
431 };
432 
433 // preset columns, working using IDs
434 // DON'T add new ids in range 2-7, they are reserved for backwards compatibility
435 enum pl_column_t {
436     DB_COLUMN_FILENUMBER = 0,
437     DB_COLUMN_PLAYING = 1,
438     DB_COLUMN_ALBUM_ART = 8,
439 };
440 
441 // replaygain constants
442 enum {
443     DDB_REPLAYGAIN_ALBUMGAIN,
444     DDB_REPLAYGAIN_ALBUMPEAK,
445     DDB_REPLAYGAIN_TRACKGAIN,
446     DDB_REPLAYGAIN_TRACKPEAK,
447 };
448 
449 // sort order constants
450 enum ddb_sort_order_t {
451     DDB_SORT_DESCENDING,
452     DDB_SORT_ASCENDING,
453 // since 1.3
454 #if (DDB_API_LEVEL >= 3)
455     DDB_SORT_RANDOM,
456 #endif
457 };
458 
459 enum ddb_sys_directory_t {
460     DDB_SYS_DIR_CONFIG = 1,
461     DDB_SYS_DIR_PREFIX = 2,
462     DDB_SYS_DIR_DOC = 3,
463     DDB_SYS_DIR_PLUGIN = 4,
464     DDB_SYS_DIR_PIXMAP = 5,
465     DDB_SYS_DIR_CACHE = 6,
466 };
467 
468 // typecasting macros
469 #define DB_PLUGIN(x) ((DB_plugin_t *)(x))
470 #define DB_CALLBACK(x) ((DB_callback_t)(x))
471 #define DB_EVENT(x) ((ddb_event_t *)(x))
472 #define DB_PLAYITEM(x) ((DB_playItem_t *)(x))
473 
474 // FILE object wrapper for vfs access
475 typedef struct {
476     struct DB_vfs_s *vfs;
477 } DB_FILE;
478 
479 // md5 calc control structure (see md5/md5.h)
480 typedef struct DB_md5_s {
481     char data[88];
482 } DB_md5_t;
483 
484 typedef struct {
485     int bps;
486     int channels;
487     int samplerate;
488     uint32_t channelmask;
489     int is_float; // bps must be 32 if this is true
490     int is_bigendian;
491 } ddb_waveformat_t;
492 
493 // since 1.5
494 #if (DDB_API_LEVEL >= 5)
495 #define DDB_FREQ_BANDS 256
496 #define DDB_FREQ_MAX_CHANNELS 9
497 typedef struct ddb_audio_data_s {
498     const ddb_waveformat_t *fmt;
499     const float *data;
500     int nframes;
501 } ddb_audio_data_t;
502 
503 typedef struct ddb_fileadd_data_s {
504     int visibility;
505     ddb_playlist_t *plt;
506     ddb_playItem_t *track;
507 } ddb_fileadd_data_t;
508 #endif
509 
510 // since 1.8
511 #if (DDB_API_LEVEL >= 8)
512 enum {
513     DDB_TF_CONTEXT_HAS_INDEX = 1,
514     DDB_TF_CONTEXT_HAS_ID = 2,
515     DDB_TF_CONTEXT_NO_DYNAMIC = 4, // skip dynamic fields (%playback_time%)
516 #if (DDB_API_LEVEL >= 9)
517     // Don't convert linebreaks to semicolons
518     DDB_TF_CONTEXT_MULTILINE = 8,
519 #endif
520 };
521 
522 // context for title formatting interpreter
523 typedef struct {
524     int _size; // must be set to sizeof(tf_context_t)
525     uint32_t flags; // DDB_TF_CONTEXT_ flags
526     ddb_playItem_t *it; // track to get information from, or NULL
527     ddb_playlist_t *plt; // playlist in which the track resides, or NULL
528 
529     // NOTE: when plt is NULL, it means that the track is not in any playlist,
530     // that is -- playlist will never be automatically guessed, for performance
531     // reasons.
532 
533     // index of the track in playlist the track belongs to
534     // if present, DDB_TF_CONTEXT_HAS_INDEX flag must be set
535     int idx;
536 
537     // predefined column id, one of the DB_COLUMN_
538     // if present, DDB_TF_CONTEXT_HAS_ID flag must be set
539     int id;
540 
541     int iter; // playlist iteration (PL_MAIN, PL_SEARCH)
542 
543     // update is a returned value
544     // meaning:
545     // 0: no automatic updates
546     // <0: updates on every call
547     // >0: number of milliseconds between updates / until next update
548     int update;
549 } ddb_tf_context_t;
550 #endif
551 
552 // forward decl for plugin struct
553 struct DB_plugin_s;
554 
555 // player api definition
556 typedef struct {
557     // versioning
558     int vmajor;
559     int vminor;
560 
561     // md5sum calc
562     void (*md5) (uint8_t sig[16], const char *in, int len);
563     void (*md5_to_str) (char *str, const uint8_t sig[16]);
564     void (*md5_init)(DB_md5_t *s);
565     void (*md5_append)(DB_md5_t *s, const uint8_t *data, int nbytes);
566     void (*md5_finish)(DB_md5_t *s, uint8_t digest[16]);
567 
568     // playback control
569     struct DB_output_s* (*get_output) (void);
570     float (*playback_get_pos) (void); // [0..100]
571     void (*playback_set_pos) (float pos); // [0..100]
572 
573     // streamer access
574     DB_playItem_t *(*streamer_get_playing_track) (void);
575     DB_playItem_t *(*streamer_get_streaming_track) (void);
576     float (*streamer_get_playpos) (void);
577     int (*streamer_ok_to_read) (int len);
578     void (*streamer_reset) (int full);
579     int (*streamer_read) (char *bytes, int size);
580     void (*streamer_set_bitrate) (int bitrate);
581     int (*streamer_get_apx_bitrate) (void);
582     struct DB_fileinfo_s *(*streamer_get_current_fileinfo) (void);
583     int (*streamer_get_current_playlist) (void);
584     struct ddb_dsp_context_s * (*streamer_get_dsp_chain) (void);
585     void (*streamer_set_dsp_chain) (struct ddb_dsp_context_s *chain);
586     void (*streamer_dsp_refresh) (void); // call after changing parameters
587 
588     // system folders
589     // normally functions will return standard folders derived from --prefix
590     // portable version will return pathes specified in comments below
591     const char *(*get_config_dir) (void) DEPRECATED_18; // installdir/config | $XDG_CONFIG_HOME/.config/deadbeef
592     const char *(*get_prefix) (void) DEPRECATED_18; // installdir | PREFIX
593     const char *(*get_doc_dir) (void) DEPRECATED_18; // installdir/doc | DOCDIR
594     const char *(*get_plugin_dir) (void) DEPRECATED_18; // installdir/plugins | LIBDIR/deadbeef
595     const char *(*get_pixmap_dir) (void) DEPRECATED_18; // installdir/pixmaps | PREFIX "/share/deadbeef/pixmaps"
596 
597     // process control
598     void (*quit) (void);
599 
600     // threading
601     intptr_t (*thread_start) (void (*fn)(void *ctx), void *ctx);
602     intptr_t (*thread_start_low_priority) (void (*fn)(void *ctx), void *ctx);
603     int (*thread_join) (intptr_t tid);
604     int (*thread_detach) (intptr_t tid);
605     void (*thread_exit) (void *retval);
606     uintptr_t (*mutex_create) (void);
607     uintptr_t (*mutex_create_nonrecursive) (void);
608     void (*mutex_free) (uintptr_t mtx);
609     int (*mutex_lock) (uintptr_t mtx);
610     int (*mutex_unlock) (uintptr_t mtx);
611     uintptr_t (*cond_create) (void);
612     void (*cond_free) (uintptr_t cond);
613     int (*cond_wait) (uintptr_t cond, uintptr_t mutex);
614     int (*cond_signal) (uintptr_t cond);
615     int (*cond_broadcast) (uintptr_t cond);
616 
617     /////// playlist management //////
618     void (*plt_ref) (ddb_playlist_t *plt);
619     void (*plt_unref) (ddb_playlist_t *plt);
620 
621     // total number of playlists
622     int (*plt_get_count) (void);
623 
624     // 1st item in playlist nr. 'plt'
625     DB_playItem_t * (*plt_get_head) (int plt);
626 
627     // nr. of selected items in playlist nr. 'plt'
628     int (*plt_get_sel_count) (int plt);
629 
630     // add new playlist into position before nr. 'before', with title='title'
631     // returns index of new playlist
632     int (*plt_add) (int before, const char *title);
633 
634     // remove playlist nr. plt
635     void (*plt_remove) (int plt);
636 
637     // clear playlist
638     void (*plt_clear) (ddb_playlist_t *plt);
639     void (*pl_clear) (void);
640 
641     // set current playlist
642     void (*plt_set_curr) (ddb_playlist_t *plt);
643     void (*plt_set_curr_idx) (int plt);
644 
645     // get current playlist
646     // note: caller is responsible to call plt_unref after using pointer
647     // returned by plt_get_curr
648     ddb_playlist_t *(*plt_get_curr) (void);
649     int (*plt_get_curr_idx) (void);
650 
651     // move playlist nr. 'from' into position before nr. 'before', where
652     // before=-1 means last position
653     void (*plt_move) (int from, int before);
654 
655     // playlist saving and loading
656     DB_playItem_t * (*plt_load) (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) DEPRECATED_15;
657     int (*plt_save) (ddb_playlist_t *plt, DB_playItem_t *first, DB_playItem_t *last, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
658 
659     ddb_playlist_t *(*plt_get_for_idx) (int idx);
660     int (*plt_get_title) (ddb_playlist_t *plt, char *buffer, int bufsize);
661     int (*plt_set_title) (ddb_playlist_t *plt, const char *title);
662 
663     // increments modification index
664     void (*plt_modified) (ddb_playlist_t *handle);
665 
666     // returns modication index
667     // the index is incremented by 1 every time playlist changes
668     int (*plt_get_modification_idx) (ddb_playlist_t *handle);
669 
670     // return index of an item in specified playlist, or -1 if not found
671     int (*plt_get_item_idx) (ddb_playlist_t *plt, DB_playItem_t *it, int iter);
672 
673     // playlist metadata
674     // this kind of metadata is stored in playlist (dbpl) files
675     // that is, this is the properties of playlist itself,
676     // not of the tracks in the playlist.
677     // for example, playlist tab color can be stored there, etc
678 
679     // add meta if it doesn't exist yet
680     void (*plt_add_meta) (ddb_playlist_t *handle, const char *key, const char *value);
681 
682     // replace (or add) existing meta
683     void (*plt_replace_meta) (ddb_playlist_t *handle, const char *key, const char *value);
684 
685     // append meta to existing one, or add if doesn't exist
686     void (*plt_append_meta) (ddb_playlist_t *handle, const char *key, const char *value);
687 
688     // set integer meta (works same as replace)
689     void (*plt_set_meta_int) (ddb_playlist_t *handle, const char *key, int value);
690 
691     // set float meta (works same as replace)
692     void (*plt_set_meta_float) (ddb_playlist_t *handle, const char *key, float value);
693 
694     // plt_find_meta must always be used in the pl_lock/unlock block
695     const char *(*plt_find_meta) (ddb_playlist_t *handle, const char *key);
696 
697     // returns head of metadata linked list, for direct access
698     // remember pl_lock/unlock
699     DB_metaInfo_t * (*plt_get_metadata_head) (ddb_playlist_t *handle);
700 
701     // delete meta item from list
702     void (*plt_delete_metadata) (ddb_playlist_t *handle, DB_metaInfo_t *meta);
703 
704     // returns integer value of requested meta, def is the default value if not found
705     int (*plt_find_meta_int) (ddb_playlist_t *handle, const char *key, int def);
706 
707     // returns float value of requested meta, def is the default value if not found
708     float (*plt_find_meta_float) (ddb_playlist_t *handle, const char *key, float def);
709 
710     // delete all metadata
711     void (*plt_delete_all_meta) (ddb_playlist_t *handle);
712 
713     // operating on playlist items
714     DB_playItem_t * (*plt_insert_item) (ddb_playlist_t *playlist, DB_playItem_t *after, DB_playItem_t *it);
715     DB_playItem_t * (*plt_insert_file) (ddb_playlist_t *playlist, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) DEPRECATED_15;
716     DB_playItem_t *(*plt_insert_dir) (ddb_playlist_t *plt, DB_playItem_t *after, const char *dirname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) DEPRECATED_15;
717     void (*plt_set_item_duration) (ddb_playlist_t *plt, DB_playItem_t *it, float duration);
718     int (*plt_remove_item) (ddb_playlist_t *playlist, DB_playItem_t *it);
719     int (*plt_getselcount) (ddb_playlist_t *playlist);
720     float (*plt_get_totaltime) (ddb_playlist_t *plt);
721     int (*plt_get_item_count) (ddb_playlist_t *plt, int iter);
722     int (*plt_delete_selected) (ddb_playlist_t *plt);
723     void (*plt_set_cursor) (ddb_playlist_t *plt, int iter, int cursor);
724     int (*plt_get_cursor) (ddb_playlist_t *plt, int iter);
725     void (*plt_select_all) (ddb_playlist_t *plt);
726     void (*plt_crop_selected) (ddb_playlist_t *plt);
727     DB_playItem_t *(*plt_get_first) (ddb_playlist_t *plt, int iter);
728     DB_playItem_t *(*plt_get_last) (ddb_playlist_t *plt, int iter);
729     DB_playItem_t * (*plt_get_item_for_idx) (ddb_playlist_t *playlist, int idx, int iter);
730     void (*plt_move_items) (ddb_playlist_t *to, int iter, ddb_playlist_t *from, DB_playItem_t *drop_before, uint32_t *indexes, int count);
731     void (*plt_copy_items) (ddb_playlist_t *to, int iter, ddb_playlist_t * from, DB_playItem_t *before, uint32_t *indices, int cnt);
732     void (*plt_search_reset) (ddb_playlist_t *plt);
733     void (*plt_search_process) (ddb_playlist_t *plt, const char *text);
734 
735     // sort using the title formatting v1 (deprecated)
736     void (*plt_sort) (ddb_playlist_t *plt, int iter, int id, const char *format, int order) DEPRECATED_18;
737 
738     // add files and folders to current playlist
739     int (*plt_add_file) (ddb_playlist_t *plt, const char *fname, int (*cb)(DB_playItem_t *it, void *data), void *user_data) DEPRECATED_15;
740     int (*plt_add_dir) (ddb_playlist_t *plt, const char *dirname, int (*cb)(DB_playItem_t *it, void *data), void *user_data) DEPRECATED_15;
741 
742     // cuesheet support
743     DB_playItem_t *(*plt_insert_cue_from_buffer) (ddb_playlist_t *plt, DB_playItem_t *after, DB_playItem_t *origin, const uint8_t *buffer, int buffersize, int numsamples, int samplerate);
744     DB_playItem_t * (*plt_insert_cue) (ddb_playlist_t *plt, DB_playItem_t *after, DB_playItem_t *origin, int numsamples, int samplerate);
745 
746     // playlist locking
747     void (*pl_lock) (void);
748     void (*pl_unlock) (void);
749 
750     // playlist tracks access
751     DB_playItem_t * (*pl_item_alloc) (void);
752     DB_playItem_t * (*pl_item_alloc_init) (const char *fname, const char *decoder_id);
753     void (*pl_item_ref) (DB_playItem_t *it);
754     void (*pl_item_unref) (DB_playItem_t *it);
755     void (*pl_item_copy) (DB_playItem_t *out, DB_playItem_t *in);
756 
757     // request lock for adding files to playlist
758     // this function may return -1 if it is not possible to add files right now.
759     // caller must cancel operation in this case,
760     // or wait until previous operation finishes
761     int (*pl_add_files_begin) (ddb_playlist_t *plt) DEPRECATED_15;
762 
763     // release the lock for adding files to playlist
764     // end must be called when add files operation is finished
765     void (*pl_add_files_end) (void) DEPRECATED_15;
766 
767     // most of this functions are self explanatory
768     // if you don't get what they do -- look in the code
769 
770     // --- the following functions work with current playlist ---
771 
772     // get index of the track in MAIN
773     int (*pl_get_idx_of) (DB_playItem_t *it);
774 
775     // get index of the track in MAIN or SEARCH
776     int (*pl_get_idx_of_iter) (DB_playItem_t *it, int iter);
777 
778     // get track for index in MAIN
779     DB_playItem_t * (*pl_get_for_idx) (int idx);
780 
781     // get track for index in MAIN or SEARCH
782     DB_playItem_t * (*pl_get_for_idx_and_iter) (int idx, int iter);
783 
784     // get total play time of all tracks in MAIN
785     float (*pl_get_totaltime) (void);
786 
787     // get number of tracks in MAIN or SEARCH
788     int (*pl_getcount) (int iter);
789 
790     // delete selected tracks
791     int (*pl_delete_selected) (void);
792 
793     // set cursor position in MAIN or SEARCH
794     void (*pl_set_cursor) (int iter, int cursor);
795 
796     // get cursor position in MAIN
797     int (*pl_get_cursor) (int iter);
798 
799     // remove all except selected tracks
800     void (*pl_crop_selected) (void);
801 
802     // get number of selected tracks
803     int (*pl_getselcount) (void);
804 
805     // get first track in MAIN or SEARCH
806     DB_playItem_t *(*pl_get_first) (int iter);
807 
808     // get last track in MAIN or SEARCH
809     DB_playItem_t *(*pl_get_last) (int iter);
810 
811     // --- misc functions ---
812 
813     // mark the track as selected or unselected (1 or 0 respectively)
814     void (*pl_set_selected) (DB_playItem_t *it, int sel);
815 
816     // test whether the track is selected
817     int (*pl_is_selected) (DB_playItem_t *it);
818 
819     // save current playlist
820     int (*pl_save_current) (void);
821 
822     // save all playlists
823     int (*pl_save_all) (void);
824 
825     // select all tracks in current playlist
826     void (*pl_select_all) (void);
827 
828     // get next track
829     DB_playItem_t *(*pl_get_next) (DB_playItem_t *it, int iter);
830 
831     // get previous track
832     DB_playItem_t *(*pl_get_prev) (DB_playItem_t *it, int iter);
833 
834     /*
835        pl_format_title formats the line for display in playlist
836        @it pointer to playlist item
837        @idx number of that item in playlist (or -1)
838        @s output buffer
839        @size size of output buffer
840        @id one of IDs defined in pl_column_id_t enum, can be -1
841        @fmt format string, used if id is -1
842        format is printf-alike. specification:
843        %a artist
844        %t title
845        %b album
846        %B band / album artist
847        %n track
848        %l length (duration)
849        %y year
850        %g genre
851        %c comment
852        %r copyright
853        %T tags
854        %f filename without path
855        %F full pathname/uri
856        %d directory without path (e.g. /home/user/file.mp3 -> user)
857        %D directory name with full path (e.g. /home/user/file.mp3 -> /home/user)
858        more to come
859     */
860     int (*pl_format_title) (DB_playItem_t *it, int idx, char *s, int size, int id, const char *fmt) DEPRECATED_18;
861 
862     // _escaped version wraps all conversions with '' and replaces every ' in conversions with \'
863     int (*pl_format_title_escaped) (DB_playItem_t *it, int idx, char *s, int size, int id, const char *fmt) DEPRECATED_18;
864 
865     // format duration 't' (fractional seconds) into string, for display in playlist
866     void (*pl_format_time) (float t, char *dur, int size);
867 
868     // find which playlist the specified item belongs to, returns NULL if none
869     ddb_playlist_t * (*pl_get_playlist) (DB_playItem_t *it);
870 
871     // direct access to metadata structures
872     // not thread-safe, make sure to wrap with pl_lock/pl_unlock
873     DB_metaInfo_t * (*pl_get_metadata_head) (DB_playItem_t *it); // returns head of metadata linked list
874     void (*pl_delete_metadata) (DB_playItem_t *it, DB_metaInfo_t *meta);
875 
876     // high-level access to metadata
877     void (*pl_add_meta) (DB_playItem_t *it, const char *key, const char *value);
878     void (*pl_append_meta) (DB_playItem_t *it, const char *key, const char *value);
879     void (*pl_set_meta_int) (DB_playItem_t *it, const char *key, int value);
880     void (*pl_set_meta_float) (DB_playItem_t *it, const char *key, float value);
881     void (*pl_delete_meta) (DB_playItem_t *it, const char *key);
882 
883     // this function is not thread-safe
884     // make sure to wrap it with pl_lock/pl_unlock block
885     const char *(*pl_find_meta) (DB_playItem_t *it, const char *key);
886 
887     // following functions are thread-safe
888     int (*pl_find_meta_int) (DB_playItem_t *it, const char *key, int def);
889     float (*pl_find_meta_float) (DB_playItem_t *it, const char *key, float def);
890     void (*pl_replace_meta) (DB_playItem_t *it, const char *key, const char *value);
891     void (*pl_delete_all_meta) (DB_playItem_t *it);
892     float (*pl_get_item_duration) (DB_playItem_t *it);
893     uint32_t (*pl_get_item_flags) (DB_playItem_t *it);
894     void (*pl_set_item_flags) (DB_playItem_t *it, uint32_t flags);
895     void (*pl_items_copy_junk)(DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last);
896     // idx is one of DDB_REPLAYGAIN_* constants
897     void (*pl_set_item_replaygain) (DB_playItem_t *it, int idx, float value);
898     float (*pl_get_item_replaygain) (DB_playItem_t *it, int idx);
899 
900     // playqueue support (obsolete since API 1.8)
901     int (*pl_playqueue_push) (DB_playItem_t *it) DEPRECATED_18;
902     void (*pl_playqueue_clear) (void) DEPRECATED_18;
903     void (*pl_playqueue_pop) (void) DEPRECATED_18;
904     void (*pl_playqueue_remove) (DB_playItem_t *it) DEPRECATED_18;
905     int (*pl_playqueue_test) (DB_playItem_t *it) DEPRECATED_18;
906 
907     // volume control
908     void (*volume_set_db) (float dB);
909     float (*volume_get_db) (void);
910     void (*volume_set_amp) (float amp);
911     float (*volume_get_amp) (void);
912     float (*volume_get_min_db) (void);
913 
914     // junk reading/writing
915     int (*junk_id3v1_read) (DB_playItem_t *it, DB_FILE *fp);
916     int (*junk_id3v1_find) (DB_FILE *fp);
917     int (*junk_id3v1_write) (FILE *fp, DB_playItem_t *it, const char *enc);
918     int (*junk_id3v2_find) (DB_FILE *fp, int *psize);
919     int (*junk_id3v2_read) (DB_playItem_t *it, DB_FILE *fp);
920     int (*junk_id3v2_read_full) (DB_playItem_t *it, DB_id3v2_tag_t *tag, DB_FILE *fp);
921     int (*junk_id3v2_convert_24_to_23) (DB_id3v2_tag_t *tag24, DB_id3v2_tag_t *tag23);
922     int (*junk_id3v2_convert_23_to_24) (DB_id3v2_tag_t *tag23, DB_id3v2_tag_t *tag24);
923     int (*junk_id3v2_convert_22_to_24) (DB_id3v2_tag_t *tag22, DB_id3v2_tag_t *tag24);
924     void (*junk_id3v2_free) (DB_id3v2_tag_t *tag);
925     int (*junk_id3v2_write) (FILE *file, DB_id3v2_tag_t *tag);
926     DB_id3v2_frame_t *(*junk_id3v2_add_text_frame) (DB_id3v2_tag_t *tag, const char *frame_id, const char *value);
927     int (*junk_id3v2_remove_frames) (DB_id3v2_tag_t *tag, const char *frame_id);
928     int (*junk_apev2_read) (DB_playItem_t *it, DB_FILE *fp);
929     int (*junk_apev2_read_mem) (DB_playItem_t *it, char *mem, int size);
930     int (*junk_apev2_read_full) (DB_playItem_t *it, DB_apev2_tag_t *tag_store, DB_FILE *fp);
931     int (*junk_apev2_read_full_mem) (DB_playItem_t *it, DB_apev2_tag_t *tag_store, char *mem, int memsize);
932     int (*junk_apev2_find) (DB_FILE *fp, int32_t *psize, uint32_t *pflags, uint32_t *pnumitems);
933     int (*junk_apev2_remove_frames) (DB_apev2_tag_t *tag, const char *frame_id);
934     DB_apev2_frame_t * (*junk_apev2_add_text_frame) (DB_apev2_tag_t *tag, const char *frame_id, const char *value);
935     void (*junk_apev2_free) (DB_apev2_tag_t *tag);
936     int (*junk_apev2_write) (FILE *fp, DB_apev2_tag_t *tag, int write_header, int write_footer);
937     int (*junk_get_leading_size) (DB_FILE *fp);
938     int (*junk_get_leading_size_stdio) (FILE *fp);
939     void (*junk_copy) (DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last);
940     const char * (*junk_detect_charset) (const char *s);
941     int (*junk_recode) (const char *in, int inlen, char *out, int outlen, const char *cs);
942     int (*junk_iconv) (const char *in, int inlen, char *out, int outlen, const char *cs_in, const char *cs_out);
943     int (*junk_rewrite_tags) (DB_playItem_t *it, uint32_t flags, int id3v2_version, const char *id3v1_encoding);
944 
945     // vfs
946     DB_FILE* (*fopen) (const char *fname);
947     void (*fclose) (DB_FILE *f);
948     size_t (*fread) (void *ptr, size_t size, size_t nmemb, DB_FILE *stream);
949     int (*fseek) (DB_FILE *stream, int64_t offset, int whence);
950     int64_t (*ftell) (DB_FILE *stream);
951     void (*rewind) (DB_FILE *stream);
952     int64_t (*fgetlength) (DB_FILE *stream);
953     const char *(*fget_content_type) (DB_FILE *stream);
954     void (*fset_track) (DB_FILE *stream, DB_playItem_t *it);
955     void (*fabort) (DB_FILE *stream);
956 
957     // message passing
958     int (*sendmessage) (uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2);
959 
960     // convenience functions to send events, uses sendmessage internally
961     ddb_event_t *(*event_alloc) (uint32_t id);
962     void (*event_free) (ddb_event_t *ev);
963     int (*event_send) (ddb_event_t *ev, uint32_t p1, uint32_t p2);
964 
965     // configuration access
966     //
967     // conf_get_str_fast is not thread-safe, and
968     // must only be used from within conf_lock/conf_unlock block
969     // it should be preferred for fast non-blocking lookups
970     //
971     // all the other config access functions are thread safe
972     void (*conf_lock) (void);
973     void (*conf_unlock) (void);
974     const char * (*conf_get_str_fast) (const char *key, const char *def);
975     void (*conf_get_str) (const char *key, const char *def, char *buffer, int buffer_size);
976     float (*conf_get_float) (const char *key, float def);
977     int (*conf_get_int) (const char *key, int def);
978     int64_t (*conf_get_int64) (const char *key, int64_t def);
979     void (*conf_set_str) (const char *key, const char *val);
980     void (*conf_set_int) (const char *key, int val);
981     void (*conf_set_int64) (const char *key, int64_t val);
982     void (*conf_set_float) (const char *key, float val);
983     DB_conf_item_t * (*conf_find) (const char *group, DB_conf_item_t *prev);
984     void (*conf_remove_items) (const char *key);
985     int (*conf_save) (void);
986 
987     // plugin communication
988     struct DB_decoder_s **(*plug_get_decoder_list) (void);
989     struct DB_vfs_s **(*plug_get_vfs_list) (void);
990     struct DB_output_s **(*plug_get_output_list) (void);
991     struct DB_dsp_s **(*plug_get_dsp_list) (void);
992     struct DB_playlist_s **(*plug_get_playlist_list) (void);
993     struct DB_plugin_s **(*plug_get_list) (void);
994     const char **(*plug_get_gui_names) (void);
995     const char * (*plug_get_decoder_id) (const char *id);
996     void (*plug_remove_decoder_id) (const char *id);
997     struct DB_plugin_s *(*plug_get_for_id) (const char *id);
998 
999     // misc utilities
1000     // returns 1 if the track is represented as a local file
1001     // returns 0 if it's a remote file, e.g. a network stream
1002     // since API 1.5 it also returns 1 for vfs tracks, e.g. from ZIP files
1003     int (*is_local_file) (const char *fname);
1004 
1005     // pcm utilities
1006     int (*pcm_convert) (const ddb_waveformat_t * inputfmt, const char *input, const ddb_waveformat_t *outputfmt, char *output, int inputsize);
1007 
1008     // dsp preset management
1009     int (*dsp_preset_load) (const char *fname, struct ddb_dsp_context_s **head);
1010     int (*dsp_preset_save) (const char *fname, struct ddb_dsp_context_s *head);
1011     void (*dsp_preset_free) (struct ddb_dsp_context_s *head);
1012 
1013     // since 1.2
1014 #if (DDB_API_LEVEL >= 2)
1015     ddb_playlist_t *(*plt_alloc) (const char *title);
1016     void (*plt_free) (ddb_playlist_t *plt);
1017 
1018     void (*plt_set_fast_mode) (ddb_playlist_t *plt, int fast);
1019     int (*plt_is_fast_mode) (ddb_playlist_t *plt);
1020 
1021     const char * (*metacache_add_string) (const char *str);
1022     void (*metacache_remove_string) (const char *str);
1023     void (*metacache_ref) (const char *str);
1024     void (*metacache_unref) (const char *str);
1025 
1026     // this function must return original un-overriden value (ignoring the keys prefixed with '!')
1027     // it's not thread-safe, and must be used under the same conditions as the
1028     // pl_find_meta
1029     const char *(*pl_find_meta_raw) (DB_playItem_t *it, const char *key);
1030 #endif
1031 
1032     // since 1.3
1033 #if (DDB_API_LEVEL >= 3)
1034     int (*streamer_dsp_chain_save) (void);
1035 #endif
1036 
1037     // since 1.4
1038 #if (DDB_API_LEVEL >= 4)
1039     int (*pl_get_meta) (DB_playItem_t *it, const char *key, char *val, int size);
1040     int (*pl_get_meta_raw) (DB_playItem_t *it, const char *key, char *val, int size);
1041     int (*plt_get_meta) (ddb_playlist_t *handle, const char *key, char *val, int size);
1042 
1043     // fast way to test if a field exists in playitem
1044     int (*pl_meta_exists) (DB_playItem_t *it, const char *key);
1045 #endif
1046 
1047     // since 1.5
1048 #if (DDB_API_LEVEL >= 5)
1049     // register/unregister for getting continuous wave data
1050     // mainly for visualization
1051     // ctx must be unique
1052     // the waveform data can be arbitrary size
1053     // the samples are interleaved
1054     void (*vis_waveform_listen) (void *ctx, void (*callback)(void *ctx, ddb_audio_data_t *data));
1055     void (*vis_waveform_unlisten) (void *ctx);
1056 
1057     // register/unregister for getting continuous spectrum (frequency domain) data
1058     // mainly for visualization
1059     // ctx must be unique
1060     // the data always contains DDB_FREQ_BANDS frames
1061     // max number of channels is DDB_FREQ_MAX_CHANNELS
1062     // the samples are non-interleaved
1063     void (*vis_spectrum_listen) (void *ctx, void (*callback)(void *ctx, ddb_audio_data_t *data));
1064     void (*vis_spectrum_unlisten) (void *ctx);
1065 
1066     // this is useful to mute/unmute audio, and query the muted status, from
1067     // plugins, without touching the volume control
1068     void (*audio_set_mute) (int mute);
1069     int (*audio_is_mute) (void);
1070 
1071     // this is useful for prompting a user when he attempts to quit the player
1072     // while something is working in background, e.g. the Converter,
1073     // and let him finish or cancel the background jobs.
1074     void (*background_job_increment) (void);
1075     void (*background_job_decrement) (void);
1076     int (*have_background_jobs) (void);
1077 
1078     // utility function to get plt idx from handle
1079     int (*plt_get_idx) (ddb_playlist_t *plt);
1080 
1081     // save referenced playlist in config
1082     // same as pl_save_current, but for index
1083     int (*plt_save_n) (int n);
1084 
1085     // same as pl_save_current, but for playlist pointer
1086     int (*plt_save_config) (ddb_playlist_t *plt);
1087 
1088     // register file added callback
1089     // the callback will be called for each file
1090     // the visibility is taken from plt_add_* arguments
1091     // the callback must return 0 to continue, or -1 to abort the operation.
1092     // returns ID
1093     int (*listen_file_added) (int (*callback)(ddb_fileadd_data_t *data, void *user_data), void *user_data);
1094     void (*unlisten_file_added) (int id);
1095 
1096     int (*listen_file_add_beginend) (void (*callback_begin) (ddb_fileadd_data_t *data, void *user_data), void (*callback_end)(ddb_fileadd_data_t *data, void *user_data), void *user_data);
1097     void (*unlisten_file_add_beginend) (int id);
1098 
1099     // visibility is a number, which tells listeners about the caller.
1100     // the value DDB_FILEADD_VISIBILITY_GUI (or 0) is reserved for callers which
1101     // want the GUI to intercept the calls and show visual updates.
1102     //
1103     // this is the default value passed from plt_load, plt_add_dir, plt_add_file.
1104     //
1105     // the values up to 10 are registered for deadbeef itself, so please avoid
1106     // using them in your plugins, unless you really know what you're doing.
1107     // any values above 10 are free for any use.
1108     //
1109     // the "callback", if not NULL, will be called with the passed "user_data",
1110     // for each track.
1111     //
1112     // the registered listeners will be called too, the ddb_fileadd_data_t
1113     // has the visibility
1114     DB_playItem_t * (*plt_load2) (int visibility, ddb_playlist_t *plt, ddb_playItem_t *after, const char *fname, int *pabort, int (*callback)(DB_playItem_t *it, void *user_data), void *user_data);
1115     int (*plt_add_file2) (int visibility, ddb_playlist_t *plt, const char *fname, int (*callback)(DB_playItem_t *it, void *user_data), void *user_data);
1116     int (*plt_add_dir2) (int visibility, ddb_playlist_t *plt, const char *dirname, int (*callback)(DB_playItem_t *it, void *user_data), void *user_data);
1117     ddb_playItem_t * (*plt_insert_file2) (int visibility, ddb_playlist_t *playlist, ddb_playItem_t *after, const char *fname, int *pabort, int (*callback)(DB_playItem_t *it, void *user_data), void *user_data);
1118     ddb_playItem_t *(*plt_insert_dir2) (int visibility, ddb_playlist_t *plt, ddb_playItem_t *after, const char *dirname, int *pabort, int (*callback)(DB_playItem_t *it, void *user_data), void *user_data);
1119 
1120     // request lock for adding files to playlist
1121     // returns 0 on success
1122     // this function may return -1 if it is not possible to add files right now.
1123     // caller must cancel operation in this case,
1124     // or wait until previous operation finishes
1125     // NOTE: it's not guaranteed that all deadbeef versions support
1126     // adding the files to different playlists in parallel.
1127     int (*plt_add_files_begin) (ddb_playlist_t *plt, int visibility);
1128 
1129     // release the lock for adding files to playlist
1130     // end must be called when add files operation is finished
1131     void (*plt_add_files_end) (ddb_playlist_t *plt, int visibility);
1132 
1133     // deselect all tracks in playlist
1134     void (*plt_deselect_all) (ddb_playlist_t *plt);
1135 #endif
1136     // since 1.6
1137 #if (DDB_API_LEVEL >= 6)
1138     void (*plt_set_scroll) (ddb_playlist_t *plt, int scroll);
1139     int (*plt_get_scroll) (ddb_playlist_t *plt);
1140 #endif
1141     // since 1.8
1142 #if (DDB_API_LEVEL >= 8)
1143     // **** title formatting v2 ****
1144 
1145     // compile the input title formatting string into bytecode
1146     // script: freeform string with title formatting special characters in it
1147     // returns the pointer to compiled bytecode, which must be tf_free'd by the caller.
1148     char *(*tf_compile) (const char *script);
1149 
1150     // free the code returned by tf_compile
1151     void (*tf_free) (char *code);
1152 
1153     // evaluate the titleformatting script in a given context
1154     // ctx: a pointer to ddb_tf_context_t structure initialized by the caller
1155     // code: the bytecode data created by tf_compile
1156     // out: buffer allocated by the caller, must be big enough to fit the output string
1157     // outlen: the size of out buffer
1158     // returns -1 on fail, output size on success
1159     int (*tf_eval) (ddb_tf_context_t *ctx, const char *code, char *out, int outlen);
1160 
1161     // sort using title formatting v2
1162     void (*plt_sort_v2) (ddb_playlist_t *plt, int iter, int id, const char *format, int order);
1163 
1164     // playqueue APIs
1165     int (*playqueue_push) (DB_playItem_t *it);
1166     void (*playqueue_pop) (void);
1167     void (*playqueue_remove) (DB_playItem_t *it);
1168     void (*playqueue_clear) (void);
1169     int (*playqueue_test) (DB_playItem_t *it);
1170     int (*playqueue_get_count) (void);
1171     DB_playItem_t *(*playqueue_get_item) (int n);
1172     int (*playqueue_remove_nth) (int n);
1173     void (*playqueue_insert_at) (int n, DB_playItem_t *it);
1174 
1175     // system directory API, returns path by id from ddb_sys_directory_t enum
1176     const char *(*get_system_dir) (int dir_id);
1177 
1178     // set the selected playlist for the ongoing plugin action.
1179     // the "set" function is expected to be called by the UI plugin,
1180     // while the "get" is expected to be called by the action code.
1181     void (*action_set_playlist) (ddb_playlist_t *plt);
1182 
1183     // returns one of:
1184     // selected playlist for context menu for the DDB_ACTION_CTX_PLAYLIST,
1185     // or the current active playlist for any other context.
1186     // returned value cannot be NULL
1187     // returned value is refcounted, so remember to call plt_unref.
1188     ddb_playlist_t *(*action_get_playlist) (void);
1189 
1190     // convert legacy title formatting to the new format, usable with tf_compile
1191     void (*tf_import_legacy) (const char *fmt, char *out, int outsize);
1192 #endif
1193 } DB_functions_t;
1194 
1195 // NOTE: an item placement must be selected like this
1196 // if (flags & DB_ACTION_COMMON)  -> main menu, or nowhere, or where GUI plugin wants
1197 //    basically, to put it into main menu, prefix the item title with the menu name
1198 //    e.g. title = "File/MyItem" --> this will add the item under File menu
1199 //
1200 // if (flags & PLAYLIST)  -> playlist (tab) context menu
1201 //
1202 // if (none of the above)  -> track context menu
1203 
1204 enum {
1205     /* Action in main menu (or whereever ui prefers) */
1206     DB_ACTION_COMMON = 1 << 0,
1207 
1208     /* Can handle single track */
1209     DB_ACTION_SINGLE_TRACK = 1 << 1,
1210 
1211     /* Can handle multiple tracks */
1212     DB_ACTION_MULTIPLE_TRACKS = 1 << 2,
1213 
1214     /* DEPRECATED in API 1.5 */
1215     DB_ACTION_ALLOW_MULTIPLE_TRACKS = 1 << 2,
1216 
1217     /* DEPRECATED in API 1.5, ignored in callback2 */
1218     /* Action can (and prefer) traverse multiple tracks by itself */
1219     DB_ACTION_CAN_MULTIPLE_TRACKS = 1 << 3,
1220 
1221     /* Action is inactive */
1222     DB_ACTION_DISABLED = 1 << 4,
1223 
1224     /* DEPRECATED in API 1.5, ignored in callback2 */
1225     /* since 1.2 */
1226     /* Action for the playlist (tab) */
1227     DB_ACTION_PLAYLIST = 1 << 5,
1228 
1229     /* add item to menu(s), if contains slash symbol(s) */
1230     DB_ACTION_ADD_MENU = 1 << 6
1231 };
1232 
1233 // action contexts
1234 // since 1.5
1235 #if (DDB_API_LEVEL >= 5)
1236 enum {
1237     DDB_ACTION_CTX_MAIN,
1238     DDB_ACTION_CTX_SELECTION,
1239     // NOTE: starting with API 1.8, plugins should be using the
1240     // action_get_playlist function for getting the playlist pointer.
1241     DDB_ACTION_CTX_PLAYLIST,
1242     DDB_ACTION_CTX_NOWPLAYING,
1243     DDB_ACTION_CTX_COUNT
1244 };
1245 #endif
1246 
1247 struct DB_plugin_action_s;
1248 
1249 typedef int (*DB_plugin_action_callback_t) (struct DB_plugin_action_s *action, void *userdata);
1250 #if (DDB_API_LEVEL >= 5)
1251 typedef int (*DB_plugin_action_callback2_t) (struct DB_plugin_action_s *action, int ctx);
1252 #endif
1253 
1254 typedef struct DB_plugin_action_s {
1255     const char *title;
1256     const char *name;
1257     uint32_t flags;
1258     // the use of "callback" is deprecated,
1259     // only use it if the code must be compatible with API 1.4
1260     // otherwise switch to callback2
1261     DB_plugin_action_callback_t callback;
1262     struct DB_plugin_action_s *next;
1263 #if (DDB_API_LEVEL >= 5)
1264     DB_plugin_action_callback2_t callback2;
1265 #endif
1266 } DB_plugin_action_t;
1267 
1268 // base plugin interface
1269 typedef struct DB_plugin_s {
1270     // type must be one of DB_PLUGIN_ types
1271     int32_t type;
1272     // api version
1273     int16_t api_vmajor;
1274     int16_t api_vminor;
1275     // plugin version
1276     int16_t version_major;
1277     int16_t version_minor;
1278 
1279     uint32_t flags; // currently unused
1280     uint32_t reserved1;
1281     uint32_t reserved2;
1282     uint32_t reserved3;
1283 
1284     // any of those can be left NULL
1285     // though it's much better to fill them with something useful
1286     const char *id; // id used for serialization and runtime binding
1287     const char *name; // short name
1288     const char *descr; // short description (what the plugin is doing)
1289     const char *copyright; // copyright notice(s), list of developers, links to original works, etc
1290     const char *website; // plugin website
1291 
1292     // plugin-specific command interface; can be NULL
1293     int (*command) (int cmd, ...);
1294 
1295     // start is called to start plugin; can be NULL
1296     int (*start) (void);
1297 
1298     // stop is called to deinit plugin; can be NULL
1299     int (*stop) (void);
1300 
1301     // connect is called to setup connections between different plugins
1302     // it is called after all plugin's start method was executed
1303     // can be NULL
1304     // NOTE for GUI plugin developers: don't initialize your widgets/windows in
1305     // the connect method. look for up-to-date information on wiki:
1306     // http://github.com/Alexey-Yakovenko/deadbeef/wiki/Porting-GUI-plugins-to-deadbeef-from-0.5.x-to-0.6.0
1307     int (*connect) (void);
1308 
1309     // opposite of connect, will be called before stop, while all plugins are still
1310     // in "started" state
1311     int (*disconnect) (void);
1312 
1313     // exec_cmdline may be called at any moment when user sends commandline to player
1314     // can be NULL if plugin doesn't support commandline processing
1315     // cmdline is 0-separated list of strings, guaranteed to have 0 at the end
1316     // cmdline_size is number of bytes pointed by cmdline
1317     int (*exec_cmdline) (const char *cmdline, int cmdline_size);
1318 
1319     // @returns linked list of actions for the specified track
1320     // when it is NULL -- the plugin must return list of all actions
1321     DB_plugin_action_t* (*get_actions) (DB_playItem_t *it);
1322 
1323     // mainloop will call this function for every plugin
1324     // so that plugins may handle all events;
1325     // can be NULL
1326     int (*message) (uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2);
1327 
1328     // plugin configuration dialog is constructed from this data
1329     // can be NULL
1330     const char *configdialog;
1331 } DB_plugin_t;
1332 
1333 // file format stuff
1334 
1335 // channel mask - combine following flags to tell streamer which channels are
1336 // present in input/output streams
1337 enum {
1338     DDB_SPEAKER_FRONT_LEFT = 0x1,
1339     DDB_SPEAKER_FRONT_RIGHT = 0x2,
1340     DDB_SPEAKER_FRONT_CENTER = 0x4,
1341     DDB_SPEAKER_LOW_FREQUENCY = 0x8,
1342     DDB_SPEAKER_BACK_LEFT = 0x10,
1343     DDB_SPEAKER_BACK_RIGHT = 0x20,
1344     DDB_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40,
1345     DDB_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80,
1346     DDB_SPEAKER_BACK_CENTER = 0x100,
1347     DDB_SPEAKER_SIDE_LEFT = 0x200,
1348     DDB_SPEAKER_SIDE_RIGHT = 0x400,
1349     DDB_SPEAKER_TOP_CENTER = 0x800,
1350     DDB_SPEAKER_TOP_FRONT_LEFT = 0x1000,
1351     DDB_SPEAKER_TOP_FRONT_CENTER = 0x2000,
1352     DDB_SPEAKER_TOP_FRONT_RIGHT = 0x4000,
1353     DDB_SPEAKER_TOP_BACK_LEFT = 0x8000,
1354     DDB_SPEAKER_TOP_BACK_CENTER = 0x10000,
1355     DDB_SPEAKER_TOP_BACK_RIGHT = 0x20000
1356 };
1357 
1358 typedef struct DB_fileinfo_s {
1359     struct DB_decoder_s *plugin;
1360 
1361     // these parameters should be set in decoder->open
1362     ddb_waveformat_t fmt;
1363 
1364     // readpos should be updated to current decoder time (in seconds)
1365     float readpos;
1366 
1367     // this is the (optional) file handle, that can be used by streamer to
1368     // request interruption of current read operation
1369     DB_FILE *file;
1370 } DB_fileinfo_t;
1371 
1372 enum {
1373     // Decoders should try to output 16 bit stream when this flag is set, for
1374     // performance reasons.
1375     DDB_DECODER_HINT_16BIT = 0x1,
1376 #if (DDB_API_LEVEL >= 8)
1377     // Decoders should only call the streamer_set_bitrate from plugin.read function,
1378     // and only when this flag is set.
1379     DDB_DECODER_HINT_NEED_BITRATE = 0x2,
1380     // Decoders can do their own infinite looping when this flag is set, in the
1381     // "Loop Single" looping mode.
1382     DDB_DECODER_HINT_CAN_LOOP = 0x4,
1383 #endif
1384 };
1385 
1386 // decoder plugin
1387 typedef struct DB_decoder_s {
1388     DB_plugin_t plugin;
1389 
1390     DB_fileinfo_t *(*open) (uint32_t hints);
1391 
1392     // init is called to prepare song to be started
1393     int (*init) (DB_fileinfo_t *info, DB_playItem_t *it);
1394 
1395     // free is called after decoding is finished
1396     void (*free) (DB_fileinfo_t *info);
1397 
1398     // read is called by streamer to decode specified number of bytes
1399     // must return number of bytes that were successfully decoded (sample aligned)
1400     int (*read) (DB_fileinfo_t *info, char *buffer, int nbytes);
1401 
1402     int (*seek) (DB_fileinfo_t *info, float seconds);
1403 
1404     // perform seeking in samples (if possible)
1405     // return -1 if failed, or 0 on success
1406     // if -1 is returned, that will mean that streamer must skip that song
1407     int (*seek_sample) (DB_fileinfo_t *info, int sample);
1408 
1409     // 'insert' is called to insert new item to playlist
1410     // decoder is responsible to calculate duration, split it into subsongs, load cuesheet, etc
1411     // after==NULL means "prepend before 1st item in playlist"
1412     DB_playItem_t * (*insert) (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname);
1413 
1414     int (*numvoices) (DB_fileinfo_t *info);
1415     void (*mutevoice) (DB_fileinfo_t *info, int voice, int mute);
1416 
1417     int (*read_metadata) (DB_playItem_t *it);
1418     int (*write_metadata) (DB_playItem_t *it);
1419 
1420     // NULL terminated array of all supported extensions
1421     // examples:
1422     // { "aac", "wma", "tak", NULL } -- supports 3 file extensions
1423     // since API 1.9: { "*", NULL } -- supports any file extensions
1424     const char **exts;
1425 
1426     // NULL terminated array of all supported prefixes (UADE support needs that)
1427     // e.g. "mod.song_title"
1428     const char **prefixes;
1429 
1430 #if (DDB_API_LEVEL >= 7)
1431     // This function's purpose is to open the file, so that the file handle is
1432     // immediately accessible via DB_fileinfo_t, and can be used with fabort.
1433     // If a plugin is using open2, it should not reopen the file from init.
1434     // Plugins _must_ implement open even if open2 is present,
1435     // because existing code may rely on it.
1436     DB_fileinfo_t *(*open2) (uint32_t hints, DB_playItem_t *it);
1437 #endif
1438 } DB_decoder_t;
1439 
1440 // output plugin
1441 typedef struct DB_output_s {
1442     DB_plugin_t plugin;
1443     // init is called once at plugin activation
1444     int (*init) (void);
1445     // free is called if output plugin was changed to another, or unload is about to happen
1446     int (*free) (void);
1447     // reconfigure output to another format
1448     int (*setformat) (ddb_waveformat_t *fmt);
1449     // play, stop, pause, unpause are called by deadbeef in response to user
1450     // events, or as part of streaming process
1451     int (*play) (void);
1452     int (*stop) (void);
1453     int (*pause) (void);
1454     int (*unpause) (void);
1455     // one of output_state_t enum values
1456     int (*state) (void);
1457     // soundcard enumeration (can be NULL)
1458     void (*enum_soundcards) (void (*callback)(const char *name, const char *desc, void*), void *userdata);
1459 
1460     // parameters of current output
1461     ddb_waveformat_t fmt;
1462 
1463     // set to 1 if volume control is done internally by plugin
1464     int has_volume;
1465 } DB_output_t;
1466 
1467 // dsp plugin
1468 // see also: examples/dsp_template.c in git
1469 #define DDB_INIT_DSP_CONTEXT(var,type,plug) {\
1470     memset(var,0,sizeof(type));\
1471     var->ctx.plugin=plug;\
1472     var->ctx.enabled=1;\
1473 }
1474 
1475 typedef struct ddb_dsp_context_s {
1476     // pointer to DSP plugin which created this context
1477     struct DB_dsp_s *plugin;
1478 
1479     // pointer to the next DSP plugin context in the chain
1480     struct ddb_dsp_context_s *next;
1481 
1482     // read only flag; set by DB_dsp_t::enable
1483     unsigned enabled : 1;
1484 } ddb_dsp_context_t;
1485 
1486 typedef struct DB_dsp_s {
1487     DB_plugin_t plugin;
1488 
1489     ddb_dsp_context_t* (*open) (void);
1490 
1491     void (*close) (ddb_dsp_context_t *ctx);
1492 
1493     // samples are always interleaved floating point
1494     // returned value is number of output frames (multichannel samples)
1495     // plugins are allowed to modify channels, samplerate, channelmask in the fmt structure
1496     // buffer size can fit up to maxframes frames
1497     // by default ratio=1, and plugins don't need to touch it unless they have to
1498     int (*process) (ddb_dsp_context_t *ctx, float *samples, int frames, int maxframes, ddb_waveformat_t *fmt, float *ratio);
1499 
1500     void (*reset) (ddb_dsp_context_t *ctx);
1501 
1502     // num_params can be NULL, to indicate that plugin doesn't expose any params
1503     //
1504     // if num_params is non-NULL -- get_param_name, set_param and get_param must
1505     // all be implemented
1506     //
1507     // param names are for display-only, and are allowed to contain spaces
1508     int (*num_params) (void);
1509     const char *(*get_param_name) (int p);
1510     void (*set_param) (ddb_dsp_context_t *ctx, int p, const char *val);
1511     void (*get_param) (ddb_dsp_context_t *ctx, int p, char *str, int len);
1512 
1513     // config dialog implementation uses set/get param, so they must be
1514     // implemented if this is nonzero
1515     const char *configdialog;
1516 
1517     // since 1.1
1518 #if (DDB_API_LEVEL >= 1)
1519     // can be NULL
1520     // should return 1 if the DSP plugin will not touch data with the current parameters;
1521     // 0 otherwise
1522     int (*can_bypass) (ddb_dsp_context_t *ctx, ddb_waveformat_t *fmt);
1523 #endif
1524 } DB_dsp_t;
1525 
1526 // misc plugin
1527 // purpose is to provide extra services
1528 // e.g. scrobbling, converting, tagging, custom gui, etc.
1529 // misc plugins should be mostly event driven, so no special entry points in them
1530 typedef struct {
1531     DB_plugin_t plugin;
1532 } DB_misc_t;
1533 
1534 // vfs plugin
1535 // provides means for reading, seeking, etc
1536 // api is based on stdio
1537 typedef struct DB_vfs_s {
1538     DB_plugin_t plugin;
1539 
1540 // capabilities
1541     const char **(*get_schemes) (void); // NULL-terminated list of supported schemes, e.g. {"http://", "ftp://", NULL}; can be NULL
1542 
1543     int (*is_streaming) (void); // return 1 if the plugin streaming data over slow connection, e.g. http; plugins will avoid scanning entire files if this is the case
1544 
1545     int (*is_container) (const char *fname); // should return 1 if this plugin can parse specified file
1546 
1547 // this allows interruption of hanging network streams
1548     void (*abort) (DB_FILE *stream);
1549 
1550 // file access, follows stdio API with few extension
1551     DB_FILE* (*open) (const char *fname);
1552     void (*close) (DB_FILE *f);
1553     size_t (*read) (void *ptr, size_t size, size_t nmemb, DB_FILE *stream);
1554     int (*seek) (DB_FILE *stream, int64_t offset, int whence);
1555     int64_t (*tell) (DB_FILE *stream);
1556     void (*rewind) (DB_FILE *stream);
1557     int64_t (*getlength) (DB_FILE *stream);
1558 
1559     // should return mime-type of a stream, if known; can be NULL
1560     const char * (*get_content_type) (DB_FILE *stream);
1561 
1562     // associates stream with a track, to allow dynamic metadata updating, like
1563     // in icy protocol
1564     void (*set_track) (DB_FILE *f, DB_playItem_t *it);
1565 
1566     // folder access, follows dirent API, and uses dirent data structures
1567     int (*scandir) (const char *dir, struct dirent ***namelist, int (*selector) (const struct dirent *), int (*cmp) (const struct dirent **, const struct dirent **));
1568 
1569 #if (DDB_API_LEVEL >= 6)
1570     // returns URI scheme for a given file name, e.g. "zip://"
1571     // can be NULL
1572     // can return NULL
1573     const char *(*get_scheme_for_name) (const char *fname);
1574 #endif
1575 } DB_vfs_t;
1576 
1577 // gui plugin
1578 // only one gui plugin can be running at the same time
1579 // should provide GUI services to other plugins
1580 
1581 // this structure represents a gui dialog with callbacks to set/get params
1582 // documentation should be available here:
1583 // http://github.com/Alexey-Yakovenko/deadbeef/wiki/GUI-Script-Syntax
1584 typedef struct {
1585     const char *title;
1586     const char *layout;
1587     void (*set_param) (const char *key, const char *value);
1588     void (*get_param) (const char *key, char *value, int len, const char *def);
1589 
1590 #if (DDB_API_LEVEL >= 4)
1591     void *parent;
1592 #endif
1593 } ddb_dialog_t;
1594 
1595 enum {
1596     ddb_button_ok,
1597     ddb_button_cancel,
1598     ddb_button_close,
1599     ddb_button_apply,
1600     ddb_button_yes,
1601     ddb_button_no,
1602     ddb_button_max,
1603 };
1604 
1605 typedef struct DB_gui_s {
1606     DB_plugin_t plugin;
1607 
1608     // returns response code (ddb_button_*)
1609     // buttons is a bitset, e.g. (1<<ddb_button_ok)|(1<<ddb_button_cancel)
1610     int (*run_dialog) (ddb_dialog_t *dlg, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx);
1611 } DB_gui_t;
1612 
1613 // playlist plugin
1614 typedef struct DB_playlist_s {
1615     DB_plugin_t plugin;
1616 
1617     DB_playItem_t * (*load) (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
1618 
1619     // will save items from first to last (inclusive)
1620     // format is determined by extension
1621     // playlist is protected from changes during the call
1622     int (*save) (ddb_playlist_t *plt, const char *fname, DB_playItem_t *first, DB_playItem_t *last);
1623 
1624     const char **extensions; // NULL-terminated list of supported file extensions, e.g. {"m3u", "pls", NULL}
1625 
1626     // since 1.5
1627 #if (DDB_API_LEVEL >= 5)
1628     DB_playItem_t * (*load2) (int visibility, ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort);
1629 #endif
1630 } DB_playlist_t;
1631 
1632 #undef DDB_DEPRECATED
1633 #undef DEPRECATED
1634 
1635 #ifdef __cplusplus
1636 }
1637 #endif
1638 
1639 #endif // __DEADBEEF_H
1640