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"
58 #define MAX_BOOKMARKS 10
59 #define MAX_BOOKMARK_SIZE 350
60 #define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark"
62 static bool add_bookmark(const char* bookmark_file_name
, const char* bookmark
,
64 static bool check_bookmark(const char* bookmark
);
65 static char* create_bookmark(void);
66 static bool delete_bookmark(const char* bookmark_file_name
, int bookmark_id
);
67 static void display_bookmark(const char* bookmark
,
70 static void say_bookmark(const char* bookmark
,
72 static bool play_bookmark(const char* bookmark
);
73 static bool generate_bookmark_file_name(const char *in
);
74 static char* get_bookmark(const char* bookmark_file
, int bookmark_count
);
75 static const char* skip_token(const char* s
);
76 static const char* int_token(const char* s
, int* dest
);
77 static const char* long_token(const char* s
, long* dest
);
78 static const char* bool_token(const char* s
, bool* dest
);
79 static bool parse_bookmark(const char *bookmark
,
83 int *resume_first_index
,
85 unsigned int resume_file_size
,
90 static char* select_bookmark(const char* bookmark_file_name
);
91 static bool system_check(void);
92 static bool write_bookmark(bool create_bookmark_file
);
93 static int get_bookmark_count(const char* bookmark_file_name
);
95 static char global_temp_buffer
[MAX_PATH
+1];
96 static char global_bookmark_file_name
[MAX_PATH
];
97 static char global_read_buffer
[MAX_BOOKMARK_SIZE
];
98 static char global_bookmark
[MAX_BOOKMARK_SIZE
];
99 static char global_filename
[MAX_PATH
];
101 /* ----------------------------------------------------------------------- */
102 /* This is the interface function from the main menu. */
103 /* ----------------------------------------------------------------------- */
104 bool bookmark_create_menu(void)
106 write_bookmark(true);
110 /* ----------------------------------------------------------------------- */
111 /* This function acts as the load interface from the main menu */
112 /* This function determines the bookmark file name and then loads that file*/
113 /* for the user. The user can then select a bookmark to load. */
114 /* If no file/directory is currently playing, the menu item does not work. */
115 /* ----------------------------------------------------------------------- */
116 bool bookmark_load_menu(void)
120 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
121 sizeof(global_temp_buffer
));
122 if (generate_bookmark_file_name(name
))
124 char* bookmark
= select_bookmark(global_bookmark_file_name
);
126 if (bookmark
!= NULL
)
128 return play_bookmark(bookmark
);
136 /* ----------------------------------------------------------------------- */
137 /* Gives the user a list of the Most Recent Bookmarks. This is an */
138 /* interface function */
139 /* ----------------------------------------------------------------------- */
140 bool bookmark_mrb_load()
142 char* bookmark
= select_bookmark(RECENT_BOOKMARK_FILE
);
144 if (bookmark
!= NULL
)
146 return play_bookmark(bookmark
);
152 /* ----------------------------------------------------------------------- */
153 /* This function handles an autobookmark creation. This is an interface */
155 /* ----------------------------------------------------------------------- */
156 bool bookmark_autobookmark(void)
161 audio_pause(); /* first pause playback */
162 switch (global_settings
.autocreatebookmark
)
165 return write_bookmark(true);
170 case BOOKMARK_RECENT_ONLY_YES
:
171 return write_bookmark(false);
173 #ifdef HAVE_LCD_BITMAP
174 unsigned char *lines
[]={str(LANG_AUTO_BOOKMARK_QUERY
)};
175 struct text_message message
={(char **)lines
, 1};
177 unsigned char *lines
[]={str(LANG_AUTO_BOOKMARK_QUERY
),
178 str(LANG_RESUME_CONFIRM_PLAYER
)};
179 struct text_message message
={(char **)lines
, 2};
182 show_main_backdrop(); /* switch to main backdrop as we may come from wps */
184 gui_syncstatusbar_draw(&statusbars
, false);
185 if(gui_syncyesno_run(&message
, NULL
, NULL
)==YESNO_YES
)
187 if (global_settings
.autocreatebookmark
== BOOKMARK_RECENT_ONLY_ASK
)
188 return write_bookmark(false);
190 return write_bookmark(true);
195 /* ----------------------------------------------------------------------- */
196 /* This function takes the current current resume information and writes */
197 /* that to the beginning of the bookmark file. */
198 /* This file will contain N number of bookmarks in the following format: */
199 /* resume_index*resume_offset*resume_seed*resume_first_index* */
200 /* resume_file*milliseconds*MP3 Title* */
201 /* ------------------------------------------------------------------------*/
202 static bool write_bookmark(bool create_bookmark_file
)
208 return false; /* something didn't happen correctly, do nothing */
210 bookmark
= create_bookmark();
212 return false; /* something didn't happen correctly, do nothing */
214 if (global_settings
.usemrb
)
215 success
= add_bookmark(RECENT_BOOKMARK_FILE
, bookmark
, true);
218 /* writing the bookmark */
219 if (create_bookmark_file
)
221 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
222 sizeof(global_temp_buffer
));
223 if (generate_bookmark_file_name(name
))
225 success
= add_bookmark(global_bookmark_file_name
, bookmark
, false);
229 gui_syncsplash(HZ
, str(success
? LANG_BOOKMARK_CREATE_SUCCESS
230 : LANG_BOOKMARK_CREATE_FAILURE
));
235 /* ----------------------------------------------------------------------- */
236 /* This function adds a bookmark to a file. */
237 /* ------------------------------------------------------------------------*/
238 static bool add_bookmark(const char* bookmark_file_name
, const char* bookmark
,
241 int temp_bookmark_file
= 0;
242 int bookmark_file
= 0;
243 int bookmark_count
= 0;
244 char* playlist
= NULL
;
250 /* Opening up a temp bookmark file */
251 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
252 "%s.tmp", bookmark_file_name
);
253 temp_bookmark_file
= open(global_temp_buffer
,
254 O_WRONLY
| O_CREAT
| O_TRUNC
);
255 if (temp_bookmark_file
< 0)
256 return false; /* can't open the temp file */
258 if (most_recent
&& (global_settings
.usemrb
== BOOKMARK_UNIQUE_ONLY
))
260 playlist
= strchr(bookmark
,'/');
261 cp
= strrchr(bookmark
,';');
266 /* Writing the new bookmark to the begining of the temp file */
267 write(temp_bookmark_file
, bookmark
, strlen(bookmark
));
268 write(temp_bookmark_file
, "\n", 1);
271 /* Reading in the previous bookmarks and writing them to the temp file */
272 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
273 if (bookmark_file
>= 0)
275 while (read_line(bookmark_file
, global_read_buffer
,
276 sizeof(global_read_buffer
)) > 0)
278 /* The MRB has a max of MAX_BOOKMARKS in it */
279 /* This keeps it from getting too large */
280 if (most_recent
&& (bookmark_count
>= MAX_BOOKMARKS
))
283 cp
= strchr(global_read_buffer
,'/');
284 tmp
= strrchr(global_read_buffer
,';');
285 if (check_bookmark(global_read_buffer
) &&
286 (!unique
|| len
!= tmp
-cp
|| strncmp(playlist
,cp
,len
)))
289 write(temp_bookmark_file
, global_read_buffer
,
290 strlen(global_read_buffer
));
291 write(temp_bookmark_file
, "\n", 1);
294 close(bookmark_file
);
296 close(temp_bookmark_file
);
298 remove(bookmark_file_name
);
299 rename(global_temp_buffer
, bookmark_file_name
);
305 /* ----------------------------------------------------------------------- */
306 /* This function takes the system resume data and formats it into a valid */
308 /* ----------------------------------------------------------------------- */
309 static char* create_bookmark()
311 int resume_index
= 0;
314 /* grab the currently playing track */
315 struct mp3entry
*id3
= audio_current_track();
319 /* Get some basic resume information */
320 /* queue_resume and queue_resume_index are not used and can be ignored.*/
321 playlist_get_resume_info(&resume_index
);
323 /* Get the currently playing file minus the path */
324 /* This is used when displaying the available bookmarks */
325 file
= strrchr(id3
->path
,'/');
329 /* create the bookmark */
330 snprintf(global_bookmark
, sizeof(global_bookmark
),
331 "%d;%ld;%d;%d;%ld;%d;%d;%s;%s",
334 playlist_get_seed(NULL
),
337 global_settings
.repeat_mode
,
338 global_settings
.playlist_shuffle
,
339 playlist_get_name(NULL
, global_temp_buffer
,
340 sizeof(global_temp_buffer
)),
343 /* checking to see if the bookmark is valid */
344 if (check_bookmark(global_bookmark
))
345 return global_bookmark
;
350 static bool check_bookmark(const char* bookmark
)
352 return parse_bookmark(bookmark
,
353 NULL
,NULL
,NULL
, NULL
,
358 /* ----------------------------------------------------------------------- */
359 /* This function will determine if an autoload is necessary. This is an */
360 /* interface function. */
361 /* ------------------------------------------------------------------------*/
362 bool bookmark_autoload(const char* file
)
368 if(global_settings
.autoloadbookmark
== BOOKMARK_NO
)
371 /*Checking to see if a bookmark file exists.*/
372 if(!generate_bookmark_file_name(file
))
376 fd
= open(global_bookmark_file_name
, O_RDONLY
);
380 if(global_settings
.autoloadbookmark
== BOOKMARK_YES
)
382 return bookmark_load(global_bookmark_file_name
, true);
386 /* Prompting user to confirm bookmark load */
388 screens
[i
].clear_display();
390 gui_syncstatusbar_draw(&statusbars
, false);
394 #ifdef HAVE_LCD_BITMAP
395 screens
[i
].setmargins(0, STATUSBAR_HEIGHT
);
396 screens
[i
].puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
397 screens
[i
].puts(0,1, str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
398 screens
[i
].puts(0,2, str(LANG_BOOKMARK_SELECT_LIST_BOOKMARKS
));
399 screens
[i
].puts(0,3, str(LANG_CANCEL_WITH_ANY_RECORDER
));
402 screens
[i
].puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY
));
403 screens
[i
].puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
407 /* Wait for a key to be pushed */
408 key
= get_action(CONTEXT_BOOKMARKSCREEN
,TIMEOUT_BLOCK
);
411 #ifdef HAVE_LCD_BITMAP
412 case ACTION_STD_NEXT
:
413 action_signalscreenchange();
414 return bookmark_load(global_bookmark_file_name
, false);
416 case ACTION_BMS_SELECT
:
417 action_signalscreenchange();
418 return bookmark_load(global_bookmark_file_name
, true);
424 action_signalscreenchange();
429 /* ----------------------------------------------------------------------- */
430 /* This function loads the bookmark information into the resume memory. */
431 /* This is an interface function. */
432 /* ------------------------------------------------------------------------*/
433 bool bookmark_load(const char* file
, bool autoload
)
436 char* bookmark
= NULL
;;
440 fd
= open(file
, O_RDONLY
);
443 if(read_line(fd
, global_read_buffer
, sizeof(global_read_buffer
)) > 0)
444 bookmark
=global_read_buffer
;
450 /* This is not an auto-load, so list the bookmarks */
451 bookmark
= select_bookmark(file
);
454 if (bookmark
!= NULL
)
456 return play_bookmark(bookmark
);
463 static int get_bookmark_count(const char* bookmark_file_name
)
466 int file
= open(bookmark_file_name
, O_RDONLY
);
471 /* Get the requested bookmark */
472 while(read_line(file
, global_read_buffer
, sizeof(global_read_buffer
)) > 0)
483 /* ----------------------------------------------------------------------- */
484 /* This displays a the bookmarks in a file and allows the user to */
485 /* select one to play. */
486 /* ------------------------------------------------------------------------*/
487 static char* select_bookmark(const char* bookmark_file_name
)
490 int bookmark_id_prev
= -1;
492 char* bookmark
= NULL
;
493 int bookmark_count
= 0;
495 #ifdef HAVE_LCD_BITMAP
499 screens
[i
].setmargins(0, global_settings
.statusbar
500 ? STATUSBAR_HEIGHT
: 0);
503 bookmark_count
= get_bookmark_count(bookmark_file_name
);
504 action_signalscreenchange();
508 bookmark_id
= bookmark_count
-1;
509 if(bookmark_id
>= bookmark_count
)
512 if (bookmark_id
!= bookmark_id_prev
)
514 bookmark
= get_bookmark(bookmark_file_name
, bookmark_id
);
515 bookmark_id_prev
= bookmark_id
;
520 /* if there were no bookmarks in the file, delete the file and exit. */
523 gui_syncsplash(HZ
, str(LANG_BOOKMARK_LOAD_EMPTY
));
524 remove(bookmark_file_name
);
525 action_signalscreenchange();
530 bookmark_id_prev
= bookmark_id
;
537 display_bookmark(bookmark
, bookmark_id
, bookmark_count
);
538 if (global_settings
.talk_menu
) /* for voice UI */
539 say_bookmark(bookmark
, bookmark_id
);
542 /* waiting for the user to click a button */
543 key
= get_action(CONTEXT_BOOKMARKSCREEN
,TIMEOUT_BLOCK
);
546 case ACTION_BMS_SELECT
:
547 /* User wants to use this bookmark */
548 action_signalscreenchange();
551 case ACTION_BMS_DELETE
:
552 /* User wants to delete this bookmark */
553 delete_bookmark(bookmark_file_name
, bookmark_id
);
556 if(bookmark_id
>= bookmark_count
)
557 bookmark_id
= bookmark_count
-1;
560 case ACTION_STD_PREV
:
561 case ACTION_STD_PREVREPEAT
:
565 case ACTION_STD_NEXT
:
566 case ACTION_STD_NEXTREPEAT
:
570 case ACTION_BMS_EXIT
:
571 action_signalscreenchange();
575 if(default_event_handler(key
) == SYS_USB_CONNECTED
)
577 action_signalscreenchange();
583 action_signalscreenchange();
588 /* ----------------------------------------------------------------------- */
589 /* This function takes a location in a bookmark file and deletes that */
591 /* ------------------------------------------------------------------------*/
592 static bool delete_bookmark(const char* bookmark_file_name
, int bookmark_id
)
594 int temp_bookmark_file
= 0;
595 int bookmark_file
= 0;
596 int bookmark_count
= 0;
598 /* Opening up a temp bookmark file */
599 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
600 "%s.tmp", bookmark_file_name
);
601 temp_bookmark_file
= open(global_temp_buffer
,
602 O_WRONLY
| O_CREAT
| O_TRUNC
);
604 if (temp_bookmark_file
< 0)
605 return false; /* can't open the temp file */
607 /* Reading in the previous bookmarks and writing them to the temp file */
608 bookmark_file
= open(bookmark_file_name
, O_RDONLY
);
609 if (bookmark_file
>= 0)
611 while (read_line(bookmark_file
, global_read_buffer
,
612 sizeof(global_read_buffer
)) > 0)
614 if (bookmark_id
!= bookmark_count
)
616 write(temp_bookmark_file
, global_read_buffer
,
617 strlen(global_read_buffer
));
618 write(temp_bookmark_file
, "\n", 1);
622 close(bookmark_file
);
624 close(temp_bookmark_file
);
626 remove(bookmark_file_name
);
627 rename(global_temp_buffer
, bookmark_file_name
);
632 /* ----------------------------------------------------------------------- */
633 /* This function parses a bookmark and displays it for the user. */
634 /* ------------------------------------------------------------------------*/
635 static void display_bookmark(const char* bookmark
,
639 int resume_index
= 0;
642 bool playlist_shuffle
= false;
647 /* getting the index and the time into the file */
648 parse_bookmark(bookmark
,
649 &resume_index
, NULL
, NULL
, NULL
, NULL
, 0,
650 &ms
, &repeat_mode
, &playlist_shuffle
,
654 screens
[i
].clear_display();
656 #ifdef HAVE_LCD_BITMAP
657 /* bookmark shuffle and repeat states*/
660 #ifdef AB_REPEAT_ENABLE
662 statusbar_icon_play_mode(Icon_RepeatAB
);
667 statusbar_icon_play_mode(Icon_RepeatOne
);
671 statusbar_icon_play_mode(Icon_Repeat
);
675 statusbar_icon_shuffle();
678 dot
= strrchr(global_filename
, '.');
684 screens
[i
].puts_scroll(0, 0, (unsigned char *)global_filename
);
689 /* bookmark number */
690 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %d/%d",
691 str(LANG_BOOKMARK_SELECT_BOOKMARK_TEXT
),
692 bookmark_id
+ 1, bookmark_count
);
694 screens
[i
].puts_scroll(0, 1, (unsigned char *)global_temp_buffer
);
696 /* bookmark resume index */
697 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %d",
698 str(LANG_BOOKMARK_SELECT_INDEX_TEXT
), resume_index
+1);
700 screens
[i
].puts_scroll(0, 2, (unsigned char *)global_temp_buffer
);
703 format_time(time_buf
, sizeof(time_buf
), ms
);
704 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
), "%s: %s",
705 str(LANG_BOOKMARK_SELECT_TIME_TEXT
), time_buf
);
707 screens
[i
].puts_scroll(0, 3, (unsigned char *)global_temp_buffer
);
712 screens
[i
].puts_scroll(0, 4, str(LANG_BOOKMARK_SELECT_PLAY
));
713 screens
[i
].puts_scroll(0, 5, str(LANG_BOOKMARK_SELECT_EXIT
));
714 screens
[i
].puts_scroll(0, 6, str(LANG_BOOKMARK_SELECT_DELETE
));
718 dot
= strrchr(global_filename
, '.');
723 format_time(time_buf
, sizeof(time_buf
), ms
);
724 snprintf(global_temp_buffer
, sizeof(global_temp_buffer
),
725 "%d/%d, %s, %s", (bookmark_id
+ 1), bookmark_count
,
726 time_buf
, global_filename
);
731 gui_syncstatusbar_draw(&statusbars
, false);
735 screens
[i
].puts_scroll(0,0,global_temp_buffer
);
736 screens
[i
].puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER
));
742 /* ----------------------------------------------------------------------- */
743 /* This function parses a bookmark, says the voice UI part of it. */
744 /* ------------------------------------------------------------------------*/
745 static void say_bookmark(const char* bookmark
,
751 bool enqueue
= false; /* only the first voice is not queued */
753 parse_bookmark(bookmark
,
759 /* disabled, because transition between talkbox and voice UI clip is not nice */
761 if (global_settings
.talk_dir
>= 3)
762 { /* "talkbox" enabled */
763 char* last
= strrchr(dir
, '/');
765 { /* compose filename for talkbox */
766 strncpy(last
+ 1, dir_thumbnail_name
, sizeof(dir
)-(last
-dir
)-1);
767 talk_file(dir
, enqueue
);
772 talk_id(VOICE_EXT_BMARK
, enqueue
);
773 talk_number(bookmark_id
+ 1, true);
774 talk_id(LANG_BOOKMARK_SELECT_INDEX_TEXT
, true);
775 talk_number(resume_index
+ 1, true);
776 talk_id(LANG_BOOKMARK_SELECT_TIME_TEXT
, true);
778 talk_value(ms
/ 60000, UNIT_MIN
, true);
779 talk_value((ms
% 60000) / 1000, UNIT_SEC
, true);
782 /* ----------------------------------------------------------------------- */
783 /* This function parses a bookmark and then plays it. */
784 /* ------------------------------------------------------------------------*/
785 static bool play_bookmark(const char* bookmark
)
791 if (parse_bookmark(bookmark
,
797 sizeof(global_temp_buffer
),
799 &global_settings
.repeat_mode
,
800 &global_settings
.playlist_shuffle
,
803 bookmark_play(global_temp_buffer
, index
, offset
, seed
,
811 /* ----------------------------------------------------------------------- */
812 /* This function retrieves a given bookmark from a file. */
813 /* If the bookmark requested is beyond the number of bookmarks available */
814 /* in the file, it will return the last one. */
815 /* It also returns the index number of the bookmark in the file */
816 /* ------------------------------------------------------------------------*/
817 static char* get_bookmark(const char* bookmark_file
, int bookmark_count
)
821 int file
= open(bookmark_file
, O_RDONLY
);
826 /* Get the requested bookmark */
827 while (read_count
< bookmark_count
)
829 /*Reading in a single bookmark */
830 result
= read_line(file
,
832 sizeof(global_read_buffer
));
834 /* Reading past the last bookmark in the file
835 causes the loop to stop */
843 if ((read_count
>= 0) && (read_count
== bookmark_count
))
844 return global_read_buffer
;
849 static const char* skip_token(const char* s
)
851 while (*s
&& *s
!= ';')
864 static const char* int_token(const char* s
, int* dest
)
871 return skip_token(s
);
874 static const char* long_token(const char* s
, long* dest
)
878 *dest
= atoi(s
); /* Should be atol, but we don't have it. */
881 return skip_token(s
);
884 static const char* bool_token(const char* s
, bool* dest
)
888 *dest
= atoi(s
) != 0;
891 return skip_token(s
);
894 /* ----------------------------------------------------------------------- */
895 /* This function takes a bookmark and parses it. This function also */
896 /* validates the bookmark. Passing in NULL for an output variable */
897 /* indicates that value is not requested. */
898 /* ----------------------------------------------------------------------- */
899 static bool parse_bookmark(const char *bookmark
,
903 int *resume_first_index
,
905 unsigned int resume_file_size
,
907 int * repeat_mode
, bool *shuffle
,
910 const char* s
= bookmark
;
913 s
= int_token(s
, resume_index
);
914 s
= int_token(s
, resume_offset
);
915 s
= int_token(s
, resume_seed
);
916 s
= int_token(s
, resume_first_index
);
917 s
= long_token(s
, ms
);
918 s
= int_token(s
, repeat_mode
);
919 s
= bool_token(s
, shuffle
);
926 end
= strchr(s
, ';');
928 if (resume_file
!= NULL
)
930 size_t len
= (end
== NULL
) ? strlen(s
) : (size_t) (end
- s
);
932 len
= MIN(resume_file_size
- 1, len
);
933 strncpy(resume_file
, s
, len
);
934 resume_file
[len
] = 0;
937 if (end
!= NULL
&& file_name
!= NULL
)
940 strncpy(file_name
, end
, MAX_PATH
- 1);
941 file_name
[MAX_PATH
- 1] = 0;
947 /* ----------------------------------------------------------------------- */
948 /* This function is used by multiple functions and is used to generate a */
949 /* bookmark named based off of the input. */
950 /* Changing this function could result in how the bookmarks are stored. */
951 /* it would be here that the centralized/decentralized bookmark code */
952 /* could be placed. */
953 /* ----------------------------------------------------------------------- */
954 static bool generate_bookmark_file_name(const char *in
)
956 int len
= strlen(in
);
958 /* if this is a root dir MP3, rename the bookmark file root_dir.bmark */
959 /* otherwise, name it based on the in variable */
960 if (!strcmp("/", in
))
961 strcpy(global_bookmark_file_name
, "/root_dir.bmark");
964 strcpy(global_bookmark_file_name
, in
);
965 if(global_bookmark_file_name
[len
-1] == '/')
967 strcpy(&global_bookmark_file_name
[len
], ".bmark");
973 /* ----------------------------------------------------------------------- */
974 /* Returns true if a bookmark file exists for the current playlist */
975 /* ----------------------------------------------------------------------- */
976 bool bookmark_exist(void)
982 char* name
= playlist_get_name(NULL
, global_temp_buffer
,
983 sizeof(global_temp_buffer
));
984 if (generate_bookmark_file_name(name
))
986 int fd
=open(global_bookmark_file_name
, O_RDONLY
);
998 /* ----------------------------------------------------------------------- */
999 /* Checks the current state of the system and returns if it is in a */
1000 /* bookmarkable state. */
1001 /* ----------------------------------------------------------------------- */
1003 /* ----------------------------------------------------------------------- */
1005 /* return bool: Indicates if the system was in a bookmarkable state */
1006 /* ----------------------------------------------------------------------- */
1007 static bool system_check(void)
1009 int resume_index
= 0;
1010 struct mp3entry
*id3
= audio_current_track();
1014 /* no track playing */
1018 /* Checking to see if playing a queued track */
1019 if (playlist_get_resume_info(&resume_index
) == -1)
1021 /* something bad happened while getting the queue information */
1024 else if (playlist_modified(NULL
))
1026 /* can't bookmark while in the queue */