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"
54 #define MAX_BOOKMARKS 10
55 #define MAX_BOOKMARK_SIZE 350
56 #define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark"
58 static bool add_bookmark(const char* bookmark_file_name
, const char* bookmark
);
59 static bool check_bookmark(const char* bookmark
);
60 static char* create_bookmark(void);
61 static bool delete_bookmark(const char* bookmark_file_name
, int bookmark_id
);
62 static void display_bookmark(const char* bookmark
,
65 static void say_bookmark(const char* bookmark
,
67 static bool generate_bookmark_file_name(const char *in
);
68 static char* get_bookmark(const char* bookmark_file
, int bookmark_count
);
69 static bool parse_bookmark(const char *bookmark
,
73 int *resume_first_index
,
75 unsigned int resume_file_size
,
80 static char* select_bookmark(const char* bookmark_file_name
);
81 static bool system_check(void);
82 static bool write_bookmark(bool create_bookmark_file
);
83 static int get_bookmark_count(const char* bookmark_file_name
);
85 static char global_temp_buffer
[MAX_PATH
+1];
86 static char global_bookmark_file_name
[MAX_PATH
];
87 static char global_read_buffer
[MAX_BOOKMARK_SIZE
];
88 static char global_bookmark
[MAX_BOOKMARK_SIZE
];
89 static char global_filename
[MAX_PATH
];
91 /* ----------------------------------------------------------------------- */
92 /* This is the interface function from the main menu. */
93 /* ----------------------------------------------------------------------- */
94 bool bookmark_create_menu(void)
100 /* ----------------------------------------------------------------------- */
101 /* This function acts as the load interface from the main menu */
102 /* This function determines the bookmark file name and then loads that file*/
103 /* for the user. The user can then select a bookmark to load. */
104 /* If no file/directory is currently playing, the menu item does not work. */
105 /* ----------------------------------------------------------------------- */
106 bool bookmark_load_menu(void)
118 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
119 sizeof(global_temp_buffer
));
120 if (generate_bookmark_file_name(name
))
122 bookmark
= select_bookmark(global_bookmark_file_name
);
124 return false; /* User exited without selecting a bookmark */
126 success
= parse_bookmark(bookmark
,
132 sizeof(global_temp_buffer
),
134 &global_settings
.repeat_mode
,
135 &global_settings
.playlist_shuffle
,
140 /* something bad happened while creating bookmark name*/
145 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
152 /* ----------------------------------------------------------------------- */
153 /* Gives the user a list of the Most Recent Bookmarks. This is an */
154 /* interface function */
155 /* ----------------------------------------------------------------------- */
156 bool bookmark_mrb_load()
164 bookmark
= select_bookmark(RECENT_BOOKMARK_FILE
);
166 return false; /* User exited without selecting a bookmark */
168 success
= parse_bookmark(bookmark
,
174 sizeof(global_temp_buffer
),
176 &global_settings
.repeat_mode
,
177 &global_settings
.playlist_shuffle
,
181 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
188 /* ----------------------------------------------------------------------- */
189 /* This function handles an autobookmark creation. This is an interface */
191 /* ----------------------------------------------------------------------- */
192 bool bookmark_autobookmark(void)
197 audio_pause(); /* first pause playback */
198 switch (global_settings
.autocreatebookmark
)
201 return write_bookmark(true);
206 case BOOKMARK_RECENT_ONLY_YES
:
207 return write_bookmark(false);
209 #ifdef HAVE_LCD_BITMAP
210 unsigned char *lines
[]={str(LANG_AUTO_BOOKMARK_QUERY
)};
211 struct text_message message
={(char **)lines
, 1};
213 unsigned char *lines
[]={str(LANG_AUTO_BOOKMARK_QUERY
),
214 str(LANG_RESUME_CONFIRM_PLAYER
)};
215 struct text_message message
={(char **)lines
, 2};
217 #ifdef HAVE_LCD_COLOR
218 show_main_backdrop(); /* switch to main backdrop as we may come from wps */
220 gui_syncstatusbar_draw(&statusbars
, false);
221 if(gui_syncyesno_run(&message
, NULL
, NULL
)==YESNO_YES
)
223 if (global_settings
.autocreatebookmark
== BOOKMARK_RECENT_ONLY_ASK
)
224 return write_bookmark(false);
226 return write_bookmark(true);
231 /* ----------------------------------------------------------------------- */
232 /* This function takes the current current resume information and writes */
233 /* that to the beginning of the bookmark file. */
234 /* This file will contain N number of bookmarks in the following format: */
235 /* resume_index*resume_offset*resume_seed*resume_first_index* */
236 /* resume_file*milliseconds*MP3 Title* */
237 /* ------------------------------------------------------------------------*/
238 static bool write_bookmark(bool create_bookmark_file
)
244 return false; /* something didn't happen correctly, do nothing */
246 bookmark
= create_bookmark();
248 return false; /* something didn't happen correctly, do nothing */
250 if (global_settings
.usemrb
)
251 success
= add_bookmark(RECENT_BOOKMARK_FILE
, bookmark
);
254 /* writing the bookmark */
255 if (create_bookmark_file
)
257 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
258 sizeof(global_temp_buffer
));
259 if (generate_bookmark_file_name(name
))
261 success
= add_bookmark(global_bookmark_file_name
, bookmark
);
266 gui_syncsplash(HZ
, true, str(LANG_BOOKMARK_CREATE_SUCCESS
));
268 gui_syncsplash(HZ
, true, str(LANG_BOOKMARK_CREATE_FAILURE
));
273 /* ----------------------------------------------------------------------- */
274 /* This function adds a bookmark to a file. */
275 /* ------------------------------------------------------------------------*/
276 static bool add_bookmark(const char* bookmark_file_name
, const char* bookmark
)
278 int temp_bookmark_file
= 0;
279 int bookmark_file
= 0;
280 int bookmark_count
= 0;
281 char* playlist
= NULL
;
287 /* Opening up a temp bookmark file */
288 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
289 "%s.tmp", bookmark_file_name
);
290 temp_bookmark_file
= open(global_temp_buffer
,
291 O_WRONLY
| O_CREAT
| O_TRUNC
);
292 if (temp_bookmark_file
< 0)
293 return false; /* can't open the temp file */
295 if (!strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
) &&
296 (global_settings
.usemrb
== BOOKMARK_UNIQUE_ONLY
))
298 playlist
= strchr(bookmark
,'/');
299 cp
= strrchr(bookmark
,';');
304 /* Writing the new bookmark to the begining of the temp file */
305 write(temp_bookmark_file
, bookmark
, strlen(bookmark
));
306 write(temp_bookmark_file
, "\n", 1);
309 /* Reading in the previous bookmarks and writing them to the temp file */
310 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
311 if (bookmark_file
>= 0)
313 while (read_line(bookmark_file
, global_read_buffer
,
314 sizeof(global_read_buffer
)))
316 /* The MRB has a max of MAX_BOOKMARKS in it */
317 /* This keeps it from getting too large */
318 if ((strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
)==0))
320 if(bookmark_count
>= MAX_BOOKMARKS
)
324 cp
= strchr(global_read_buffer
,'/');
325 tmp
= strrchr(global_read_buffer
,';');
326 if (check_bookmark(global_read_buffer
) &&
327 (!unique
|| len
!= tmp
-cp
|| strncmp(playlist
,cp
,len
)))
330 write(temp_bookmark_file
, global_read_buffer
,
331 strlen(global_read_buffer
));
332 write(temp_bookmark_file
, "\n", 1);
335 close(bookmark_file
);
337 close(temp_bookmark_file
);
339 remove(bookmark_file_name
);
340 rename(global_temp_buffer
, bookmark_file_name
);
346 /* ----------------------------------------------------------------------- */
347 /* This function takes the system resume data and formats it into a valid */
349 /* ----------------------------------------------------------------------- */
350 static char* create_bookmark()
352 int resume_index
= 0;
355 /* grab the currently playing track */
356 struct mp3entry
*id3
= audio_current_track();
360 /* Get some basic resume information */
361 /* queue_resume and queue_resume_index are not used and can be ignored.*/
362 playlist_get_resume_info(&resume_index
);
364 /* Get the currently playing file minus the path */
365 /* This is used when displaying the available bookmarks */
366 file
= strrchr(id3
->path
,'/');
370 /* create the bookmark */
371 snprintf(global_bookmark
, sizeof(global_bookmark
),
372 "%d;%ld;%d;%d;%ld;%d;%d;%s;%s",
375 playlist_get_seed(NULL
),
378 global_settings
.repeat_mode
,
379 global_settings
.playlist_shuffle
,
380 playlist_get_name(NULL
, global_temp_buffer
,
381 sizeof(global_temp_buffer
)),
384 /* checking to see if the bookmark is valid */
385 if (check_bookmark(global_bookmark
))
386 return global_bookmark
;
391 static bool check_bookmark(const char* bookmark
)
393 return parse_bookmark(bookmark
,
394 NULL
,NULL
,NULL
, NULL
,
399 /* ----------------------------------------------------------------------- */
400 /* This function will determine if an autoload is necessary. This is an */
401 /* interface function. */
402 /* ------------------------------------------------------------------------*/
403 bool bookmark_autoload(const char* file
)
409 if(global_settings
.autoloadbookmark
== BOOKMARK_NO
)
412 /*Checking to see if a bookmark file exists.*/
413 if(!generate_bookmark_file_name(file
))
417 fd
= open(global_bookmark_file_name
, O_RDONLY
);
420 if(-1 == lseek(fd
, 0, SEEK_END
))
426 if(global_settings
.autoloadbookmark
== BOOKMARK_YES
)
428 return bookmark_load(global_bookmark_file_name
, true);
432 /* Prompting user to confirm bookmark load */
434 gui_syncstatusbar_draw(&statusbars
, false);
435 #ifdef HAVE_LCD_BITMAP
436 lcd_setmargins(0, STATUSBAR_HEIGHT
);
437 lcd_puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
438 lcd_puts(0,1, str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
439 lcd_puts(0,2, str(LANG_BOOKMARK_SELECT_LIST_BOOKMARKS
));
440 lcd_puts(0,3, str(LANG_CANCEL_WITH_ANY_RECORDER
));
442 lcd_puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
443 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
449 /* Wait for a key to be pushed */
450 key
= button_get(true);
453 #ifdef HAVE_LCD_BITMAP
455 return bookmark_load(global_bookmark_file_name
, false);
458 return bookmark_load(global_bookmark_file_name
, true);
461 /* Handle sys events, ignore button releases & repeats */
462 if (default_event_handler(key
) ||
463 !(key
& (BUTTON_REPEAT
|BUTTON_REL
)))
472 /* ----------------------------------------------------------------------- */
473 /* This function loads the bookmark information into the resume memory. */
474 /* This is an interface function. */
475 /* ------------------------------------------------------------------------*/
476 bool bookmark_load(const char* file
, bool autoload
)
483 char* bookmark
= NULL
;;
487 fd
= open(file
, O_RDONLY
);
490 if(read_line(fd
, global_read_buffer
, sizeof(global_read_buffer
)))
491 bookmark
=global_read_buffer
;
497 /* This is not an auto-load, so list the bookmarks */
498 bookmark
=select_bookmark(file
);
500 return true; /* User exited without selecting a bookmark */
505 success
= parse_bookmark(bookmark
,
511 sizeof(global_temp_buffer
),
513 &global_settings
.repeat_mode
,
514 &global_settings
.playlist_shuffle
,
520 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
527 static int get_bookmark_count(const char* bookmark_file_name
)
530 int file
= open(bookmark_file_name
, O_RDONLY
);
535 /* Get the requested bookmark */
536 while(read_line(file
, global_read_buffer
, sizeof(global_read_buffer
)))
538 if(check_bookmark(global_read_buffer
))
548 /* ----------------------------------------------------------------------- */
549 /* This displays a the bookmarks in a file and allows the user to */
550 /* select one to play. */
551 /* ------------------------------------------------------------------------*/
552 static char* select_bookmark(const char* bookmark_file_name
)
555 int bookmark_id_prev
= -1;
557 int lastkey
= BUTTON_NONE
;
558 char* bookmark
= NULL
;
559 int bookmark_count
= 0;
561 #ifdef HAVE_LCD_BITMAP
562 int x
= lcd_getxmargin();
563 int y
= lcd_getymargin();
564 lcd_setmargins(0, 0);
567 bookmark_count
= get_bookmark_count(bookmark_file_name
);
572 bookmark_id
= bookmark_count
-1;
573 if(bookmark_id
>= bookmark_count
)
576 if (bookmark_id
!= bookmark_id_prev
)
578 bookmark
= get_bookmark(bookmark_file_name
, bookmark_id
);
579 bookmark_id_prev
= bookmark_id
;
584 /* if there were no bookmarks in the file, delete the file and exit. */
587 gui_syncsplash(HZ
, true, str(LANG_BOOKMARK_LOAD_EMPTY
));
588 remove(bookmark_file_name
);
593 bookmark_id_prev
= bookmark_id
;
599 display_bookmark(bookmark
, bookmark_id
, bookmark_count
);
600 if (global_settings
.talk_menu
) /* for voice UI */
601 say_bookmark(bookmark
, bookmark_id
);
604 /* waiting for the user to click a button */
605 key
= button_get(true);
608 case BOOKMARK_SELECT
:
609 #ifdef BOOKMARK_SELECT_PRE
610 if (lastkey
!= BOOKMARK_SELECT_PRE
)
613 /* User wants to use this bookmark */
614 #ifdef HAVE_LCD_BITMAP
615 if (global_settings
.statusbar
)
616 lcd_setmargins(0, STATUSBAR_HEIGHT
);
618 lcd_setmargins(0, 0);
622 case BOOKMARK_DELETE
:
623 /* User wants to delete this bookmark */
624 delete_bookmark(bookmark_file_name
, bookmark_id
);
627 if(bookmark_id
>= bookmark_count
)
628 bookmark_id
= bookmark_count
-1;
632 case SETTINGS_DEC
| BUTTON_REPEAT
:
637 case SETTINGS_INC
| BUTTON_REPEAT
:
641 case SETTINGS_CANCEL
:
642 #ifdef SETTINGS_CANCEL2
643 case SETTINGS_CANCEL2
:
648 #ifdef HAVE_LCD_BITMAP
649 lcd_setmargins(x
, y
);
654 if(default_event_handler(key
) == SYS_USB_CONNECTED
)
665 /* ----------------------------------------------------------------------- */
666 /* This function takes a location in a bookmark file and deletes that */
668 /* ------------------------------------------------------------------------*/
669 static bool delete_bookmark(const char* bookmark_file_name
, int bookmark_id
)
671 int temp_bookmark_file
= 0;
672 int bookmark_file
= 0;
673 int bookmark_count
= 0;
675 /* Opening up a temp bookmark file */
676 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
677 "%s.tmp", bookmark_file_name
);
678 temp_bookmark_file
= open(global_temp_buffer
,
679 O_WRONLY
| O_CREAT
| O_TRUNC
);
680 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
682 if (temp_bookmark_file
< 0 || bookmark_file
< 0)
683 return false; /* can't open one of the files */
685 /* Reading in the previous bookmarks and writing them to the temp file */
686 while (read_line(bookmark_file
, global_read_buffer
,
687 sizeof(global_read_buffer
)))
689 /* The MRB has a max of MAX_BOOKMARKS in it */
690 /* This keeps it from getting too large */
691 if ((strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
)==0))
693 if(bookmark_count
>= MAX_BOOKMARKS
)
697 if (check_bookmark(global_read_buffer
))
699 if (bookmark_id
!= bookmark_count
)
701 write(temp_bookmark_file
, global_read_buffer
,
702 strlen(global_read_buffer
));
703 write(temp_bookmark_file
, "\n", 1);
709 close(bookmark_file
);
710 close(temp_bookmark_file
);
712 remove(bookmark_file_name
);
713 rename(global_temp_buffer
, bookmark_file_name
);
718 /* ----------------------------------------------------------------------- */
719 /* This function parses a bookmark and displays it for the user. */
720 /* ------------------------------------------------------------------------*/
721 static void display_bookmark(const char* bookmark
,
725 int resume_index
= 0;
728 bool playlist_shuffle
= false;
732 /* getting the index and the time into the file */
733 parse_bookmark(bookmark
,
734 &resume_index
, NULL
, NULL
, NULL
, NULL
, 0,
735 &ms
, &repeat_mode
, &playlist_shuffle
,
741 #ifdef HAVE_LCD_BITMAP
742 /* bookmark shuffle and repeat states*/
745 #if (AB_REPEAT_ENABLE == 1)
747 statusbar_icon_play_mode(Icon_RepeatAB
);
752 statusbar_icon_play_mode(Icon_RepeatOne
);
756 statusbar_icon_play_mode(Icon_Repeat
);
760 statusbar_icon_shuffle();
763 len
=strlen(global_filename
);
765 dot
=strrchr(global_filename
+ len
- 4, '.');
770 lcd_puts_scroll(0, 0, (unsigned char *)global_filename
);
774 /* bookmark number */
775 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %2d/%2d",
776 str(LANG_BOOKMARK_SELECT_BOOKMARK_TEXT
),
777 bookmark_id
+ 1, bookmark_count
);
778 lcd_puts_scroll(0, 1, (unsigned char *)global_temp_buffer
);
780 /* bookmark resume index */
781 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %2d",
782 str(LANG_BOOKMARK_SELECT_INDEX_TEXT
), resume_index
+1);
783 lcd_puts_scroll(0, 2, (unsigned char *)global_temp_buffer
);
788 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %ld:%02d",
789 str(LANG_BOOKMARK_SELECT_TIME_TEXT
),
791 (unsigned int)(ms
% 60000) / 1000);
792 /* unsigned int: hinting for 16bits archs */
796 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
797 "%s: %ld:%02ld:%02d",
798 str(LANG_BOOKMARK_SELECT_TIME_TEXT
),
800 ms
% 3600000 / 60000,
801 (unsigned int)(ms
% 60000) / 1000);
803 lcd_puts_scroll(0, 3, (unsigned char *)global_temp_buffer
);
806 lcd_puts_scroll(0, 4, str(LANG_BOOKMARK_SELECT_PLAY
));
807 lcd_puts_scroll(0, 5, str(LANG_BOOKMARK_SELECT_EXIT
));
808 lcd_puts_scroll(0, 6, str(LANG_BOOKMARK_SELECT_DELETE
));
811 len
=strlen(global_filename
);
813 dot
=strrchr(global_filename
+len
-4,'.');
820 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
821 "%2d, %ld:%02ld, %s,",
829 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
830 "%2d, %ld:%02ld:%02ld, %s,",
833 ms
% 3600000 / 60000,
838 gui_syncstatusbar_draw(&statusbars
, false);
839 lcd_puts_scroll(0,0,global_temp_buffer
);
840 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
848 /* ----------------------------------------------------------------------- */
849 /* This function parses a bookmark, says the voice UI part of it. */
850 /* ------------------------------------------------------------------------*/
851 static void say_bookmark(const char* bookmark
,
857 bool enqueue
= false; /* only the first voice is not queued */
859 parse_bookmark(bookmark
,
865 /* disabled, because transition between talkbox and voice UI clip is not nice */
867 if (global_settings
.talk_dir
>= 3)
868 { /* "talkbox" enabled */
869 char* last
= strrchr(dir
, '/');
871 { /* compose filename for talkbox */
872 strncpy(last
+ 1, dir_thumbnail_name
, sizeof(dir
)-(last
-dir
)-1);
873 talk_file(dir
, enqueue
);
878 talk_id(VOICE_EXT_BMARK
, enqueue
);
879 talk_number(bookmark_id
+ 1, true);
880 talk_id(LANG_BOOKMARK_SELECT_INDEX_TEXT
, true);
881 talk_number(resume_index
+ 1, true);
882 talk_id(LANG_BOOKMARK_SELECT_TIME_TEXT
, true);
884 talk_value(ms
/ 60000, UNIT_MIN
, true);
885 talk_value((ms
% 60000) / 1000, UNIT_SEC
, true);
889 /* ----------------------------------------------------------------------- */
890 /* This function retrieves a given bookmark from a file. */
891 /* If the bookmark requested is beyond the number of bookmarks available */
892 /* in the file, it will return the last one. */
893 /* It also returns the index number of the bookmark in the file */
894 /* ------------------------------------------------------------------------*/
895 static char* get_bookmark(const char* bookmark_file
, int bookmark_count
)
899 int file
= open(bookmark_file
, O_RDONLY
);
904 if (bookmark_count
< 0)
907 /* Get the requested bookmark */
908 while (read_count
< bookmark_count
)
910 /*Reading in a single bookmark */
911 result
= read_line(file
,
913 sizeof(global_read_buffer
));
915 /* Reading past the last bookmark in the file
916 causes the loop to stop */
924 if (read_count
== bookmark_count
)
925 return global_read_buffer
;
930 /* ----------------------------------------------------------------------- */
931 /* This function takes a bookmark and parses it. This function also */
932 /* validates the bookmark. Passing in NULL for an output variable */
933 /* indicates that value is not requested. */
934 /* ----------------------------------------------------------------------- */
935 static bool parse_bookmark(const char *bookmark
,
939 int *resume_first_index
,
941 unsigned int resume_file_size
,
943 int * repeat_mode
, bool *shuffle
,
946 /* First check to see if a valid line was passed in. */
947 int bookmark_len
= strlen(bookmark
);
948 int local_resume_index
= 0;
949 int local_resume_offset
= 0;
950 int local_resume_seed
= 0;
951 int local_resume_first_index
= 0;
953 int local_shuffle
= 0;
954 int local_repeat_mode
= 0;
955 char* local_resume_file
= NULL
;
956 char* local_file_name
= NULL
;
959 static char bookmarkcopy
[MAX_BOOKMARK_SIZE
];
961 /* Don't do anything if the bookmark length is 0 */
962 if (bookmark_len
<= 0)
965 /* Making a dup of the bookmark to use with strtok_r */
966 strncpy(bookmarkcopy
, bookmark
, sizeof(bookmarkcopy
));
967 bookmarkcopy
[sizeof(bookmarkcopy
) - 1] = 0;
970 if ((field
= strtok_r(bookmarkcopy
, ";", &end
)))
971 local_resume_index
= atoi(field
);
976 if ((field
= strtok_r(NULL
, ";", &end
)))
977 local_resume_offset
= atoi(field
);
982 if ((field
= strtok_r(NULL
, ";", &end
)))
983 local_resume_seed
= atoi(field
);
987 /* resume_first_index */
988 if ((field
= strtok_r(NULL
, ";", &end
)))
989 local_resume_first_index
= atoi(field
);
993 /* Milliseconds into MP3. Used for the bookmark select menu */
994 if ((field
= strtok_r(NULL
, ";", &end
)))
995 local_mS
= atoi(field
);
1000 if ((field
= strtok_r(NULL
, ";", &end
)))
1001 local_repeat_mode
= atoi(field
);
1006 if ((field
= strtok_r(NULL
, ";", &end
)))
1007 local_shuffle
= atoi(field
);
1011 /* resume_file & file_name (for the bookmark select menu)*/
1014 local_resume_file
= strtok_r(NULL
, ";", &end
);
1017 local_file_name
= strtok_r(NULL
, ";", &end
);
1022 /* Only return the values the calling function wants */
1024 *resume_index
= local_resume_index
;
1027 *resume_offset
= local_resume_offset
;
1030 *resume_seed
= local_resume_seed
;
1032 if (resume_first_index
)
1033 *resume_first_index
= local_resume_first_index
;
1035 if (resume_file
&& local_resume_file
)
1037 strncpy(resume_file
, local_resume_file
,
1038 MIN(strlen(local_resume_file
), resume_file_size
-1));
1039 resume_file
[MIN(strlen(local_resume_file
), resume_file_size
-1)]=0;
1046 *shuffle
= local_shuffle
;
1049 *repeat_mode
= local_repeat_mode
;
1051 if (file_name
&& local_file_name
)
1053 strncpy(file_name
, local_file_name
,MAX_PATH
-1);
1054 file_name
[MAX_PATH
-1] = 0;
1060 /* ----------------------------------------------------------------------- */
1061 /* This function is used by multiple functions and is used to generate a */
1062 /* bookmark named based off of the input. */
1063 /* Changing this function could result in how the bookmarks are stored. */
1064 /* it would be here that the centralized/decentralized bookmark code */
1065 /* could be placed. */
1066 /* ----------------------------------------------------------------------- */
1067 static bool generate_bookmark_file_name(const char *in
)
1069 int len
= strlen(in
);
1071 /* if this is a root dir MP3, rename the bookmark file root_dir.bmark */
1072 /* otherwise, name it based on the in variable */
1073 if (!strcmp("/", in
))
1074 strcpy(global_bookmark_file_name
, "/root_dir.bmark");
1077 strcpy(global_bookmark_file_name
, in
);
1078 if(global_bookmark_file_name
[len
-1] == '/')
1080 strcpy(&global_bookmark_file_name
[len
], ".bmark");
1086 /* ----------------------------------------------------------------------- */
1087 /* Returns the bookmark name for the current playlist */
1088 /* ----------------------------------------------------------------------- */
1089 bool bookmark_exist(void)
1095 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
1096 sizeof(global_temp_buffer
));
1097 if (generate_bookmark_file_name(name
))
1099 int fd
=open(global_bookmark_file_name
, O_RDONLY
);
1111 /* ----------------------------------------------------------------------- */
1112 /* Checks the current state of the system and returns if it is in a */
1113 /* bookmarkable state. */
1114 /* ----------------------------------------------------------------------- */
1116 /* ----------------------------------------------------------------------- */
1118 /* return bool: Indicates if the system was in a bookmarkable state */
1119 /* ----------------------------------------------------------------------- */
1120 static bool system_check(void)
1122 int resume_index
= 0;
1123 struct mp3entry
*id3
= audio_current_track();
1127 /* no track playing */
1131 /* Checking to see if playing a queued track */
1132 if (playlist_get_resume_info(&resume_index
) == -1)
1134 /* something bad happened while getting the queue information */
1137 else if (playlist_modified(NULL
))
1139 /* can't bookmark while in the queue */