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 #include "tv_preferences.h"
28 /* text viewer bookmark functions */
31 TV_BOOKMARK_SYSTEM
= 1,
36 struct tv_bookmark_info
{
37 struct tv_screen_pos pos
;
41 /* bookmark stored array */
42 struct tv_bookmark_info bookmarks
[TV_MAX_BOOKMARKS
+ 1];
43 static unsigned char bookmark_count
;
45 static int tv_compare_screen_pos(const struct tv_screen_pos
*p1
, const struct tv_screen_pos
*p2
)
47 if (p1
->page
!= p2
->page
)
48 return p1
->page
- p2
->page
;
50 return p1
->line
- p2
->line
;
53 static int bm_comp(const void *a
, const void *b
)
55 struct tv_bookmark_info
*pa
;
56 struct tv_bookmark_info
*pb
;
58 pa
= (struct tv_bookmark_info
*)a
;
59 pb
= (struct tv_bookmark_info
*)b
;
61 return tv_compare_screen_pos(&pa
->pos
, &pb
->pos
);
64 static int tv_add_bookmark(const struct tv_screen_pos
*pos
)
66 if (bookmark_count
>= TV_MAX_BOOKMARKS
)
69 bookmarks
[bookmark_count
].pos
= *pos
;
70 bookmarks
[bookmark_count
].flag
= TV_BOOKMARK_USER
;
72 return bookmark_count
++;
75 static void tv_remove_bookmark(int idx
)
79 if (idx
>= 0 && idx
< bookmark_count
)
81 for (k
= idx
+ 1; k
< bookmark_count
; k
++)
82 bookmarks
[k
-1] = bookmarks
[k
];
88 static int tv_find_bookmark(const struct tv_screen_pos
*pos
)
92 for (i
= 0; i
< bookmark_count
; i
++)
94 if (tv_compare_screen_pos(&bookmarks
[i
].pos
, pos
) == 0)
100 static int tv_change_preferences(const struct tv_preferences
*oldp
)
106 for (i
= 0; i
< bookmark_count
; i
++)
107 tv_convert_fpos(bookmarks
[i
].pos
.file_pos
, &bookmarks
[i
].pos
);
109 return TV_CALLBACK_OK
;
112 bool tv_init_bookmark(unsigned char **buf
, size_t *size
)
117 tv_add_preferences_change_listner(tv_change_preferences
);
121 void tv_finalize_bookmark(void)
123 /* no-operation function */
126 int tv_get_bookmark_positions(struct tv_screen_pos
*pos_array
)
130 for(i
= 0; i
< bookmark_count
; i
++)
131 *pos_array
++ = bookmarks
[i
].pos
;
133 return bookmark_count
;
136 void tv_toggle_bookmark(void)
138 const struct tv_screen_pos
*pos
= tv_get_screen_pos();
139 int idx
= tv_find_bookmark(pos
);
143 if (tv_add_bookmark(pos
) >= 0)
144 rb
->splash(HZ
/2, "Bookmark add");
146 rb
->splash(HZ
/2, "No more add bookmark");
149 tv_remove_bookmark(idx
);
150 rb
->splash(HZ
/2, "Bookmark remove");
153 void tv_create_system_bookmark(void)
155 const struct tv_screen_pos
*pos
= tv_get_screen_pos();
156 int idx
= tv_find_bookmark(pos
);
159 bookmarks
[idx
].flag
|= TV_BOOKMARK_SYSTEM
;
162 bookmarks
[bookmark_count
].pos
= *pos
;
163 bookmarks
[bookmark_count
].flag
= TV_BOOKMARK_SYSTEM
;
168 static const char* get_bookmark_name(int selected
, void * data
,
169 char * buffer
, size_t buffer_len
)
172 struct tv_bookmark_info
*bookmark
= &bookmarks
[selected
];
173 rb
->snprintf(buffer
, buffer_len
,
174 #ifdef HAVE_LCD_BITMAP
175 "%cPage: %d Line: %d",
179 (bookmark
->flag
& TV_BOOKMARK_SYSTEM
)? '*' : ' ',
180 bookmark
->pos
.page
+ 1, bookmark
->pos
.line
+ 1);
184 static int list_action_callback(int action
, struct gui_synclist
*lists
)
187 if (action
== ACTION_STD_OK
)
188 return ACTION_STD_CANCEL
;
192 void tv_select_bookmark(void)
195 struct tv_screen_pos select_pos
;
197 for (i
= 0; i
< bookmark_count
; i
++)
199 if (bookmarks
[i
].flag
& TV_BOOKMARK_SYSTEM
)
203 /* if does not find the system bookmark, add the system bookmark. */
204 if (i
>= bookmark_count
)
205 tv_create_system_bookmark();
207 if (bookmark_count
== 1)
208 select_pos
= bookmarks
[0].pos
;
211 struct simplelist_info info
;
213 rb
->qsort(bookmarks
, bookmark_count
, sizeof(struct tv_bookmark_info
), bm_comp
);
215 rb
->simplelist_info_init(&info
, "Select bookmark",
216 bookmark_count
, bookmarks
);
217 info
.get_name
= get_bookmark_name
;
218 info
.action_callback
= list_action_callback
;
219 rb
->simplelist_show_list(&info
);
221 if (info
.selection
>= 0 && info
.selection
< bookmark_count
)
222 select_pos
= bookmarks
[info
.selection
].pos
;
225 /* when does not select any bookmarks, move to the current page */
226 tv_copy_screen_pos(&select_pos
);
228 if (select_pos
.file_pos
== 0)
229 rb
->splash(HZ
, "Start the first page");
231 rb
->splash(HZ
, "Return to the current page");
235 /* deletes the system bookmark */
236 for (i
= 0; i
< bookmark_count
; i
++)
238 if ((bookmarks
[i
].flag
&= TV_BOOKMARK_USER
) == 0)
240 tv_remove_bookmark(i
);
245 /* move to the select position */
246 if (preferences
->vertical_scroll_mode
== VS_PAGE
)
249 tv_move_screen(select_pos
.page
, select_pos
.line
, SEEK_SET
);
252 /* serialize or deserialize of the bookmark array */
253 static bool tv_read_bookmark_info(int fd
, struct tv_bookmark_info
*b
)
255 unsigned char buf
[SERIALIZE_BOOKMARK_SIZE
];
257 if (rb
->read(fd
, buf
, sizeof(buf
)) < 0)
260 b
->pos
.file_pos
= (buf
[0] << 24)|(buf
[1] << 16)|(buf
[2] << 8)|buf
[3];
261 b
->pos
.page
= (buf
[4] << 8)|buf
[5];
262 b
->pos
.line
= buf
[6];
268 bool tv_deserialize_bookmarks(int fd
)
273 if (rb
->read(fd
, &bookmark_count
, 1) < 0)
276 for (i
= 0; i
< bookmark_count
; i
++)
278 if (!tv_read_bookmark_info(fd
, &bookmarks
[i
]))
289 static void tv_write_bookmark_info(unsigned char *p
, const struct tv_bookmark_info
*b
)
291 *p
++ = b
->pos
.file_pos
>> 24;
292 *p
++ = b
->pos
.file_pos
>> 16;
293 *p
++ = b
->pos
.file_pos
>> 8;
294 *p
++ = b
->pos
.file_pos
;
296 *p
++ = b
->pos
.page
>> 8;
303 int tv_serialize_bookmarks(unsigned char *buf
)
307 buf
[0] = bookmark_count
;
309 for (i
= 0; i
< bookmark_count
; i
++)
311 tv_write_bookmark_info(buf
+ i
* SERIALIZE_BOOKMARK_SIZE
+ 1, &bookmarks
[i
]);
313 return i
* SERIALIZE_BOOKMARK_SIZE
+ 1;