1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2003 by Benjamin Metzler
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
25 #include "applimits.h"
49 #define MAX_BOOKMARKS 10
50 #define MAX_BOOKMARK_SIZE 350
51 #define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark"
53 static bool add_bookmark(char* bookmark_file_name
, char* bookmark
);
54 static bool bookmark_load_menu(void);
55 static bool check_bookmark(char* bookmark
);
56 static char* create_bookmark(void);
57 static bool delete_bookmark(char* bookmark_file_name
, int bookmark_id
);
58 static void display_bookmark(char* bookmark
,
61 static void say_bookmark(char* bookmark
,
63 static bool generate_bookmark_file_name(char *in
,
65 unsigned int max_length
);
66 static char* get_bookmark(char* bookmark_file
, int bookmark_count
);
67 static bool parse_bookmark(char *bookmark
,
71 int *resume_first_index
,
73 unsigned int resume_file_size
,
78 unsigned int max_file_name_size
);
79 static char* select_bookmark(char* bookmark_file_name
);
80 static bool system_check(void);
81 static bool write_bookmark(bool create_bookmark_file
);
82 static int get_bookmark_count(char* bookmark_file_name
);
84 static char global_temp_buffer
[MAX_PATH
+1];
85 static char global_bookmark_file_name
[MAX_PATH
];
86 static char global_read_buffer
[MAX_BOOKMARK_SIZE
];
87 static char global_bookmark
[MAX_BOOKMARK_SIZE
];
89 /* ----------------------------------------------------------------------- */
90 /* Displays the bookmark menu options for the user to decide. This is an */
91 /* interface function. */
92 /* ----------------------------------------------------------------------- */
93 bool bookmark_menu(void)
98 struct menu_item items
[] = {
99 { STR(LANG_BOOKMARK_MENU_CREATE
), bookmark_create_menu
},
100 { STR(LANG_BOOKMARK_MENU_LIST
), bookmark_load_menu
},
101 { STR(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS
), bookmark_mrb_load
},
104 m
=menu_init( items
, sizeof items
/ sizeof(struct menu_item
), NULL
,
107 #ifdef HAVE_LCD_CHARCELLS
108 status_set_param(true);
110 result
= menu_run(m
);
111 #ifdef HAVE_LCD_CHARCELLS
112 status_set_param(false);
121 /* ----------------------------------------------------------------------- */
122 /* This is the interface function from the main menu. */
123 /* ----------------------------------------------------------------------- */
124 bool bookmark_create_menu(void)
126 write_bookmark(true);
130 /* ----------------------------------------------------------------------- */
131 /* This function acts as the load interface from the main menu */
132 /* This function determines the bookmark file name and then loads that file*/
133 /* for the user. The user can then select a bookmark to load. */
134 /* If no file/directory is currently playing, the menu item does not work. */
135 /* ----------------------------------------------------------------------- */
136 static bool bookmark_load_menu(void)
148 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
149 sizeof(global_temp_buffer
));
150 if (generate_bookmark_file_name(name
,
151 global_bookmark_file_name
,
152 sizeof(global_bookmark_file_name
)))
154 bookmark
= select_bookmark(global_bookmark_file_name
);
156 return false; /* User exited without selecting a bookmark */
158 success
= parse_bookmark(bookmark
,
164 sizeof(global_temp_buffer
),
166 &global_settings
.repeat_mode
,
167 &global_settings
.playlist_shuffle
,
172 /* something bad happened while creating bookmark name*/
177 bookmark_play(global_temp_buffer
, index
, offset
, seed
);
183 /* ----------------------------------------------------------------------- */
184 /* Gives the user a list of the Most Recent Bookmarks. This is an */
185 /* interface function */
186 /* ----------------------------------------------------------------------- */
187 bool bookmark_mrb_load()
195 bookmark
= select_bookmark(RECENT_BOOKMARK_FILE
);
197 return false; /* User exited without selecting a bookmark */
199 success
= parse_bookmark(bookmark
,
205 sizeof(global_temp_buffer
),
207 &global_settings
.repeat_mode
,
208 &global_settings
.playlist_shuffle
,
212 bookmark_play(global_temp_buffer
, index
, offset
, seed
);
218 /* ----------------------------------------------------------------------- */
219 /* This function handles an autobookmark creation. This is an interface */
221 /* ----------------------------------------------------------------------- */
222 bool bookmark_autobookmark(void)
224 /* prompts the user as to create a bookmark */
231 mpeg_pause(); /* first pause playback */
232 switch (global_settings
.autocreatebookmark
)
235 return write_bookmark(true);
240 case BOOKMARK_RECENT_ONLY_YES
:
241 return write_bookmark(false);
244 /* Prompting user to confirm bookmark creation */
246 #ifdef HAVE_LCD_BITMAP
247 lcd_puts(0,0, str(LANG_AUTO_BOOKMARK_QUERY
));
248 lcd_puts(0,1, str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
249 lcd_puts(0,2, str(LANG_CANCEL_WITH_ANY_RECORDER
));
252 lcd_puts(0,0, str(LANG_AUTO_BOOKMARK_QUERY
));
253 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
259 /* Wait for a key to be pushed */
260 key
= button_get(true);
263 case BUTTON_DOWN
| BUTTON_REL
:
264 case BUTTON_ON
| BUTTON_REL
:
265 #ifdef HAVE_RECORDER_KEYPAD
266 case BUTTON_OFF
| BUTTON_REL
:
267 case BUTTON_RIGHT
| BUTTON_REL
:
268 case BUTTON_UP
| BUTTON_REL
:
270 case BUTTON_LEFT
| BUTTON_REL
:
274 case BUTTON_PLAY
| BUTTON_REL
:
275 if (global_settings
.autocreatebookmark
==
276 BOOKMARK_RECENT_ONLY_ASK
)
277 write_bookmark(false);
279 write_bookmark(true);
283 case SYS_USB_CONNECTED
:
285 #ifdef HAVE_LCD_CHARCELLS
286 status_set_param(true);
294 /* ----------------------------------------------------------------------- */
295 /* This function takes the current current resume information and writes */
296 /* that to the beginning of the bookmark file. */
297 /* This file will contain N number of bookmarks in the following format: */
298 /* resume_index*resume_offset*resume_seed*resume_first_index* */
299 /* resume_file*milliseconds*MP3 Title* */
300 /* ------------------------------------------------------------------------*/
301 static bool write_bookmark(bool create_bookmark_file
)
307 return false; /* something didn't happen correctly, do nothing */
309 bookmark
= create_bookmark();
311 return false; /* something didn't happen correctly, do nothing */
313 if (global_settings
.usemrb
)
314 success
= add_bookmark(RECENT_BOOKMARK_FILE
, bookmark
);
317 /* writing the bookmark */
318 if (create_bookmark_file
)
320 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
321 sizeof(global_temp_buffer
));
322 if (generate_bookmark_file_name(name
,
323 global_bookmark_file_name
,
324 sizeof(global_bookmark_file_name
)))
326 success
= add_bookmark(global_bookmark_file_name
, bookmark
);
331 splash(HZ
, true, str(LANG_BOOKMARK_CREATE_SUCCESS
));
333 splash(HZ
, true, str(LANG_BOOKMARK_CREATE_FAILURE
));
338 /* ----------------------------------------------------------------------- */
339 /* This function adds a bookmark to a file. */
340 /* ------------------------------------------------------------------------*/
341 static bool add_bookmark(char* bookmark_file_name
, char* bookmark
)
343 int temp_bookmark_file
= 0;
344 int bookmark_file
= 0;
345 int bookmark_count
= 0;
346 char* playlist
= NULL
;
352 /* Opening up a temp bookmark file */
353 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
354 "%s.tmp", bookmark_file_name
);
355 temp_bookmark_file
= open(global_temp_buffer
,
356 O_WRONLY
| O_CREAT
| O_TRUNC
);
357 if (temp_bookmark_file
< 0)
358 return false; /* can't open the temp file */
360 if (!strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
) &&
361 (global_settings
.usemrb
== BOOKMARK_UNIQUE_ONLY
))
363 playlist
= strchr(bookmark
,'/');
364 cp
= strrchr(bookmark
,';');
369 /* Writing the new bookmark to the begining of the temp file */
370 write(temp_bookmark_file
, bookmark
, strlen(bookmark
));
371 write(temp_bookmark_file
, "\n", 1);
374 /* Reading in the previous bookmarks and writing them to the temp file */
375 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
376 if (bookmark_file
>= 0)
378 while (read_line(bookmark_file
, global_read_buffer
,
379 sizeof(global_read_buffer
)))
381 /* The MRB has a max of MAX_BOOKMARKS in it */
382 /* This keeps it from getting too large */
383 if ((strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
)==0))
385 if(bookmark_count
>= MAX_BOOKMARKS
)
389 cp
= strchr(global_read_buffer
,'/');
390 tmp
= strrchr(global_read_buffer
,';');
391 if (check_bookmark(global_read_buffer
) &&
392 (!unique
|| len
!= tmp
-cp
|| strncmp(playlist
,cp
,len
)))
395 write(temp_bookmark_file
, global_read_buffer
,
396 strlen(global_read_buffer
));
397 write(temp_bookmark_file
, "\n", 1);
400 close(bookmark_file
);
402 close(temp_bookmark_file
);
404 remove(bookmark_file_name
);
405 rename(global_temp_buffer
, bookmark_file_name
);
411 /* ----------------------------------------------------------------------- */
412 /* This function takes the system resume data and formats it into a valid */
414 /* ----------------------------------------------------------------------- */
415 static char* create_bookmark()
417 int resume_index
= 0;
420 /* grab the currently playing track */
421 struct mp3entry
*id3
= mpeg_current_track();
425 /* Get some basic resume information */
426 /* queue_resume and queue_resume_index are not used and can be ignored.*/
427 playlist_get_resume_info(&resume_index
);
429 /* Get the currently playing file minus the path */
430 /* This is used when displaying the available bookmarks */
431 file
= strrchr(id3
->path
,'/');
435 /* create the bookmark */
436 snprintf(global_bookmark
, sizeof(global_bookmark
),
437 "%d;%d;%d;%d;%d;%d;%d;%s;%s",
440 playlist_get_seed(NULL
),
443 global_settings
.repeat_mode
,
444 global_settings
.playlist_shuffle
,
445 playlist_get_name(NULL
, global_temp_buffer
,
446 sizeof(global_temp_buffer
)),
449 /* checking to see if the bookmark is valid */
450 if (check_bookmark(global_bookmark
))
451 return global_bookmark
;
456 static bool check_bookmark(char* bookmark
)
458 return parse_bookmark(bookmark
,
459 NULL
,NULL
,NULL
, NULL
,
464 /* ----------------------------------------------------------------------- */
465 /* This function will determine if an autoload is necessary. This is an */
466 /* interface function. */
467 /* ------------------------------------------------------------------------*/
468 bool bookmark_autoload(char* file
)
474 if(global_settings
.autoloadbookmark
== BOOKMARK_NO
)
477 /*Checking to see if a bookmark file exists.*/
478 if(!generate_bookmark_file_name(file
,
479 global_bookmark_file_name
,
480 sizeof(global_bookmark_file_name
)))
485 fd
= open(global_bookmark_file_name
, O_RDONLY
);
488 if(-1 == lseek(fd
, 0, SEEK_END
))
495 if(global_settings
.autoloadbookmark
== BOOKMARK_YES
)
497 return bookmark_load(global_bookmark_file_name
, true);
501 while (button_get(false)); /* clear button queue */
502 /* Prompting user to confirm bookmark load */
504 #ifdef HAVE_LCD_BITMAP
505 lcd_puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
506 lcd_puts(0,1, str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
507 lcd_puts(0,2, str(LANG_BOOKMARK_SELECT_LIST_BOOKMARKS
));
508 lcd_puts(0,3, str(LANG_CANCEL_WITH_ANY_RECORDER
));
511 lcd_puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
512 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
520 /* Wait for a key to be pushed */
521 while (button_get(false)); /* clear button queue */
522 key
= button_get(true);
527 #ifdef HAVE_LCD_BITMAP
529 return bookmark_load(global_bookmark_file_name
, false);
532 return bookmark_load(global_bookmark_file_name
, true);
533 case SYS_USB_CONNECTED
:
534 status_set_playmode(STATUS_STOP
);
536 #ifdef HAVE_LCD_CHARCELLS
537 status_set_param(true);
546 /* ----------------------------------------------------------------------- */
547 /* This function loads the bookmark information into the resume memory. */
548 /* This is an interface function. */
549 /* ------------------------------------------------------------------------*/
550 bool bookmark_load(char* file
, bool autoload
)
557 char* bookmark
= NULL
;;
561 fd
= open(file
, O_RDONLY
);
564 if(read_line(fd
, global_read_buffer
, sizeof(global_read_buffer
)))
565 bookmark
=global_read_buffer
;
571 /* This is not an auto-load, so list the bookmarks */
572 bookmark
=select_bookmark(file
);
574 return true; /* User exited without selecting a bookmark */
579 success
= parse_bookmark(bookmark
,
585 sizeof(global_temp_buffer
),
587 &global_settings
.repeat_mode
,
588 &global_settings
.playlist_shuffle
,
594 bookmark_play(global_temp_buffer
,index
,offset
,seed
);
600 static int get_bookmark_count(char* bookmark_file_name
)
603 int file
= open(bookmark_file_name
, O_RDONLY
);
608 /* Get the requested bookmark */
609 while(read_line(file
, global_read_buffer
, sizeof(global_read_buffer
)))
611 if(check_bookmark(global_read_buffer
))
622 /* ----------------------------------------------------------------------- */
623 /* This displays a the bookmarks in a file and allows the user to */
624 /* select one to play. */
625 /* ------------------------------------------------------------------------*/
626 static char* select_bookmark(char* bookmark_file_name
)
629 int bookmark_id_prev
= -1;
631 char* bookmark
= NULL
;
632 int bookmark_count
= 0;
634 #ifdef HAVE_LCD_BITMAP
635 lcd_setmargins(0, 0);
638 while (button_get(false)); /* clear button queue */
639 bookmark_count
= get_bookmark_count(bookmark_file_name
);
644 bookmark_id
= bookmark_count
-1;
645 if(bookmark_id
== bookmark_count
)
648 if (bookmark_id
!= bookmark_id_prev
)
650 bookmark
= get_bookmark(bookmark_file_name
, bookmark_id
);
651 bookmark_id_prev
= bookmark_id
;
656 /* if there were no bookmarks in the file, delete the file and exit. */
659 splash(HZ
, true, str(LANG_BOOKMARK_LOAD_EMPTY
));
660 remove(bookmark_file_name
);
661 while (button_get(false)); /* clear button queue */
666 bookmark_id_prev
= bookmark_id
;
672 display_bookmark(bookmark
, bookmark_id
, bookmark_count
);
673 if (global_settings
.talk_menu
) /* for voice UI */
674 say_bookmark(bookmark
, bookmark_id
);
677 /* waiting for the user to click a button */
678 key
= button_get(true);
682 /* User wants to use this bookmark */
683 #ifdef HAVE_LCD_BITMAP
684 if (global_settings
.statusbar
)
685 lcd_setmargins(0, STATUSBAR_HEIGHT
);
687 lcd_setmargins(0, 0);
691 case BUTTON_ON
| BUTTON_PLAY
:
692 /* User wants to delete this bookmark */
693 delete_bookmark(bookmark_file_name
, bookmark_id
);
697 while (button_get(false)); /* clear button queue */
700 case SYS_USB_CONNECTED
:
702 #ifdef HAVE_LCD_CHARCELLS
703 status_set_param(true);
706 #ifdef HAVE_RECORDER_KEYPAD
717 #ifdef HAVE_LCD_BITMAP
718 if (global_settings
.statusbar
)
719 lcd_setmargins(0, STATUSBAR_HEIGHT
);
721 lcd_setmargins(0, 0);
743 /* ----------------------------------------------------------------------- */
744 /* This function takes a location in a bookmark file and deletes that */
746 /* ------------------------------------------------------------------------*/
747 static bool delete_bookmark(char* bookmark_file_name
, int bookmark_id
)
749 int temp_bookmark_file
= 0;
750 int bookmark_file
= 0;
751 int bookmark_count
= 0;
753 /* Opening up a temp bookmark file */
754 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
755 "%s.tmp", bookmark_file_name
);
756 temp_bookmark_file
= open(global_temp_buffer
,
757 O_WRONLY
| O_CREAT
| O_TRUNC
);
758 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
760 if (temp_bookmark_file
< 0 || bookmark_file
< 0)
761 return false; /* can't open one of the files */
763 /* Reading in the previous bookmarks and writing them to the temp file */
764 while (read_line(bookmark_file
, global_read_buffer
,
765 sizeof(global_read_buffer
)))
767 /* The MRB has a max of MAX_BOOKMARKS in it */
768 /* This keeps it from getting too large */
769 if ((strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
)==0))
771 if(bookmark_count
>= MAX_BOOKMARKS
)
775 if (check_bookmark(global_read_buffer
))
777 if (bookmark_id
!= bookmark_count
)
779 write(temp_bookmark_file
, global_read_buffer
,
780 strlen(global_read_buffer
));
781 write(temp_bookmark_file
, "\n", 1);
787 close(bookmark_file
);
788 close(temp_bookmark_file
);
790 remove(bookmark_file_name
);
791 rename(global_temp_buffer
, bookmark_file_name
);
796 /* ----------------------------------------------------------------------- */
797 /* This function parses a bookmark and displays it for the user. */
798 /* ------------------------------------------------------------------------*/
799 static void display_bookmark(char* bookmark
,
803 int resume_index
= 0;
806 bool playlist_shuffle
= false;
807 char MP3_file_name
[45];
811 /* getting the index and the time into the file */
812 parse_bookmark(bookmark
,
813 &resume_index
, NULL
, NULL
, NULL
, NULL
, 0,
814 &ms
, &repeat_mode
, &playlist_shuffle
,
815 MP3_file_name
, sizeof(MP3_file_name
));
820 #ifdef HAVE_LCD_BITMAP
821 /* bookmark shuffle and repeat states*/
825 statusbar_icon_play_mode(Icon_RepeatOne
);
829 statusbar_icon_play_mode(Icon_Repeat
);
833 statusbar_icon_shuffle();
836 len
=strlen(MP3_file_name
);
838 dot
=strrchr(MP3_file_name
+ len
- 4, '.');
843 lcd_puts_scroll(0, 0, MP3_file_name
);
847 /* bookmark number */
848 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %2d/%2d",
849 str(LANG_BOOKMARK_SELECT_BOOKMARK_TEXT
),
850 bookmark_id
+ 1, bookmark_count
);
851 lcd_puts_scroll(0, 1, global_temp_buffer
);
853 /* bookmark resume index */
854 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %2d",
855 str(LANG_BOOKMARK_SELECT_INDEX_TEXT
), resume_index
+1);
856 lcd_puts_scroll(0, 2, global_temp_buffer
);
859 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %d:%02d",
860 str(LANG_BOOKMARK_SELECT_TIME_TEXT
),
863 lcd_puts_scroll(0, 3, global_temp_buffer
);
866 lcd_puts_scroll(0, 4, str(LANG_BOOKMARK_SELECT_PLAY
));
867 lcd_puts_scroll(0, 5, str(LANG_BOOKMARK_SELECT_EXIT
));
868 lcd_puts_scroll(0, 6, str(LANG_BOOKMARK_SELECT_DELETE
));
871 len
=strlen(MP3_file_name
);
873 dot
=strrchr(MP3_file_name
+len
-4,'.');
878 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
885 lcd_puts_scroll(0,0,global_temp_buffer
);
886 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
894 /* ----------------------------------------------------------------------- */
895 /* This function parses a bookmark, says the voice UI part of it. */
896 /* ------------------------------------------------------------------------*/
897 static void say_bookmark(char* bookmark
,
903 bool enqueue
= false; /* only the first voice is not queued */
905 parse_bookmark(bookmark
,
911 /* disabled, because transition between talkbox and voice UI clip is not nice */
913 if (global_settings
.talk_dir
>= 3)
914 { /* "talkbox" enabled */
915 char* last
= strrchr(dir
, '/');
917 { /* compose filename for talkbox */
918 strncpy(last
+ 1, dir_thumbnail_name
, sizeof(dir
)-(last
-dir
)-1);
919 talk_file(dir
, enqueue
);
924 talk_id(VOICE_EXT_BMARK
, enqueue
);
925 talk_number(bookmark_id
+ 1, true);
926 talk_id(LANG_BOOKMARK_SELECT_INDEX_TEXT
, true);
927 talk_number(resume_index
+ 1, true);
928 talk_id(LANG_BOOKMARK_SELECT_TIME_TEXT
, true);
930 talk_value(ms
/ 60000, UNIT_MIN
, true);
931 talk_value((ms
% 60000) / 1000, UNIT_SEC
, true);
935 /* ----------------------------------------------------------------------- */
936 /* This function retrieves a given bookmark from a file. */
937 /* If the bookmark requested is beyond the number of bookmarks available */
938 /* in the file, it will return the last one. */
939 /* It also returns the index number of the bookmark in the file */
940 /* ------------------------------------------------------------------------*/
941 static char* get_bookmark(char* bookmark_file
, int bookmark_count
)
945 int file
= open(bookmark_file
, O_RDONLY
);
950 /* Get the requested bookmark */
951 while (read_count
< bookmark_count
)
953 /*Reading in a single bookmark */
954 result
= read_line(file
,
956 sizeof(global_read_buffer
));
958 /* Reading past the last bookmark in the file
959 causes the loop to stop */
967 if (read_count
== bookmark_count
)
968 return global_read_buffer
;
973 /* ----------------------------------------------------------------------- */
974 /* This function takes a bookmark and parses it. This function also */
975 /* validates the bookmark. Passing in NULL for an output variable */
976 /* indicates that value is not requested. */
977 /* ----------------------------------------------------------------------- */
978 static bool parse_bookmark(char *bookmark
,
982 int *resume_first_index
,
984 unsigned int resume_file_size
,
986 int * repeat_mode
, bool *shuffle
,
988 unsigned int max_file_name_size
)
990 /* First check to see if a valid line was passed in. */
991 int bookmark_len
= strlen(bookmark
);
992 int local_resume_index
= 0;
993 int local_resume_offset
= 0;
994 int local_resume_seed
= 0;
995 int local_resume_first_index
= 0;
997 int local_shuffle
= 0;
998 int local_repeat_mode
= 0;
999 char* local_resume_file
= NULL
;
1000 char* local_file_name
= NULL
;
1003 static char bookmarkcopy
[MAX_BOOKMARK_SIZE
];
1005 /* Don't do anything if the bookmark length is 0 */
1006 if (bookmark_len
<= 0)
1009 /* Making a dup of the bookmark to use with strtok_r */
1010 strncpy(bookmarkcopy
, bookmark
, sizeof(bookmarkcopy
));
1011 bookmarkcopy
[sizeof(bookmarkcopy
) - 1] = 0;
1014 if ((field
= strtok_r(bookmarkcopy
, ";", &end
)))
1015 local_resume_index
= atoi(field
);
1020 if ((field
= strtok_r(NULL
, ";", &end
)))
1021 local_resume_offset
= atoi(field
);
1026 if ((field
= strtok_r(NULL
, ";", &end
)))
1027 local_resume_seed
= atoi(field
);
1031 /* resume_first_index */
1032 if ((field
= strtok_r(NULL
, ";", &end
)))
1033 local_resume_first_index
= atoi(field
);
1037 /* Milliseconds into MP3. Used for the bookmark select menu */
1038 if ((field
= strtok_r(NULL
, ";", &end
)))
1039 local_mS
= atoi(field
);
1044 if ((field
= strtok_r(NULL
, ";", &end
)))
1045 local_repeat_mode
= atoi(field
);
1050 if ((field
= strtok_r(NULL
, ";", &end
)))
1051 local_shuffle
= atoi(field
);
1055 /* resume_file & file_name (for the bookmark select menu)*/
1058 local_resume_file
= strtok_r(NULL
, ";", &end
);
1061 local_file_name
= strtok_r(NULL
, ";", &end
);
1066 /* Only return the values the calling function wants */
1068 *resume_index
= local_resume_index
;
1071 *resume_offset
= local_resume_offset
;
1074 *resume_seed
= local_resume_seed
;
1076 if (resume_first_index
)
1077 *resume_first_index
= local_resume_first_index
;
1079 if (resume_file
&& local_resume_file
)
1081 strncpy(resume_file
, local_resume_file
,
1082 MIN(strlen(local_resume_file
), resume_file_size
-1));
1083 resume_file
[MIN(strlen(local_resume_file
), resume_file_size
-1)]=0;
1090 *shuffle
= local_shuffle
;
1093 *repeat_mode
= local_repeat_mode
;
1095 if (file_name
&& local_file_name
)
1097 strncpy(file_name
, local_file_name
,
1098 MIN(strlen(local_file_name
),max_file_name_size
-1));
1099 file_name
[MIN(strlen(local_file_name
),max_file_name_size
-1)]=0;
1105 /* ----------------------------------------------------------------------- */
1106 /* This function is used by multiple functions and is used to generate a */
1107 /* bookmark named based off of the input. */
1108 /* Changing this function could result in how the bookmarks are stored. */
1109 /* it would be here that the centralized/decentralized bookmark code */
1110 /* could be placed. */
1111 /* ----------------------------------------------------------------------- */
1112 static bool generate_bookmark_file_name(char *in
, char *out
,
1113 unsigned int max_length
)
1117 if (!in
|| !out
|| max_length
<= 0)
1120 if (max_length
< strlen(in
)+6)
1123 /* if this is a root dir MP3, rename the boomark file root_dir.bmark */
1124 /* otherwise, name it based on the in variable */
1127 cp
= in
+ strlen(in
) - 1;
1136 snprintf(out
, max_length
, "/%s.%s", cp
, "bmark");
1138 snprintf(out
, max_length
, "/root_dir.%s", "bmark");
1143 /* ----------------------------------------------------------------------- */
1144 /* Checks the current state of the system and returns if it is in a */
1145 /* bookmarkable state. */
1146 /* ----------------------------------------------------------------------- */
1148 /* ----------------------------------------------------------------------- */
1150 /* return bool: Indicates if the system was in a bookmarkable state */
1151 /* ----------------------------------------------------------------------- */
1152 static bool system_check(void)
1154 int resume_index
= 0;
1155 struct mp3entry
*id3
= mpeg_current_track();
1159 /* no track playing */
1163 /* Checking to see if playing a queued track */
1164 if (playlist_get_resume_info(&resume_index
) == -1)
1166 /* something bad happened while getting the queue information */
1169 else if (playlist_modified(NULL
))
1171 /* can't bookmark while in the queue */