1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Gilles Roux
12 * 2010 Yoshihisa Uchida
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
24 #include "tv_bookmark.h"
26 /* text viewer bookmark functions */
34 #ifndef HAVE_LCD_BITMAP
35 #define BOOKMARK_ICON "\xee\x84\x81\x00"
38 #define BOOKMARK_SIZE 8
39 #define MAX_BOOKMARKS 10 /* user setting bookmarks + last read page */
42 struct bookmark_info bookmarks
[MAX_BOOKMARKS
];
43 static int bookmark_count
;
45 static int bm_comp(const void *a
, const void *b
)
47 struct bookmark_info
*pa
;
48 struct bookmark_info
*pb
;
50 pa
= (struct bookmark_info
*)a
;
51 pb
= (struct bookmark_info
*)b
;
53 if (pa
->page
!= pb
->page
)
54 return pa
->page
- pb
->page
;
56 return pa
->line
- pb
->line
;
59 int viewer_find_bookmark(int page
, int line
)
63 for (i
= 0; i
< bookmark_count
; i
++)
65 if (bookmarks
[i
].page
== page
&& bookmarks
[i
].line
== line
)
71 void viewer_add_bookmark(int page
, int line
)
73 if (bookmark_count
>= MAX_BOOKMARKS
-1)
76 bookmarks
[bookmark_count
].file_position
77 = file_pos
+ screen_top_ptr
- buffer
;
78 bookmarks
[bookmark_count
].page
= page
;
79 bookmarks
[bookmark_count
].line
= line
;
80 bookmarks
[bookmark_count
].flag
= BOOKMARK_USER
;
84 static int viewer_add_last_read_bookmark(void)
88 i
= viewer_find_bookmark(cpage
, cline
);
90 bookmarks
[i
].flag
|= BOOKMARK_LAST
;
93 viewer_add_bookmark();
95 bookmarks
[i
].flag
= BOOKMARK_LAST
;
100 static void viewer_remove_bookmark(int i
)
104 if (i
< 0 || i
>= bookmark_count
)
107 for (j
= i
+1; j
< bookmark_count
; j
++)
108 rb
->memcpy(&bookmarks
[j
-1], &bookmarks
[j
],
109 sizeof(struct bookmark_info
));
114 void viewer_remove_last_read_bookmark(void)
118 for (i
= 0; i
< bookmark_count
; i
++)
120 if (bookmarks
[i
].flag
& BOOKMARK_LAST
)
122 if (bookmarks
[i
].flag
== BOOKMARK_LAST
)
124 for (j
= i
+1; j
< bookmark_count
; j
++)
125 rb
->memcpy(&bookmarks
[j
-1], &bookmarks
[j
],
126 sizeof(struct bookmark_info
));
131 bookmarks
[i
].flag
= BOOKMARK_USER
;
138 * the function that a bookmark add when there is not a bookmark in the given position
139 * or the bookmark remove when there exist a bookmark in the given position.
142 void viewer_add_remove_bookmark(int page
, int line
)
144 int idx
= viewer_find_bookmark(cpage
, cline
);
148 if (bookmark_count
>= MAX_BOOKMARKS
-1)
149 rb
->splash(HZ
/2, "No more add bookmark.");
152 viewer_add_bookmark(page
, line
);
153 rb
->splash(HZ
/2, "Bookmark add.");
156 viewer_remove_bookmark(idx
);
157 rb
->splash(HZ
/2, "Bookmark remove.");
160 static int viewer_get_last_read_bookmark(void)
164 for (i
= 0; i
< bookmark_count
; i
++)
166 if (bookmarks
[i
].flag
& BOOKMARK_LAST
)
172 void viewer_select_bookmark(int initval
)
181 struct opt_items items
[bookmark_count
];
182 unsigned char names
[bookmark_count
][38];
184 if (initval
>= 0 && initval
< bookmark_count
)
186 ipage
= bookmarks
[initval
].page
;
187 iline
= bookmarks
[initval
].line
;
190 rb
->qsort(bookmarks
, bookmark_count
, sizeof(struct bookmark_info
),
193 for (i
= 0; i
< bookmark_count
; i
++)
195 rb
->snprintf(names
[i
], sizeof(names
[0]),
196 #if CONFIG_KEYPAD != PLAYER_PAD
197 "%sPage: %d Line: %d",
201 (bookmarks
[i
].flag
&BOOKMARK_LAST
)? "*":" ",
204 items
[i
].string
= names
[i
];
205 items
[i
].voice_id
= -1;
206 if (selected
< 0 && bookmarks
[i
].page
== ipage
&& bookmarks
[i
].line
== iline
)
210 rb
->set_option("Select bookmark", &selected
, INT
, items
,
211 sizeof(items
) / sizeof(items
[0]), NULL
);
213 if (selected
< 0 || selected
>= bookmark_count
)
215 if (initval
< 0 || (selected
= viewer_get_last_read_bookmark()) < 0)
218 rb
->splash(HZ
, "Start the first page.");
220 screen_top_ptr
= buffer
;
223 buffer_end
= BUFFER_END();
228 screen_pos
= bookmarks
[selected
].file_position
;
229 screen_top
= screen_pos
% buffer_size
;
230 file_pos
= screen_pos
- screen_top
;
231 screen_top_ptr
= buffer
+ screen_top
;
232 cpage
= bookmarks
[selected
].page
;
233 cline
= bookmarks
[selected
].line
;
234 buffer_end
= BUFFER_END();
238 static bool viewer_read_bookmark_info(int bfd
, struct bookmark_info
*b
)
240 unsigned char buf
[BOOKMARK_SIZE
];
242 if (rb
->read(bfd
, buf
, sizeof(buf
)) != sizeof(buf
))
245 b
->file_position
= (buf
[0] << 24)|(buf
[1] << 16)|(buf
[2] << 8)|buf
[3];
246 b
->page
= (buf
[4] << 8)|buf
[5];
253 bool viewer_read_bookmark_infos(int fd
)
258 if (rb
->read(fd
, &c
, 1) != 1)
265 if (bookmark_count
> MAX_BOOKMARKS
)
266 bookmark_count
= MAX_BOOKMARKS
;
268 for (i
= 0; i
< bookmark_count
; i
++)
270 if (!viewer_read_bookmark_info(fd
, &bookmarks
[i
]))
279 static bool viewer_write_bookmark_info(int bfd
, struct bookmark_info
*b
)
281 unsigned char buf
[BOOKMARK_SIZE
];
282 unsigned char *p
= buf
;
285 ul
= b
->file_position
;
298 return (rb
->write(bfd
, buf
, sizeof(buf
)) == sizeof(buf
));
301 bool viewer_write_bookmark_infos(int fd
)
303 unsigned char c
= bookmark_count
;
306 if (rb
->write(fd
, &c
, 1) != 1)
309 for (i
= 0; i
< bookmark_count
; i
++)
311 if (!viewer_write_bookmark_info(fd
, &bookmarks
[i
]))
318 bool copy_bookmark_file(int sfd
, int dfd
, off_t start
, off_t size
)
322 if (rb
->lseek(sfd
, start
, SEEK_SET
) < 0)
327 if (size
> buffer_size
)
333 if (rb
->read(sfd
, buffer
, rsize
) != rsize
||
334 rb
->write(dfd
, buffer
, rsize
) != rsize
)