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"
50 #define MAX_BOOKMARKS 10
51 #define MAX_BOOKMARK_SIZE 350
52 #define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark"
54 static bool add_bookmark(const char* bookmark_file_name
, const char* bookmark
);
55 static bool bookmark_load_menu(void);
56 static bool check_bookmark(const char* bookmark
);
57 static char* create_bookmark(void);
58 static bool delete_bookmark(const char* bookmark_file_name
, int bookmark_id
);
59 static void display_bookmark(const char* bookmark
,
62 static void say_bookmark(const char* bookmark
,
64 static bool generate_bookmark_file_name(const char *in
);
65 static char* get_bookmark(const char* bookmark_file
, int bookmark_count
);
66 static bool parse_bookmark(const char *bookmark
,
70 int *resume_first_index
,
72 unsigned int resume_file_size
,
77 static char* select_bookmark(const char* bookmark_file_name
);
78 static bool system_check(void);
79 static bool write_bookmark(bool create_bookmark_file
);
80 static int get_bookmark_count(const char* bookmark_file_name
);
82 static char global_temp_buffer
[MAX_PATH
+1];
83 static char global_bookmark_file_name
[MAX_PATH
];
84 static char global_read_buffer
[MAX_BOOKMARK_SIZE
];
85 static char global_bookmark
[MAX_BOOKMARK_SIZE
];
86 static char global_filename
[MAX_PATH
];
88 /* ----------------------------------------------------------------------- */
89 /* Displays the bookmark menu options for the user to decide. This is an */
90 /* interface function. */
91 /* ----------------------------------------------------------------------- */
92 bool bookmark_menu(void)
97 static const struct menu_item items
[] = {
98 { ID2P(LANG_BOOKMARK_MENU_CREATE
), bookmark_create_menu
},
99 { ID2P(LANG_BOOKMARK_MENU_LIST
), bookmark_load_menu
},
100 { ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS
), bookmark_mrb_load
},
103 m
=menu_init( items
, sizeof items
/ sizeof(struct menu_item
), NULL
,
106 #ifdef HAVE_LCD_CHARCELLS
107 status_set_param(true);
109 result
= menu_run(m
);
110 #ifdef HAVE_LCD_CHARCELLS
111 status_set_param(false);
120 /* ----------------------------------------------------------------------- */
121 /* This is the interface function from the main menu. */
122 /* ----------------------------------------------------------------------- */
123 bool bookmark_create_menu(void)
125 write_bookmark(true);
129 /* ----------------------------------------------------------------------- */
130 /* This function acts as the load interface from the main menu */
131 /* This function determines the bookmark file name and then loads that file*/
132 /* for the user. The user can then select a bookmark to load. */
133 /* If no file/directory is currently playing, the menu item does not work. */
134 /* ----------------------------------------------------------------------- */
135 static bool bookmark_load_menu(void)
147 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
148 sizeof(global_temp_buffer
));
149 if (generate_bookmark_file_name(name
))
151 bookmark
= select_bookmark(global_bookmark_file_name
);
153 return false; /* User exited without selecting a bookmark */
155 success
= parse_bookmark(bookmark
,
161 sizeof(global_temp_buffer
),
163 &global_settings
.repeat_mode
,
164 &global_settings
.playlist_shuffle
,
169 /* something bad happened while creating bookmark name*/
174 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
181 /* ----------------------------------------------------------------------- */
182 /* Gives the user a list of the Most Recent Bookmarks. This is an */
183 /* interface function */
184 /* ----------------------------------------------------------------------- */
185 bool bookmark_mrb_load()
193 bookmark
= select_bookmark(RECENT_BOOKMARK_FILE
);
195 return false; /* User exited without selecting a bookmark */
197 success
= parse_bookmark(bookmark
,
203 sizeof(global_temp_buffer
),
205 &global_settings
.repeat_mode
,
206 &global_settings
.playlist_shuffle
,
210 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
217 /* ----------------------------------------------------------------------- */
218 /* This function handles an autobookmark creation. This is an interface */
220 /* ----------------------------------------------------------------------- */
221 bool bookmark_autobookmark(void)
223 /* prompts the user as to create a bookmark */
230 mpeg_pause(); /* first pause playback */
231 switch (global_settings
.autocreatebookmark
)
234 return write_bookmark(true);
239 case BOOKMARK_RECENT_ONLY_YES
:
240 return write_bookmark(false);
243 /* Prompting user to confirm bookmark creation */
245 #ifdef HAVE_LCD_BITMAP
246 lcd_setmargins(0, STATUSBAR_HEIGHT
);
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);
264 if (global_settings
.autocreatebookmark
==
265 BOOKMARK_RECENT_ONLY_ASK
)
266 return write_bookmark(false);
268 return write_bookmark(true);
272 /* Handle sys events, ignore button releases & repeats */
273 if(default_event_handler(key
) ||
274 !(key
& (BUTTON_REL
|BUTTON_REPEAT
)))
282 /* ----------------------------------------------------------------------- */
283 /* This function takes the current current resume information and writes */
284 /* that to the beginning of the bookmark file. */
285 /* This file will contain N number of bookmarks in the following format: */
286 /* resume_index*resume_offset*resume_seed*resume_first_index* */
287 /* resume_file*milliseconds*MP3 Title* */
288 /* ------------------------------------------------------------------------*/
289 static bool write_bookmark(bool create_bookmark_file
)
295 return false; /* something didn't happen correctly, do nothing */
297 bookmark
= create_bookmark();
299 return false; /* something didn't happen correctly, do nothing */
301 if (global_settings
.usemrb
)
302 success
= add_bookmark(RECENT_BOOKMARK_FILE
, bookmark
);
305 /* writing the bookmark */
306 if (create_bookmark_file
)
308 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
309 sizeof(global_temp_buffer
));
310 if (generate_bookmark_file_name(name
))
312 success
= add_bookmark(global_bookmark_file_name
, bookmark
);
317 splash(HZ
, true, str(LANG_BOOKMARK_CREATE_SUCCESS
));
319 splash(HZ
, true, str(LANG_BOOKMARK_CREATE_FAILURE
));
324 /* ----------------------------------------------------------------------- */
325 /* This function adds a bookmark to a file. */
326 /* ------------------------------------------------------------------------*/
327 static bool add_bookmark(const char* bookmark_file_name
, const char* bookmark
)
329 int temp_bookmark_file
= 0;
330 int bookmark_file
= 0;
331 int bookmark_count
= 0;
332 char* playlist
= NULL
;
338 /* Opening up a temp bookmark file */
339 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
340 "%s.tmp", bookmark_file_name
);
341 temp_bookmark_file
= open(global_temp_buffer
,
342 O_WRONLY
| O_CREAT
| O_TRUNC
);
343 if (temp_bookmark_file
< 0)
344 return false; /* can't open the temp file */
346 if (!strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
) &&
347 (global_settings
.usemrb
== BOOKMARK_UNIQUE_ONLY
))
349 playlist
= strchr(bookmark
,'/');
350 cp
= strrchr(bookmark
,';');
355 /* Writing the new bookmark to the begining of the temp file */
356 write(temp_bookmark_file
, bookmark
, strlen(bookmark
));
357 write(temp_bookmark_file
, "\n", 1);
360 /* Reading in the previous bookmarks and writing them to the temp file */
361 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
362 if (bookmark_file
>= 0)
364 while (read_line(bookmark_file
, global_read_buffer
,
365 sizeof(global_read_buffer
)))
367 /* The MRB has a max of MAX_BOOKMARKS in it */
368 /* This keeps it from getting too large */
369 if ((strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
)==0))
371 if(bookmark_count
>= MAX_BOOKMARKS
)
375 cp
= strchr(global_read_buffer
,'/');
376 tmp
= strrchr(global_read_buffer
,';');
377 if (check_bookmark(global_read_buffer
) &&
378 (!unique
|| len
!= tmp
-cp
|| strncmp(playlist
,cp
,len
)))
381 write(temp_bookmark_file
, global_read_buffer
,
382 strlen(global_read_buffer
));
383 write(temp_bookmark_file
, "\n", 1);
386 close(bookmark_file
);
388 close(temp_bookmark_file
);
390 remove(bookmark_file_name
);
391 rename(global_temp_buffer
, bookmark_file_name
);
397 /* ----------------------------------------------------------------------- */
398 /* This function takes the system resume data and formats it into a valid */
400 /* ----------------------------------------------------------------------- */
401 static char* create_bookmark()
403 int resume_index
= 0;
406 /* grab the currently playing track */
407 struct mp3entry
*id3
= mpeg_current_track();
411 /* Get some basic resume information */
412 /* queue_resume and queue_resume_index are not used and can be ignored.*/
413 playlist_get_resume_info(&resume_index
);
415 /* Get the currently playing file minus the path */
416 /* This is used when displaying the available bookmarks */
417 file
= strrchr(id3
->path
,'/');
421 /* create the bookmark */
422 snprintf(global_bookmark
, sizeof(global_bookmark
),
423 "%d;%d;%d;%d;%d;%d;%d;%s;%s",
426 playlist_get_seed(NULL
),
429 global_settings
.repeat_mode
,
430 global_settings
.playlist_shuffle
,
431 playlist_get_name(NULL
, global_temp_buffer
,
432 sizeof(global_temp_buffer
)),
435 /* checking to see if the bookmark is valid */
436 if (check_bookmark(global_bookmark
))
437 return global_bookmark
;
442 static bool check_bookmark(const char* bookmark
)
444 return parse_bookmark(bookmark
,
445 NULL
,NULL
,NULL
, NULL
,
450 /* ----------------------------------------------------------------------- */
451 /* This function will determine if an autoload is necessary. This is an */
452 /* interface function. */
453 /* ------------------------------------------------------------------------*/
454 bool bookmark_autoload(const char* file
)
460 if(global_settings
.autoloadbookmark
== BOOKMARK_NO
)
463 /*Checking to see if a bookmark file exists.*/
464 if(!generate_bookmark_file_name(file
))
469 fd
= open(global_bookmark_file_name
, O_RDONLY
);
472 if(-1 == lseek(fd
, 0, SEEK_END
))
479 if(global_settings
.autoloadbookmark
== BOOKMARK_YES
)
481 return bookmark_load(global_bookmark_file_name
, true);
485 button_clear_queue(); /* clear button queue */
486 /* Prompting user to confirm bookmark load */
488 #ifdef HAVE_LCD_BITMAP
489 lcd_setmargins(0, STATUSBAR_HEIGHT
);
490 lcd_puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
491 lcd_puts(0,1, str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
492 lcd_puts(0,2, str(LANG_BOOKMARK_SELECT_LIST_BOOKMARKS
));
493 lcd_puts(0,3, str(LANG_CANCEL_WITH_ANY_RECORDER
));
496 lcd_puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
497 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
505 button_clear_queue();
507 /* Wait for a key to be pushed */
508 key
= button_get(true);
511 #ifdef HAVE_LCD_BITMAP
513 return bookmark_load(global_bookmark_file_name
, false);
516 return bookmark_load(global_bookmark_file_name
, true);
519 if(default_event_handler(key
) == SYS_USB_CONNECTED
)
528 /* ----------------------------------------------------------------------- */
529 /* This function loads the bookmark information into the resume memory. */
530 /* This is an interface function. */
531 /* ------------------------------------------------------------------------*/
532 bool bookmark_load(const char* file
, bool autoload
)
539 char* bookmark
= NULL
;;
543 fd
= open(file
, O_RDONLY
);
546 if(read_line(fd
, global_read_buffer
, sizeof(global_read_buffer
)))
547 bookmark
=global_read_buffer
;
553 /* This is not an auto-load, so list the bookmarks */
554 bookmark
=select_bookmark(file
);
556 return true; /* User exited without selecting a bookmark */
561 success
= parse_bookmark(bookmark
,
567 sizeof(global_temp_buffer
),
569 &global_settings
.repeat_mode
,
570 &global_settings
.playlist_shuffle
,
576 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
583 static int get_bookmark_count(const char* bookmark_file_name
)
586 int file
= open(bookmark_file_name
, O_RDONLY
);
591 /* Get the requested bookmark */
592 while(read_line(file
, global_read_buffer
, sizeof(global_read_buffer
)))
594 if(check_bookmark(global_read_buffer
))
605 /* ----------------------------------------------------------------------- */
606 /* This displays a the bookmarks in a file and allows the user to */
607 /* select one to play. */
608 /* ------------------------------------------------------------------------*/
609 static char* select_bookmark(const char* bookmark_file_name
)
612 int bookmark_id_prev
= -1;
614 char* bookmark
= NULL
;
615 int bookmark_count
= 0;
617 #ifdef HAVE_LCD_BITMAP
618 lcd_setmargins(0, 0);
621 button_clear_queue(); /* clear button queue */
622 bookmark_count
= get_bookmark_count(bookmark_file_name
);
627 bookmark_id
= bookmark_count
-1;
628 if(bookmark_id
>= bookmark_count
)
631 if (bookmark_id
!= bookmark_id_prev
)
633 bookmark
= get_bookmark(bookmark_file_name
, bookmark_id
);
634 bookmark_id_prev
= bookmark_id
;
639 /* if there were no bookmarks in the file, delete the file and exit. */
642 splash(HZ
, true, str(LANG_BOOKMARK_LOAD_EMPTY
));
643 remove(bookmark_file_name
);
644 button_clear_queue(); /* clear button queue */
649 bookmark_id_prev
= bookmark_id
;
655 display_bookmark(bookmark
, bookmark_id
, bookmark_count
);
656 if (global_settings
.talk_menu
) /* for voice UI */
657 say_bookmark(bookmark
, bookmark_id
);
660 /* waiting for the user to click a button */
661 key
= button_get(true);
665 /* User wants to use this bookmark */
666 #ifdef HAVE_LCD_BITMAP
667 if (global_settings
.statusbar
)
668 lcd_setmargins(0, STATUSBAR_HEIGHT
);
670 lcd_setmargins(0, 0);
674 #if CONFIG_KEYPAD == ONDIO_PAD
675 case BUTTON_MENU
| BUTTON_RIGHT
:
676 #elif CONFIG_KEYPAD == IRIVER_H100_PAD
677 case BUTTON_ON
| BUTTON_SELECT
:
679 case BUTTON_ON
| BUTTON_PLAY
:
681 /* User wants to delete this bookmark */
682 delete_bookmark(bookmark_file_name
, bookmark_id
);
685 if(bookmark_id
>= bookmark_count
)
686 bookmark_id
= bookmark_count
-1;
687 button_clear_queue(); /* clear button queue */
698 #if CONFIG_KEYPAD != ONDIO_PAD
699 case SETTINGS_CANCEL
:
701 #ifdef SETTINGS_CANCEL2
702 case SETTINGS_CANCEL2
:
710 if(default_event_handler(key
) == SYS_USB_CONNECTED
)
720 /* ----------------------------------------------------------------------- */
721 /* This function takes a location in a bookmark file and deletes that */
723 /* ------------------------------------------------------------------------*/
724 static bool delete_bookmark(const char* bookmark_file_name
, int bookmark_id
)
726 int temp_bookmark_file
= 0;
727 int bookmark_file
= 0;
728 int bookmark_count
= 0;
730 /* Opening up a temp bookmark file */
731 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
732 "%s.tmp", bookmark_file_name
);
733 temp_bookmark_file
= open(global_temp_buffer
,
734 O_WRONLY
| O_CREAT
| O_TRUNC
);
735 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
737 if (temp_bookmark_file
< 0 || bookmark_file
< 0)
738 return false; /* can't open one of the files */
740 /* Reading in the previous bookmarks and writing them to the temp file */
741 while (read_line(bookmark_file
, global_read_buffer
,
742 sizeof(global_read_buffer
)))
744 /* The MRB has a max of MAX_BOOKMARKS in it */
745 /* This keeps it from getting too large */
746 if ((strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
)==0))
748 if(bookmark_count
>= MAX_BOOKMARKS
)
752 if (check_bookmark(global_read_buffer
))
754 if (bookmark_id
!= bookmark_count
)
756 write(temp_bookmark_file
, global_read_buffer
,
757 strlen(global_read_buffer
));
758 write(temp_bookmark_file
, "\n", 1);
764 close(bookmark_file
);
765 close(temp_bookmark_file
);
767 remove(bookmark_file_name
);
768 rename(global_temp_buffer
, bookmark_file_name
);
773 /* ----------------------------------------------------------------------- */
774 /* This function parses a bookmark and displays it for the user. */
775 /* ------------------------------------------------------------------------*/
776 static void display_bookmark(const char* bookmark
,
780 int resume_index
= 0;
783 bool playlist_shuffle
= false;
787 /* getting the index and the time into the file */
788 parse_bookmark(bookmark
,
789 &resume_index
, NULL
, NULL
, NULL
, NULL
, 0,
790 &ms
, &repeat_mode
, &playlist_shuffle
,
796 #ifdef HAVE_LCD_BITMAP
797 /* bookmark shuffle and repeat states*/
801 statusbar_icon_play_mode(Icon_RepeatOne
);
805 statusbar_icon_play_mode(Icon_Repeat
);
809 statusbar_icon_shuffle();
812 len
=strlen(global_filename
);
814 dot
=strrchr(global_filename
+ len
- 4, '.');
819 lcd_puts_scroll(0, 0, global_filename
);
823 /* bookmark number */
824 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %2d/%2d",
825 str(LANG_BOOKMARK_SELECT_BOOKMARK_TEXT
),
826 bookmark_id
+ 1, bookmark_count
);
827 lcd_puts_scroll(0, 1, global_temp_buffer
);
829 /* bookmark resume index */
830 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %2d",
831 str(LANG_BOOKMARK_SELECT_INDEX_TEXT
), resume_index
+1);
832 lcd_puts_scroll(0, 2, global_temp_buffer
);
837 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %d:%02d",
838 str(LANG_BOOKMARK_SELECT_TIME_TEXT
),
844 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
846 str(LANG_BOOKMARK_SELECT_TIME_TEXT
),
848 ms
% 3600000 / 60000,
851 lcd_puts_scroll(0, 3, global_temp_buffer
);
854 lcd_puts_scroll(0, 4, str(LANG_BOOKMARK_SELECT_PLAY
));
855 lcd_puts_scroll(0, 5, str(LANG_BOOKMARK_SELECT_EXIT
));
856 lcd_puts_scroll(0, 6, str(LANG_BOOKMARK_SELECT_DELETE
));
859 len
=strlen(global_filename
);
861 dot
=strrchr(global_filename
+len
-4,'.');
868 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
877 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
878 "%2d, %d:%02d:%02d, %s,",
881 ms
% 3600000 / 60000,
887 lcd_puts_scroll(0,0,global_temp_buffer
);
888 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
896 /* ----------------------------------------------------------------------- */
897 /* This function parses a bookmark, says the voice UI part of it. */
898 /* ------------------------------------------------------------------------*/
899 static void say_bookmark(const char* bookmark
,
905 bool enqueue
= false; /* only the first voice is not queued */
907 parse_bookmark(bookmark
,
913 /* disabled, because transition between talkbox and voice UI clip is not nice */
915 if (global_settings
.talk_dir
>= 3)
916 { /* "talkbox" enabled */
917 char* last
= strrchr(dir
, '/');
919 { /* compose filename for talkbox */
920 strncpy(last
+ 1, dir_thumbnail_name
, sizeof(dir
)-(last
-dir
)-1);
921 talk_file(dir
, enqueue
);
926 talk_id(VOICE_EXT_BMARK
, enqueue
);
927 talk_number(bookmark_id
+ 1, true);
928 talk_id(LANG_BOOKMARK_SELECT_INDEX_TEXT
, true);
929 talk_number(resume_index
+ 1, true);
930 talk_id(LANG_BOOKMARK_SELECT_TIME_TEXT
, true);
932 talk_value(ms
/ 60000, UNIT_MIN
, true);
933 talk_value((ms
% 60000) / 1000, UNIT_SEC
, true);
937 /* ----------------------------------------------------------------------- */
938 /* This function retrieves a given bookmark from a file. */
939 /* If the bookmark requested is beyond the number of bookmarks available */
940 /* in the file, it will return the last one. */
941 /* It also returns the index number of the bookmark in the file */
942 /* ------------------------------------------------------------------------*/
943 static char* get_bookmark(const char* bookmark_file
, int bookmark_count
)
947 int file
= open(bookmark_file
, O_RDONLY
);
952 if (bookmark_count
< 0)
955 /* Get the requested bookmark */
956 while (read_count
< bookmark_count
)
958 /*Reading in a single bookmark */
959 result
= read_line(file
,
961 sizeof(global_read_buffer
));
963 /* Reading past the last bookmark in the file
964 causes the loop to stop */
972 if (read_count
== bookmark_count
)
973 return global_read_buffer
;
978 /* ----------------------------------------------------------------------- */
979 /* This function takes a bookmark and parses it. This function also */
980 /* validates the bookmark. Passing in NULL for an output variable */
981 /* indicates that value is not requested. */
982 /* ----------------------------------------------------------------------- */
983 static bool parse_bookmark(const char *bookmark
,
987 int *resume_first_index
,
989 unsigned int resume_file_size
,
991 int * repeat_mode
, bool *shuffle
,
994 /* First check to see if a valid line was passed in. */
995 int bookmark_len
= strlen(bookmark
);
996 int local_resume_index
= 0;
997 int local_resume_offset
= 0;
998 int local_resume_seed
= 0;
999 int local_resume_first_index
= 0;
1001 int local_shuffle
= 0;
1002 int local_repeat_mode
= 0;
1003 char* local_resume_file
= NULL
;
1004 char* local_file_name
= NULL
;
1007 static char bookmarkcopy
[MAX_BOOKMARK_SIZE
];
1009 /* Don't do anything if the bookmark length is 0 */
1010 if (bookmark_len
<= 0)
1013 /* Making a dup of the bookmark to use with strtok_r */
1014 strncpy(bookmarkcopy
, bookmark
, sizeof(bookmarkcopy
));
1015 bookmarkcopy
[sizeof(bookmarkcopy
) - 1] = 0;
1018 if ((field
= strtok_r(bookmarkcopy
, ";", &end
)))
1019 local_resume_index
= atoi(field
);
1024 if ((field
= strtok_r(NULL
, ";", &end
)))
1025 local_resume_offset
= atoi(field
);
1030 if ((field
= strtok_r(NULL
, ";", &end
)))
1031 local_resume_seed
= atoi(field
);
1035 /* resume_first_index */
1036 if ((field
= strtok_r(NULL
, ";", &end
)))
1037 local_resume_first_index
= atoi(field
);
1041 /* Milliseconds into MP3. Used for the bookmark select menu */
1042 if ((field
= strtok_r(NULL
, ";", &end
)))
1043 local_mS
= atoi(field
);
1048 if ((field
= strtok_r(NULL
, ";", &end
)))
1049 local_repeat_mode
= atoi(field
);
1054 if ((field
= strtok_r(NULL
, ";", &end
)))
1055 local_shuffle
= atoi(field
);
1059 /* resume_file & file_name (for the bookmark select menu)*/
1062 local_resume_file
= strtok_r(NULL
, ";", &end
);
1065 local_file_name
= strtok_r(NULL
, ";", &end
);
1070 /* Only return the values the calling function wants */
1072 *resume_index
= local_resume_index
;
1075 *resume_offset
= local_resume_offset
;
1078 *resume_seed
= local_resume_seed
;
1080 if (resume_first_index
)
1081 *resume_first_index
= local_resume_first_index
;
1083 if (resume_file
&& local_resume_file
)
1085 strncpy(resume_file
, local_resume_file
,
1086 MIN(strlen(local_resume_file
), resume_file_size
-1));
1087 resume_file
[MIN(strlen(local_resume_file
), resume_file_size
-1)]=0;
1094 *shuffle
= local_shuffle
;
1097 *repeat_mode
= local_repeat_mode
;
1099 if (file_name
&& local_file_name
)
1101 strncpy(file_name
, local_file_name
,MAX_PATH
-1);
1102 file_name
[MAX_PATH
-1] = 0;
1108 /* ----------------------------------------------------------------------- */
1109 /* This function is used by multiple functions and is used to generate a */
1110 /* bookmark named based off of the input. */
1111 /* Changing this function could result in how the bookmarks are stored. */
1112 /* it would be here that the centralized/decentralized bookmark code */
1113 /* could be placed. */
1114 /* ----------------------------------------------------------------------- */
1115 static bool generate_bookmark_file_name(const char *in
)
1117 int len
= strlen(in
);
1119 /* if this is a root dir MP3, rename the bookmark file root_dir.bmark */
1120 /* otherwise, name it based on the in variable */
1121 if (!strcmp("/", in
))
1122 strcpy(global_bookmark_file_name
, "/root_dir.bmark");
1125 strcpy(global_bookmark_file_name
, in
);
1126 if(global_bookmark_file_name
[len
-1] == '/')
1128 strcpy(&global_bookmark_file_name
[len
], ".bmark");
1134 /* ----------------------------------------------------------------------- */
1135 /* Checks the current state of the system and returns if it is in a */
1136 /* bookmarkable state. */
1137 /* ----------------------------------------------------------------------- */
1139 /* ----------------------------------------------------------------------- */
1141 /* return bool: Indicates if the system was in a bookmarkable state */
1142 /* ----------------------------------------------------------------------- */
1143 static bool system_check(void)
1145 int resume_index
= 0;
1146 struct mp3entry
*id3
= mpeg_current_track();
1150 /* no track playing */
1154 /* Checking to see if playing a queued track */
1155 if (playlist_get_resume_info(&resume_index
) == -1)
1157 /* something bad happened while getting the queue information */
1160 else if (playlist_modified(NULL
))
1162 /* can't bookmark while in the queue */