1 /*
2  * Copyright (c) 2011 Tim van der Molen <tim@kariliq.nl>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <errno.h>
18 #include <pthread.h>
19 #include <stdarg.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 
23 #include "config.h"
24 
25 #include "attribute.h"
26 #include "compat.h"
27 
28 /* File paths. */
29 #define CONF_DIR		".siren"
30 #define CACHE_FILE		"metadata"
31 #define CONF_FILE		"config"
32 #define LIBRARY_FILE		"library"
33 #define PLUGIN_IP_DIR		PLUGIN_DIR "/ip"
34 #define PLUGIN_OP_DIR		PLUGIN_DIR "/op"
35 
36 /* Priority of input plug-ins. */
37 #define IP_PRIORITY_FLAC	0
38 #define IP_PRIORITY_MAD		0
39 #define IP_PRIORITY_OPUS	0
40 #define IP_PRIORITY_SNDFILE	0
41 #define IP_PRIORITY_VORBIS	0
42 #define IP_PRIORITY_WAVPACK	0
43 #define IP_PRIORITY_MPG123	1
44 #define IP_PRIORITY_FFMPEG	2
45 #define IP_PRIORITY_AAC		3
46 
47 /* Priority of output plug-ins. */
48 #define OP_PRIORITY_SNDIO	0
49 #define OP_PRIORITY_PULSE	1
50 #define OP_PRIORITY_SUN		2
51 #define OP_PRIORITY_ALSA	3
52 #define OP_PRIORITY_OSS		4
53 #define OP_PRIORITY_AO		5
54 #define OP_PRIORITY_PORTAUDIO	6
55 
56 /* Size of the buffer to be passed to strerror_r(). The value is arbitrary. */
57 #define STRERROR_BUFSIZE	256
58 
59 /* Character attributes. */
60 #define ATTRIB_NORMAL		0x0
61 #define ATTRIB_BLINK		0x1
62 #define ATTRIB_BOLD		0x2
63 #define ATTRIB_DIM		0x4
64 #define ATTRIB_REVERSE		0x8
65 #define ATTRIB_STANDOUT		0x10
66 #define ATTRIB_UNDERLINE	0x20
67 
68 /* Keys. */
69 #define K_NONE			0x100
70 #define K_BACKSPACE		0x101
71 #define K_BACKTAB		0x102
72 #define K_DELETE		0x103
73 #define K_DOWN			0x104
74 #define K_END			0x105
75 #define K_ENTER			0x106
76 #define K_ESCAPE		0x107
77 #define K_HOME			0x108
78 #define K_INSERT		0x109
79 #define K_LEFT			0x110
80 #define K_PAGEDOWN		0x111
81 #define K_PAGEUP		0x112
82 #define K_RIGHT			0x113
83 #define K_TAB			0x114
84 #define K_UP			0x115
85 #define K_F1			0x116
86 #define K_F2			0x117
87 #define K_F3			0x118
88 #define K_F4			0x119
89 #define K_F5			0x120
90 #define K_F6			0x121
91 #define K_F7			0x122
92 #define K_F8			0x123
93 #define K_F9			0x124
94 #define K_F10			0x125
95 #define K_F11			0x126
96 #define K_F12			0x127
97 #define K_F13			0x128
98 #define K_F14			0x129
99 #define K_F15			0x130
100 #define K_F16			0x131
101 #define K_F17			0x132
102 #define K_F18			0x133
103 #define K_F19			0x134
104 #define K_F20			0x135
105 
106 /* Whether a character is a control character. */
107 #define K_IS_CTRL(c)		(((c) & ~0x1F) == 0 || (c) == 0x7F)
108 
109 /*
110  * Convert a control character to its matching printable character and vice
111  * versa. For example, convert the ^A control character to "A". Conversion in
112  * both directions is done by negating the 7th bit.
113  */
114 #define K_CTRL(c)		((~(c) & 0x40) | ((c) & 0xBF))
115 #define K_UNCTRL(c)		K_CTRL(c)
116 
117 /* Time conversion macros. */
118 #define HOURS(s)		((s) / 3600)
119 #define MINS(s)			((s) / 60)
120 #define MSECS(s)		((s) % 60)
121 #define HMINS(s)		(MINS(s) % 60)
122 
123 /* Traverse each entry of a menu. */
124 #define MENU_FOR_EACH_ENTRY(menu, entry)				\
125 	for ((entry) = menu_get_first_entry(menu);			\
126 	    (entry) != NULL;						\
127 	    (entry) = menu_get_next_entry(entry))
128 
129 #define MENU_FOR_EACH_ENTRY_REVERSE(menu, entry)			\
130 	for ((entry) = menu_get_last_entry(menu);			\
131 	    (entry) != NULL;						\
132 	    (entry) = menu_get_prev_entry(entry))
133 
134 /* Number of elements in an array. */
135 #define NELEMENTS(x)		(sizeof (x) / sizeof (x)[0])
136 
137 /*
138  * Wrappers for log functions.
139  */
140 
141 #define LOG_ERR(...)		log_err(__func__, __VA_ARGS__)
142 #define LOG_ERRX(...)		log_errx(__func__, __VA_ARGS__)
143 #define LOG_FATAL(...)		log_fatal(__func__, __VA_ARGS__)
144 #define LOG_FATALX(...)		log_fatalx(__func__, __VA_ARGS__)
145 #define LOG_INFO(...)		log_info(__func__, __VA_ARGS__)
146 #define LOG_VERRX(...)		log_verrx(__func__, __VA_ARGS__)
147 
148 #ifndef DEBUG
149 #define LOG_DEBUG(...)
150 #else
151 #define LOG_DEBUG(...)		log_info(__func__, __VA_ARGS__)
152 #endif
153 
154 /*
155  * Wrappers for pthreads functions.
156  */
157 
158 #define XPTHREAD_WRAPPER(func, ...)					\
159 	do								\
160 		if ((errno = pthread_ ## func(__VA_ARGS__)) != 0)	\
161 			LOG_FATAL("pthread_" #func);			\
162 	while (0)
163 
164 #define XPTHREAD_COND_BROADCAST(cond)	XPTHREAD_WRAPPER(cond_broadcast, cond)
165 #define XPTHREAD_COND_DESTROY(cond)	XPTHREAD_WRAPPER(cond_destroy, cond)
166 #define XPTHREAD_COND_INIT(cond, attr)	XPTHREAD_WRAPPER(cond_init, cond, attr)
167 #define XPTHREAD_COND_WAIT(cond, mtx)	XPTHREAD_WRAPPER(cond_wait, cond, mtx)
168 #define XPTHREAD_CREATE(thd, attr, func, arg) \
169 	XPTHREAD_WRAPPER(create, thd, attr, func, arg)
170 #define XPTHREAD_JOIN(thd, ret)		XPTHREAD_WRAPPER(join, thd, ret)
171 #define XPTHREAD_MUTEX_LOCK(mtx)	XPTHREAD_WRAPPER(mutex_lock, mtx)
172 #define XPTHREAD_MUTEX_UNLOCK(mtx)	XPTHREAD_WRAPPER(mutex_unlock, mtx)
173 
174 /* Scopes for key bindings. */
175 enum bind_scope {
176 	BIND_SCOPE_COMMON,
177 	BIND_SCOPE_BROWSER,
178 	BIND_SCOPE_LIBRARY,
179 	BIND_SCOPE_MENU,
180 	BIND_SCOPE_PLAYLIST,
181 	BIND_SCOPE_PROMPT,
182 	BIND_SCOPE_QUEUE
183 };
184 
185 enum byte_order {
186 	BYTE_ORDER_BIG,
187 	BYTE_ORDER_LITTLE
188 };
189 
190 enum cache_mode {
191 	CACHE_MODE_READ,
192 	CACHE_MODE_WRITE
193 };
194 
195 enum colour {
196 	COLOUR_BLACK	= -1,
197 	COLOUR_BLUE	= -2,
198 	COLOUR_CYAN	= -3,
199 	COLOUR_DEFAULT	= -4,
200 	COLOUR_GREEN	= -5,
201 	COLOUR_MAGENTA	= -6,
202 	COLOUR_RED	= -7,
203 	COLOUR_WHITE	= -8,
204 	COLOUR_YELLOW	= -9
205 };
206 
207 enum file_type {
208 	FILE_TYPE_DIRECTORY,
209 	FILE_TYPE_REGULAR,
210 	FILE_TYPE_OTHER
211 };
212 
213 enum input_mode {
214 	INPUT_MODE_PROMPT,
215 	INPUT_MODE_VIEW
216 };
217 
218 enum menu_scroll {
219 	MENU_SCROLL_HALF_PAGE,
220 	MENU_SCROLL_LINE,
221 	MENU_SCROLL_PAGE
222 };
223 
224 enum option_type {
225 	OPTION_TYPE_ATTRIB,
226 	OPTION_TYPE_BOOLEAN,
227 	OPTION_TYPE_COLOUR,
228 	OPTION_TYPE_FORMAT,
229 	OPTION_TYPE_NUMBER,
230 	OPTION_TYPE_STRING
231 };
232 
233 enum player_source {
234 	PLAYER_SOURCE_BROWSER,
235 	PLAYER_SOURCE_LIBRARY,
236 	PLAYER_SOURCE_PLAYLIST
237 };
238 
239 enum view_id {
240 	VIEW_ID_BROWSER,
241 	VIEW_ID_LIBRARY,
242 	VIEW_ID_PLAYLIST,
243 	VIEW_ID_QUEUE
244 };
245 
246 struct command;
247 
248 struct history;
249 
250 struct menu;
251 
252 struct menu_entry;
253 
254 struct dir;
255 
256 struct dir_entry {
257 	char		*name;
258 	char		*path;
259 	size_t		 pathsize;
260 	enum file_type	 type;
261 };
262 
263 struct format;
264 
265 struct format_variable {
266 	const char		*lname;
267 	char			 sname;
268 	enum {
269 		FORMAT_VARIABLE_NUMBER,
270 		FORMAT_VARIABLE_STRING,
271 		FORMAT_VARIABLE_TIME
272 	} type;
273 	union {
274 		int			 number;
275 		unsigned int		 time;
276 		const char		*string;
277 	} value;
278 };
279 
280 struct sample_buffer {
281 	void		*data;
282 	int8_t		*data1;
283 	int16_t		*data2;
284 	int32_t		*data4;
285 
286 	size_t		 size_b;
287 	size_t		 size_s;
288 	size_t		 len_b;
289 	size_t		 len_s;
290 
291 	unsigned int	 nbytes;
292 	int		 swap;
293 };
294 
295 struct sample_format {
296 	enum byte_order	 byte_order;
297 	unsigned int	 nbits;
298 	unsigned int	 nchannels;
299 	unsigned int	 rate;
300 };
301 
302 struct track {
303 	char		*path;
304 
305 	const struct ip	*ip;
306 	void		*ipdata;
307 
308 	char		*album;
309 	char		*albumartist;
310 	char		*artist;
311 	char		*comment;
312 	char		*date;
313 	char		*discnumber;
314 	char		*disctotal;
315 	char		*filename;
316 	char		*genre;
317 	char		*title;
318 	char		*tracknumber;
319 	char		*tracktotal;
320 	unsigned int	 duration;
321 
322 	struct sample_format format;
323 };
324 
325 /* Input plug-in. */
326 struct ip {
327 	const char	 *name;
328 	const int	  priority;
329 	const char	**extensions;
330 	void		  (*close)(struct track *) NONNULL();
331 	void		  (*get_metadata)(struct track *) NONNULL();
332 	int		  (*get_position)(struct track *, unsigned int *)
333 			    NONNULL();
334 	int		  (*init)(void);
335 	int		  (*open)(struct track *) NONNULL();
336 	int		  (*read)(struct track *, struct sample_buffer *)
337 			    NONNULL();
338 	void		  (*seek)(struct track *, unsigned int) NONNULL();
339 };
340 
341 /* Output plug-in. */
342 struct op {
343 	const char	*name;
344 	const int	 priority;
345 	const char	*promises;
346 	void		 (*close)(void);
347 	size_t		 (*get_buffer_size)(void);
348 	int		 (*get_volume)(void);
349 	int		 (*get_volume_support)(void);
350 	int		 (*init)(void);
351 	int		 (*open)(void);
352 	void		 (*set_volume)(unsigned int);
353 	int		 (*start)(struct sample_format *) NONNULL();
354 	int		 (*stop)(void);
355 	int		 (*write)(struct sample_buffer *) NONNULL();
356 };
357 
358 const char	*argv_error(int);
359 void		 argv_free(int, char **);
360 int		 argv_parse(const char *, int *, char ***);
361 
362 void		 bind_end(void);
363 int		 bind_execute(enum bind_scope, int);
364 const char	*bind_get_command(enum bind_scope, int key);
365 void		 bind_init(void);
366 void		 bind_set(enum bind_scope, int, struct command *, void *,
367 		    const char *) NONNULL();
368 int		 bind_string_to_scope(const char *, enum bind_scope *)
369 		    NONNULL();
370 int		 bind_string_to_key(const char *) NONNULL();
371 int		 bind_unset(enum bind_scope, int);
372 
373 void		 browser_activate_entry(void);
374 void		 browser_change_dir(const char *);
375 void		 browser_copy_entry(enum view_id);
376 void		 browser_end(void);
377 const char	*browser_get_dir(void);
378 struct track	*browser_get_next_track(void);
379 struct track	*browser_get_prev_track(void);
380 void		 browser_init(void);
381 void		 browser_print(void);
382 void		 browser_refresh_dir(void);
383 void		 browser_scroll_down(enum menu_scroll);
384 void		 browser_scroll_up(enum menu_scroll);
385 void		 browser_search_next(const char *);
386 void		 browser_search_prev(const char *);
387 void		 browser_select_active_entry(void);
388 void		 browser_select_first_entry(void);
389 void		 browser_select_last_entry(void);
390 void		 browser_select_next_entry(void);
391 void		 browser_select_prev_entry(void);
392 
393 void		 cache_close(void);
394 int		 cache_open(enum cache_mode);
395 int		 cache_read_entry(struct track *) NONNULL();
396 void		 cache_update(void);
397 void		 cache_write_entry(const struct track *) NONNULL();
398 
399 void		 command_execute(struct command *, void *) NONNULL(1);
400 void		 command_free_data(struct command *, void *) NONNULL(1);
401 int		 command_parse_string(const char *, struct command **, void **,
402 		    char **) NONNULL();
403 int		 command_process(const char *, char **) NONNULL();
404 
405 void		 conf_end(void);
406 void		 conf_init(const char *);
407 char		*conf_get_path(const char *) NONNULL();
408 void		 conf_read_file(void);
409 void		 conf_source_file(const char *) NONNULL();
410 
411 void		 dir_close(struct dir *) NONNULL();
412 struct dir_entry *dir_get_entry(struct dir *) NONNULL();
413 struct dir	*dir_open(const char *) NONNULL();
414 
415 void		 format_free(struct format *);
416 struct format	*format_parse(const char *) NONNULL();
417 void		 format_snprintf(char *, size_t, const struct format *,
418 		    const struct format_variable *, size_t) NONNULL();
419 const char	*format_to_string(const struct format *) NONNULL();
420 void		 format_track_snprintf(char *, size_t, const struct format *,
421 		    const struct format *, const struct track *) NONNULL();
422 
423 void		 history_add(struct history *, const char *) NONNULL();
424 void		 history_free(struct history *) NONNULL();
425 const char	*history_get_next(struct history *) NONNULL();
426 const char	*history_get_prev(struct history *) NONNULL();
427 struct history	*history_init(void);
428 void		 history_rewind(struct history *) NONNULL();
429 
430 void		 input_end(void);
431 enum input_mode	 input_get_mode(void);
432 void		 input_handle_key(void);
433 void		 input_init(void);
434 void		 input_set_mode(enum input_mode);
435 
436 void		 library_activate_entry(void);
437 void		 library_add_dir(const char *) NONNULL();
438 void		 library_add_track(struct track *) NONNULL();
439 void		 library_copy_entry(enum view_id);
440 void		 library_delete_all_entries(void);
441 void		 library_delete_entry(void);
442 void		 library_end(void);
443 struct track	*library_get_next_track(void);
444 struct track	*library_get_prev_track(void);
445 void		 library_init(void);
446 void		 library_print(void);
447 void		 library_read_file(void);
448 void		 library_scroll_down(enum menu_scroll);
449 void		 library_scroll_up(enum menu_scroll);
450 void		 library_search_next(const char *);
451 void		 library_search_prev(const char *);
452 void		 library_select_active_entry(void);
453 void		 library_select_first_entry(void);
454 void		 library_select_last_entry(void);
455 void		 library_select_next_entry(void);
456 void		 library_select_prev_entry(void);
457 void		 library_update(void);
458 int		 library_write_file(void);
459 
460 void		 log_end(void);
461 void		 log_err(const char *, const char *, ...) PRINTFLIKE(2, 3);
462 void		 log_errx(const char *, const char *, ...) PRINTFLIKE(2, 3);
463 void		 log_fatal(const char *, const char *, ...) NORETURN
464 		    PRINTFLIKE(2, 3);
465 void		 log_fatalx(const char *, const char *, ...) NORETURN
466 		    PRINTFLIKE(2, 3);
467 void		 log_info(const char *, const char *, ...) PRINTFLIKE(2, 3);
468 void		 log_init(int);
469 void		 log_verrx(const char *, const char *, va_list)
470 		    PRINTFLIKE(2, 0);
471 
472 void		 menu_activate_entry(struct menu *, struct menu_entry *)
473 		    NONNULL();
474 void		 menu_free(struct menu *) NONNULL();
475 struct menu_entry *menu_get_active_entry(const struct menu *) NONNULL();
476 void		*menu_get_entry_data(const struct menu_entry *) NONNULL();
477 struct menu_entry *menu_get_first_entry(const struct menu *) NONNULL();
478 struct menu_entry *menu_get_last_entry(const struct menu *) NONNULL();
479 unsigned int	 menu_get_nentries(const struct menu *) NONNULL();
480 struct menu_entry *menu_get_next_entry(const struct menu_entry *) NONNULL();
481 struct menu_entry *menu_get_prev_entry(const struct menu_entry *) NONNULL();
482 struct menu_entry *menu_get_selected_entry(const struct menu *) NONNULL();
483 void		*menu_get_selected_entry_data(const struct menu *) NONNULL();
484 struct menu	*menu_init(void (*)(void *),
485 		    void (*)(const void *, char *, size_t),
486 		    int (*)(const void *, const char *));
487 void		 menu_insert_after(struct menu *, struct menu_entry *, void *)
488 		    NONNULL();
489 void		 menu_insert_before(struct menu *, struct menu_entry *,
490 		    void *) NONNULL();
491 void		 menu_insert_head(struct menu *, void *) NONNULL();
492 void		 menu_insert_tail(struct menu *, void *) NONNULL();
493 void		 menu_move_entry_before(struct menu *, struct menu_entry *,
494 		    struct menu_entry *) NONNULL();
495 void		 menu_move_entry_down(struct menu *, struct menu_entry *)
496 		    NONNULL();
497 void		 menu_move_entry_up(struct menu *, struct menu_entry *)
498 		    NONNULL();
499 void		 menu_print(struct menu *) NONNULL();
500 void		 menu_remove_all_entries(struct menu *) NONNULL();
501 void		 menu_remove_entry(struct menu *, struct menu_entry *)
502 		    NONNULL();
503 void		 menu_remove_selected_entry(struct menu *) NONNULL();
504 void		 menu_scroll_down(struct menu *, enum menu_scroll) NONNULL();
505 void		 menu_scroll_up(struct menu *, enum menu_scroll) NONNULL();
506 void		 menu_search_next(struct menu *, const char *) NONNULL();
507 void		 menu_search_prev(struct menu *, const char *) NONNULL();
508 void		 menu_select_active_entry(struct menu *) NONNULL();
509 void		 menu_select_entry(struct menu *, struct menu_entry *)
510 		    NONNULL();
511 void		 menu_select_first_entry(struct menu *) NONNULL();
512 void		 menu_select_last_entry(struct menu *) NONNULL();
513 void		 menu_select_next_entry(struct menu *) NONNULL();
514 void		 menu_select_prev_entry(struct menu *) NONNULL();
515 
516 void		 msg_clear(void);
517 void		 msg_err(const char *, ...) PRINTFLIKE(1, 2);
518 void		 msg_errx(const char *, ...) PRINTFLIKE(1, 2);
519 void		 msg_info(const char *, ...) PRINTFLIKE(1, 2);
520 
521 void		 option_add_number(const char *, int, int, int, void (*)(void))
522 		    NONNULL(1);
523 void		 option_add_string(const char *, const char *,
524 		    void (*)(void)) NONNULL(1, 2);
525 char		*option_attrib_to_string(int);
526 const char	*option_boolean_to_string(int);
527 char		*option_colour_to_string(int);
528 void		 option_end(void);
529 const char	*option_format_to_string(const struct format *) NONNULL();
530 int		 option_get_attrib(const char *) NONNULL();
531 int		 option_get_boolean(const char *) NONNULL();
532 int		 option_get_colour(const char *) NONNULL();
533 struct format	*option_get_format(const char *) NONNULL();
534 int		 option_get_number(const char *) NONNULL();
535 void		 option_get_number_range(const char *, int *, int *) NONNULL();
536 char		*option_get_string(const char *) NONNULL();
537 int		 option_get_type(const char *, enum option_type *) NONNULL();
538 void		 option_init(void);
539 void		 option_lock(void);
540 void		 option_set_attrib(const char *, int) NONNULL();
541 void		 option_set_boolean(const char *, int) NONNULL();
542 void		 option_set_colour(const char *, int) NONNULL();
543 void		 option_set_format(const char *, struct format *) NONNULL();
544 void		 option_set_number(const char *, int) NONNULL();
545 void		 option_set_string(const char *, const char *) NONNULL();
546 int		 option_string_to_attrib(const char *) NONNULL();
547 int		 option_string_to_boolean(const char *) NONNULL();
548 int		 option_string_to_colour(const char *, int *)
549 		    NONNULL();
550 void		 option_toggle_boolean(const char *) NONNULL();
551 void		 option_unlock(void);
552 
553 char		*path_get_cwd(void);
554 char		*path_get_dirname(const char *);
555 char		*path_get_home_dir(const char *);
556 char		*path_normalise(const char *) NONNULL();
557 
558 void		 player_change_op(void);
559 void		 player_end(void);
560 void		 player_forcibly_close_op(void);
561 enum byte_order	 player_get_byte_order(void);
562 void		 player_init(void);
563 void		 player_pause(void);
564 void		 player_play(void);
565 void		 player_play_next(void);
566 void		 player_play_prev(void);
567 void		 player_play_track(struct track *) NONNULL();
568 void		 player_print(void);
569 void		 player_reopen_op(void);
570 void		 player_seek(int, int);
571 void		 player_set_source(enum player_source);
572 void		 player_set_volume(int, int);
573 void		 player_stop(void);
574 
575 void		 playlist_activate_entry(void);
576 void		 playlist_copy_entry(enum view_id);
577 void		 playlist_end(void);
578 struct track	*playlist_get_next_track(void);
579 struct track	*playlist_get_prev_track(void);
580 void		 playlist_init(void);
581 void		 playlist_load(const char *) NONNULL();
582 void		 playlist_print(void);
583 void		 playlist_scroll_down(enum menu_scroll);
584 void		 playlist_scroll_up(enum menu_scroll);
585 void		 playlist_search_next(const char *);
586 void		 playlist_search_prev(const char *);
587 void		 playlist_select_active_entry(void);
588 void		 playlist_select_first_entry(void);
589 void		 playlist_select_last_entry(void);
590 void		 playlist_select_next_entry(void);
591 void		 playlist_select_prev_entry(void);
592 void		 playlist_update(void);
593 
594 #ifdef HAVE_PLEDGE
595 void		 plugin_append_promises(char **) NONNULL();
596 #endif
597 void		 plugin_end(void);
598 void		 plugin_init(void);
599 const struct ip	*plugin_find_ip(const char *) NONNULL();
600 const struct op	*plugin_find_op(const char *) NONNULL();
601 
602 void		 prompt_end(void);
603 void		 prompt_get_answer(const char *, void (*)(char *, void *),
604 		    void *) NONNULL(1, 2);
605 void		 prompt_get_command(const char *, void (*)(char *, void *),
606 		    void *) NONNULL(1, 2);
607 void		 prompt_get_search_query(const char *,
608 		    void (*)(char *, void *), void *) NONNULL(1, 2);
609 void		 prompt_handle_key(int);
610 void		 prompt_init(void);
611 void		 prompt_print(void);
612 
613 void		 queue_activate_entry(void);
614 void		 queue_add_dir(const char *) NONNULL();
615 void		 queue_add_track(struct track *) NONNULL();
616 void		 queue_copy_entry(enum view_id);
617 void		 queue_delete_all_entries(void);
618 void		 queue_delete_entry(void);
619 void		 queue_end(void);
620 struct track	*queue_get_next_track(void);
621 void		 queue_init(void);
622 void		 queue_move_entry_down(void);
623 void		 queue_move_entry_up(void);
624 void		 queue_print(void);
625 void		 queue_scroll_down(enum menu_scroll);
626 void		 queue_scroll_up(enum menu_scroll);
627 void		 queue_search_next(const char *);
628 void		 queue_search_prev(const char *);
629 void		 queue_select_first_entry(void);
630 void		 queue_select_last_entry(void);
631 void		 queue_select_next_entry(void);
632 void		 queue_select_prev_entry(void);
633 void		 queue_update(void);
634 
635 void		 screen_configure_cursor(void);
636 void		 screen_configure_objects(void);
637 void		 screen_end(void);
638 int		 screen_get_key(void);
639 int		 screen_get_ncolours(void);
640 unsigned int	 screen_get_ncols(void);
641 void		 screen_init(void);
642 void		 screen_msg_error_printf(const char *, ...) NONNULL()
643 		    PRINTFLIKE(1, 2);
644 void		 screen_msg_error_vprintf(const char *, va_list) NONNULL()
645 		    PRINTFLIKE(1, 0);
646 void		 screen_msg_info_vprintf(const char *, va_list) NONNULL()
647 		    PRINTFLIKE(1, 0);
648 void		 screen_player_status_printf(const struct format *,
649 		    const struct format_variable *, size_t) NONNULL();
650 void		 screen_player_track_printf(const struct format *,
651 		    const struct format *, const struct track *) NONNULL(1, 2);
652 void		 screen_print(void);
653 void		 screen_prompt_begin(void);
654 void		 screen_prompt_end(void);
655 void		 screen_prompt_printf(size_t, const char *, ...) NONNULL()
656 		    PRINTFLIKE(2, 3);
657 void		 screen_refresh(void);
658 void		 screen_status_clear(void);
659 unsigned int	 screen_view_get_nrows(void);
660 void		 screen_view_print(const char *) NONNULL();
661 void		 screen_view_print_active(const char *) NONNULL();
662 void		 screen_view_print_begin(void);
663 void		 screen_view_print_end(void);
664 void		 screen_view_print_selected(const char *) NONNULL();
665 void		 screen_view_title_printf(const char *, ...) PRINTFLIKE(1, 2);
666 void		 screen_view_title_printf_right(const char *, ...)
667 		    PRINTFLIKE(1, 2);
668 
669 int		 track_cmp(const struct track *, const struct track *)
670 		    NONNULL();
671 void		 track_copy_vorbis_comment(struct track *, const char *);
672 void		 track_end(void);
673 struct track	*track_get(char *, const struct ip *) NONNULL(1);
674 void		 track_init(void);
675 void		 track_lock_metadata(void);
676 struct track	*track_require(char *);
677 int		 track_search(const struct track *, const char *);
678 void		 track_split_tag(const char *, char **, char **);
679 void		 track_unlock_metadata(void);
680 void		 track_update_metadata(int);
681 int		 track_write_cache(void);
682 
683 void		 view_activate_entry(void);
684 void		 view_add_dir(enum view_id, const char *) NONNULL();
685 void		 view_add_track(enum view_id, struct track *) NONNULL();
686 void		 view_copy_entry(enum view_id);
687 void		 view_delete_all_entries(void);
688 void		 view_delete_entry(void);
689 enum view_id	 view_get_id(void);
690 void		 view_handle_key(int);
691 void		 view_move_entry_down(void);
692 void		 view_move_entry_up(void);
693 void		 view_print(void);
694 void		 view_scroll_down(enum menu_scroll);
695 void		 view_scroll_up(enum menu_scroll);
696 void		 view_search_next(const char *);
697 void		 view_search_prev(const char *);
698 void		 view_select_active_entry(void);
699 void		 view_select_first_entry(void);
700 void		 view_select_last_entry(void);
701 void		 view_select_next_entry(void);
702 void		 view_select_prev_entry(void);
703 void		 view_select_view(enum view_id);
704 
705 int		 xasprintf(char **, const char *, ...) NONNULL()
706 		    PRINTFLIKE(2, 3);
707 void		*xmalloc(size_t);
708 void		*xrealloc(void *, size_t);
709 void		*xreallocarray(void *, size_t, size_t);
710 int		 xsnprintf(char *, size_t, const char *, ...) PRINTFLIKE(3, 4);
711 char		*xstrdup(const char *) NONNULL();
712 char		*xstrndup(const char *, size_t) NONNULL();
713 int		 xvasprintf(char **, const char *, va_list) NONNULL()
714 		    PRINTFLIKE(2, 0);
715 int		 xvsnprintf(char *, size_t, const char *, va_list) NONNULL()
716 		    PRINTFLIKE(3, 0);
717