1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 Jonathan Gordon
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "lib/playback_control.h"
24 #define MAX_LINE_LEN 2048
27 static unsigned char *buffer
;
28 static size_t buffer_size
;
29 static size_t char_count
= 0;
30 static int line_count
= 0;
31 static int last_action_line
= 0;
32 static int last_char_index
= 0;
33 static bool audio_buf
= false;
35 static char temp_line
[MAX_LINE_LEN
];
36 static char copy_buffer
[MAX_LINE_LEN
];
37 static char filename
[MAX_PATH
];
41 #define ACTION_INSERT 0
43 #define ACTION_REMOVE 2
44 #define ACTION_UPDATE 3
45 #define ACTION_CONCAT 4
47 static char* _do_action(int action
, char* str
, int line
);
48 #ifndef HAVE_ADJUSTABLE_CPU_FREQ
49 #define do_action _do_action
51 static char* do_action(int action
, char* str
, int line
)
55 r
= _do_action(action
,str
,line
);
61 static char* _do_action(int action
, char* str
, int line
)
65 if (line
>=last_action_line
)
70 while (i
<line
&& i
<line_count
)
72 c
+= rb
->strlen(&buffer
[c
])+1;
78 len
= rb
->strlen(str
)+1;
79 if ( char_count
+ len
> buffer_size
)
81 rb
->memmove(&buffer
[c
+len
],&buffer
[c
],char_count
-c
);
82 rb
->strcpy(&buffer
[c
],str
);
87 if (line
> line_count
)
91 if (line
> line_count
)
93 len
= rb
->strlen(&buffer
[c
])+1;
94 rb
->memmove(&buffer
[c
],&buffer
[c
+len
],char_count
-c
-len
);
99 if (line
> line_count
)
101 len
= rb
->strlen(&buffer
[c
])+1;
102 lennew
= rb
->strlen(str
)+1;
103 if ( char_count
+ lennew
-len
> buffer_size
)
105 rb
->memmove(&buffer
[c
+lennew
],&buffer
[c
+len
],char_count
-c
-len
);
106 rb
->strcpy(&buffer
[c
],str
);
107 char_count
+= lennew
-len
;
110 if (line
> line_count
)
112 rb
->memmove(&buffer
[c
-1],&buffer
[c
],char_count
-c
);
119 last_action_line
= i
;
123 static const char* list_get_name_cb(int selected_item
, void* data
,
124 char* buf
, size_t buf_len
)
127 char *b
= do_action(ACTION_GET
, 0, selected_item
);
128 /* strlcpy(dst, src, siz) returns strlen(src) */
129 if (rb
->strlcpy(buf
, b
, buf_len
) >= buf_len
)
131 rb
->strcpy(&buf
[buf_len
-10], " ...");
136 static void get_eol_string(char* fn
)
141 /* assume LF first */
142 rb
->strcpy(eol
,"\n");
146 fd
= rb
->open(fn
,O_RDONLY
);
152 if (!rb
->read(fd
,&t
,1) || t
== '\n')
158 if (rb
->read(fd
,&t
,1) && t
=='\n')
159 rb
->strcpy(eol
,"\r\n");
161 rb
->strcpy(eol
,"\r");
169 static bool save_changes(int overwrite
)
174 if (newfile
|| !overwrite
)
176 if(rb
->kbd_input(filename
,MAX_PATH
) < 0)
183 fd
= rb
->open(filename
,O_WRONLY
|O_CREAT
|O_TRUNC
, 0666);
187 rb
->splash(HZ
*2, "Changes NOT saved");
191 rb
->lcd_clear_display();
192 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
195 for (i
=0;i
<line_count
;i
++)
197 rb
->fdprintf(fd
,"%s%s", do_action(ACTION_GET
, 0, i
), eol
);
199 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
204 if (newfile
|| !overwrite
)
205 /* current directory may have changed */
206 rb
->reload_directory();
212 static void setup_lists(struct gui_synclist
*lists
, int sel
)
214 rb
->gui_synclist_init(lists
,list_get_name_cb
,0, false, 1, NULL
);
215 rb
->gui_synclist_set_icon_callback(lists
,NULL
);
216 rb
->gui_synclist_set_nb_items(lists
,line_count
);
217 rb
->gui_synclist_limit_scroll(lists
,true);
218 rb
->gui_synclist_select_item(lists
, sel
);
219 rb
->gui_synclist_draw(lists
);
227 static int do_item_menu(int cur_sel
)
229 int ret
= MENU_RET_NO_UPDATE
;
230 MENUITEM_STRINGLIST(menu
, "Line Options", NULL
,
231 "Cut/Delete", "Copy",
232 "Insert Above", "Insert Below",
234 "Save", "Playback Control");
236 switch (rb
->do_menu(&menu
, NULL
, NULL
, false))
239 rb
->strlcpy(copy_buffer
, do_action(ACTION_GET
, 0, cur_sel
),
241 do_action(ACTION_REMOVE
, 0, cur_sel
);
242 ret
= MENU_RET_UPDATE
;
245 rb
->strlcpy(copy_buffer
, do_action(ACTION_GET
, 0, cur_sel
),
247 ret
= MENU_RET_NO_UPDATE
;
249 case 2: /* insert above */
250 if (!rb
->kbd_input(copy_buffer
,MAX_LINE_LEN
))
252 do_action(ACTION_INSERT
,copy_buffer
,cur_sel
);
254 ret
= MENU_RET_UPDATE
;
257 case 3: /* insert below */
258 if (!rb
->kbd_input(copy_buffer
,MAX_LINE_LEN
))
260 do_action(ACTION_INSERT
,copy_buffer
,cur_sel
+1);
262 ret
= MENU_RET_UPDATE
;
265 case 4: /* cat to above */
268 do_action(ACTION_CONCAT
,0,cur_sel
);
269 ret
= MENU_RET_UPDATE
;
275 case 6: /* playback menu */
277 playback_control(NULL
);
279 rb
->splash(HZ
, "Cannot restart playback");
280 ret
= MENU_RET_NO_UPDATE
;
283 ret
= MENU_RET_NO_UPDATE
;
289 #ifdef HAVE_LCD_COLOR
291 #define hex2dec(c) (((c) >= '0' && ((c) <= '9')) ? (toupper(c)) - '0' : \
292 (toupper(c)) - 'A' + 10)
294 static int my_hex_to_rgb(const char* hex
, int* color
)
297 int red
, green
, blue
;
299 if (rb
->strlen(hex
) == 6) {
300 for (i
=0; i
< 6; i
++ ) {
301 if (!isxdigit(hex
[i
])) {
308 red
= (hex2dec(hex
[0]) << 4) | hex2dec(hex
[1]);
309 green
= (hex2dec(hex
[2]) << 4) | hex2dec(hex
[3]);
310 blue
= (hex2dec(hex
[4]) << 4) | hex2dec(hex
[5]);
311 *color
= LCD_RGBPACK(red
,green
,blue
);
318 #endif /* HAVE_LCD_COLOR */
320 /* this is the plugin entry point */
321 enum plugin_status
plugin_start(const void* parameter
)
325 struct gui_synclist lists
;
328 bool changed
= false;
330 #ifdef HAVE_LCD_COLOR
331 bool edit_colors_file
= false;
337 rb
->lcd_set_backdrop(NULL
);
339 buffer
= rb
->plugin_get_buffer(&buffer_size
);
341 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
346 #ifdef HAVE_LCD_COLOR
349 rb
->strlcpy(filename
, (char*)parameter
, MAX_PATH
);
350 get_eol_string(filename
);
351 fd
= rb
->open(filename
,O_RDONLY
);
354 rb
->splashf(HZ
*2, "Couldnt open file: %s", filename
);
357 #ifdef HAVE_LCD_COLOR
358 c
= rb
->strrchr(filename
, '.');
359 if (c
&& !rb
->strcmp(c
, ".colours"))
360 edit_colors_file
= true;
362 if (buffer_size
<= (size_t)rb
->filesize(fd
) + 0x400)
364 buffer
= rb
->plugin_get_audio_buffer(&buffer_size
);
367 /* read in the file */
368 while (rb
->read_line(fd
,temp_line
,MAX_LINE_LEN
) > 0)
370 if (!do_action(ACTION_INSERT
,temp_line
,line_count
))
372 rb
->splashf(HZ
*2,"Error reading file: %s",(char*)parameter
);
382 rb
->strcpy(filename
,"/");
383 rb
->strcpy(eol
,"\n");
387 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
390 /* now dump it in the list */
391 setup_lists(&lists
,0);
395 rb
->gui_synclist_draw(&lists
);
396 cur_sel
= rb
->gui_synclist_get_sel_pos(&lists
);
397 button
= rb
->get_action(CONTEXT_LIST
,TIMEOUT_BLOCK
);
398 if (rb
->gui_synclist_do_button(&lists
,&button
,LIST_WRAP_UNLESS_HELD
))
405 rb
->strlcpy(temp_line
, do_action(ACTION_GET
, 0, cur_sel
),
407 #ifdef HAVE_LCD_COLOR
408 if (edit_colors_file
&& line_count
)
410 char *name
= temp_line
, *value
= NULL
;
412 int color
, old_color
;
413 bool temp_changed
= false;
415 MENUITEM_STRINGLIST(menu
, "Edit What?", NULL
,
416 "Extension", "Colour");
418 rb
->settings_parseline(temp_line
, &name
, &value
);
419 rb
->strlcpy(extension
, name
, sizeof(extension
));
421 my_hex_to_rgb(value
, &color
);
425 switch (rb
->do_menu(&menu
, NULL
, NULL
, false))
428 temp_changed
= !rb
->kbd_input(extension
, sizeof(extension
));
432 rb
->set_color(rb
->screens
[SCREEN_MAIN
], name
, &color
, -1);
433 temp_changed
= (value
== NULL
) || (color
!= old_color
);
439 rb
->snprintf(temp_line
, MAX_LINE_LEN
, "%s: %02X%02X%02X",
440 extension
, RGB_UNPACK_RED(color
),
441 RGB_UNPACK_GREEN(color
),
442 RGB_UNPACK_BLUE(color
));
443 do_action(ACTION_UPDATE
, temp_line
, cur_sel
);
449 if (!rb
->kbd_input(temp_line
,MAX_LINE_LEN
))
452 do_action(ACTION_UPDATE
,temp_line
,cur_sel
);
454 do_action(ACTION_INSERT
,temp_line
,cur_sel
);
459 case ACTION_STD_CONTEXT
:
460 if (!line_count
) break;
461 rb
->strlcpy(copy_buffer
, do_action(ACTION_GET
, 0, cur_sel
),
463 do_action(ACTION_REMOVE
, 0, cur_sel
);
466 case ACTION_STD_MENU
:
468 /* do the item menu */
469 switch (do_item_menu(cur_sel
))
475 case MENU_RET_UPDATE
:
478 case MENU_RET_NO_UPDATE
:
483 case ACTION_STD_CANCEL
:
486 MENUITEM_STRINGLIST(menu
, "Do What?", NULL
,
488 "Playback Control", "Save Changes",
489 "Save As...", "Save and Exit",
490 "Ignore Changes and Exit");
491 switch (rb
->do_menu(&menu
, NULL
, NULL
, false))
497 playback_control(NULL
);
499 rb
->splash(HZ
, "Cannot restart playback");
501 case 2: //save to disk
521 rb
->gui_synclist_set_nb_items(&lists
,line_count
);
522 if(line_count
> 0 && line_count
<= cur_sel
)
523 rb
->gui_synclist_select_item(&lists
,line_count
-1);