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"
52 #define MAX_BOOKMARKS 10
53 #define MAX_BOOKMARK_SIZE 350
54 #define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark"
56 static bool add_bookmark(const char* bookmark_file_name
, const char* bookmark
);
57 static bool check_bookmark(const char* bookmark
);
58 static char* create_bookmark(void);
59 static bool delete_bookmark(const char* bookmark_file_name
, int bookmark_id
);
60 static void display_bookmark(const char* bookmark
,
63 static void say_bookmark(const char* bookmark
,
65 static bool generate_bookmark_file_name(const char *in
);
66 static char* get_bookmark(const char* bookmark_file
, int bookmark_count
);
67 static bool parse_bookmark(const char *bookmark
,
71 int *resume_first_index
,
73 unsigned int resume_file_size
,
78 static char* select_bookmark(const char* bookmark_file_name
);
79 static bool system_check(void);
80 static bool write_bookmark(bool create_bookmark_file
);
81 static int get_bookmark_count(const char* bookmark_file_name
);
83 static char global_temp_buffer
[MAX_PATH
+1];
84 static char global_bookmark_file_name
[MAX_PATH
];
85 static char global_read_buffer
[MAX_BOOKMARK_SIZE
];
86 static char global_bookmark
[MAX_BOOKMARK_SIZE
];
87 static char global_filename
[MAX_PATH
];
89 /* ----------------------------------------------------------------------- */
90 /* This is the interface function from the main menu. */
91 /* ----------------------------------------------------------------------- */
92 bool bookmark_create_menu(void)
98 /* ----------------------------------------------------------------------- */
99 /* This function acts as the load interface from the main menu */
100 /* This function determines the bookmark file name and then loads that file*/
101 /* for the user. The user can then select a bookmark to load. */
102 /* If no file/directory is currently playing, the menu item does not work. */
103 /* ----------------------------------------------------------------------- */
104 bool bookmark_load_menu(void)
116 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
117 sizeof(global_temp_buffer
));
118 if (generate_bookmark_file_name(name
))
120 bookmark
= select_bookmark(global_bookmark_file_name
);
122 return false; /* User exited without selecting a bookmark */
124 success
= parse_bookmark(bookmark
,
130 sizeof(global_temp_buffer
),
132 &global_settings
.repeat_mode
,
133 &global_settings
.playlist_shuffle
,
138 /* something bad happened while creating bookmark name*/
143 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
150 /* ----------------------------------------------------------------------- */
151 /* Gives the user a list of the Most Recent Bookmarks. This is an */
152 /* interface function */
153 /* ----------------------------------------------------------------------- */
154 bool bookmark_mrb_load()
162 bookmark
= select_bookmark(RECENT_BOOKMARK_FILE
);
164 return false; /* User exited without selecting a bookmark */
166 success
= parse_bookmark(bookmark
,
172 sizeof(global_temp_buffer
),
174 &global_settings
.repeat_mode
,
175 &global_settings
.playlist_shuffle
,
179 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
186 /* ----------------------------------------------------------------------- */
187 /* This function handles an autobookmark creation. This is an interface */
189 /* ----------------------------------------------------------------------- */
190 bool bookmark_autobookmark(void)
192 /* prompts the user as to create a bookmark */
199 audio_pause(); /* first pause playback */
200 switch (global_settings
.autocreatebookmark
)
203 return write_bookmark(true);
208 case BOOKMARK_RECENT_ONLY_YES
:
209 return write_bookmark(false);
212 /* Prompting user to confirm bookmark creation */
214 #ifdef HAVE_LCD_BITMAP
215 lcd_setmargins(0, STATUSBAR_HEIGHT
);
216 lcd_puts(0,0, str(LANG_AUTO_BOOKMARK_QUERY
));
217 lcd_puts(0,1, str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
218 lcd_puts(0,2, str(LANG_CANCEL_WITH_ANY_RECORDER
));
221 lcd_puts(0,0, str(LANG_AUTO_BOOKMARK_QUERY
));
222 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
228 /* Wait for a key to be pushed */
229 key
= button_get(true);
233 if (global_settings
.autocreatebookmark
==
234 BOOKMARK_RECENT_ONLY_ASK
)
235 return write_bookmark(false);
237 return write_bookmark(true);
241 /* Handle sys events, ignore button releases & repeats */
242 if(default_event_handler(key
) ||
243 !(key
& (BUTTON_REL
|BUTTON_REPEAT
)))
251 /* ----------------------------------------------------------------------- */
252 /* This function takes the current current resume information and writes */
253 /* that to the beginning of the bookmark file. */
254 /* This file will contain N number of bookmarks in the following format: */
255 /* resume_index*resume_offset*resume_seed*resume_first_index* */
256 /* resume_file*milliseconds*MP3 Title* */
257 /* ------------------------------------------------------------------------*/
258 static bool write_bookmark(bool create_bookmark_file
)
264 return false; /* something didn't happen correctly, do nothing */
266 bookmark
= create_bookmark();
268 return false; /* something didn't happen correctly, do nothing */
270 if (global_settings
.usemrb
)
271 success
= add_bookmark(RECENT_BOOKMARK_FILE
, bookmark
);
274 /* writing the bookmark */
275 if (create_bookmark_file
)
277 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
278 sizeof(global_temp_buffer
));
279 if (generate_bookmark_file_name(name
))
281 success
= add_bookmark(global_bookmark_file_name
, bookmark
);
286 splash(HZ
, true, str(LANG_BOOKMARK_CREATE_SUCCESS
));
288 splash(HZ
, true, str(LANG_BOOKMARK_CREATE_FAILURE
));
293 /* ----------------------------------------------------------------------- */
294 /* This function adds a bookmark to a file. */
295 /* ------------------------------------------------------------------------*/
296 static bool add_bookmark(const char* bookmark_file_name
, const char* bookmark
)
298 int temp_bookmark_file
= 0;
299 int bookmark_file
= 0;
300 int bookmark_count
= 0;
301 char* playlist
= NULL
;
307 /* Opening up a temp bookmark file */
308 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
309 "%s.tmp", bookmark_file_name
);
310 temp_bookmark_file
= open(global_temp_buffer
,
311 O_WRONLY
| O_CREAT
| O_TRUNC
);
312 if (temp_bookmark_file
< 0)
313 return false; /* can't open the temp file */
315 if (!strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
) &&
316 (global_settings
.usemrb
== BOOKMARK_UNIQUE_ONLY
))
318 playlist
= strchr(bookmark
,'/');
319 cp
= strrchr(bookmark
,';');
324 /* Writing the new bookmark to the begining of the temp file */
325 write(temp_bookmark_file
, bookmark
, strlen(bookmark
));
326 write(temp_bookmark_file
, "\n", 1);
329 /* Reading in the previous bookmarks and writing them to the temp file */
330 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
331 if (bookmark_file
>= 0)
333 while (read_line(bookmark_file
, global_read_buffer
,
334 sizeof(global_read_buffer
)))
336 /* The MRB has a max of MAX_BOOKMARKS in it */
337 /* This keeps it from getting too large */
338 if ((strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
)==0))
340 if(bookmark_count
>= MAX_BOOKMARKS
)
344 cp
= strchr(global_read_buffer
,'/');
345 tmp
= strrchr(global_read_buffer
,';');
346 if (check_bookmark(global_read_buffer
) &&
347 (!unique
|| len
!= tmp
-cp
|| strncmp(playlist
,cp
,len
)))
350 write(temp_bookmark_file
, global_read_buffer
,
351 strlen(global_read_buffer
));
352 write(temp_bookmark_file
, "\n", 1);
355 close(bookmark_file
);
357 close(temp_bookmark_file
);
359 remove(bookmark_file_name
);
360 rename(global_temp_buffer
, bookmark_file_name
);
366 /* ----------------------------------------------------------------------- */
367 /* This function takes the system resume data and formats it into a valid */
369 /* ----------------------------------------------------------------------- */
370 static char* create_bookmark()
372 int resume_index
= 0;
375 /* grab the currently playing track */
376 struct mp3entry
*id3
= audio_current_track();
380 /* Get some basic resume information */
381 /* queue_resume and queue_resume_index are not used and can be ignored.*/
382 playlist_get_resume_info(&resume_index
);
384 /* Get the currently playing file minus the path */
385 /* This is used when displaying the available bookmarks */
386 file
= strrchr(id3
->path
,'/');
390 /* create the bookmark */
391 snprintf(global_bookmark
, sizeof(global_bookmark
),
392 "%d;%ld;%d;%d;%ld;%d;%d;%s;%s",
395 playlist_get_seed(NULL
),
398 global_settings
.repeat_mode
,
399 global_settings
.playlist_shuffle
,
400 playlist_get_name(NULL
, global_temp_buffer
,
401 sizeof(global_temp_buffer
)),
404 /* checking to see if the bookmark is valid */
405 if (check_bookmark(global_bookmark
))
406 return global_bookmark
;
411 static bool check_bookmark(const char* bookmark
)
413 return parse_bookmark(bookmark
,
414 NULL
,NULL
,NULL
, NULL
,
419 /* ----------------------------------------------------------------------- */
420 /* This function will determine if an autoload is necessary. This is an */
421 /* interface function. */
422 /* ------------------------------------------------------------------------*/
423 bool bookmark_autoload(const char* file
)
429 if(global_settings
.autoloadbookmark
== BOOKMARK_NO
)
432 /*Checking to see if a bookmark file exists.*/
433 if(!generate_bookmark_file_name(file
))
438 fd
= open(global_bookmark_file_name
, O_RDONLY
);
441 if(-1 == lseek(fd
, 0, SEEK_END
))
448 if(global_settings
.autoloadbookmark
== BOOKMARK_YES
)
450 return bookmark_load(global_bookmark_file_name
, true);
454 /* Prompting user to confirm bookmark load */
456 #ifdef HAVE_LCD_BITMAP
457 lcd_setmargins(0, STATUSBAR_HEIGHT
);
458 lcd_puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
459 lcd_puts(0,1, str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
460 lcd_puts(0,2, str(LANG_BOOKMARK_SELECT_LIST_BOOKMARKS
));
461 lcd_puts(0,3, str(LANG_CANCEL_WITH_ANY_RECORDER
));
464 lcd_puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
465 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
471 /* Wait for a key to be pushed */
472 key
= button_get(true);
475 #ifdef HAVE_LCD_BITMAP
477 return bookmark_load(global_bookmark_file_name
, false);
480 return bookmark_load(global_bookmark_file_name
, true);
483 /* Handle sys events, ignore button releases & repeats */
484 if (default_event_handler(key
) ||
485 !(key
& (BUTTON_REPEAT
|BUTTON_REL
)))
494 /* ----------------------------------------------------------------------- */
495 /* This function loads the bookmark information into the resume memory. */
496 /* This is an interface function. */
497 /* ------------------------------------------------------------------------*/
498 bool bookmark_load(const char* file
, bool autoload
)
505 char* bookmark
= NULL
;;
509 fd
= open(file
, O_RDONLY
);
512 if(read_line(fd
, global_read_buffer
, sizeof(global_read_buffer
)))
513 bookmark
=global_read_buffer
;
519 /* This is not an auto-load, so list the bookmarks */
520 bookmark
=select_bookmark(file
);
522 return true; /* User exited without selecting a bookmark */
527 success
= parse_bookmark(bookmark
,
533 sizeof(global_temp_buffer
),
535 &global_settings
.repeat_mode
,
536 &global_settings
.playlist_shuffle
,
542 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
549 static int get_bookmark_count(const char* bookmark_file_name
)
552 int file
= open(bookmark_file_name
, O_RDONLY
);
557 /* Get the requested bookmark */
558 while(read_line(file
, global_read_buffer
, sizeof(global_read_buffer
)))
560 if(check_bookmark(global_read_buffer
))
570 #if CONFIG_KEYPAD == ONDIO_PAD
571 #define BOOKMARK_SELECT_PRE BUTTON_RIGHT
572 #define BOOKMARK_SELECT (BUTTON_RIGHT | BUTTON_REL)
573 #define BOOKMARK_DELETE (BUTTON_RIGHT | BUTTON_REPEAT)
575 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
576 (CONFIG_KEYPAD == IRIVER_H300_PAD)
577 #define BOOKMARK_SELECT BUTTON_SELECT
578 #define BOOKMARK_DELETE (BUTTON_ON | BUTTON_SELECT)
580 #else /* player, recorder, gmini */
581 #define BOOKMARK_SELECT BUTTON_PLAY
582 #define BOOKMARK_DELETE (BUTTON_ON | BUTTON_PLAY)
585 /* ----------------------------------------------------------------------- */
586 /* This displays a the bookmarks in a file and allows the user to */
587 /* select one to play. */
588 /* ------------------------------------------------------------------------*/
589 static char* select_bookmark(const char* bookmark_file_name
)
592 int bookmark_id_prev
= -1;
594 int lastkey
= BUTTON_NONE
;
595 char* bookmark
= NULL
;
596 int bookmark_count
= 0;
598 #ifdef HAVE_LCD_BITMAP
599 int x
= lcd_getxmargin();
600 int y
= lcd_getymargin();
601 lcd_setmargins(0, 0);
604 bookmark_count
= get_bookmark_count(bookmark_file_name
);
609 bookmark_id
= bookmark_count
-1;
610 if(bookmark_id
>= bookmark_count
)
613 if (bookmark_id
!= bookmark_id_prev
)
615 bookmark
= get_bookmark(bookmark_file_name
, bookmark_id
);
616 bookmark_id_prev
= bookmark_id
;
621 /* if there were no bookmarks in the file, delete the file and exit. */
624 splash(HZ
, true, str(LANG_BOOKMARK_LOAD_EMPTY
));
625 remove(bookmark_file_name
);
630 bookmark_id_prev
= bookmark_id
;
636 display_bookmark(bookmark
, bookmark_id
, bookmark_count
);
637 if (global_settings
.talk_menu
) /* for voice UI */
638 say_bookmark(bookmark
, bookmark_id
);
641 /* waiting for the user to click a button */
642 key
= button_get(true);
645 case BOOKMARK_SELECT
:
646 #ifdef BOOKMARK_SELECT_PRE
647 if (lastkey
!= BOOKMARK_SELECT_PRE
)
650 /* User wants to use this bookmark */
651 #ifdef HAVE_LCD_BITMAP
652 if (global_settings
.statusbar
)
653 lcd_setmargins(0, STATUSBAR_HEIGHT
);
655 lcd_setmargins(0, 0);
659 case BOOKMARK_DELETE
:
660 /* User wants to delete this bookmark */
661 delete_bookmark(bookmark_file_name
, bookmark_id
);
664 if(bookmark_id
>= bookmark_count
)
665 bookmark_id
= bookmark_count
-1;
669 case SETTINGS_DEC
| BUTTON_REPEAT
:
674 case SETTINGS_INC
| BUTTON_REPEAT
:
678 case SETTINGS_CANCEL
:
679 #ifdef SETTINGS_CANCEL2
680 case SETTINGS_CANCEL2
:
685 #ifdef HAVE_LCD_BITMAP
686 lcd_setmargins(x
, y
);
691 if(default_event_handler(key
) == SYS_USB_CONNECTED
)
702 /* ----------------------------------------------------------------------- */
703 /* This function takes a location in a bookmark file and deletes that */
705 /* ------------------------------------------------------------------------*/
706 static bool delete_bookmark(const char* bookmark_file_name
, int bookmark_id
)
708 int temp_bookmark_file
= 0;
709 int bookmark_file
= 0;
710 int bookmark_count
= 0;
712 /* Opening up a temp bookmark file */
713 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
714 "%s.tmp", bookmark_file_name
);
715 temp_bookmark_file
= open(global_temp_buffer
,
716 O_WRONLY
| O_CREAT
| O_TRUNC
);
717 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
719 if (temp_bookmark_file
< 0 || bookmark_file
< 0)
720 return false; /* can't open one of the files */
722 /* Reading in the previous bookmarks and writing them to the temp file */
723 while (read_line(bookmark_file
, global_read_buffer
,
724 sizeof(global_read_buffer
)))
726 /* The MRB has a max of MAX_BOOKMARKS in it */
727 /* This keeps it from getting too large */
728 if ((strcmp(bookmark_file_name
,RECENT_BOOKMARK_FILE
)==0))
730 if(bookmark_count
>= MAX_BOOKMARKS
)
734 if (check_bookmark(global_read_buffer
))
736 if (bookmark_id
!= bookmark_count
)
738 write(temp_bookmark_file
, global_read_buffer
,
739 strlen(global_read_buffer
));
740 write(temp_bookmark_file
, "\n", 1);
746 close(bookmark_file
);
747 close(temp_bookmark_file
);
749 remove(bookmark_file_name
);
750 rename(global_temp_buffer
, bookmark_file_name
);
755 /* ----------------------------------------------------------------------- */
756 /* This function parses a bookmark and displays it for the user. */
757 /* ------------------------------------------------------------------------*/
758 static void display_bookmark(const char* bookmark
,
762 int resume_index
= 0;
765 bool playlist_shuffle
= false;
769 /* getting the index and the time into the file */
770 parse_bookmark(bookmark
,
771 &resume_index
, NULL
, NULL
, NULL
, NULL
, 0,
772 &ms
, &repeat_mode
, &playlist_shuffle
,
778 #ifdef HAVE_LCD_BITMAP
779 /* bookmark shuffle and repeat states*/
782 #ifdef AB_REPEAT_ENABLE
784 statusbar_icon_play_mode(Icon_RepeatAB
);
789 statusbar_icon_play_mode(Icon_RepeatOne
);
793 statusbar_icon_play_mode(Icon_Repeat
);
797 statusbar_icon_shuffle();
800 len
=strlen(global_filename
);
802 dot
=strrchr(global_filename
+ len
- 4, '.');
807 lcd_puts_scroll(0, 0, global_filename
);
811 /* bookmark number */
812 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %2d/%2d",
813 str(LANG_BOOKMARK_SELECT_BOOKMARK_TEXT
),
814 bookmark_id
+ 1, bookmark_count
);
815 lcd_puts_scroll(0, 1, global_temp_buffer
);
817 /* bookmark resume index */
818 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %2d",
819 str(LANG_BOOKMARK_SELECT_INDEX_TEXT
), resume_index
+1);
820 lcd_puts_scroll(0, 2, global_temp_buffer
);
825 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %ld:%02d",
826 str(LANG_BOOKMARK_SELECT_TIME_TEXT
),
828 (unsigned int)(ms
% 60000) / 1000);
829 /* unsigned int: hinting for 16bits archs */
833 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
834 "%s: %ld:%02ld:%02d",
835 str(LANG_BOOKMARK_SELECT_TIME_TEXT
),
837 ms
% 3600000 / 60000,
838 (unsigned int)(ms
% 60000) / 1000);
840 lcd_puts_scroll(0, 3, global_temp_buffer
);
843 lcd_puts_scroll(0, 4, str(LANG_BOOKMARK_SELECT_PLAY
));
844 lcd_puts_scroll(0, 5, str(LANG_BOOKMARK_SELECT_EXIT
));
845 lcd_puts_scroll(0, 6, str(LANG_BOOKMARK_SELECT_DELETE
));
848 len
=strlen(global_filename
);
850 dot
=strrchr(global_filename
+len
-4,'.');
857 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
858 "%2d, %ld:%02ld, %s,",
866 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
867 "%2d, %ld:%02ld:%02ld, %s,",
870 ms
% 3600000 / 60000,
876 lcd_puts_scroll(0,0,global_temp_buffer
);
877 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
885 /* ----------------------------------------------------------------------- */
886 /* This function parses a bookmark, says the voice UI part of it. */
887 /* ------------------------------------------------------------------------*/
888 static void say_bookmark(const char* bookmark
,
894 bool enqueue
= false; /* only the first voice is not queued */
896 parse_bookmark(bookmark
,
902 /* disabled, because transition between talkbox and voice UI clip is not nice */
904 if (global_settings
.talk_dir
>= 3)
905 { /* "talkbox" enabled */
906 char* last
= strrchr(dir
, '/');
908 { /* compose filename for talkbox */
909 strncpy(last
+ 1, dir_thumbnail_name
, sizeof(dir
)-(last
-dir
)-1);
910 talk_file(dir
, enqueue
);
915 talk_id(VOICE_EXT_BMARK
, enqueue
);
916 talk_number(bookmark_id
+ 1, true);
917 talk_id(LANG_BOOKMARK_SELECT_INDEX_TEXT
, true);
918 talk_number(resume_index
+ 1, true);
919 talk_id(LANG_BOOKMARK_SELECT_TIME_TEXT
, true);
921 talk_value(ms
/ 60000, UNIT_MIN
, true);
922 talk_value((ms
% 60000) / 1000, UNIT_SEC
, true);
926 /* ----------------------------------------------------------------------- */
927 /* This function retrieves a given bookmark from a file. */
928 /* If the bookmark requested is beyond the number of bookmarks available */
929 /* in the file, it will return the last one. */
930 /* It also returns the index number of the bookmark in the file */
931 /* ------------------------------------------------------------------------*/
932 static char* get_bookmark(const char* bookmark_file
, int bookmark_count
)
936 int file
= open(bookmark_file
, O_RDONLY
);
941 if (bookmark_count
< 0)
944 /* Get the requested bookmark */
945 while (read_count
< bookmark_count
)
947 /*Reading in a single bookmark */
948 result
= read_line(file
,
950 sizeof(global_read_buffer
));
952 /* Reading past the last bookmark in the file
953 causes the loop to stop */
961 if (read_count
== bookmark_count
)
962 return global_read_buffer
;
967 /* ----------------------------------------------------------------------- */
968 /* This function takes a bookmark and parses it. This function also */
969 /* validates the bookmark. Passing in NULL for an output variable */
970 /* indicates that value is not requested. */
971 /* ----------------------------------------------------------------------- */
972 static bool parse_bookmark(const char *bookmark
,
976 int *resume_first_index
,
978 unsigned int resume_file_size
,
980 int * repeat_mode
, bool *shuffle
,
983 /* First check to see if a valid line was passed in. */
984 int bookmark_len
= strlen(bookmark
);
985 int local_resume_index
= 0;
986 int local_resume_offset
= 0;
987 int local_resume_seed
= 0;
988 int local_resume_first_index
= 0;
990 int local_shuffle
= 0;
991 int local_repeat_mode
= 0;
992 char* local_resume_file
= NULL
;
993 char* local_file_name
= NULL
;
996 static char bookmarkcopy
[MAX_BOOKMARK_SIZE
];
998 /* Don't do anything if the bookmark length is 0 */
999 if (bookmark_len
<= 0)
1002 /* Making a dup of the bookmark to use with strtok_r */
1003 strncpy(bookmarkcopy
, bookmark
, sizeof(bookmarkcopy
));
1004 bookmarkcopy
[sizeof(bookmarkcopy
) - 1] = 0;
1007 if ((field
= strtok_r(bookmarkcopy
, ";", &end
)))
1008 local_resume_index
= atoi(field
);
1013 if ((field
= strtok_r(NULL
, ";", &end
)))
1014 local_resume_offset
= atoi(field
);
1019 if ((field
= strtok_r(NULL
, ";", &end
)))
1020 local_resume_seed
= atoi(field
);
1024 /* resume_first_index */
1025 if ((field
= strtok_r(NULL
, ";", &end
)))
1026 local_resume_first_index
= atoi(field
);
1030 /* Milliseconds into MP3. Used for the bookmark select menu */
1031 if ((field
= strtok_r(NULL
, ";", &end
)))
1032 local_mS
= atoi(field
);
1037 if ((field
= strtok_r(NULL
, ";", &end
)))
1038 local_repeat_mode
= atoi(field
);
1043 if ((field
= strtok_r(NULL
, ";", &end
)))
1044 local_shuffle
= atoi(field
);
1048 /* resume_file & file_name (for the bookmark select menu)*/
1051 local_resume_file
= strtok_r(NULL
, ";", &end
);
1054 local_file_name
= strtok_r(NULL
, ";", &end
);
1059 /* Only return the values the calling function wants */
1061 *resume_index
= local_resume_index
;
1064 *resume_offset
= local_resume_offset
;
1067 *resume_seed
= local_resume_seed
;
1069 if (resume_first_index
)
1070 *resume_first_index
= local_resume_first_index
;
1072 if (resume_file
&& local_resume_file
)
1074 strncpy(resume_file
, local_resume_file
,
1075 MIN(strlen(local_resume_file
), resume_file_size
-1));
1076 resume_file
[MIN(strlen(local_resume_file
), resume_file_size
-1)]=0;
1083 *shuffle
= local_shuffle
;
1086 *repeat_mode
= local_repeat_mode
;
1088 if (file_name
&& local_file_name
)
1090 strncpy(file_name
, local_file_name
,MAX_PATH
-1);
1091 file_name
[MAX_PATH
-1] = 0;
1097 /* ----------------------------------------------------------------------- */
1098 /* This function is used by multiple functions and is used to generate a */
1099 /* bookmark named based off of the input. */
1100 /* Changing this function could result in how the bookmarks are stored. */
1101 /* it would be here that the centralized/decentralized bookmark code */
1102 /* could be placed. */
1103 /* ----------------------------------------------------------------------- */
1104 static bool generate_bookmark_file_name(const char *in
)
1106 int len
= strlen(in
);
1108 /* if this is a root dir MP3, rename the bookmark file root_dir.bmark */
1109 /* otherwise, name it based on the in variable */
1110 if (!strcmp("/", in
))
1111 strcpy(global_bookmark_file_name
, "/root_dir.bmark");
1114 strcpy(global_bookmark_file_name
, in
);
1115 if(global_bookmark_file_name
[len
-1] == '/')
1117 strcpy(&global_bookmark_file_name
[len
], ".bmark");
1123 /* ----------------------------------------------------------------------- */
1124 /* Returns the bookmark name for the current playlist */
1125 /* ----------------------------------------------------------------------- */
1126 bool bookmark_exist(void)
1132 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
1133 sizeof(global_temp_buffer
));
1134 if (generate_bookmark_file_name(name
))
1136 int fd
=open(global_bookmark_file_name
, O_RDONLY
);
1148 /* ----------------------------------------------------------------------- */
1149 /* Checks the current state of the system and returns if it is in a */
1150 /* bookmarkable state. */
1151 /* ----------------------------------------------------------------------- */
1153 /* ----------------------------------------------------------------------- */
1155 /* return bool: Indicates if the system was in a bookmarkable state */
1156 /* ----------------------------------------------------------------------- */
1157 static bool system_check(void)
1159 int resume_index
= 0;
1160 struct mp3entry
*id3
= audio_current_track();
1164 /* no track playing */
1168 /* Checking to see if playing a queued track */
1169 if (playlist_get_resume_info(&resume_index
) == -1)
1171 /* something bad happened while getting the queue information */
1174 else if (playlist_modified(NULL
))
1176 /* can't bookmark while in the queue */