summaryrefslogtreecommitdiff
path: root/apps/bookmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/bookmark.c')
-rw-r--r--apps/bookmark.c553
1 files changed, 278 insertions, 275 deletions
diff --git a/apps/bookmark.c b/apps/bookmark.c
index a878dedb13..e466ae944d 100644
--- a/apps/bookmark.c
+++ b/apps/bookmark.c
@@ -16,7 +16,6 @@
16 * 16 *
17 ****************************************************************************/ 17 ****************************************************************************/
18 18
19
20#include <stdio.h> 19#include <stdio.h>
21#include <stdlib.h> 20#include <stdlib.h>
22#include <string.h> 21#include <string.h>
@@ -50,6 +49,8 @@
50#include "abrepeat.h" 49#include "abrepeat.h"
51#include "splash.h" 50#include "splash.h"
52#include "yesno.h" 51#include "yesno.h"
52#include "list.h"
53#include "plugin.h"
53 54
54#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) 55#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
55#include "backdrop.h" 56#include "backdrop.h"
@@ -59,19 +60,28 @@
59#define MAX_BOOKMARK_SIZE 350 60#define MAX_BOOKMARK_SIZE 350
60#define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark" 61#define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark"
61 62
63/* Used to buffer bookmarks while displaying the bookmark list. */
64struct bookmark_list
65{
66 const char* filename;
67 size_t buffer_size;
68 int start;
69 int count;
70 int total_count;
71 bool show_dont_resume;
72 bool reload;
73 char* items[];
74};
75
62static bool add_bookmark(const char* bookmark_file_name, const char* bookmark, 76static bool add_bookmark(const char* bookmark_file_name, const char* bookmark,
63 bool most_recent); 77 bool most_recent);
64static bool check_bookmark(const char* bookmark); 78static bool check_bookmark(const char* bookmark);
65static char* create_bookmark(void); 79static char* create_bookmark(void);
66static bool delete_bookmark(const char* bookmark_file_name, int bookmark_id); 80static bool delete_bookmark(const char* bookmark_file_name, int bookmark_id);
67static void display_bookmark(const char* bookmark,
68 int bookmark_id,
69 int bookmark_count);
70static void say_bookmark(const char* bookmark, 81static void say_bookmark(const char* bookmark,
71 int bookmark_id); 82 int bookmark_id);
72static bool play_bookmark(const char* bookmark); 83static bool play_bookmark(const char* bookmark);
73static bool generate_bookmark_file_name(const char *in); 84static bool generate_bookmark_file_name(const char *in);
74static char* get_bookmark(const char* bookmark_file, int bookmark_count);
75static const char* skip_token(const char* s); 85static const char* skip_token(const char* s);
76static const char* int_token(const char* s, int* dest); 86static const char* int_token(const char* s, int* dest);
77static const char* long_token(const char* s, long* dest); 87static const char* long_token(const char* s, long* dest);
@@ -87,15 +97,20 @@ static bool parse_bookmark(const char *bookmark,
87 int * repeat_mode, 97 int * repeat_mode,
88 bool *shuffle, 98 bool *shuffle,
89 char* file_name); 99 char* file_name);
90static char* select_bookmark(const char* bookmark_file_name); 100static int buffer_bookmarks(struct bookmark_list* bookmarks, int first_line);
101static char* get_bookmark_info(int list_index, void* data, char *buffer);
102static char* select_bookmark(const char* bookmark_file_name, bool show_dont_resume);
91static bool system_check(void); 103static bool system_check(void);
92static bool write_bookmark(bool create_bookmark_file); 104static bool write_bookmark(bool create_bookmark_file);
93static int get_bookmark_count(const char* bookmark_file_name); 105static int get_bookmark_count(const char* bookmark_file_name);
94 106
95static char global_temp_buffer[MAX_PATH+1]; 107static char global_temp_buffer[MAX_PATH+1];
108/* File name created by generate_bookmark_file_name */
96static char global_bookmark_file_name[MAX_PATH]; 109static char global_bookmark_file_name[MAX_PATH];
97static char global_read_buffer[MAX_BOOKMARK_SIZE]; 110static char global_read_buffer[MAX_BOOKMARK_SIZE];
111/* Bookmark created by create_bookmark*/
98static char global_bookmark[MAX_BOOKMARK_SIZE]; 112static char global_bookmark[MAX_BOOKMARK_SIZE];
113/* Filename from parsed bookmark (can be made local where needed) */
99static char global_filename[MAX_PATH]; 114static char global_filename[MAX_PATH];
100 115
101/* ----------------------------------------------------------------------- */ 116/* ----------------------------------------------------------------------- */
@@ -121,7 +136,7 @@ bool bookmark_load_menu(void)
121 sizeof(global_temp_buffer)); 136 sizeof(global_temp_buffer));
122 if (generate_bookmark_file_name(name)) 137 if (generate_bookmark_file_name(name))
123 { 138 {
124 char* bookmark = select_bookmark(global_bookmark_file_name); 139 char* bookmark = select_bookmark(global_bookmark_file_name, false);
125 140
126 if (bookmark != NULL) 141 if (bookmark != NULL)
127 { 142 {
@@ -139,7 +154,7 @@ bool bookmark_load_menu(void)
139/* ----------------------------------------------------------------------- */ 154/* ----------------------------------------------------------------------- */
140bool bookmark_mrb_load() 155bool bookmark_mrb_load()
141{ 156{
142 char* bookmark = select_bookmark(RECENT_BOOKMARK_FILE); 157 char* bookmark = select_bookmark(RECENT_BOOKMARK_FILE, false);
143 158
144 if (bookmark != NULL) 159 if (bookmark != NULL)
145 { 160 {
@@ -364,9 +379,7 @@ static bool check_bookmark(const char* bookmark)
364/* ------------------------------------------------------------------------*/ 379/* ------------------------------------------------------------------------*/
365bool bookmark_autoload(const char* file) 380bool bookmark_autoload(const char* file)
366{ 381{
367 int key;
368 int fd; 382 int fd;
369 int i;
370 383
371 if(global_settings.autoloadbookmark == BOOKMARK_NO) 384 if(global_settings.autoloadbookmark == BOOKMARK_NO)
372 return false; 385 return false;
@@ -386,43 +399,11 @@ bool bookmark_autoload(const char* file)
386 } 399 }
387 else 400 else
388 { 401 {
389 /* Prompting user to confirm bookmark load */ 402 char* bookmark = select_bookmark(global_bookmark_file_name, true);
390 FOR_NB_SCREENS(i)
391 screens[i].clear_display();
392 403
393 gui_syncstatusbar_draw(&statusbars, true); 404 if (bookmark)
394
395 FOR_NB_SCREENS(i)
396 {
397#ifdef HAVE_LCD_BITMAP
398 screens[i].setmargins(0, global_settings.statusbar
399 ? STATUSBAR_HEIGHT : 0);
400 screens[i].puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY));
401 screens[i].puts(0,1, str(LANG_CONFIRM_WITH_PLAY_RECORDER));
402 screens[i].puts(0,2, str(LANG_BOOKMARK_SELECT_LIST_BOOKMARKS));
403 screens[i].puts(0,3, str(LANG_CANCEL_WITH_ANY_RECORDER));
404#else
405 screens[i].puts_scroll(0,0, str(LANG_BOOKMARK_AUTOLOAD_QUERY));
406 screens[i].puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER));
407#endif
408 screens[i].update();
409 }
410
411 /* Wait for a key to be pushed */
412 key = get_action(CONTEXT_BOOKMARKSCREEN,TIMEOUT_BLOCK);
413 switch(key)
414 { 405 {
415#ifdef HAVE_LCD_BITMAP 406 return bookmark_load(global_bookmark_file_name, true);
416 case ACTION_STD_NEXT:
417 action_signalscreenchange();
418 return bookmark_load(global_bookmark_file_name, false);
419#endif
420 case ACTION_BMS_SELECT:
421 action_signalscreenchange();
422 return bookmark_load(global_bookmark_file_name, true);
423
424 default:
425 break;
426 } 407 }
427 408
428 action_signalscreenchange(); 409 action_signalscreenchange();
@@ -452,7 +433,7 @@ bool bookmark_load(const char* file, bool autoload)
452 else 433 else
453 { 434 {
454 /* This is not an auto-load, so list the bookmarks */ 435 /* This is not an auto-load, so list the bookmarks */
455 bookmark = select_bookmark(file); 436 bookmark = select_bookmark(file, false);
456 } 437 }
457 438
458 if (bookmark != NULL) 439 if (bookmark != NULL)
@@ -480,120 +461,290 @@ static int get_bookmark_count(const char* bookmark_file_name)
480 461
481 close(file); 462 close(file);
482 return read_count; 463 return read_count;
483 464}
465
466static int buffer_bookmarks(struct bookmark_list* bookmarks, int first_line)
467{
468 char* dest = ((char*) bookmarks) + bookmarks->buffer_size - 1;
469 int read_count = 0;
470 int file = open(bookmarks->filename, O_RDONLY);
471
472 if (file < 0)
473 {
474 return -1;
475 }
476
477 if ((first_line != 0) && ((size_t) filesize(file) < bookmarks->buffer_size
478 - sizeof(*bookmarks) - (sizeof(char*) * bookmarks->total_count)))
479 {
480 /* Entire file fits in buffer */
481 first_line = 0;
482 }
483
484 bookmarks->start = first_line;
485 bookmarks->count = 0;
486 bookmarks->reload = false;
484 487
488 while(read_line(file, global_read_buffer, sizeof(global_read_buffer)) > 0)
489 {
490 read_count++;
491
492 if (read_count >= first_line)
493 {
494 dest -= strlen(global_read_buffer) + 1;
495
496 if (dest < ((char*) bookmarks) + sizeof(*bookmarks)
497 + (sizeof(char*) * (bookmarks->count + 1)))
498 {
499 break;
500 }
501
502 strcpy(dest, global_read_buffer);
503 bookmarks->items[bookmarks->count] = dest;
504 bookmarks->count++;
505 }
506 }
507
508 close(file);
509 return bookmarks->start + bookmarks->count;
485} 510}
486 511
487/* ----------------------------------------------------------------------- */ 512static char* get_bookmark_info(int list_index, void* data, char *buffer)
488/* This displays a the bookmarks in a file and allows the user to */
489/* select one to play. */
490/* ------------------------------------------------------------------------*/
491static char* select_bookmark(const char* bookmark_file_name)
492{ 513{
493 int bookmark_id = 0; 514 struct bookmark_list* bookmarks = (struct bookmark_list*) data;
494 int bookmark_id_prev = -1; 515 int index = list_index / 2;
495 int key; 516 int resume_index = 0;
496 char* bookmark = NULL; 517 long resume_time = 0;
497 int bookmark_count = 0; 518 bool shuffle = false;
498 519
499#ifdef HAVE_LCD_BITMAP 520 if (bookmarks->show_dont_resume)
500 int i; 521 {
522 if (index == 0)
523 {
524 return list_index % 2 == 0
525 ? (char*) str(LANG_BOOKMARK_DONT_RESUME) : " ";
526 }
527
528 index--;
529 }
501 530
502 FOR_NB_SCREENS(i) 531 if (bookmarks->reload || (index >= bookmarks->start + bookmarks->count)
503 screens[i].setmargins(0, global_settings.statusbar 532 || (index < bookmarks->start))
504 ? STATUSBAR_HEIGHT : 0); 533 {
505#endif 534 int read_index = index;
535
536 /* Using count as a guide on how far to move could possibly fail
537 * sometimes. Use byte count if that is a problem?
538 */
539
540 if (read_index != 0)
541 {
542 /* Move count * 3 / 4 items in the direction the user is moving,
543 * but don't go too close to the end.
544 */
545 int offset = bookmarks->count;
546 int max = bookmarks->total_count - (bookmarks->count / 2);
547
548 if (read_index < bookmarks->start)
549 {
550 offset *= 3;
551 }
552
553 read_index = index - offset / 4;
506 554
507 bookmark_count = get_bookmark_count(bookmark_file_name); 555 if (read_index > max)
508 if (bookmark_count < 1) /* error opening file, or empty file */ 556 {
557 read_index = max;
558 }
559
560 if (read_index < 0)
561 {
562 read_index = 0;
563 }
564 }
565
566 if (buffer_bookmarks(bookmarks, read_index) <= index)
567 {
568 return "";
569 }
570 }
571
572 if (!parse_bookmark(bookmarks->items[index - bookmarks->start],
573 &resume_index, NULL, NULL, NULL, NULL, 0, &resume_time, NULL,
574 &shuffle, global_filename))
509 { 575 {
510 gui_syncsplash(HZ, str(LANG_BOOKMARK_LOAD_EMPTY)); 576 return list_index % 2 == 0 ? (char*) str(LANG_BOOKMARK_INVALID) : " ";
511 return NULL;
512 } 577 }
513 action_signalscreenchange(); 578
514 while(true) 579 if (list_index % 2 == 0)
515 { 580 {
516 if(bookmark_id < 0) 581 char* dot = strrchr(global_filename, '.');
517 bookmark_id = bookmark_count -1;
518 if(bookmark_id >= bookmark_count)
519 bookmark_id = 0;
520 582
521 if (bookmark_id != bookmark_id_prev) 583 if (dot)
522 { 584 {
523 bookmark = get_bookmark(bookmark_file_name, bookmark_id); 585 *dot = '\0';
524 bookmark_id_prev = bookmark_id;
525 } 586 }
587
588 return global_filename;
589 }
590 else
591 {
592 char time_buf[32];
593
594 format_time(time_buf, sizeof(time_buf), resume_time);
595 snprintf(buffer, MAX_PATH, "%s, %d%s", time_buf, resume_index + 1,
596 shuffle ? (char*) str(LANG_BOOKMARK_SHUFFLE) : "");
597 return buffer;
598 }
599}
600
601/* ----------------------------------------------------------------------- */
602/* This displays a the bookmarks in a file and allows the user to */
603/* select one to play. */
604/* ------------------------------------------------------------------------*/
605static char* select_bookmark(const char* bookmark_file_name, bool show_dont_resume)
606{
607 struct bookmark_list* bookmarks;
608 struct gui_synclist list;
609 int last_item = -2;
610 int item = 0;
611 int action;
612 size_t size;
613 bool exit = false;
614 bool refresh = true;
615
616 bookmarks = plugin_get_buffer(&size);
617 bookmarks->buffer_size = size;
618 bookmarks->show_dont_resume = show_dont_resume;
619 bookmarks->filename = bookmark_file_name;
620 bookmarks->start = 0;
621 gui_synclist_init(&list, &get_bookmark_info, (void*) bookmarks, false, 2);
622 gui_synclist_set_title(&list, str(LANG_BOOKMARK_SELECT_BOOKMARK),
623 Icon_Bookmark);
624 gui_syncstatusbar_draw(&statusbars, true);
625 action_signalscreenchange();
626
627 while (!exit)
628 {
629 gui_syncstatusbar_draw(&statusbars, false);
526 630
527 if (!bookmark) 631 if (refresh)
528 { 632 {
529 /* if there were no bookmarks in the file, delete the file and exit. */ 633 int count = get_bookmark_count(bookmark_file_name);
530 if(bookmark_id <= 0) 634 bookmarks->total_count = count;
635
636 if (bookmarks->total_count < 1)
531 { 637 {
638 /* No more bookmarks, delete file and exit */
532 gui_syncsplash(HZ, str(LANG_BOOKMARK_LOAD_EMPTY)); 639 gui_syncsplash(HZ, str(LANG_BOOKMARK_LOAD_EMPTY));
533 remove(bookmark_file_name); 640 remove(bookmark_file_name);
534 action_signalscreenchange(); 641 action_signalscreenchange();
535 return NULL; 642 return NULL;
536 } 643 }
644
645 if (bookmarks->show_dont_resume)
646 {
647 count++;
648 item++;
649 }
650
651 gui_synclist_set_nb_items(&list, count * 2);
652
653 if (item >= count)
654 {
655 /* Selected item has been deleted */
656 item = count - 1;
657 gui_synclist_select_item(&list, item * 2);
658 }
659
660 buffer_bookmarks(bookmarks, bookmarks->start);
661 gui_synclist_draw(&list);
662 refresh = false;
663 }
664
665 action = get_action(CONTEXT_BOOKMARKSCREEN, HZ / 2);
666 gui_synclist_do_button(&list, action, LIST_WRAP_UNLESS_HELD);
667 item = gui_synclist_get_sel_pos(&list) / 2;
668
669 if (bookmarks->show_dont_resume)
670 {
671 item--;
672 }
673
674 if (item != last_item && global_settings.talk_menu)
675 {
676 last_item = item;
677
678 if (item == -1)
679 {
680 talk_id(LANG_BOOKMARK_DONT_RESUME, true);
681 }
537 else 682 else
538 { 683 {
539 bookmark_id_prev = bookmark_id; 684 say_bookmark(bookmarks->items[item - bookmarks->start], item);
540 bookmark_id--;
541 continue;
542 } 685 }
543 } 686 }
544 else 687
688 if (action == ACTION_STD_CONTEXT)
545 { 689 {
546 display_bookmark(bookmark, bookmark_id, bookmark_count); 690 MENUITEM_STRINGLIST(menu_items, ID2P(LANG_BOOKMARK_CONTEXT_MENU),
547 if (global_settings.talk_menu) /* for voice UI */ 691 NULL, ID2P(LANG_BOOKMARK_CONTEXT_RESUME),
548 say_bookmark(bookmark, bookmark_id); 692 ID2P(LANG_BOOKMARK_CONTEXT_DELETE));
693 static const int menu_actions[] =
694 {
695 ACTION_STD_OK, ACTION_BMS_DELETE
696 };
697 int selection = do_menu(&menu_items, NULL);
698
699 refresh = true;
700
701 if (selection >= 0 && selection <=
702 (int) (sizeof(menu_actions) / sizeof(menu_actions[0])))
703 {
704 action = menu_actions[selection];
705 }
549 } 706 }
550 707
551 /* waiting for the user to click a button */ 708 switch (action)
552 key = get_action(CONTEXT_BOOKMARKSCREEN,TIMEOUT_BLOCK);
553 switch(key)
554 { 709 {
555 case ACTION_BMS_SELECT: 710 case ACTION_STD_OK:
556 /* User wants to use this bookmark */ 711 if (item >= 0)
712 {
557 action_signalscreenchange(); 713 action_signalscreenchange();
558 return bookmark; 714 return bookmarks->items[item - bookmarks->start];
559 715 }
560 case ACTION_BMS_DELETE: 716
561 /* User wants to delete this bookmark */ 717 /* Else fall through */
562 delete_bookmark(bookmark_file_name, bookmark_id);
563 bookmark_id_prev=-2;
564 bookmark_count--;
565 if(bookmark_id >= bookmark_count)
566 bookmark_id = bookmark_count -1;
567 break;
568 718
569 case ACTION_STD_PREV: 719 case ACTION_TREE_WPS:
570 case ACTION_STD_PREVREPEAT: 720 case ACTION_STD_CANCEL:
571 bookmark_id--; 721 exit = true;
572 break; 722 break;
573 723
574 case ACTION_STD_NEXT: 724 case ACTION_BMS_DELETE:
575 case ACTION_STD_NEXTREPEAT: 725 if (item >= 0)
576 bookmark_id++; 726 {
577 break; 727 delete_bookmark(bookmark_file_name, item);
728 bookmarks->reload = true;
729 refresh = true;
730 last_item = -2;
731 }
732 break;
578 733
579 case ACTION_BMS_EXIT: 734 default:
580 action_signalscreenchange(); 735 if (default_event_handler(action) == SYS_USB_CONNECTED)
581 return NULL; 736 {
737 exit = true;
738 }
582 739
583 default: 740 break;
584 if(default_event_handler(key) == SYS_USB_CONNECTED)
585 {
586 action_signalscreenchange();
587 return NULL;
588 }
589 break;
590 } 741 }
591 } 742 }
743
592 action_signalscreenchange(); 744 action_signalscreenchange();
593 return NULL; 745 return NULL;
594} 746}
595 747
596
597/* ----------------------------------------------------------------------- */ 748/* ----------------------------------------------------------------------- */
598/* This function takes a location in a bookmark file and deletes that */ 749/* This function takes a location in a bookmark file and deletes that */
599/* bookmark. */ 750/* bookmark. */
@@ -639,117 +790,6 @@ static bool delete_bookmark(const char* bookmark_file_name, int bookmark_id)
639} 790}
640 791
641/* ----------------------------------------------------------------------- */ 792/* ----------------------------------------------------------------------- */
642/* This function parses a bookmark and displays it for the user. */
643/* ------------------------------------------------------------------------*/
644static void display_bookmark(const char* bookmark,
645 int bookmark_id,
646 int bookmark_count)
647{
648 int resume_index = 0;
649 long ms = 0;
650 int repeat_mode = 0;
651 bool playlist_shuffle = false;
652 char *dot;
653 char time_buf[32];
654 int i;
655
656 /* getting the index and the time into the file */
657 parse_bookmark(bookmark,
658 &resume_index, NULL, NULL, NULL, NULL, 0,
659 &ms, &repeat_mode, &playlist_shuffle,
660 global_filename);
661
662 FOR_NB_SCREENS(i)
663 screens[i].clear_display();
664
665#ifdef HAVE_LCD_BITMAP
666 /* bookmark shuffle and repeat states*/
667 switch (repeat_mode)
668 {
669#ifdef AB_REPEAT_ENABLE
670 case REPEAT_AB:
671 statusbar_icon_play_mode(Icon_RepeatAB);
672 break;
673#endif
674
675 case REPEAT_ONE:
676 statusbar_icon_play_mode(Icon_RepeatOne);
677 break;
678
679 case REPEAT_ALL:
680 statusbar_icon_play_mode(Icon_Repeat);
681 break;
682 }
683 if(playlist_shuffle)
684 statusbar_icon_shuffle();
685
686 /* File Name */
687 dot = strrchr(global_filename, '.');
688
689 if (dot)
690 *dot='\0';
691
692 FOR_NB_SCREENS(i)
693 screens[i].puts_scroll(0, 0, (unsigned char *)global_filename);
694
695 if (dot)
696 *dot='.';
697
698 /* bookmark number */
699 snprintf(global_temp_buffer, sizeof(global_temp_buffer), "%s: %d/%d",
700 str(LANG_BOOKMARK_SELECT_BOOKMARK_TEXT),
701 bookmark_id + 1, bookmark_count);
702 FOR_NB_SCREENS(i)
703 screens[i].puts_scroll(0, 1, (unsigned char *)global_temp_buffer);
704
705 /* bookmark resume index */
706 snprintf(global_temp_buffer, sizeof(global_temp_buffer), "%s: %d",
707 str(LANG_BOOKMARK_SELECT_INDEX_TEXT), resume_index+1);
708 FOR_NB_SCREENS(i)
709 screens[i].puts_scroll(0, 2, (unsigned char *)global_temp_buffer);
710
711 /* elapsed time*/
712 format_time(time_buf, sizeof(time_buf), ms);
713 snprintf(global_temp_buffer, sizeof(global_temp_buffer), "%s: %s",
714 str(LANG_BOOKMARK_SELECT_TIME_TEXT), time_buf);
715 FOR_NB_SCREENS(i)
716 screens[i].puts_scroll(0, 3, (unsigned char *)global_temp_buffer);
717
718 /* commands */
719 FOR_NB_SCREENS(i)
720 {
721 screens[i].puts_scroll(0, 4, str(LANG_BOOKMARK_SELECT_PLAY));
722 screens[i].puts_scroll(0, 5, str(LANG_BOOKMARK_SELECT_EXIT));
723 screens[i].puts_scroll(0, 6, str(LANG_BOOKMARK_SELECT_DELETE));
724 screens[i].update();
725 }
726#else
727 dot = strrchr(global_filename, '.');
728
729 if (dot)
730 *dot='\0';
731
732 format_time(time_buf, sizeof(time_buf), ms);
733 snprintf(global_temp_buffer, sizeof(global_temp_buffer),
734 "%d/%d, %s, %s", (bookmark_id + 1), bookmark_count,
735 time_buf, global_filename);
736
737 if (dot)
738 *dot='.';
739
740 gui_syncstatusbar_draw(&statusbars, false);
741
742 FOR_NB_SCREENS(i)
743 {
744 screens[i].puts_scroll(0,0,global_temp_buffer);
745 screens[i].puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER));
746 screens[i].update();
747 }
748#endif
749}
750
751
752/* ----------------------------------------------------------------------- */
753/* This function parses a bookmark, says the voice UI part of it. */ 793/* This function parses a bookmark, says the voice UI part of it. */
754/* ------------------------------------------------------------------------*/ 794/* ------------------------------------------------------------------------*/
755static void say_bookmark(const char* bookmark, 795static void say_bookmark(const char* bookmark,
@@ -760,12 +800,13 @@ static void say_bookmark(const char* bookmark,
760 char dir[MAX_PATH]; 800 char dir[MAX_PATH];
761 bool enqueue = false; /* only the first voice is not queued */ 801 bool enqueue = false; /* only the first voice is not queued */
762 802
763 parse_bookmark(bookmark, 803 if (!parse_bookmark(bookmark, &resume_index, NULL, NULL, NULL,
764 &resume_index, 804 dir, sizeof(dir), &ms, NULL, NULL, NULL))
765 NULL, NULL, NULL, 805 {
766 dir, sizeof(dir), 806 talk_id(LANG_BOOKMARK_INVALID, true);
767 &ms, NULL, NULL, 807 return;
768 NULL); 808 }
809
769/* disabled, because transition between talkbox and voice UI clip is not nice */ 810/* disabled, because transition between talkbox and voice UI clip is not nice */
770#if 0 811#if 0
771 if (global_settings.talk_dir >= 3) 812 if (global_settings.talk_dir >= 3)
@@ -818,44 +859,6 @@ static bool play_bookmark(const char* bookmark)
818 return false; 859 return false;
819} 860}
820 861
821/* ----------------------------------------------------------------------- */
822/* This function retrieves a given bookmark from a file. */
823/* If the bookmark requested is beyond the number of bookmarks available */
824/* in the file, it will return the last one. */
825/* It also returns the index number of the bookmark in the file */
826/* ------------------------------------------------------------------------*/
827static char* get_bookmark(const char* bookmark_file, int bookmark_count)
828{
829 int read_count = -1;
830 int result = 0;
831 int file = open(bookmark_file, O_RDONLY);
832
833 if (file < 0)
834 return NULL;
835
836 /* Get the requested bookmark */
837 while (read_count < bookmark_count)
838 {
839 /*Reading in a single bookmark */
840 result = read_line(file,
841 global_read_buffer,
842 sizeof(global_read_buffer));
843
844 /* Reading past the last bookmark in the file
845 causes the loop to stop */
846 if (result <= 0)
847 break;
848
849 read_count++;
850 }
851
852 close(file);
853 if ((read_count >= 0) && (read_count == bookmark_count))
854 return global_read_buffer;
855 else
856 return NULL;
857}
858
859static const char* skip_token(const char* s) 862static const char* skip_token(const char* s)
860{ 863{
861 while (*s && *s != ';') 864 while (*s && *s != ';')