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,
35 #define SERIALIZE_BOOKMARK_SIZE 8
37 struct tv_bookmark_info
{
38 struct tv_screen_pos pos
;
42 /* bookmark stored array */
43 struct tv_bookmark_info bookmarks
[TV_MAX_BOOKMARKS
+ 1];
44 static unsigned char bookmark_count
;
46 static int tv_compare_screen_pos(const struct tv_screen_pos
*p1
, const struct tv_screen_pos
*p2
)
48 if (p1
->page
!= p2
->page
)
49 return p1
->page
- p2
->page
;
51 return p1
->line
- p2
->line
;
54 static int bm_comp(const void *a
, const void *b
)
56 struct tv_bookmark_info
*pa
;
57 struct tv_bookmark_info
*pb
;
59 pa
= (struct tv_bookmark_info
*)a
;
60 pb
= (struct tv_bookmark_info
*)b
;
62 return tv_compare_screen_pos(&pa
->pos
, &pb
->pos
);
65 static int tv_add_bookmark(const struct tv_screen_pos
*pos
)
67 if (bookmark_count
>= TV_MAX_BOOKMARKS
)
70 bookmarks
[bookmark_count
].pos
= *pos
;
71 bookmarks
[bookmark_count
].flag
= TV_BOOKMARK_USER
;
73 return bookmark_count
++;
76 static void tv_remove_bookmark(int idx
)
80 if (idx
>= 0 && idx
< bookmark_count
)
82 for (k
= idx
+ 1; k
< bookmark_count
; k
++)
83 bookmarks
[k
-1] = bookmarks
[k
];
89 static int tv_find_bookmark(const struct tv_screen_pos
*pos
)
93 for (i
= 0; i
< bookmark_count
; i
++)
95 if (tv_compare_screen_pos(&bookmarks
[i
].pos
, pos
) == 0)
101 static void tv_change_preferences(const struct tv_preferences
*oldp
)
108 for (i
= 0; i
< bookmark_count
; i
++)
109 tv_convert_fpos(bookmarks
[i
].pos
.file_pos
, &bookmarks
[i
].pos
);
112 void tv_init_bookmark(void)
114 tv_add_preferences_change_listner(tv_change_preferences
);
117 int tv_get_bookmark_positions(struct tv_screen_pos
*pos_array
)
121 for(i
= 0; i
< bookmark_count
; i
++)
122 *pos_array
++ = bookmarks
[i
].pos
;
124 return bookmark_count
;
127 void tv_toggle_bookmark(void)
129 const struct tv_screen_pos
*pos
= tv_get_screen_pos();
130 int idx
= tv_find_bookmark(pos
);
134 if (tv_add_bookmark(pos
) >= 0)
135 rb
->splash(HZ
/2, "Bookmark add");
137 rb
->splash(HZ
/2, "No more add bookmark");
140 tv_remove_bookmark(idx
);
141 rb
->splash(HZ
/2, "Bookmark remove");
144 void tv_create_system_bookmark(void)
146 const struct tv_screen_pos
*pos
= tv_get_screen_pos();
147 int idx
= tv_find_bookmark(pos
);
150 bookmarks
[idx
].flag
|= TV_BOOKMARK_SYSTEM
;
153 bookmarks
[bookmark_count
].pos
= *pos
;
154 bookmarks
[bookmark_count
].flag
= TV_BOOKMARK_SYSTEM
;
159 void tv_select_bookmark(void)
162 struct tv_screen_pos select_pos
;
164 for (i
= 0; i
< bookmark_count
; i
++)
166 if (bookmarks
[i
].flag
& TV_BOOKMARK_SYSTEM
)
170 /* if does not find the system bookmark, add the system bookmark. */
171 if (i
>= bookmark_count
)
172 tv_create_system_bookmark();
174 if (bookmark_count
== 1)
175 select_pos
= bookmarks
[0].pos
;
179 struct opt_items items
[bookmark_count
];
180 unsigned char names
[bookmark_count
][24];
182 rb
->qsort(bookmarks
, bookmark_count
, sizeof(struct tv_bookmark_info
), bm_comp
);
184 for (i
= 0; i
< bookmark_count
; i
++)
186 rb
->snprintf(names
[i
], sizeof(names
[0]),
187 #if CONFIG_KEYPAD != PLAYER_PAD
188 "%cPage: %d Line: %d",
192 (bookmarks
[i
].flag
& TV_BOOKMARK_SYSTEM
)? '*' : ' ',
193 bookmarks
[i
].pos
.page
+ 1,
194 bookmarks
[i
].pos
.line
+ 1);
195 items
[i
].string
= names
[i
];
196 items
[i
].voice_id
= -1;
199 rb
->set_option("Select bookmark", &selected
, INT
, items
,
200 bookmark_count
, NULL
);
202 if (selected
>= 0 && selected
< bookmark_count
)
203 select_pos
= bookmarks
[selected
].pos
;
206 /* when does not select any bookmarks, move to the current page */
207 tv_copy_screen_pos(&select_pos
);
209 if (select_pos
.file_pos
== 0)
210 rb
->splash(HZ
, "Start the first page");
212 rb
->splash(HZ
, "Return to the current page");
216 /* deletes the system bookmark */
217 for (i
= 0; i
< bookmark_count
; i
++)
219 if ((bookmarks
[i
].flag
&= TV_BOOKMARK_USER
) == 0)
221 tv_remove_bookmark(i
);
226 /* move to the select position */
227 if (preferences
->vertical_scroll_mode
== VS_PAGE
)
230 tv_move_screen(select_pos
.page
, select_pos
.line
, SEEK_SET
);
233 /* serialize or deserialize of the bookmark array */
234 static bool tv_read_bookmark_info(int fd
, struct tv_bookmark_info
*b
)
236 unsigned char buf
[SERIALIZE_BOOKMARK_SIZE
];
238 if (rb
->read(fd
, buf
, sizeof(buf
)) < 0)
241 b
->pos
.file_pos
= (buf
[0] << 24)|(buf
[1] << 16)|(buf
[2] << 8)|buf
[3];
242 b
->pos
.page
= (buf
[4] << 8)|buf
[5];
243 b
->pos
.line
= buf
[6];
249 bool tv_deserialize_bookmarks(int fd
)
254 if (rb
->read(fd
, &bookmark_count
, 1) < 0)
257 for (i
= 0; i
< bookmark_count
; i
++)
259 if (!tv_read_bookmark_info(fd
, &bookmarks
[i
]))
270 static bool tv_write_bookmark_info(int fd
, const struct tv_bookmark_info
*b
)
272 unsigned char buf
[SERIALIZE_BOOKMARK_SIZE
];
273 unsigned char *p
= buf
;
275 *p
++ = b
->pos
.file_pos
>> 24;
276 *p
++ = b
->pos
.file_pos
>> 16;
277 *p
++ = b
->pos
.file_pos
>> 8;
278 *p
++ = b
->pos
.file_pos
;
280 *p
++ = b
->pos
.page
>> 8;
286 return (rb
->write(fd
, buf
, SERIALIZE_BOOKMARK_SIZE
) >= 0);
289 int tv_serialize_bookmarks(int fd
)
293 if (rb
->write(fd
, &bookmark_count
, 1) < 0)
296 for (i
= 0; i
< bookmark_count
; i
++)
298 if (!tv_write_bookmark_info(fd
, &bookmarks
[i
]))
301 return i
* SERIALIZE_BOOKMARK_SIZE
+ 1;