ao_write: Silence sparse warning.
[paraslash.git] / gui_theme.c
1 /* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
2
3 /** \file gui_theme.c Theme definitions. */
4
5 #include "para.h"
6 #include "gui.h"
7 #include <curses.h>
8
9 static void init_theme_simple(struct gui_theme *t)
10 {
11         struct stat_item_data *d = t->data;
12         t->author = "Andre Noll";
13         t->lines_min = 5;
14         t->top_lines_min = 2;
15         t->cols_min = 40;
16         t->top_lines_default = 2;
17         t->sb.bg = COLOR_CYAN;
18         t->sb.fg = COLOR_BLACK;
19         t->cmd.bg = COLOR_WHITE;
20         t->cmd.fg = COLOR_BLACK;
21         t->output.bg = COLOR_BLUE;
22         t->output.fg = COLOR_WHITE;
23         t->msg.bg = COLOR_BLUE;
24         t->msg.fg = COLOR_YELLOW;
25         t->err_msg.bg = COLOR_RED;
26         t->err_msg.fg = COLOR_WHITE;
27         t->sep.bg = COLOR_BLUE;
28         t->sep.fg = COLOR_CYAN;
29         t->dflt.fg = COLOR_WHITE;
30         t->dflt.bg = COLOR_BLUE;
31         t->sep_char = '*';
32
33         d[SI_basename].prefix = "";
34         d[SI_basename].postfix = "";
35         d[SI_basename].color.fg = COLOR_WHITE;
36         d[SI_basename].color.bg = COLOR_BLUE;
37         d[SI_basename].align = CENTER;
38         d[SI_basename].x = 0;
39         d[SI_basename].y = 7;
40         d[SI_basename].len = 100;
41
42         d[SI_status].prefix = "para_server: ";
43         d[SI_status].postfix = "";
44         d[SI_status].color.fg = COLOR_WHITE;
45         d[SI_status].color.bg = COLOR_BLUE;
46         d[SI_status].align = CENTER;
47         d[SI_status].x = 0;
48         d[SI_status].y = 60;
49         d[SI_status].len = 50;
50
51         d[SI_audiod_status].prefix = "para_audiod: ";
52         d[SI_audiod_status].postfix = "";
53         d[SI_audiod_status].color.fg = COLOR_WHITE;
54         d[SI_audiod_status].color.bg = COLOR_BLUE;
55         d[SI_audiod_status].align = CENTER;
56         d[SI_audiod_status].x = 50;
57         d[SI_audiod_status].y = 60;
58         d[SI_audiod_status].len = 50;
59
60 }
61
62 static void init_theme_colorful_blackness(struct gui_theme *t)
63 {
64         struct stat_item_data *d = t->data;
65         t->author = "Andre Noll";
66         /* minimal number of lines that is needed to display all
67          * information provided by this theme
68          */
69         t->lines_min = 15;
70         t->cols_min = 80;
71         t->top_lines_min = 9;
72         t->top_lines_default = 11; /* default number of lines */
73
74         t->sb.bg = COLOR_GREEN; /* status bar background */
75         t->sb.fg = COLOR_BLACK; /* status bar foreground */
76         t->cmd.bg = COLOR_BLACK;
77         t->cmd.fg = COLOR_YELLOW;
78         t->output.bg = COLOR_BLACK;
79         t->output.fg = COLOR_CYAN;
80         t->msg.bg = COLOR_BLACK;
81         t->msg.fg = COLOR_WHITE;
82         t->err_msg.bg = COLOR_RED;
83         t->err_msg.fg = COLOR_WHITE;
84         t->sep.bg = COLOR_BLACK; /* color of the separator */
85         t->sep.fg = COLOR_BLUE;
86         t->sep_char = 0; /* default (ACS_HLINE) */
87         t->dflt.bg = COLOR_BLACK;
88         t->dflt.fg = COLOR_MAGENTA;
89
90
91         d[SI_play_time].prefix = "";
92         d[SI_play_time].postfix = "";
93         d[SI_play_time].color.fg = COLOR_CYAN;
94         d[SI_play_time].color.bg = COLOR_BLACK;
95         d[SI_play_time].align = CENTER;
96         d[SI_play_time].x = 0;
97         d[SI_play_time].y = 7;
98         d[SI_play_time].len = 35;
99
100         d[SI_basename].prefix = "";
101         d[SI_basename].postfix = "";
102         d[SI_basename].color.fg = COLOR_CYAN;
103         d[SI_basename].color.bg = COLOR_BLACK;
104         d[SI_basename].align = LEFT;
105         d[SI_basename].x = 35;
106         d[SI_basename].y = 7;
107         d[SI_basename].len = 65;
108
109         d[SI_status].prefix = "";
110         d[SI_status].postfix = " ";
111         d[SI_status].color.fg = COLOR_RED;
112         d[SI_status].color.bg = COLOR_BLACK;
113         d[SI_status].align = RIGHT;
114         d[SI_status].x = 0;
115         d[SI_status].y = 17;
116         d[SI_status].len = 11;
117
118         d[SI_status_flags].prefix = "(";
119         d[SI_status_flags].postfix = ")";
120         d[SI_status_flags].color.fg = COLOR_RED;
121         d[SI_status_flags].color.bg = COLOR_BLACK;
122         d[SI_status_flags].align = LEFT;
123         d[SI_status_flags].x = 11;
124         d[SI_status_flags].y = 17;
125         d[SI_status_flags].len = 10;
126
127         d[SI_image_id].prefix = "img: ";
128         d[SI_image_id].postfix = "";
129         d[SI_image_id].color.fg = COLOR_RED;
130         d[SI_image_id].color.bg = COLOR_BLACK;
131         d[SI_image_id].align = CENTER;
132         d[SI_image_id].x = 21;
133         d[SI_image_id].y = 17;
134         d[SI_image_id].len = 10;
135
136         d[SI_lyrics_id].prefix = "lyr: ";
137         d[SI_lyrics_id].postfix = "";
138         d[SI_lyrics_id].color.fg = COLOR_RED;
139         d[SI_lyrics_id].color.bg = COLOR_BLACK;
140         d[SI_lyrics_id].align = CENTER;
141         d[SI_lyrics_id].x = 31;
142         d[SI_lyrics_id].y = 17;
143         d[SI_lyrics_id].len = 11;
144
145         d[SI_format].prefix = "format: ";
146         d[SI_format].postfix = "";
147         d[SI_format].color.fg = COLOR_RED;
148         d[SI_format].color.bg = COLOR_BLACK;
149         d[SI_format].align = CENTER;
150         d[SI_format].x = 42;
151         d[SI_format].y = 17;
152         d[SI_format].len = 18;
153
154         d[SI_num_played].prefix = "#";
155         d[SI_num_played].postfix = "";
156         d[SI_num_played].color.fg = COLOR_RED;
157         d[SI_num_played].color.bg = COLOR_BLACK;
158         d[SI_num_played].align = LEFT;
159         d[SI_num_played].x = 60;
160         d[SI_num_played].y = 17;
161         d[SI_num_played].len = 5;
162
163         d[SI_bitrate].prefix = "";
164         d[SI_bitrate].postfix = "";
165         d[SI_bitrate].color.fg = COLOR_RED;
166         d[SI_bitrate].color.bg = COLOR_BLACK;
167         d[SI_bitrate].align = CENTER;
168         d[SI_bitrate].x = 65;
169         d[SI_bitrate].y = 17;
170         d[SI_bitrate].len = 13;
171
172         d[SI_frequency].prefix = "";
173         d[SI_frequency].postfix = "";
174         d[SI_frequency].color.fg = COLOR_RED;
175         d[SI_frequency].color.bg = COLOR_BLACK;
176         d[SI_frequency].align = CENTER;
177         d[SI_frequency].x = 78;
178         d[SI_frequency].y = 17;
179         d[SI_frequency].len = 10;
180
181         d[SI_score].prefix = "sc: ";
182         d[SI_score].postfix = "";
183         d[SI_score].color.fg = COLOR_RED;
184         d[SI_score].color.bg = COLOR_BLACK;
185         d[SI_score].align = CENTER;
186         d[SI_score].x = 88;
187         d[SI_score].y = 17;
188         d[SI_score].len = 10;
189
190         d[SI_audiod_status].prefix = "";
191         d[SI_audiod_status].postfix = "";
192         d[SI_audiod_status].color.fg = COLOR_MAGENTA;
193         d[SI_audiod_status].color.bg = COLOR_BLACK;
194         d[SI_audiod_status].align = CENTER;
195         d[SI_audiod_status].x = 0;
196         d[SI_audiod_status].y = 27;
197         d[SI_audiod_status].len = 5;
198
199         d[SI_decoder_flags].prefix = "[";
200         d[SI_decoder_flags].postfix = "]";
201         d[SI_decoder_flags].color.fg = COLOR_MAGENTA;
202         d[SI_decoder_flags].color.bg = COLOR_BLACK;
203         d[SI_decoder_flags].align = CENTER;
204         d[SI_decoder_flags].x = 5;
205         d[SI_decoder_flags].y = 27;
206         d[SI_decoder_flags].len = 10;
207
208         d[SI_mtime].prefix = "mod: ";
209         d[SI_mtime].postfix = "";
210         d[SI_mtime].color.fg = COLOR_MAGENTA;
211         d[SI_mtime].color.bg = COLOR_BLACK;
212         d[SI_mtime].align = CENTER;
213         d[SI_mtime].x = 15;
214         d[SI_mtime].y = 27;
215         d[SI_mtime].len = 22;
216
217         d[SI_file_size].prefix = "";
218         d[SI_file_size].postfix = "kb";
219         d[SI_file_size].color.fg = COLOR_MAGENTA;
220         d[SI_file_size].color.bg = COLOR_BLACK;
221         d[SI_file_size].align = CENTER;
222         d[SI_file_size].x = 37;
223         d[SI_file_size].y = 27;
224         d[SI_file_size].len = 10;
225
226         d[SI_channels].prefix = "";
227         d[SI_channels].postfix = "ch";
228         d[SI_channels].color.fg = COLOR_MAGENTA;
229         d[SI_channels].color.bg = COLOR_BLACK;
230         d[SI_channels].align = CENTER;
231         d[SI_channels].x = 47;
232         d[SI_channels].y = 27;
233         d[SI_channels].len = 5;
234
235         d[SI_last_played].prefix = "lp: ";
236         d[SI_last_played].postfix = "";
237         d[SI_last_played].color.fg = COLOR_MAGENTA;
238         d[SI_last_played].color.bg = COLOR_BLACK;
239         d[SI_last_played].align = CENTER;
240         d[SI_last_played].x = 52;
241         d[SI_last_played].y = 27;
242         d[SI_last_played].len = 21;
243
244         d[SI_num_chunks].prefix = "";
245         d[SI_num_chunks].postfix = "x";
246         d[SI_num_chunks].color.fg = COLOR_MAGENTA;
247         d[SI_num_chunks].color.bg = COLOR_BLACK;
248         d[SI_num_chunks].align = RIGHT;
249         d[SI_num_chunks].x = 73;
250         d[SI_num_chunks].y = 27;
251         d[SI_num_chunks].len = 11;
252
253         d[SI_chunk_time].prefix = "";
254         d[SI_chunk_time].postfix = "ms";
255         d[SI_chunk_time].color.fg = COLOR_MAGENTA;
256         d[SI_chunk_time].color.bg = COLOR_BLACK;
257         d[SI_chunk_time].align = LEFT;
258         d[SI_chunk_time].x = 84;
259         d[SI_chunk_time].y = 27;
260         d[SI_chunk_time].len = 8;
261
262         d[SI_amplification].prefix = "amp:";
263         d[SI_amplification].postfix = "";
264         d[SI_amplification].color.fg = COLOR_MAGENTA;
265         d[SI_amplification].color.bg = COLOR_BLACK;
266         d[SI_amplification].align = RIGHT;
267         d[SI_amplification].x = 92;
268         d[SI_amplification].y = 27;
269         d[SI_amplification].len = 8;
270
271         d[SI_techinfo].prefix = "";
272         d[SI_techinfo].postfix = "";
273         d[SI_techinfo].color.fg = COLOR_GREEN;
274         d[SI_techinfo].color.bg = COLOR_BLACK;
275         d[SI_techinfo].align = CENTER;
276         d[SI_techinfo].x = 0;
277         d[SI_techinfo].y = 43;
278         d[SI_techinfo].len = 100;
279
280         d[SI_title].prefix = "";
281         d[SI_title].postfix = ",";
282         d[SI_title].color.fg = COLOR_GREEN;
283         d[SI_title].color.bg = COLOR_BLACK;
284         d[SI_title].align = RIGHT;
285         d[SI_title].x = 0;
286         d[SI_title].y = 53;
287         d[SI_title].len = 45;
288
289         d[SI_artist].prefix = " by ";
290         d[SI_artist].postfix = "";
291         d[SI_artist].color.fg = COLOR_GREEN;
292         d[SI_artist].color.bg = COLOR_BLACK;
293         d[SI_artist].align = LEFT;
294         d[SI_artist].x = 45;
295         d[SI_artist].y = 53;
296         d[SI_artist].len = 45;
297
298         d[SI_year].prefix = "(";
299         d[SI_year].postfix = ")";
300         d[SI_year].color.fg = COLOR_GREEN;
301         d[SI_year].color.bg = COLOR_BLACK;
302         d[SI_year].align = RIGHT;
303         d[SI_year].x = 90;
304         d[SI_year].y = 53;
305         d[SI_year].len = 10;
306
307         d[SI_album].prefix = "A: ";
308         d[SI_album].postfix = ",";
309         d[SI_album].color.fg = COLOR_GREEN;
310         d[SI_album].color.bg = COLOR_BLACK;
311         d[SI_album].align = RIGHT;
312         d[SI_album].x = 0;
313         d[SI_album].y = 63;
314         d[SI_album].len = 50;
315
316         d[SI_comment].prefix = " C: ";
317         d[SI_comment].postfix = "";
318         d[SI_comment].color.fg = COLOR_GREEN;
319         d[SI_comment].color.bg = COLOR_BLACK;
320         d[SI_comment].align = LEFT;
321         d[SI_comment].x = 50;
322         d[SI_comment].y = 63;
323         d[SI_comment].len = 50;
324
325         d[SI_afs_mode].prefix = "";
326         d[SI_afs_mode].postfix = "";
327         d[SI_afs_mode].color.fg = COLOR_YELLOW;
328         d[SI_afs_mode].color.bg = COLOR_BLACK;
329         d[SI_afs_mode].align = CENTER;
330         d[SI_afs_mode].x = 0;
331         d[SI_afs_mode].y = 77;
332         d[SI_afs_mode].len = 100;
333
334         d[SI_attributes_txt].prefix = "";
335         d[SI_attributes_txt].postfix = "";
336         d[SI_attributes_txt].color.fg = COLOR_YELLOW;
337         d[SI_attributes_txt].color.bg = COLOR_BLACK;
338         d[SI_attributes_txt].align = CENTER;
339         d[SI_attributes_txt].x = 0;
340         d[SI_attributes_txt].y = 87;
341         d[SI_attributes_txt].len = 100;
342
343         d[SI_directory].prefix = "dir: ";
344         d[SI_directory].postfix = "";
345         d[SI_directory].color.fg = COLOR_YELLOW;
346         d[SI_directory].color.bg = COLOR_BLACK;
347         d[SI_directory].align = CENTER;
348         d[SI_directory].x = 0;
349         d[SI_directory].y = 97;
350         d[SI_directory].len = 100;
351 }
352
353 struct theme_description {
354         const char *name;
355         void (*init)(struct gui_theme *t);
356 };
357
358 static struct theme_description themes[] = {
359         {
360                 .name = "colorful blackness",
361                 .init = init_theme_colorful_blackness,
362         },
363         {
364                 .name = "simple",
365                 .init = init_theme_simple,
366         },
367 };
368
369 /** Number of elements in the \a themes array. */
370 #define NUM_THEMES (ARRAY_SIZE(themes))
371
372 static int current_theme_num;
373
374 static void set_theme(int num, struct gui_theme *t)
375 {
376         int i;
377         FOR_EACH_STATUS_ITEM(i)
378                 t->data[i].len = 0;
379         num %= NUM_THEMES;
380         t->name = themes[num].name;
381         themes[num].init(t);
382         current_theme_num = num;
383         PARA_NOTICE_LOG("theme: %s\n", t->name);
384 }
385
386 /**
387  * Initialize a theme.
388  *
389  * \param name Name of the theme to be initialized.
390  * \param t The function fills out this structure.
391  *
392  * This function exits if there is no theme called \a name.
393  */
394 void theme_init(const char *name, struct gui_theme *t)
395 {
396         int i;
397
398         if (!name)
399                 return set_theme(0, t);
400         for (i = 0; i < NUM_THEMES; i++)
401                 if (strcmp(name, themes[i].name) == 0)
402                         return set_theme(i, t);
403         fprintf(stderr, "Available themes:\n");
404         for (i = 0; i < NUM_THEMES; i++)
405                 fprintf(stderr, "\t%s\n", themes[i].name);
406         exit(EXIT_FAILURE);
407 }
408
409 /**
410  * Activate the previous available theme.
411  *
412  * \param t Theme definition is stored here.
413  *
414  * This picks the theme that comes before the currently active one, or the last
415  * available theme, if the current one is the first.
416  *
417  * \sa \ref theme_next().
418  */
419 void theme_prev(struct gui_theme *t)
420 {
421         return set_theme(++current_theme_num, t);
422 }
423
424 /**
425  * Activate the next available theme.
426  *
427  * \param t Theme definition is stored here.
428  *
429  * This works exactly as theme_prev() but cycles forwards through the list of
430  * available themes.
431  */
432 void theme_next(struct gui_theme *t)
433 {
434         return set_theme(--current_theme_num, t);
435 }