audiod clean_exit(): Only check status fd once
[paraslash.git] / slider.c
1 /*
2  * Copyright (C) 2004-2006 Andre Noll <maan@systemlinux.org>
3  *
4  *     This program is free software; you can redistribute it and/or modify
5  *     it under the terms of the GNU General Public License as published by
6  *     the Free Software Foundation; either version 2 of the License, or
7  *     (at your option) any later version.
8  *
9  *     This program is distributed in the hope that it will be useful,
10  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *     GNU General Public License for more details.
13  *
14  *     You should have received a copy of the GNU General Public License
15  *     along with this program; if not, write to the Free Software
16  *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17  */
18
19 /** \file slider.c libzmw-based stream creator for paraslash */
20
21 #include "para.h"
22 #include "zmw/zmw.h"
23 #include "math.h"
24 #include "string.h"
25
26 #define WIDTH 300
27 #define SLIDER_RATIO 6
28 #define VAL_2_SL_VAL(v) (v) * (SLIDER_RATIO - 1.0) / SLIDER_RATIO
29 #define SL_VAL_2_VAL(v) (v) * SLIDER_RATIO / (SLIDER_RATIO - 1.0)
30 #define VAL_2_SCORE(v) (v) > 0.5? 1 / (1.03 - (v)) / (1.03 - (v)) :\
31         - 1 / ((v) + 0.03) / ((v) + 0.03)
32
33 #define RGB(R,G,B) (((R)<<12) + ((G)<<6) + (B))
34
35 #define EPSILON 0.001
36 #define LASTPLAYED_FORMULA(v) \
37         1 / (pow((v), 10) + EPSILON * EPSILON) - 1 / (1 + EPSILON) + EPSILON
38
39 #define NUMPLAYED_FORMULA(v)\
40         10 * (v) + (v) / (1 - (v) * (1 - EPSILON))
41
42 static int argc;
43 static char **argv;
44 char *streamname = NULL;
45 static Zmw_Float_0_1 *slider_vals, lastplayed_val, numplayed_val;
46
47 void para_log(int ll, const char* fmt,...) /* no logging */
48 {
49 }
50
51 static void rst(void)
52 {
53         int i;
54         for (i = 1; argv[i]; i++)
55                 slider_vals[i] = VAL_2_SL_VAL(.5);
56         if (streamname)
57                 free(streamname);
58         streamname = para_strdup("slider");
59         //printf("rst: \n");
60 }
61
62 static char *get_value_filename(void)
63 {
64         char *ret, *home =para_homedir();
65         ret = make_message("%s/.paraslash/slide.values", home);
66         free(home);
67         return ret;
68 }
69
70 static void load(void)
71 {
72         char *tmp;
73         char att[999];
74         FILE *f;
75         int i;
76         Zmw_Float_0_1 val;
77
78         tmp = get_value_filename();
79         f  = fopen(tmp, "r");
80         free(tmp);
81         if (!f)
82                 return;
83         while (fscanf(f, "%900s %g", att, &val) == 2) {
84                 if (!strcmp(att, "lastplayed")) {
85                         lastplayed_val = val;
86                         continue;
87                 }
88                 if (!strcmp(att, "numplayed")) {
89                         numplayed_val = val;
90                         continue;
91                 }
92                 for (i = 1; argv[i]; i++)
93                         if (!strcmp(argv[i], att)) {
94                                 slider_vals[i] = val;
95                                 break;
96                         }
97
98         }
99         fclose(f);
100 }
101
102 static void save(void)
103 {
104         char *filename;
105         FILE *f;
106         int i;
107
108         filename = get_value_filename();
109         f  = fopen(filename, "w");
110         free(filename);
111         if (!f)
112                 return;
113         fprintf(f, "lastplayed %g\n", lastplayed_val);
114         fprintf(f, "numplayed %g\n", numplayed_val);
115         for (i = 1; argv[i]; i++)
116                 fprintf(f, "%s %g\n", argv[i], slider_vals[i]);
117         fclose(f);
118 }
119
120
121 static void print_score(FILE *fd)
122 {
123         int i;
124
125         for (i = 1; argv[i]; i++) {
126                 if (SL_VAL_2_VAL(slider_vals[i]) > .99)
127                         fprintf(fd, "deny: IS_N_SET(%s)\n", argv[i]);
128                 if (slider_vals[i] < .01)
129                         fprintf(fd, "deny: IS_SET(%s)\n", argv[i]);
130         }
131         fprintf(fd, "score: 0 ");
132         for (i = 1; argv[i]; i++) {
133                 if (slider_vals[i] < .01)
134                         continue;
135                 fprintf(fd, "+ %i * IS_SET(%s) ",
136                         (int) (VAL_2_SCORE(SL_VAL_2_VAL(slider_vals[i]))),
137                         argv[i]
138                 );
139         }
140         fprintf(fd, " + round((LASTPLAYED()/1440 - 1000 / (LASTPLAYED()/1440 + 1)) / %f"
141                         " - %f * NUMPLAYED(), 2)\n",
142                 LASTPLAYED_FORMULA(SL_VAL_2_VAL(lastplayed_val)),
143                 NUMPLAYED_FORMULA(SL_VAL_2_VAL(numplayed_val)));
144 }
145
146 static void stradd(void)
147 {
148         FILE *pipe;
149         char *cmd = make_message("para_client stradd %s", streamname);
150
151         pipe = popen(cmd, "w");
152         free(cmd);
153         if (!pipe)
154                 return;
155         print_score(pipe);
156         pclose(pipe);
157 }
158
159 static void b_save(void)
160 {
161         stradd();
162         save();
163 }
164
165 static void go(void)
166 {
167         stradd();
168         system("para_client cs slider");
169         system("para_client stop");
170         system("para_client play");
171 }
172
173 static void ok()
174 {
175         stradd();
176         system("para_client cs slider");
177         system("para_client play");
178         save();
179         zmw_main_quit(EXIT_SUCCESS);
180 }
181
182 static void make_buttons(void)
183 {
184         /* Add a frame around the box */
185         ZMW(zmw_decorator(Zmw_Decorator_Border_Embossed)) {
186                 /* the buttons */
187                 ZMW(zmw_hbox()) {
188                         zmw_button("save");
189                         if (zmw_activated())
190                                 b_save();
191                         zmw_button("ok");
192                         if (zmw_activated())
193                                 ok();
194                         zmw_button("go!");
195                         if (zmw_activated())
196                                 go();
197                         zmw_button("rst");
198                         if (zmw_activated())
199                                 rst();
200 //                      zmw_x(WIDTH);
201                         zmw_button("abort");
202                         if (zmw_activated())
203                                 zmw_main_quit(EXIT_FAILURE);
204                 }
205         }
206 }
207 static void make_stream_input_field(void)
208 {
209         static char *text1 = NULL;
210         static int cursor_pos = 1; // Must be static
211         static int text1_length ;
212
213         ZMW(zmw_vbox()) {
214                 if ( text1 == NULL ) {
215                         // The initial value must be malloced
216                         text1 = strdup("slider") ;
217                         text1_length = strlen(text1) ;
218                 }
219                 ZMW(zmw_fixed()) {
220                         zmw_y(6);
221                         zmw_x(0);
222                         zmw_label("stream: ");
223                         zmw_color(Zmw_Color_Foreground, RGB(63, 63, 63));
224                         zmw_y(0);
225                         zmw_x(100);
226                         zmw_width(WIDTH);
227                         zmw_entry_with_cursor(&streamname, &cursor_pos);
228                         if (zmw_changed())
229                                 text1_length = strlen(text1);
230                 }
231         }
232 }
233
234 /* the sliders, one for each member in argv */
235 static void make_sliders(void)
236 {
237         int i;
238         char *txt;
239
240         zmw_height(ZMW_VALUE_UNDEFINED);
241 //                zmw_horizontal_expand(Zmw_True);
242         ZMW(zmw_hbox()) {
243                 ZMW(zmw_vbox()) {
244                         zmw_color(Zmw_Color_Foreground, RGB(0, 63, 63)); /* font */
245                         txt = make_message("lp: (%i%%)",
246                                 (int)(.5 + 100 * SL_VAL_2_VAL(lastplayed_val)));
247                         zmw_label(txt);
248                         free(txt);
249                         txt = make_message("np: (%i%%)",
250                                 (int)(.5 + 100 * SL_VAL_2_VAL(numplayed_val)));
251                         zmw_label(txt);
252                         free(txt);
253                         zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
254                         for (i = 1; argv[i]; i++) {
255                                 txt = make_message("%s: (%i%%)", argv[i],
256                                         (int)(.5 + 100 * SL_VAL_2_VAL(slider_vals[i])));
257                                 zmw_label(txt);
258                                 free(txt);
259                         }
260                 }
261                 ZMW(zmw_vbox()) {
262                         zmw_width(200) ;
263                         zmw_hscrollbar(&lastplayed_val, 1.0 / SLIDER_RATIO);
264                         zmw_hscrollbar(&numplayed_val, 1.0 / SLIDER_RATIO);
265                         for (i = 1; argv[i]; i++) {
266                                 zmw_hscrollbar(&slider_vals[i],
267                                         1.0 / SLIDER_RATIO);
268                         }
269                 }
270         }
271 }
272
273 static void anchor(void)
274 {
275
276         zmw_font_family("terminal");
277         zmw_font_size(14);
278         zmw_rgb(0.1, 0.1, 0.1);
279         zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
280         zmw_color(Zmw_Color_Background_Pushed, RGB(0, 10, 4)); /* slider bg */
281         zmw_color(Zmw_Color_Background_Poped, RGB(0, 42, 42)); /* button bg */
282         zmw_color(Zmw_Color_Border_Light, RGB(0, 7, 63)); /* slider/button border */
283
284         ZMW(zmw_window("para_slider")) {
285                 ZMW(zmw_vbox()) {
286                         make_buttons();
287                         make_stream_input_field();
288                         zmw_color(Zmw_Color_Foreground, RGB(0, 63, 63)); /* font */
289 //                      make_special_sliders();
290                         zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
291                         make_sliders();
292                 }
293         }
294 }
295
296 static void get_atts(void)
297 {
298         char buf[256];
299         FILE *p = popen("para_client laa", "r");
300         argv = para_malloc(255 * sizeof(char *)); /* FIXME */
301
302         argv[0] = para_strdup("all_attributes");
303         argc = 1;
304         if (!p)
305                 goto err_out;
306         while (fgets(buf, 255, p)) {
307                 chop(buf);
308                 argv[argc] = para_strdup(buf);
309                 argc++;
310         }
311         pclose(p);
312         argv[argc] = NULL;
313         argc--;
314         if (argc > 1)
315                 return; /* success */
316 err_out:
317         if (argc > 1)
318                 for (argc = 1; argv[argc]; argc++)
319                         free(argv[argc]);
320         free(argv);
321         argc = 1;
322 }
323
324 int main(int the_argc, char *the_argv[])
325 {
326         argc = the_argc;
327         argv = the_argv;
328         if (argc < 2) {
329                 get_atts();
330                 if (argc < 2)
331                         return -1;
332         }
333         slider_vals = para_malloc((argc + 1) * sizeof(int*));
334         rst();
335         load();
336 //      printf("argc: %d\n", argc);
337 //      for (i = 1; argv[i]; i++)
338 //              printf("argv[%d]: %s\n", i, argv[i]);
339         zmw_init(&argc, &argv);
340         zmw_main(anchor);
341         return 0;
342 }