diff options
-rw-r--r-- | apps/plugins/viewer.c | 1601 |
1 files changed, 1398 insertions, 203 deletions
diff --git a/apps/plugins/viewer.c b/apps/plugins/viewer.c index 8dae52780e..0901be427b 100644 --- a/apps/plugins/viewer.c +++ b/apps/plugins/viewer.c | |||
@@ -24,22 +24,108 @@ | |||
24 | 24 | ||
25 | PLUGIN_HEADER | 25 | PLUGIN_HEADER |
26 | 26 | ||
27 | #define SETTINGS_FILE VIEWERS_DIR "/viewer.dat" /* binary file, so dont use .cfg */ | 27 | /* global settings file |
28 | #define BOOKMARKS_FILE VIEWERS_DIR "/viewer_bookmarks.dat" | 28 | * binary file, so dont use .cfg |
29 | * | ||
30 | * setting file format | ||
31 | * | ||
32 | * part byte count | ||
33 | * -------------------------------- | ||
34 | * 'TVGS' 4 | ||
35 | * version 1 | ||
36 | * word_mode 1 | ||
37 | * line_mode 1 | ||
38 | * view_mode 1 | ||
39 | * encoding 1 | ||
40 | * scrollbar_mode 1 | ||
41 | * need_scrollbar 1 | ||
42 | * page_mode 1 | ||
43 | * page_number_mode 1 | ||
44 | * title_mode 1 | ||
45 | * scroll_mode 1 | ||
46 | * autoscroll_speed 1 | ||
47 | * font name MAX_PATH | ||
48 | */ | ||
49 | #define GLOBAL_SETTINGS_FILE VIEWERS_DIR "/viewer.dat" | ||
50 | |||
51 | /* temporary file */ | ||
52 | #define GLOBAL_SETTINGS_TMP_FILE VIEWERS_DIR "/viewer_file.tmp" | ||
53 | |||
54 | #define GLOBAL_SETTINGS_HEADER "\x54\x56\x47\x53\x31" /* header="TVGS" version=1 */ | ||
55 | #define GLOBAL_SETTINGS_H_SIZE 5 | ||
56 | |||
57 | /* preferences and bookmarks at each file | ||
58 | * binary file, so dont use .cfg | ||
59 | * | ||
60 | * setting file format | ||
61 | * | ||
62 | * part byte count | ||
63 | * -------------------------------- | ||
64 | * 'TVS' 3 | ||
65 | * version 1 | ||
66 | * file count 2 | ||
67 | * [1st file] | ||
68 | * file path MAX_PATH | ||
69 | * next file pos 2 | ||
70 | * [preferences] | ||
71 | * word_mode 1 | ||
72 | * line_mode 1 | ||
73 | * view_mode 1 | ||
74 | * encoding 1 | ||
75 | * scrollbar_mode 1 | ||
76 | * need_scrollbar 1 | ||
77 | * page_mode 1 | ||
78 | * header_mode 1 | ||
79 | * footer_mode 1 | ||
80 | * scroll_mode 1 | ||
81 | * autoscroll_speed 1 | ||
82 | * font name MAX_PATH | ||
83 | * bookmark count 1 | ||
84 | * [1st bookmark] | ||
85 | * file_position 4 | ||
86 | * page 2 | ||
87 | * line 1 | ||
88 | * flag 1 | ||
89 | * [2nd bookmark] | ||
90 | * ... | ||
91 | * [last bookmark] | ||
92 | * [2nd file] | ||
93 | * ... | ||
94 | * [last file] | ||
95 | */ | ||
96 | #define SETTINGS_FILE VIEWERS_DIR "/viewer_file.dat" | ||
97 | |||
98 | /* temporary file */ | ||
99 | #define SETTINGS_TMP_FILE VIEWERS_DIR "/viewer_file.tmp" | ||
100 | |||
101 | #define SETTINGS_HEADER "\x54\x56\x53\x32" /* header="TVS" version=2 */ | ||
102 | #define SETTINGS_H_SIZE 4 | ||
29 | 103 | ||
30 | #define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */ | 104 | #define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */ |
31 | #define MAX_COLUMNS 64 /* Max displayable string len (over-estimate) */ | 105 | #define NARROW_MAX_COLUMNS 64 /* Max displayable string len [narrow] (over-estimate) */ |
106 | #define WIDE_MAX_COLUMNS 128 /* Max displayable string len [wide] (over-estimate) */ | ||
32 | #define MAX_WIDTH 910 /* Max line length in WIDE mode */ | 107 | #define MAX_WIDTH 910 /* Max line length in WIDE mode */ |
33 | #define READ_PREV_ZONE 910 /* Arbitrary number less than SMALL_BLOCK_SIZE */ | 108 | #define READ_PREV_ZONE (block_size*9/10) /* Arbitrary number less than SMALL_BLOCK_SIZE */ |
34 | #define SMALL_BLOCK_SIZE 0x1000 /* 4k: Smallest file chunk we will read */ | 109 | #define SMALL_BLOCK_SIZE block_size /* Smallest file chunk we will read */ |
35 | #define LARGE_BLOCK_SIZE 0x2000 /* 8k: Preferable size of file chunk to read */ | 110 | #define LARGE_BLOCK_SIZE (block_size << 1) /* Preferable size of file chunk to read */ |
36 | #define TOP_SECTOR buffer | 111 | #define TOP_SECTOR buffer |
37 | #define MID_SECTOR (buffer + SMALL_BLOCK_SIZE) | 112 | #define MID_SECTOR (buffer + SMALL_BLOCK_SIZE) |
38 | #define BOTTOM_SECTOR (buffer + 2*(SMALL_BLOCK_SIZE)) | 113 | #define BOTTOM_SECTOR (buffer + (SMALL_BLOCK_SIZE << 1)) |
39 | #undef SCROLLBAR_WIDTH | 114 | #undef SCROLLBAR_WIDTH |
40 | #define SCROLLBAR_WIDTH rb->global_settings->scrollbar_width | 115 | #define SCROLLBAR_WIDTH rb->global_settings->scrollbar_width |
116 | #define MAX_PAGE 9999 | ||
117 | |||
118 | #define BOOKMARK_SIZE 8 | ||
119 | #define MAX_BOOKMARKS 10 /* user setting bookmarks + last read page */ | ||
41 | 120 | ||
42 | #define MAX_BOOKMARKED_FILES ((buffer_size/(signed)sizeof(struct bookmarked_file_info))-1) | 121 | #define BOOKMARK_LAST 1 |
122 | #define BOOKMARK_USER 2 | ||
123 | |||
124 | #ifndef HAVE_LCD_BITMAP | ||
125 | #define BOOKMARK_ICON "\xee\x84\x81\x00" | ||
126 | #endif | ||
127 | |||
128 | #define PREFERENCES_SIZE (11 + MAX_PATH) | ||
43 | 129 | ||
44 | /* Out-Of-Bounds test for any pointer to data in the buffer */ | 130 | /* Out-Of-Bounds test for any pointer to data in the buffer */ |
45 | #define BUFFER_OOB(p) ((p) < buffer || (p) >= buffer_end) | 131 | #define BUFFER_OOB(p) ((p) < buffer || (p) >= buffer_end) |
@@ -77,6 +163,7 @@ PLUGIN_HEADER | |||
77 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) | 163 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) |
78 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) | 164 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) |
79 | #define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT) | 165 | #define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT) |
166 | #define VIEWER_BOOKMARK BUTTON_F2 | ||
80 | 167 | ||
81 | #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD | 168 | #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD |
82 | #define VIEWER_QUIT BUTTON_OFF | 169 | #define VIEWER_QUIT BUTTON_OFF |
@@ -90,6 +177,7 @@ PLUGIN_HEADER | |||
90 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) | 177 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) |
91 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) | 178 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) |
92 | #define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT) | 179 | #define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT) |
180 | #define VIEWER_BOOKMARK BUTTON_F2 | ||
93 | 181 | ||
94 | /* Ondio keys */ | 182 | /* Ondio keys */ |
95 | #elif CONFIG_KEYPAD == ONDIO_PAD | 183 | #elif CONFIG_KEYPAD == ONDIO_PAD |
@@ -101,6 +189,7 @@ PLUGIN_HEADER | |||
101 | #define VIEWER_MENU (BUTTON_MENU|BUTTON_REPEAT) | 189 | #define VIEWER_MENU (BUTTON_MENU|BUTTON_REPEAT) |
102 | #define VIEWER_AUTOSCROLL_PRE BUTTON_MENU | 190 | #define VIEWER_AUTOSCROLL_PRE BUTTON_MENU |
103 | #define VIEWER_AUTOSCROLL (BUTTON_MENU|BUTTON_REL) | 191 | #define VIEWER_AUTOSCROLL (BUTTON_MENU|BUTTON_REL) |
192 | #define VIEWER_BOOKMARK (BUTTON_MENU|BUTTON_OFF) | ||
104 | 193 | ||
105 | /* Player keys */ | 194 | /* Player keys */ |
106 | #elif CONFIG_KEYPAD == PLAYER_PAD | 195 | #elif CONFIG_KEYPAD == PLAYER_PAD |
@@ -111,6 +200,7 @@ PLUGIN_HEADER | |||
111 | #define VIEWER_SCREEN_RIGHT (BUTTON_ON|BUTTON_RIGHT) | 200 | #define VIEWER_SCREEN_RIGHT (BUTTON_ON|BUTTON_RIGHT) |
112 | #define VIEWER_MENU BUTTON_MENU | 201 | #define VIEWER_MENU BUTTON_MENU |
113 | #define VIEWER_AUTOSCROLL BUTTON_PLAY | 202 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
203 | #define VIEWER_BOOKMARK BUTTON_ON | ||
114 | 204 | ||
115 | /* iRiver H1x0 && H3x0 keys */ | 205 | /* iRiver H1x0 && H3x0 keys */ |
116 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | 206 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ |
@@ -126,6 +216,7 @@ PLUGIN_HEADER | |||
126 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) | 216 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) |
127 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) | 217 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) |
128 | #define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT) | 218 | #define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT) |
219 | #define VIEWER_BOOKMARK (BUTTON_ON | BUTTON_SELECT) | ||
129 | 220 | ||
130 | #define VIEWER_RC_QUIT BUTTON_RC_STOP | 221 | #define VIEWER_RC_QUIT BUTTON_RC_STOP |
131 | 222 | ||
@@ -141,6 +232,7 @@ PLUGIN_HEADER | |||
141 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 232 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
142 | #define VIEWER_MENU BUTTON_MENU | 233 | #define VIEWER_MENU BUTTON_MENU |
143 | #define VIEWER_AUTOSCROLL BUTTON_PLAY | 234 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
235 | #define VIEWER_BOOKMARK BUTTON_SELECT | ||
144 | 236 | ||
145 | /* iFP7xx keys */ | 237 | /* iFP7xx keys */ |
146 | #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD | 238 | #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD |
@@ -151,6 +243,7 @@ PLUGIN_HEADER | |||
151 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 243 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
152 | #define VIEWER_MENU BUTTON_MODE | 244 | #define VIEWER_MENU BUTTON_MODE |
153 | #define VIEWER_AUTOSCROLL BUTTON_SELECT | 245 | #define VIEWER_AUTOSCROLL BUTTON_SELECT |
246 | #define VIEWER_BOOKMARK (BUTTON_LEFT|BUTTON_SELECT) | ||
154 | 247 | ||
155 | /* iAudio X5 keys */ | 248 | /* iAudio X5 keys */ |
156 | #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD | 249 | #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD |
@@ -161,6 +254,7 @@ PLUGIN_HEADER | |||
161 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 254 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
162 | #define VIEWER_MENU BUTTON_SELECT | 255 | #define VIEWER_MENU BUTTON_SELECT |
163 | #define VIEWER_AUTOSCROLL BUTTON_PLAY | 256 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
257 | #define VIEWER_BOOKMARK BUTTON_REC | ||
164 | 258 | ||
165 | /* GIGABEAT keys */ | 259 | /* GIGABEAT keys */ |
166 | #elif CONFIG_KEYPAD == GIGABEAT_PAD | 260 | #elif CONFIG_KEYPAD == GIGABEAT_PAD |
@@ -171,6 +265,7 @@ PLUGIN_HEADER | |||
171 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 265 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
172 | #define VIEWER_MENU BUTTON_MENU | 266 | #define VIEWER_MENU BUTTON_MENU |
173 | #define VIEWER_AUTOSCROLL BUTTON_A | 267 | #define VIEWER_AUTOSCROLL BUTTON_A |
268 | #define VIEWER_BOOKMARK BUTTON_SELECT | ||
174 | 269 | ||
175 | /* Sansa E200 keys */ | 270 | /* Sansa E200 keys */ |
176 | #elif CONFIG_KEYPAD == SANSA_E200_PAD | 271 | #elif CONFIG_KEYPAD == SANSA_E200_PAD |
@@ -183,6 +278,7 @@ PLUGIN_HEADER | |||
183 | #define VIEWER_AUTOSCROLL BUTTON_REC | 278 | #define VIEWER_AUTOSCROLL BUTTON_REC |
184 | #define VIEWER_LINE_UP BUTTON_SCROLL_BACK | 279 | #define VIEWER_LINE_UP BUTTON_SCROLL_BACK |
185 | #define VIEWER_LINE_DOWN BUTTON_SCROLL_FWD | 280 | #define VIEWER_LINE_DOWN BUTTON_SCROLL_FWD |
281 | #define VIEWER_BOOKMARK (BUTTON_DOWN|BUTTON_SELECT) | ||
186 | 282 | ||
187 | /* Sansa Fuze keys */ | 283 | /* Sansa Fuze keys */ |
188 | #elif CONFIG_KEYPAD == SANSA_FUZE_PAD | 284 | #elif CONFIG_KEYPAD == SANSA_FUZE_PAD |
@@ -195,6 +291,7 @@ PLUGIN_HEADER | |||
195 | #define VIEWER_AUTOSCROLL BUTTON_SELECT|BUTTON_DOWN | 291 | #define VIEWER_AUTOSCROLL BUTTON_SELECT|BUTTON_DOWN |
196 | #define VIEWER_LINE_UP BUTTON_SCROLL_BACK | 292 | #define VIEWER_LINE_UP BUTTON_SCROLL_BACK |
197 | #define VIEWER_LINE_DOWN BUTTON_SCROLL_FWD | 293 | #define VIEWER_LINE_DOWN BUTTON_SCROLL_FWD |
294 | #define VIEWER_BOOKMARK BUTTON_SELECT | ||
198 | 295 | ||
199 | /* Sansa C200 keys */ | 296 | /* Sansa C200 keys */ |
200 | #elif CONFIG_KEYPAD == SANSA_C200_PAD | 297 | #elif CONFIG_KEYPAD == SANSA_C200_PAD |
@@ -207,6 +304,7 @@ PLUGIN_HEADER | |||
207 | #define VIEWER_AUTOSCROLL BUTTON_REC | 304 | #define VIEWER_AUTOSCROLL BUTTON_REC |
208 | #define VIEWER_LINE_UP BUTTON_UP | 305 | #define VIEWER_LINE_UP BUTTON_UP |
209 | #define VIEWER_LINE_DOWN BUTTON_DOWN | 306 | #define VIEWER_LINE_DOWN BUTTON_DOWN |
307 | #define VIEWER_BOOKMARK (BUTTON_DOWN | BUTTON_SELECT) | ||
210 | 308 | ||
211 | /* Sansa Clip keys */ | 309 | /* Sansa Clip keys */ |
212 | #elif CONFIG_KEYPAD == SANSA_CLIP_PAD | 310 | #elif CONFIG_KEYPAD == SANSA_CLIP_PAD |
@@ -219,6 +317,7 @@ PLUGIN_HEADER | |||
219 | #define VIEWER_AUTOSCROLL BUTTON_HOME | 317 | #define VIEWER_AUTOSCROLL BUTTON_HOME |
220 | #define VIEWER_LINE_UP BUTTON_UP | 318 | #define VIEWER_LINE_UP BUTTON_UP |
221 | #define VIEWER_LINE_DOWN BUTTON_DOWN | 319 | #define VIEWER_LINE_DOWN BUTTON_DOWN |
320 | #define VIEWER_BOOKMARK (BUTTON_DOWN|BUTTON_SELECT) | ||
222 | 321 | ||
223 | /* Sansa M200 keys */ | 322 | /* Sansa M200 keys */ |
224 | #elif CONFIG_KEYPAD == SANSA_M200_PAD | 323 | #elif CONFIG_KEYPAD == SANSA_M200_PAD |
@@ -231,6 +330,7 @@ PLUGIN_HEADER | |||
231 | #define VIEWER_AUTOSCROLL (BUTTON_SELECT | BUTTON_REL) | 330 | #define VIEWER_AUTOSCROLL (BUTTON_SELECT | BUTTON_REL) |
232 | #define VIEWER_LINE_UP BUTTON_UP | 331 | #define VIEWER_LINE_UP BUTTON_UP |
233 | #define VIEWER_LINE_DOWN BUTTON_DOWN | 332 | #define VIEWER_LINE_DOWN BUTTON_DOWN |
333 | #define VIEWER_BOOKMARK (BUTTON_DOWN|BUTTON_SELECT) | ||
234 | 334 | ||
235 | /* iriver H10 keys */ | 335 | /* iriver H10 keys */ |
236 | #elif CONFIG_KEYPAD == IRIVER_H10_PAD | 336 | #elif CONFIG_KEYPAD == IRIVER_H10_PAD |
@@ -241,6 +341,7 @@ PLUGIN_HEADER | |||
241 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 341 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
242 | #define VIEWER_MENU BUTTON_REW | 342 | #define VIEWER_MENU BUTTON_REW |
243 | #define VIEWER_AUTOSCROLL BUTTON_PLAY | 343 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
344 | #define VIEWER_BOOKMARK BUTTON_FF | ||
244 | 345 | ||
245 | /*M-Robe 500 keys */ | 346 | /*M-Robe 500 keys */ |
246 | #elif CONFIG_KEYPAD == MROBE500_PAD | 347 | #elif CONFIG_KEYPAD == MROBE500_PAD |
@@ -251,6 +352,7 @@ PLUGIN_HEADER | |||
251 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 352 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
252 | #define VIEWER_MENU BUTTON_RC_HEART | 353 | #define VIEWER_MENU BUTTON_RC_HEART |
253 | #define VIEWER_AUTOSCROLL BUTTON_RC_MODE | 354 | #define VIEWER_AUTOSCROLL BUTTON_RC_MODE |
355 | #define VIEWER_BOOKMARK BUTTON_CENTER | ||
254 | 356 | ||
255 | /*Gigabeat S keys */ | 357 | /*Gigabeat S keys */ |
256 | #elif CONFIG_KEYPAD == GIGABEAT_S_PAD | 358 | #elif CONFIG_KEYPAD == GIGABEAT_S_PAD |
@@ -266,6 +368,7 @@ PLUGIN_HEADER | |||
266 | #define VIEWER_LINE_DOWN BUTTON_DOWN | 368 | #define VIEWER_LINE_DOWN BUTTON_DOWN |
267 | #define VIEWER_COLUMN_LEFT BUTTON_LEFT | 369 | #define VIEWER_COLUMN_LEFT BUTTON_LEFT |
268 | #define VIEWER_COLUMN_RIGHT BUTTON_RIGHT | 370 | #define VIEWER_COLUMN_RIGHT BUTTON_RIGHT |
371 | #define VIEWER_BOOKMARK BUTTON_SELECT | ||
269 | 372 | ||
270 | /*M-Robe 100 keys */ | 373 | /*M-Robe 100 keys */ |
271 | #elif CONFIG_KEYPAD == MROBE100_PAD | 374 | #elif CONFIG_KEYPAD == MROBE100_PAD |
@@ -276,17 +379,19 @@ PLUGIN_HEADER | |||
276 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 379 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
277 | #define VIEWER_MENU BUTTON_MENU | 380 | #define VIEWER_MENU BUTTON_MENU |
278 | #define VIEWER_AUTOSCROLL BUTTON_DISPLAY | 381 | #define VIEWER_AUTOSCROLL BUTTON_DISPLAY |
382 | #define VIEWER_BOOKMARK BUTTON_SELECT | ||
279 | 383 | ||
280 | /* iAUdio M3 keys */ | 384 | /* iAUdio M3 keys */ |
281 | #elif CONFIG_KEYPAD == IAUDIO_M3_PAD | 385 | #elif CONFIG_KEYPAD == IAUDIO_M3_PAD |
282 | #define VIEWER_QUIT BUTTON_RC_REC | 386 | #define VIEWER_QUIT BUTTON_REC |
283 | #define VIEWER_PAGE_UP BUTTON_RC_VOL_UP | 387 | #define VIEWER_PAGE_UP BUTTON_RC_VOL_UP |
284 | #define VIEWER_PAGE_DOWN BUTTON_RC_VOL_DOWN | 388 | #define VIEWER_PAGE_DOWN BUTTON_RC_VOL_DOWN |
285 | #define VIEWER_SCREEN_LEFT BUTTON_RC_REW | 389 | #define VIEWER_SCREEN_LEFT BUTTON_RC_REW |
286 | #define VIEWER_SCREEN_RIGHT BUTTON_RC_FF | 390 | #define VIEWER_SCREEN_RIGHT BUTTON_RC_FF |
287 | #define VIEWER_MENU BUTTON_RC_MENU | 391 | #define VIEWER_MENU BUTTON_RC_MENU |
288 | #define VIEWER_AUTOSCROLL BUTTON_RC_MODE | 392 | #define VIEWER_AUTOSCROLL BUTTON_RC_MODE |
289 | #define VIEWER_RC_QUIT BUTTON_REC | 393 | #define VIEWER_RC_QUIT BUTTON_RC_REC |
394 | #define VIEWER_BOOKMARK BUTTON_RC_PLAY | ||
290 | 395 | ||
291 | /* Cowon D2 keys */ | 396 | /* Cowon D2 keys */ |
292 | #elif CONFIG_KEYPAD == COWON_D2_PAD | 397 | #elif CONFIG_KEYPAD == COWON_D2_PAD |
@@ -294,6 +399,7 @@ PLUGIN_HEADER | |||
294 | #define VIEWER_MENU BUTTON_MENU | 399 | #define VIEWER_MENU BUTTON_MENU |
295 | #define VIEWER_PAGE_UP BUTTON_MINUS | 400 | #define VIEWER_PAGE_UP BUTTON_MINUS |
296 | #define VIEWER_PAGE_DOWN BUTTON_PLUS | 401 | #define VIEWER_PAGE_DOWN BUTTON_PLUS |
402 | #define VIEWER_BOOKMARK (BUTTON_MENU|BUTTON_PLUS) | ||
297 | 403 | ||
298 | #elif CONFIG_KEYPAD == IAUDIO67_PAD | 404 | #elif CONFIG_KEYPAD == IAUDIO67_PAD |
299 | #define VIEWER_QUIT BUTTON_POWER | 405 | #define VIEWER_QUIT BUTTON_POWER |
@@ -304,6 +410,7 @@ PLUGIN_HEADER | |||
304 | #define VIEWER_MENU BUTTON_MENU | 410 | #define VIEWER_MENU BUTTON_MENU |
305 | #define VIEWER_AUTOSCROLL BUTTON_PLAY | 411 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
306 | #define VIEWER_RC_QUIT BUTTON_STOP | 412 | #define VIEWER_RC_QUIT BUTTON_STOP |
413 | #define VIEWER_BOOKMARK (BUTTON_LEFT|BUTTON_PLAY) | ||
307 | 414 | ||
308 | /* Creative Zen Vision:M keys */ | 415 | /* Creative Zen Vision:M keys */ |
309 | #elif CONFIG_KEYPAD == CREATIVEZVM_PAD | 416 | #elif CONFIG_KEYPAD == CREATIVEZVM_PAD |
@@ -314,6 +421,7 @@ PLUGIN_HEADER | |||
314 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 421 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
315 | #define VIEWER_MENU BUTTON_MENU | 422 | #define VIEWER_MENU BUTTON_MENU |
316 | #define VIEWER_AUTOSCROLL BUTTON_SELECT | 423 | #define VIEWER_AUTOSCROLL BUTTON_SELECT |
424 | #define VIEWER_BOOKMARK BUTTON_PLAY | ||
317 | 425 | ||
318 | /* Philips HDD1630 keys */ | 426 | /* Philips HDD1630 keys */ |
319 | #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD | 427 | #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD |
@@ -324,6 +432,7 @@ PLUGIN_HEADER | |||
324 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 432 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
325 | #define VIEWER_MENU BUTTON_MENU | 433 | #define VIEWER_MENU BUTTON_MENU |
326 | #define VIEWER_AUTOSCROLL BUTTON_VIEW | 434 | #define VIEWER_AUTOSCROLL BUTTON_VIEW |
435 | #define VIEWER_BOOKMARK BUTTON_SELECT | ||
327 | 436 | ||
328 | /* Philips SA9200 keys */ | 437 | /* Philips SA9200 keys */ |
329 | #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD | 438 | #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD |
@@ -334,15 +443,18 @@ PLUGIN_HEADER | |||
334 | #define VIEWER_SCREEN_RIGHT BUTTON_NEXT | 443 | #define VIEWER_SCREEN_RIGHT BUTTON_NEXT |
335 | #define VIEWER_MENU BUTTON_MENU | 444 | #define VIEWER_MENU BUTTON_MENU |
336 | #define VIEWER_AUTOSCROLL BUTTON_PLAY | 445 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
446 | #define VIEWER_BOOKMARK BUTTON_RIGHT | ||
337 | 447 | ||
338 | /* Onda VX747 keys */ | 448 | /* Onda VX747 keys */ |
339 | #elif CONFIG_KEYPAD == ONDAVX747_PAD | 449 | #elif CONFIG_KEYPAD == ONDAVX747_PAD |
340 | #define VIEWER_QUIT BUTTON_POWER | 450 | #define VIEWER_QUIT BUTTON_POWER |
341 | #define VIEWER_MENU BUTTON_MENU | 451 | #define VIEWER_MENU BUTTON_MENU |
452 | #define VIEWER_BOOKMARK BUTTON_RIGHT | ||
342 | 453 | ||
343 | /* Onda VX777 keys */ | 454 | /* Onda VX777 keys */ |
344 | #elif CONFIG_KEYPAD == ONDAVX777_PAD | 455 | #elif CONFIG_KEYPAD == ONDAVX777_PAD |
345 | #define VIEWER_QUIT BUTTON_POWER | 456 | #define VIEWER_QUIT BUTTON_POWER |
457 | #define VIEWER_BOOKMARK BUTTON_RIGHT | ||
346 | 458 | ||
347 | /* SAMSUNG YH-820 / YH-920 / YH-925 keys */ | 459 | /* SAMSUNG YH-820 / YH-920 / YH-925 keys */ |
348 | #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD | 460 | #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD |
@@ -353,6 +465,7 @@ PLUGIN_HEADER | |||
353 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 465 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
354 | #define VIEWER_MENU BUTTON_PLAY | 466 | #define VIEWER_MENU BUTTON_PLAY |
355 | #define VIEWER_AUTOSCROLL BUTTON_REW | 467 | #define VIEWER_AUTOSCROLL BUTTON_REW |
468 | #define VIEWER_BOOKMARK BUTTON_FFWD | ||
356 | 469 | ||
357 | /* Packard Bell Vibe 500 keys */ | 470 | /* Packard Bell Vibe 500 keys */ |
358 | #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD | 471 | #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD |
@@ -365,6 +478,7 @@ PLUGIN_HEADER | |||
365 | #define VIEWER_SCREEN_RIGHT BUTTON_NEXT | 478 | #define VIEWER_SCREEN_RIGHT BUTTON_NEXT |
366 | #define VIEWER_MENU BUTTON_MENU | 479 | #define VIEWER_MENU BUTTON_MENU |
367 | #define VIEWER_AUTOSCROLL BUTTON_PLAY | 480 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
481 | #define VIEWER_BOOKMARK BUTTON_POWER | ||
368 | 482 | ||
369 | #else | 483 | #else |
370 | #error No keymap defined! | 484 | #error No keymap defined! |
@@ -403,15 +517,11 @@ PLUGIN_HEADER | |||
403 | #endif | 517 | #endif |
404 | 518 | ||
405 | /* stuff for the bookmarking */ | 519 | /* stuff for the bookmarking */ |
406 | struct bookmarked_file_info { | 520 | struct bookmark_info { |
407 | long file_position; | 521 | long file_position; |
408 | int top_ptr_pos; | 522 | int page; |
409 | char filename[MAX_PATH]; | 523 | int line; |
410 | }; | 524 | unsigned char flag; |
411 | |||
412 | struct bookmark_file_data { | ||
413 | signed int bookmarked_files_count; | ||
414 | struct bookmarked_file_info bookmarks[]; | ||
415 | }; | 525 | }; |
416 | 526 | ||
417 | struct preferences { | 527 | struct preferences { |
@@ -434,7 +544,6 @@ struct preferences { | |||
434 | 544 | ||
435 | enum codepages encoding; | 545 | enum codepages encoding; |
436 | 546 | ||
437 | #ifdef HAVE_LCD_BITMAP | ||
438 | enum { | 547 | enum { |
439 | SB_OFF=0, | 548 | SB_OFF=0, |
440 | SB_ON, | 549 | SB_ON, |
@@ -445,7 +554,20 @@ struct preferences { | |||
445 | NO_OVERLAP=0, | 554 | NO_OVERLAP=0, |
446 | OVERLAP, | 555 | OVERLAP, |
447 | } page_mode; | 556 | } page_mode; |
448 | #endif /* HAVE_LCD_BITMAP */ | 557 | |
558 | enum { | ||
559 | HD_NONE = 0, | ||
560 | HD_PATH, | ||
561 | HD_SBAR, | ||
562 | HD_BOTH, | ||
563 | } header_mode; | ||
564 | |||
565 | enum { | ||
566 | FT_NONE = 0, | ||
567 | FT_PAGE, | ||
568 | FT_SBAR, | ||
569 | FT_BOTH, | ||
570 | } footer_mode; | ||
449 | 571 | ||
450 | enum { | 572 | enum { |
451 | PAGE=0, | 573 | PAGE=0, |
@@ -453,6 +575,13 @@ struct preferences { | |||
453 | } scroll_mode; | 575 | } scroll_mode; |
454 | 576 | ||
455 | int autoscroll_speed; | 577 | int autoscroll_speed; |
578 | |||
579 | unsigned char font[MAX_PATH]; | ||
580 | }; | ||
581 | |||
582 | enum { | ||
583 | VIEWER_FONT_MENU = 0, | ||
584 | VIEWER_FONT_TEXT, | ||
456 | }; | 585 | }; |
457 | 586 | ||
458 | struct preferences prefs; | 587 | struct preferences prefs; |
@@ -460,6 +589,7 @@ struct preferences old_prefs; | |||
460 | 589 | ||
461 | static unsigned char *buffer; | 590 | static unsigned char *buffer; |
462 | static long buffer_size; | 591 | static long buffer_size; |
592 | static long block_size = 0x1000; | ||
463 | static unsigned char line_break[] = {0,0x20,9,0xB,0xC,'-'}; | 593 | static unsigned char line_break[] = {0,0x20,9,0xB,0xC,'-'}; |
464 | static int display_columns; /* number of (pixel) columns on the display */ | 594 | static int display_columns; /* number of (pixel) columns on the display */ |
465 | static int display_lines; /* number of lines on the display */ | 595 | static int display_lines; /* number of lines on the display */ |
@@ -471,18 +601,34 @@ static long file_size; | |||
471 | static long start_position; /* position in the file after the viewer is started */ | 601 | static long start_position; /* position in the file after the viewer is started */ |
472 | static bool mac_text; | 602 | static bool mac_text; |
473 | static long file_pos; /* Position of the top of the buffer in the file */ | 603 | static long file_pos; /* Position of the top of the buffer in the file */ |
604 | static long last_file_pos; | ||
474 | static unsigned char *buffer_end; /*Set to BUFFER_END() when file_pos changes*/ | 605 | static unsigned char *buffer_end; /*Set to BUFFER_END() when file_pos changes*/ |
475 | static int max_line_len; | 606 | static int max_line_len; |
607 | static int max_width; | ||
608 | static int max_columns; | ||
609 | static int cline = 1; | ||
610 | static int cpage = 1; | ||
611 | static int lpage = 0; | ||
476 | static unsigned char *screen_top_ptr; | 612 | static unsigned char *screen_top_ptr; |
477 | static unsigned char *next_screen_ptr; | 613 | static unsigned char *next_screen_ptr; |
478 | static unsigned char *next_screen_to_draw_ptr; | 614 | static unsigned char *next_screen_to_draw_ptr; |
479 | static unsigned char *next_line_ptr; | 615 | static unsigned char *next_line_ptr; |
616 | static unsigned char *last_screen_top_ptr = NULL; | ||
480 | #ifdef HAVE_LCD_BITMAP | 617 | #ifdef HAVE_LCD_BITMAP |
481 | static struct font *pf; | 618 | static struct font *pf; |
619 | static int header_height = 0; | ||
620 | static int footer_height = 0; | ||
482 | #endif | 621 | #endif |
622 | struct bookmark_info bookmarks[MAX_BOOKMARKS]; | ||
623 | static int bookmark_count; | ||
624 | |||
625 | /* UTF-8 BOM */ | ||
626 | #define BOM "\xef\xbb\xbf" | ||
627 | #define BOM_SIZE 3 | ||
483 | 628 | ||
629 | static bool is_bom = false; | ||
484 | 630 | ||
485 | int glyph_width(int ch) | 631 | static int glyph_width(int ch) |
486 | { | 632 | { |
487 | if (ch == 0) | 633 | if (ch == 0) |
488 | ch = ' '; | 634 | ch = ' '; |
@@ -494,7 +640,7 @@ int glyph_width(int ch) | |||
494 | #endif | 640 | #endif |
495 | } | 641 | } |
496 | 642 | ||
497 | unsigned char* get_ucs(const unsigned char* str, unsigned short* ch) | 643 | static unsigned char* get_ucs(const unsigned char* str, unsigned short* ch) |
498 | { | 644 | { |
499 | unsigned char utf8_tmp[6]; | 645 | unsigned char utf8_tmp[6]; |
500 | int count; | 646 | int count; |
@@ -515,12 +661,60 @@ unsigned char* get_ucs(const unsigned char* str, unsigned short* ch) | |||
515 | return (unsigned char*)str+1; | 661 | return (unsigned char*)str+1; |
516 | } | 662 | } |
517 | 663 | ||
664 | static unsigned char *decode2utf8(const unsigned char *src, unsigned char *dst, | ||
665 | int skip_width, int disp_width) | ||
666 | { | ||
667 | unsigned short ch; | ||
668 | const unsigned char *oldstr; | ||
669 | const unsigned char *str = src; | ||
670 | unsigned char *utf8 = dst; | ||
671 | int width = 0; | ||
672 | |||
673 | while (*str != '\0') | ||
674 | { | ||
675 | oldstr = str; | ||
676 | str = get_ucs(oldstr, &ch); | ||
677 | width += glyph_width(ch); | ||
678 | if (width > skip_width) | ||
679 | { | ||
680 | str = oldstr; | ||
681 | break; | ||
682 | } | ||
683 | } | ||
684 | width = 0; | ||
685 | while(*str != '\0') | ||
686 | { | ||
687 | str = get_ucs(str, &ch); | ||
688 | width += glyph_width(ch); | ||
689 | if (width > disp_width) | ||
690 | break; | ||
691 | |||
692 | utf8 = rb->utf8encode(ch, utf8); | ||
693 | } | ||
694 | |||
695 | return utf8; | ||
696 | } | ||
697 | |||
698 | static void calc_max_width(void) | ||
699 | { | ||
700 | if (prefs.view_mode == NARROW) | ||
701 | { | ||
702 | max_columns = NARROW_MAX_COLUMNS; | ||
703 | max_width = draw_columns; | ||
704 | } | ||
705 | else | ||
706 | { | ||
707 | max_columns = WIDE_MAX_COLUMNS; | ||
708 | max_width = 2 * draw_columns; | ||
709 | } | ||
710 | } | ||
711 | |||
518 | bool done = false; | 712 | bool done = false; |
519 | int col = 0; | 713 | int col = 0; |
520 | 714 | ||
521 | #define ADVANCE_COUNTERS(c) { width += glyph_width(c); k++; } | 715 | #define ADVANCE_COUNTERS(c) { width += glyph_width(c); k++; } |
522 | #define LINE_IS_FULL ((k>=MAX_COLUMNS-1) ||( width >= draw_columns)) | 716 | #define LINE_IS_FULL ((k>=max_columns-1) ||( width >= max_width)) |
523 | #define LINE_IS_NOT_FULL ((k<MAX_COLUMNS-1) &&( width < draw_columns)) | 717 | #define LINE_IS_NOT_FULL ((k<max_columns-1) &&( width < max_width)) |
524 | static unsigned char* crop_at_width(const unsigned char* p) | 718 | static unsigned char* crop_at_width(const unsigned char* p) |
525 | { | 719 | { |
526 | int k,width; | 720 | int k,width; |
@@ -531,6 +725,8 @@ static unsigned char* crop_at_width(const unsigned char* p) | |||
531 | 725 | ||
532 | while (LINE_IS_NOT_FULL) { | 726 | while (LINE_IS_NOT_FULL) { |
533 | oldp = p; | 727 | oldp = p; |
728 | if (BUFFER_OOB(p)) | ||
729 | break; | ||
534 | p = get_ucs(p, &ch); | 730 | p = get_ucs(p, &ch); |
535 | ADVANCE_COUNTERS(ch); | 731 | ADVANCE_COUNTERS(ch); |
536 | } | 732 | } |
@@ -716,7 +912,11 @@ static unsigned char* find_next_line(const unsigned char* cur_line, bool *is_sho | |||
716 | next_line++; | 912 | next_line++; |
717 | 913 | ||
718 | if (BUFFER_OOB(next_line)) | 914 | if (BUFFER_OOB(next_line)) |
915 | { | ||
916 | if (BUFFER_EOF() && next_line != cur_line) | ||
917 | return (unsigned char*) next_line; | ||
719 | return NULL; | 918 | return NULL; |
919 | } | ||
720 | 920 | ||
721 | if (is_short) | 921 | if (is_short) |
722 | *is_short = false; | 922 | *is_short = false; |
@@ -758,7 +958,7 @@ static unsigned char* find_prev_line(const unsigned char* cur_line) | |||
758 | /* (else return NULL and read previous block) */ | 958 | /* (else return NULL and read previous block) */ |
759 | 959 | ||
760 | /* Wrap downwards until too far, then use the one before. */ | 960 | /* Wrap downwards until too far, then use the one before. */ |
761 | while (p < cur_line && p != NULL) { | 961 | while (p != NULL && p < cur_line) { |
762 | prev_line = p; | 962 | prev_line = p; |
763 | p = find_next_line(prev_line, NULL); | 963 | p = find_next_line(prev_line, NULL); |
764 | } | 964 | } |
@@ -769,15 +969,34 @@ static unsigned char* find_prev_line(const unsigned char* cur_line) | |||
769 | return (unsigned char*) prev_line; | 969 | return (unsigned char*) prev_line; |
770 | } | 970 | } |
771 | 971 | ||
972 | static void check_bom(void) | ||
973 | { | ||
974 | unsigned char bom[BOM_SIZE]; | ||
975 | off_t orig = rb->lseek(fd, 0, SEEK_CUR); | ||
976 | |||
977 | is_bom = false; | ||
978 | |||
979 | rb->lseek(fd, 0, SEEK_SET); | ||
980 | |||
981 | if (rb->read(fd, bom, BOM_SIZE) == BOM_SIZE) | ||
982 | is_bom = !memcmp(bom, BOM, BOM_SIZE); | ||
983 | |||
984 | rb->lseek(fd, orig, SEEK_SET); | ||
985 | } | ||
986 | |||
772 | static void fill_buffer(long pos, unsigned char* buf, unsigned size) | 987 | static void fill_buffer(long pos, unsigned char* buf, unsigned size) |
773 | { | 988 | { |
774 | /* Read from file and preprocess the data */ | 989 | /* Read from file and preprocess the data */ |
775 | /* To minimize disk access, always read on sector boundaries */ | 990 | /* To minimize disk access, always read on sector boundaries */ |
776 | unsigned numread, i; | 991 | unsigned numread, i; |
777 | bool found_CR = false; | 992 | bool found_CR = false; |
993 | off_t offset = rb->lseek(fd, pos, SEEK_SET); | ||
994 | |||
995 | if (offset == 0 && prefs.encoding == UTF_8 && is_bom) | ||
996 | rb->lseek(fd, BOM_SIZE, SEEK_SET); | ||
778 | 997 | ||
779 | rb->lseek(fd, pos, SEEK_SET); | ||
780 | numread = rb->read(fd, buf, size); | 998 | numread = rb->read(fd, buf, size); |
999 | buf[numread] = 0; | ||
781 | rb->button_clear_queue(); /* clear button queue */ | 1000 | rb->button_clear_queue(); /* clear button queue */ |
782 | 1001 | ||
783 | for(i = 0; i < numread; i++) { | 1002 | for(i = 0; i < numread; i++) { |
@@ -810,6 +1029,18 @@ static void fill_buffer(long pos, unsigned char* buf, unsigned size) | |||
810 | } | 1029 | } |
811 | } | 1030 | } |
812 | 1031 | ||
1032 | static int viewer_find_bookmark(int page, int line) | ||
1033 | { | ||
1034 | int i; | ||
1035 | |||
1036 | for (i = 0; i < bookmark_count; i++) | ||
1037 | { | ||
1038 | if (bookmarks[i].page == page && bookmarks[i].line == line) | ||
1039 | return i; | ||
1040 | } | ||
1041 | return -1; | ||
1042 | } | ||
1043 | |||
813 | static int read_and_synch(int direction) | 1044 | static int read_and_synch(int direction) |
814 | { | 1045 | { |
815 | /* Read next (or prev) block, and reposition global pointers. */ | 1046 | /* Read next (or prev) block, and reposition global pointers. */ |
@@ -848,6 +1079,48 @@ static int read_and_synch(int direction) | |||
848 | return move_vector; | 1079 | return move_vector; |
849 | } | 1080 | } |
850 | 1081 | ||
1082 | static void get_next_line_position(unsigned char **line_begin, | ||
1083 | unsigned char **line_end, | ||
1084 | bool *is_short) | ||
1085 | { | ||
1086 | int resynch_move; | ||
1087 | |||
1088 | *line_begin = *line_end; | ||
1089 | *line_end = find_next_line(*line_begin, is_short); | ||
1090 | |||
1091 | if (*line_end == NULL && !BUFFER_EOF()) | ||
1092 | { | ||
1093 | resynch_move = read_and_synch(1); /* Read block & move ptrs */ | ||
1094 | *line_begin -= resynch_move; | ||
1095 | if (next_line_ptr > buffer) | ||
1096 | next_line_ptr -= resynch_move; | ||
1097 | |||
1098 | *line_end = find_next_line(*line_begin, is_short); | ||
1099 | } | ||
1100 | } | ||
1101 | |||
1102 | static void increment_current_line(void) | ||
1103 | { | ||
1104 | if (cline < display_lines) | ||
1105 | cline++; | ||
1106 | else if (cpage < MAX_PAGE) | ||
1107 | { | ||
1108 | cpage++; | ||
1109 | cline = 1; | ||
1110 | } | ||
1111 | } | ||
1112 | |||
1113 | static void decrement_current_line(void) | ||
1114 | { | ||
1115 | if (cline > 1) | ||
1116 | cline--; | ||
1117 | else if (cpage > 1) | ||
1118 | { | ||
1119 | cpage--; | ||
1120 | cline = display_lines; | ||
1121 | } | ||
1122 | } | ||
1123 | |||
851 | static void viewer_scroll_up(void) | 1124 | static void viewer_scroll_up(void) |
852 | { | 1125 | { |
853 | unsigned char *p; | 1126 | unsigned char *p; |
@@ -859,17 +1132,33 @@ static void viewer_scroll_up(void) | |||
859 | } | 1132 | } |
860 | if (p != NULL) | 1133 | if (p != NULL) |
861 | screen_top_ptr = p; | 1134 | screen_top_ptr = p; |
1135 | |||
1136 | decrement_current_line(); | ||
862 | } | 1137 | } |
863 | 1138 | ||
864 | static void viewer_scroll_down(void) | 1139 | static void viewer_scroll_down(bool autoscroll) |
865 | { | 1140 | { |
866 | if (next_screen_ptr != NULL) | 1141 | if (cpage == lpage) |
1142 | return; | ||
1143 | |||
1144 | if (next_line_ptr != NULL) | ||
867 | screen_top_ptr = next_line_ptr; | 1145 | screen_top_ptr = next_line_ptr; |
1146 | |||
1147 | if (prefs.scroll_mode == LINE || autoscroll) | ||
1148 | increment_current_line(); | ||
1149 | } | ||
1150 | |||
1151 | static void viewer_scroll_to_top_line(void) | ||
1152 | { | ||
1153 | int line; | ||
1154 | |||
1155 | for (line = cline; line > 1; line--) | ||
1156 | viewer_scroll_up(); | ||
868 | } | 1157 | } |
869 | 1158 | ||
870 | #ifdef HAVE_LCD_BITMAP | 1159 | #ifdef HAVE_LCD_BITMAP |
871 | static void viewer_scrollbar(void) { | 1160 | static void viewer_scrollbar(void) { |
872 | int items, min_shown, max_shown; | 1161 | int items, min_shown, max_shown, sb_begin_y, sb_height; |
873 | 1162 | ||
874 | items = (int) file_size; /* (SH1 int is same as long) */ | 1163 | items = (int) file_size; /* (SH1 int is same as long) */ |
875 | min_shown = (int) file_pos + (screen_top_ptr - buffer); | 1164 | min_shown = (int) file_pos + (screen_top_ptr - buffer); |
@@ -879,14 +1168,47 @@ static void viewer_scrollbar(void) { | |||
879 | else | 1168 | else |
880 | max_shown = min_shown + (next_screen_ptr - screen_top_ptr); | 1169 | max_shown = min_shown + (next_screen_ptr - screen_top_ptr); |
881 | 1170 | ||
882 | rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, 0, SCROLLBAR_WIDTH-1, | 1171 | sb_begin_y = header_height; |
883 | LCD_HEIGHT, items, min_shown, max_shown, VERTICAL); | 1172 | sb_height = LCD_HEIGHT - header_height - footer_height; |
1173 | |||
1174 | rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, sb_begin_y, | ||
1175 | SCROLLBAR_WIDTH-1, sb_height, | ||
1176 | items, min_shown, max_shown, VERTICAL); | ||
1177 | } | ||
1178 | #endif | ||
1179 | |||
1180 | #ifdef HAVE_LCD_BITMAP | ||
1181 | static void viewer_show_header(void) | ||
1182 | { | ||
1183 | if (prefs.header_mode == HD_SBAR || prefs.header_mode == HD_BOTH) | ||
1184 | rb->gui_syncstatusbar_draw(rb->statusbars, true); | ||
1185 | |||
1186 | if (prefs.header_mode == HD_PATH || prefs.header_mode == HD_BOTH) | ||
1187 | rb->lcd_putsxy(0, header_height - pf->height, file_name); | ||
1188 | } | ||
1189 | |||
1190 | static void viewer_show_footer(void) | ||
1191 | { | ||
1192 | if (prefs.footer_mode == FT_SBAR || prefs.footer_mode == FT_BOTH) | ||
1193 | rb->gui_syncstatusbar_draw(rb->statusbars, true); | ||
1194 | |||
1195 | if (prefs.footer_mode == FT_PAGE || prefs.footer_mode == FT_BOTH) | ||
1196 | { | ||
1197 | unsigned char buf[12]; | ||
1198 | |||
1199 | if (cline == 1) | ||
1200 | rb->snprintf(buf, sizeof(buf), "%d", cpage); | ||
1201 | else | ||
1202 | rb->snprintf(buf, sizeof(buf), "%d - %d", cpage, cpage+1); | ||
1203 | |||
1204 | rb->lcd_putsxy(0, LCD_HEIGHT - footer_height, buf); | ||
1205 | } | ||
884 | } | 1206 | } |
885 | #endif | 1207 | #endif |
886 | 1208 | ||
887 | static void viewer_draw(int col) | 1209 | static void viewer_draw(int col) |
888 | { | 1210 | { |
889 | int i, j, k, line_len, line_width, resynch_move, spaces, left_col=0; | 1211 | int i, j, k, line_len, line_width, spaces, left_col=0; |
890 | int width, extra_spaces, indent_spaces, spaces_per_word; | 1212 | int width, extra_spaces, indent_spaces, spaces_per_word; |
891 | bool multiple_spacing, line_is_short; | 1213 | bool multiple_spacing, line_is_short; |
892 | unsigned short ch; | 1214 | unsigned short ch; |
@@ -894,8 +1216,8 @@ static void viewer_draw(int col) | |||
894 | unsigned char *line_begin; | 1216 | unsigned char *line_begin; |
895 | unsigned char *line_end; | 1217 | unsigned char *line_end; |
896 | unsigned char c; | 1218 | unsigned char c; |
897 | unsigned char scratch_buffer[MAX_COLUMNS + 1]; | 1219 | unsigned char scratch_buffer[max_columns + 1]; |
898 | unsigned char utf8_buffer[MAX_COLUMNS*4 + 1]; | 1220 | unsigned char utf8_buffer[max_columns*4 + 1]; |
899 | unsigned char *endptr; | 1221 | unsigned char *endptr; |
900 | 1222 | ||
901 | /* If col==-1 do all calculations but don't display */ | 1223 | /* If col==-1 do all calculations but don't display */ |
@@ -912,39 +1234,26 @@ static void viewer_draw(int col) | |||
912 | 1234 | ||
913 | for (i = 0; i < display_lines; i++) { | 1235 | for (i = 0; i < display_lines; i++) { |
914 | if (BUFFER_OOB(line_end)) | 1236 | if (BUFFER_OOB(line_end)) |
915 | break; /* Happens after display last line at BUFFER_EOF() */ | 1237 | { |
916 | 1238 | if (lpage == cpage) | |
917 | line_begin = line_end; | 1239 | break; /* Happens after display last line at BUFFER_EOF() */ |
918 | line_end = find_next_line(line_begin, &line_is_short); | ||
919 | |||
920 | if (line_end == NULL) { | ||
921 | if (BUFFER_EOF()) { | ||
922 | if (i < display_lines - 1 && !BUFFER_BOF()) { | ||
923 | if (col != -1) | ||
924 | rb->lcd_clear_display(); | ||
925 | |||
926 | for (; i < display_lines - 1; i++) | ||
927 | viewer_scroll_up(); | ||
928 | 1240 | ||
929 | line_begin = line_end = screen_top_ptr; | 1241 | if (lpage == 0 && cline == 1) |
930 | i = -1; | 1242 | { |
931 | continue; | 1243 | lpage = cpage; |
932 | } | 1244 | last_screen_top_ptr = screen_top_ptr; |
933 | else { | 1245 | last_file_pos = file_pos; |
934 | line_end = buffer_end; | ||
935 | } | ||
936 | } | ||
937 | else { | ||
938 | resynch_move = read_and_synch(1); /* Read block & move ptrs */ | ||
939 | line_begin -= resynch_move; | ||
940 | if (i > 0) | ||
941 | next_line_ptr -= resynch_move; | ||
942 | |||
943 | line_end = find_next_line(line_begin, NULL); | ||
944 | if (line_end == NULL) /* Should not really happen */ | ||
945 | break; | ||
946 | } | 1246 | } |
947 | } | 1247 | } |
1248 | |||
1249 | get_next_line_position(&line_begin, &line_end, &line_is_short); | ||
1250 | if (line_end == NULL) | ||
1251 | { | ||
1252 | if (BUFFER_OOB(line_begin)) | ||
1253 | break; | ||
1254 | line_end = buffer_end + 1; | ||
1255 | } | ||
1256 | |||
948 | line_len = line_end - line_begin; | 1257 | line_len = line_end - line_begin; |
949 | 1258 | ||
950 | /* calculate line_len */ | 1259 | /* calculate line_len */ |
@@ -970,7 +1279,7 @@ static void viewer_draw(int col) | |||
970 | line_len--; | 1279 | line_len--; |
971 | } | 1280 | } |
972 | for (j=k=spaces=0; j < line_len; j++) { | 1281 | for (j=k=spaces=0; j < line_len; j++) { |
973 | if (k == MAX_COLUMNS) | 1282 | if (k == max_columns) |
974 | break; | 1283 | break; |
975 | 1284 | ||
976 | c = line_begin[j]; | 1285 | c = line_begin[j]; |
@@ -986,7 +1295,7 @@ static void viewer_draw(int col) | |||
986 | while (spaces) { | 1295 | while (spaces) { |
987 | spaces--; | 1296 | spaces--; |
988 | scratch_buffer[k++] = ' '; | 1297 | scratch_buffer[k++] = ' '; |
989 | if (k == MAX_COLUMNS - 1) | 1298 | if (k == max_columns - 1) |
990 | break; | 1299 | break; |
991 | } | 1300 | } |
992 | scratch_buffer[k++] = c; | 1301 | scratch_buffer[k++] = c; |
@@ -995,8 +1304,7 @@ static void viewer_draw(int col) | |||
995 | } | 1304 | } |
996 | if (col != -1) { | 1305 | if (col != -1) { |
997 | scratch_buffer[k] = 0; | 1306 | scratch_buffer[k] = 0; |
998 | endptr = rb->iso_decode(scratch_buffer + col, utf8_buffer, | 1307 | endptr = decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns); |
999 | prefs.encoding, draw_columns/glyph_width('i')); | ||
1000 | *endptr = 0; | 1308 | *endptr = 0; |
1001 | } | 1309 | } |
1002 | } | 1310 | } |
@@ -1036,7 +1344,7 @@ static void viewer_draw(int col) | |||
1036 | 1344 | ||
1037 | if (spaces) { | 1345 | if (spaces) { |
1038 | /* total number of spaces to insert between words */ | 1346 | /* total number of spaces to insert between words */ |
1039 | extra_spaces = (draw_columns-width)/glyph_width(' ') | 1347 | extra_spaces = (max_width-width)/glyph_width(' ') |
1040 | - indent_spaces; | 1348 | - indent_spaces; |
1041 | /* number of spaces between each word*/ | 1349 | /* number of spaces between each word*/ |
1042 | spaces_per_word = extra_spaces / spaces; | 1350 | spaces_per_word = extra_spaces / spaces; |
@@ -1056,7 +1364,7 @@ static void viewer_draw(int col) | |||
1056 | 1364 | ||
1057 | multiple_spacing = false; | 1365 | multiple_spacing = false; |
1058 | for (j=k=spaces=0; j < line_len; j++) { | 1366 | for (j=k=spaces=0; j < line_len; j++) { |
1059 | if (k == MAX_COLUMNS) | 1367 | if (k == max_columns) |
1060 | break; | 1368 | break; |
1061 | 1369 | ||
1062 | c = line_begin[j]; | 1370 | c = line_begin[j]; |
@@ -1081,11 +1389,9 @@ static void viewer_draw(int col) | |||
1081 | break; | 1389 | break; |
1082 | } | 1390 | } |
1083 | } | 1391 | } |
1084 | |||
1085 | if (col != -1) { | 1392 | if (col != -1) { |
1086 | scratch_buffer[k] = 0; | 1393 | scratch_buffer[k] = 0; |
1087 | endptr = rb->iso_decode(scratch_buffer + col, utf8_buffer, | 1394 | endptr = decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns); |
1088 | prefs.encoding, k-col); | ||
1089 | *endptr = 0; | 1395 | *endptr = 0; |
1090 | } | 1396 | } |
1091 | } | 1397 | } |
@@ -1116,11 +1422,29 @@ static void viewer_draw(int col) | |||
1116 | } | 1422 | } |
1117 | } | 1423 | } |
1118 | if (col != -1 && line_width > col) | 1424 | if (col != -1 && line_width > col) |
1425 | { | ||
1426 | int dpage = (cline+i <= display_lines)?cpage:cpage+1; | ||
1427 | int dline = cline+i - ((cline+i <= display_lines)?0:display_lines); | ||
1428 | bool bflag = (viewer_find_bookmark(dpage, dline) >= 0); | ||
1429 | #ifdef HAVE_LCD_BITMAP | ||
1430 | int dy = i * pf->height + header_height; | ||
1431 | #endif | ||
1432 | if (bflag) | ||
1119 | #ifdef HAVE_LCD_BITMAP | 1433 | #ifdef HAVE_LCD_BITMAP |
1120 | rb->lcd_putsxy(left_col, i*pf->height, utf8_buffer); | 1434 | { |
1435 | rb->lcd_set_drawmode(DRMODE_BG|DRMODE_FG); | ||
1436 | rb->lcd_fillrect(left_col, dy, LCD_WIDTH, pf->height); | ||
1437 | rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
1438 | } | ||
1439 | rb->lcd_putsxy(left_col, dy, utf8_buffer); | ||
1440 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
1121 | #else | 1441 | #else |
1122 | rb->lcd_puts(left_col, i, utf8_buffer); | 1442 | { |
1443 | rb->lcd_puts(left_col, i, BOOKMARK_ICON); | ||
1444 | } | ||
1445 | rb->lcd_puts(left_col+1, i, utf8_buffer); | ||
1123 | #endif | 1446 | #endif |
1447 | } | ||
1124 | if (line_width > max_line_len) | 1448 | if (line_width > max_line_len) |
1125 | max_line_len = line_width; | 1449 | max_line_len = line_width; |
1126 | 1450 | ||
@@ -1140,6 +1464,14 @@ static void viewer_draw(int col) | |||
1140 | next_screen_to_draw_ptr = next_screen_ptr; | 1464 | next_screen_to_draw_ptr = next_screen_ptr; |
1141 | #endif | 1465 | #endif |
1142 | 1466 | ||
1467 | #ifdef HAVE_LCD_BITMAP | ||
1468 | /* show header */ | ||
1469 | viewer_show_header(); | ||
1470 | |||
1471 | /* show footer */ | ||
1472 | viewer_show_footer(); | ||
1473 | #endif | ||
1474 | |||
1143 | if (col != -1) | 1475 | if (col != -1) |
1144 | rb->lcd_update(); | 1476 | rb->lcd_update(); |
1145 | } | 1477 | } |
@@ -1150,38 +1482,53 @@ static void viewer_top(void) | |||
1150 | and point screen pointer to top */ | 1482 | and point screen pointer to top */ |
1151 | if (file_pos != 0) | 1483 | if (file_pos != 0) |
1152 | { | 1484 | { |
1485 | rb->splash(0, "Loading..."); | ||
1486 | |||
1153 | file_pos = 0; | 1487 | file_pos = 0; |
1154 | buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ | 1488 | buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ |
1155 | fill_buffer(0, buffer, buffer_size); | 1489 | fill_buffer(0, buffer, buffer_size); |
1156 | } | 1490 | } |
1157 | 1491 | ||
1158 | screen_top_ptr = buffer; | 1492 | screen_top_ptr = buffer; |
1493 | cpage = 1; | ||
1494 | cline = 1; | ||
1159 | } | 1495 | } |
1160 | 1496 | ||
1161 | static void viewer_bottom(void) | 1497 | static void viewer_bottom(void) |
1162 | { | 1498 | { |
1163 | /* Read bottom of file into buffer | 1499 | unsigned char *line_begin; |
1164 | and point screen pointer to bottom */ | 1500 | unsigned char *line_end; |
1165 | long last_sectors; | ||
1166 | 1501 | ||
1167 | if (file_size > buffer_size) { | 1502 | rb->splash(0, "Loading..."); |
1168 | /* Find last buffer in file, round up to next sector boundary */ | ||
1169 | last_sectors = file_size - buffer_size + SMALL_BLOCK_SIZE; | ||
1170 | last_sectors /= SMALL_BLOCK_SIZE; | ||
1171 | last_sectors *= SMALL_BLOCK_SIZE; | ||
1172 | } | ||
1173 | else { | ||
1174 | last_sectors = 0; | ||
1175 | } | ||
1176 | 1503 | ||
1177 | if (file_pos != last_sectors) | 1504 | if (last_screen_top_ptr) |
1178 | { | 1505 | { |
1179 | file_pos = last_sectors; | 1506 | cpage = lpage; |
1180 | buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ | 1507 | cline = 1; |
1181 | fill_buffer(last_sectors, buffer, buffer_size); | 1508 | screen_top_ptr = last_screen_top_ptr; |
1509 | file_pos = last_file_pos; | ||
1510 | fill_buffer(file_pos, buffer, buffer_size); | ||
1511 | buffer_end = BUFFER_END(); | ||
1512 | return; | ||
1182 | } | 1513 | } |
1183 | 1514 | ||
1184 | screen_top_ptr = buffer_end-1; | 1515 | line_end = screen_top_ptr; |
1516 | |||
1517 | while (!BUFFER_EOF() || !BUFFER_OOB(line_end)) | ||
1518 | { | ||
1519 | get_next_line_position(&line_begin, &line_end, NULL); | ||
1520 | if (line_end == NULL) | ||
1521 | break; | ||
1522 | |||
1523 | increment_current_line(); | ||
1524 | if (cline == 1) | ||
1525 | screen_top_ptr = line_end; | ||
1526 | } | ||
1527 | lpage = cpage; | ||
1528 | cline = 1; | ||
1529 | last_screen_top_ptr = screen_top_ptr; | ||
1530 | last_file_pos = file_pos; | ||
1531 | buffer_end = BUFFER_END(); | ||
1185 | } | 1532 | } |
1186 | 1533 | ||
1187 | #ifdef HAVE_LCD_BITMAP | 1534 | #ifdef HAVE_LCD_BITMAP |
@@ -1192,18 +1539,80 @@ static void init_need_scrollbar(void) { | |||
1192 | prefs.need_scrollbar = NEED_SCROLLBAR(); | 1539 | prefs.need_scrollbar = NEED_SCROLLBAR(); |
1193 | draw_columns = prefs.need_scrollbar? display_columns-SCROLLBAR_WIDTH : display_columns; | 1540 | draw_columns = prefs.need_scrollbar? display_columns-SCROLLBAR_WIDTH : display_columns; |
1194 | par_indent_spaces = draw_columns/(5*glyph_width(' ')); | 1541 | par_indent_spaces = draw_columns/(5*glyph_width(' ')); |
1542 | calc_max_width(); | ||
1543 | } | ||
1544 | |||
1545 | static void init_header_and_footer(void) | ||
1546 | { | ||
1547 | header_height = 0; | ||
1548 | footer_height = 0; | ||
1549 | if (rb->global_settings->statusbar == STATUSBAR_TOP) | ||
1550 | { | ||
1551 | if (prefs.header_mode == HD_SBAR || prefs.header_mode == HD_BOTH) | ||
1552 | header_height = STATUSBAR_HEIGHT; | ||
1553 | |||
1554 | if (prefs.footer_mode == FT_SBAR) | ||
1555 | prefs.footer_mode = FT_NONE; | ||
1556 | else if (prefs.footer_mode == FT_BOTH) | ||
1557 | prefs.footer_mode = FT_PAGE; | ||
1558 | } | ||
1559 | else if (rb->global_settings->statusbar == STATUSBAR_BOTTOM) | ||
1560 | { | ||
1561 | if (prefs.footer_mode == FT_SBAR || prefs.footer_mode == FT_BOTH) | ||
1562 | footer_height = STATUSBAR_HEIGHT; | ||
1563 | |||
1564 | if (prefs.header_mode == HD_SBAR) | ||
1565 | prefs.header_mode = HD_NONE; | ||
1566 | else if (prefs.header_mode == HD_BOTH) | ||
1567 | prefs.header_mode = HD_PATH; | ||
1568 | } | ||
1569 | else /* STATUSBAR_OFF || STATUSBAR_CUSTOM */ | ||
1570 | { | ||
1571 | if (prefs.header_mode == HD_SBAR) | ||
1572 | prefs.header_mode = HD_NONE; | ||
1573 | else if (prefs.header_mode == HD_BOTH) | ||
1574 | prefs.header_mode = HD_PATH; | ||
1575 | |||
1576 | if (prefs.footer_mode == FT_SBAR) | ||
1577 | prefs.footer_mode = FT_NONE; | ||
1578 | else if (prefs.footer_mode == FT_BOTH) | ||
1579 | prefs.footer_mode = FT_PAGE; | ||
1580 | } | ||
1581 | |||
1582 | if (prefs.header_mode == HD_NONE || prefs.header_mode == HD_PATH || | ||
1583 | prefs.footer_mode == FT_NONE || prefs.footer_mode == FT_PAGE) | ||
1584 | rb->gui_syncstatusbar_draw(rb->statusbars, false); | ||
1585 | |||
1586 | if (prefs.header_mode == HD_PATH || prefs.header_mode == HD_BOTH) | ||
1587 | header_height += pf->height; | ||
1588 | if (prefs.footer_mode == FT_PAGE || prefs.footer_mode == FT_BOTH) | ||
1589 | footer_height += pf->height; | ||
1590 | |||
1591 | display_lines = (LCD_HEIGHT - header_height - footer_height) / pf->height; | ||
1592 | |||
1593 | lpage = 0; | ||
1594 | last_file_pos = 0; | ||
1595 | last_screen_top_ptr = NULL; | ||
1596 | } | ||
1597 | |||
1598 | static void change_font(unsigned char *font) | ||
1599 | { | ||
1600 | unsigned char buf[MAX_PATH]; | ||
1601 | |||
1602 | if (font == NULL || *font == '\0') | ||
1603 | return; | ||
1604 | |||
1605 | rb->snprintf(buf, MAX_PATH, "%s/%s.fnt", FONT_DIR, font); | ||
1606 | if (rb->font_load(NULL, buf) < 0) | ||
1607 | rb->splash(HZ/2, "font load failed."); | ||
1195 | } | 1608 | } |
1196 | #else | ||
1197 | #define init_need_scrollbar() | ||
1198 | #endif | 1609 | #endif |
1199 | 1610 | ||
1200 | static bool viewer_init(void) | 1611 | static bool viewer_init(void) |
1201 | { | 1612 | { |
1202 | #ifdef HAVE_LCD_BITMAP | 1613 | #ifdef HAVE_LCD_BITMAP |
1203 | 1614 | /* initialize fonts */ | |
1204 | pf = rb->font_get(FONT_UI); | 1615 | pf = rb->font_get(FONT_UI); |
1205 | |||
1206 | display_lines = LCD_HEIGHT / pf->height; | ||
1207 | draw_columns = display_columns = LCD_WIDTH; | 1616 | draw_columns = display_columns = LCD_WIDTH; |
1208 | #else | 1617 | #else |
1209 | /* REAL fixed pitch :) all chars use up 1 cell */ | 1618 | /* REAL fixed pitch :) all chars use up 1 cell */ |
@@ -1216,172 +1625,727 @@ static bool viewer_init(void) | |||
1216 | if (fd < 0) | 1625 | if (fd < 0) |
1217 | return false; | 1626 | return false; |
1218 | 1627 | ||
1219 | file_size = rb->filesize(fd); | ||
1220 | if (file_size==-1) | ||
1221 | return false; | ||
1222 | |||
1223 | /* Init mac_text value used in processing buffer */ | 1628 | /* Init mac_text value used in processing buffer */ |
1224 | mac_text = false; | 1629 | mac_text = false; |
1225 | 1630 | ||
1226 | return true; | 1631 | return true; |
1227 | } | 1632 | } |
1228 | 1633 | ||
1229 | static void viewer_default_settings(void) | 1634 | /* When a file is UTF-8 file with BOM, if prefs.encoding is UTF-8, |
1635 | * then file size decreases only BOM_SIZE. | ||
1636 | */ | ||
1637 | static void get_filesize(void) | ||
1638 | { | ||
1639 | file_size = rb->filesize(fd); | ||
1640 | if (file_size == -1) | ||
1641 | return; | ||
1642 | |||
1643 | if (prefs.encoding == UTF_8 && is_bom) | ||
1644 | file_size -= BOM_SIZE; | ||
1645 | } | ||
1646 | |||
1647 | static int bm_comp(const void *a, const void *b) | ||
1648 | { | ||
1649 | struct bookmark_info *pa; | ||
1650 | struct bookmark_info *pb; | ||
1651 | |||
1652 | pa = (struct bookmark_info*)a; | ||
1653 | pb = (struct bookmark_info*)b; | ||
1654 | |||
1655 | if (pa->page != pb->page) | ||
1656 | return pa->page - pb->page; | ||
1657 | |||
1658 | return pa->line - pb->line; | ||
1659 | } | ||
1660 | |||
1661 | static void viewer_add_bookmark(void) | ||
1662 | { | ||
1663 | if (bookmark_count >= MAX_BOOKMARKS-1) | ||
1664 | return; | ||
1665 | |||
1666 | bookmarks[bookmark_count].file_position | ||
1667 | = file_pos + screen_top_ptr - buffer; | ||
1668 | bookmarks[bookmark_count].page = cpage; | ||
1669 | bookmarks[bookmark_count].line = cline; | ||
1670 | bookmarks[bookmark_count].flag = BOOKMARK_USER; | ||
1671 | bookmark_count++; | ||
1672 | } | ||
1673 | |||
1674 | static int viewer_add_last_read_bookmark(void) | ||
1675 | { | ||
1676 | int i; | ||
1677 | |||
1678 | i = viewer_find_bookmark(cpage, cline); | ||
1679 | if (i >= 0) | ||
1680 | bookmarks[i].flag |= BOOKMARK_LAST; | ||
1681 | else | ||
1682 | { | ||
1683 | viewer_add_bookmark(); | ||
1684 | i = bookmark_count-1; | ||
1685 | bookmarks[i].flag = BOOKMARK_LAST; | ||
1686 | } | ||
1687 | return i; | ||
1688 | } | ||
1689 | |||
1690 | static void viewer_remove_bookmark(int i) | ||
1691 | { | ||
1692 | int j; | ||
1693 | |||
1694 | if (i < 0 || i >= bookmark_count) | ||
1695 | return; | ||
1696 | |||
1697 | for (j = i+1; j < bookmark_count; j++) | ||
1698 | rb->memcpy(&bookmarks[j-1], &bookmarks[j], | ||
1699 | sizeof(struct bookmark_info)); | ||
1700 | |||
1701 | bookmark_count--; | ||
1702 | } | ||
1703 | |||
1704 | static void viewer_remove_last_read_bookmark(void) | ||
1705 | { | ||
1706 | int i, j; | ||
1707 | |||
1708 | for (i = 0; i < bookmark_count; i++) | ||
1709 | { | ||
1710 | if (bookmarks[i].flag & BOOKMARK_LAST) | ||
1711 | { | ||
1712 | if (bookmarks[i].flag == BOOKMARK_LAST) | ||
1713 | { | ||
1714 | for (j = i+1; j < bookmark_count; j++) | ||
1715 | rb->memcpy(&bookmarks[j-1], &bookmarks[j], | ||
1716 | sizeof(struct bookmark_info)); | ||
1717 | |||
1718 | bookmark_count--; | ||
1719 | } | ||
1720 | else | ||
1721 | bookmarks[i].flag = BOOKMARK_USER; | ||
1722 | break; | ||
1723 | } | ||
1724 | } | ||
1725 | } | ||
1726 | |||
1727 | static int viewer_get_last_read_bookmark(void) | ||
1728 | { | ||
1729 | int i; | ||
1730 | |||
1731 | for (i = 0; i < bookmark_count; i++) | ||
1732 | { | ||
1733 | if (bookmarks[i].flag & BOOKMARK_LAST) | ||
1734 | return i; | ||
1735 | } | ||
1736 | return -1; | ||
1737 | } | ||
1738 | |||
1739 | static void viewer_select_bookmark(int initval) | ||
1740 | { | ||
1741 | int i; | ||
1742 | int ipage = 0; | ||
1743 | int iline = 0; | ||
1744 | int screen_pos; | ||
1745 | int screen_top; | ||
1746 | int selected = -1; | ||
1747 | |||
1748 | struct opt_items items[bookmark_count]; | ||
1749 | unsigned char names[bookmark_count][38]; | ||
1750 | |||
1751 | if (initval >= 0 && initval < bookmark_count) | ||
1752 | { | ||
1753 | ipage = bookmarks[initval].page; | ||
1754 | iline = bookmarks[initval].line; | ||
1755 | } | ||
1756 | |||
1757 | rb->qsort(bookmarks, bookmark_count, sizeof(struct bookmark_info), | ||
1758 | bm_comp); | ||
1759 | |||
1760 | for (i = 0; i < bookmark_count; i++) | ||
1761 | { | ||
1762 | rb->snprintf(names[i], sizeof(names[0]), | ||
1763 | #if CONFIG_KEYPAD != PLAYER_PAD | ||
1764 | "%sPage: %d Line: %d", | ||
1765 | #else | ||
1766 | "%sP:%d L:%d", | ||
1767 | #endif | ||
1768 | (bookmarks[i].flag&BOOKMARK_LAST)? "*":" ", | ||
1769 | bookmarks[i].page, | ||
1770 | bookmarks[i].line); | ||
1771 | items[i].string = names[i]; | ||
1772 | items[i].voice_id = -1; | ||
1773 | if (selected < 0 && bookmarks[i].page == ipage && bookmarks[i].line == iline) | ||
1774 | selected = i; | ||
1775 | } | ||
1776 | |||
1777 | rb->set_option("Select bookmark", &selected, INT, items, | ||
1778 | sizeof(items) / sizeof(items[0]), NULL); | ||
1779 | |||
1780 | if (selected < 0 || selected >= bookmark_count) | ||
1781 | { | ||
1782 | if (initval < 0 || (selected = viewer_get_last_read_bookmark()) < 0) | ||
1783 | { | ||
1784 | if (initval < 0) | ||
1785 | rb->splash(HZ, "Start the first page."); | ||
1786 | file_pos = 0; | ||
1787 | screen_top_ptr = buffer; | ||
1788 | cpage = 1; | ||
1789 | cline = 1; | ||
1790 | buffer_end = BUFFER_END(); | ||
1791 | return; | ||
1792 | } | ||
1793 | } | ||
1794 | |||
1795 | screen_pos = bookmarks[selected].file_position; | ||
1796 | screen_top = screen_pos % buffer_size; | ||
1797 | file_pos = screen_pos - screen_top; | ||
1798 | screen_top_ptr = buffer + screen_top; | ||
1799 | cpage = bookmarks[selected].page; | ||
1800 | cline = bookmarks[selected].line; | ||
1801 | buffer_end = BUFFER_END(); | ||
1802 | } | ||
1803 | |||
1804 | static void viewer_default_preferences(void) | ||
1230 | { | 1805 | { |
1231 | prefs.word_mode = WRAP; | 1806 | prefs.word_mode = WRAP; |
1232 | prefs.line_mode = NORMAL; | 1807 | prefs.line_mode = NORMAL; |
1233 | prefs.view_mode = NARROW; | 1808 | prefs.view_mode = NARROW; |
1234 | prefs.scroll_mode = PAGE; | 1809 | prefs.scroll_mode = PAGE; |
1235 | #ifdef HAVE_LCD_BITMAP | ||
1236 | prefs.page_mode = NO_OVERLAP; | 1810 | prefs.page_mode = NO_OVERLAP; |
1237 | prefs.scrollbar_mode = SB_OFF; | 1811 | prefs.scrollbar_mode = SB_OFF; |
1812 | rb->memset(prefs.font, 0, MAX_PATH); | ||
1813 | #ifdef HAVE_LCD_BITMAP | ||
1814 | prefs.header_mode = HD_BOTH; | ||
1815 | prefs.footer_mode = FT_BOTH; | ||
1816 | rb->snprintf(prefs.font, MAX_PATH, "%s", rb->global_settings->font_file); | ||
1817 | #else | ||
1818 | prefs.header_mode = HD_NONE; | ||
1819 | prefs.footer_mode = FT_NONE; | ||
1238 | #endif | 1820 | #endif |
1239 | prefs.autoscroll_speed = 1; | 1821 | prefs.autoscroll_speed = 1; |
1240 | /* Set codepage to system default */ | 1822 | /* Set codepage to system default */ |
1241 | prefs.encoding = rb->global_settings->default_codepage; | 1823 | prefs.encoding = rb->global_settings->default_codepage; |
1242 | } | 1824 | } |
1243 | 1825 | ||
1244 | static void viewer_load_settings(void) /* same name as global, but not the same file.. */ | 1826 | static bool viewer_read_preferences(int pfd) |
1827 | { | ||
1828 | unsigned char buf[PREFERENCES_SIZE]; | ||
1829 | unsigned char *p = buf; | ||
1830 | |||
1831 | if (rb->read(pfd, buf, sizeof(buf)) != sizeof(buf)) | ||
1832 | return false; | ||
1833 | |||
1834 | prefs.word_mode = *p++; | ||
1835 | prefs.line_mode = *p++; | ||
1836 | prefs.view_mode = *p++; | ||
1837 | prefs.encoding = *p++; | ||
1838 | prefs.scrollbar_mode = *p++; | ||
1839 | prefs.need_scrollbar = *p++; | ||
1840 | prefs.page_mode = *p++; | ||
1841 | prefs.header_mode = *p++; | ||
1842 | prefs.footer_mode = *p++; | ||
1843 | prefs.scroll_mode = *p++; | ||
1844 | prefs.autoscroll_speed = *p++; | ||
1845 | rb->memcpy(prefs.font, p, MAX_PATH); | ||
1846 | |||
1847 | return true; | ||
1848 | } | ||
1849 | |||
1850 | static bool viewer_write_preferences(int pfd) | ||
1851 | { | ||
1852 | unsigned char buf[PREFERENCES_SIZE]; | ||
1853 | unsigned char *p = buf; | ||
1854 | |||
1855 | *p++ = prefs.word_mode; | ||
1856 | *p++ = prefs.line_mode; | ||
1857 | *p++ = prefs.view_mode; | ||
1858 | *p++ = prefs.encoding; | ||
1859 | *p++ = prefs.scrollbar_mode; | ||
1860 | *p++ = prefs.need_scrollbar; | ||
1861 | *p++ = prefs.page_mode; | ||
1862 | *p++ = prefs.header_mode; | ||
1863 | *p++ = prefs.footer_mode; | ||
1864 | *p++ = prefs.scroll_mode; | ||
1865 | *p++ = prefs.autoscroll_speed; | ||
1866 | rb->memcpy(p, prefs.font, MAX_PATH); | ||
1867 | |||
1868 | return (rb->write(pfd, buf, sizeof(buf)) == sizeof(buf)); | ||
1869 | } | ||
1870 | |||
1871 | static bool viewer_read_bookmark_info(int bfd, struct bookmark_info *b) | ||
1872 | { | ||
1873 | unsigned char buf[BOOKMARK_SIZE]; | ||
1874 | |||
1875 | if (rb->read(bfd, buf, sizeof(buf)) != sizeof(buf)) | ||
1876 | return false; | ||
1877 | |||
1878 | b->file_position = (buf[0] << 24)|(buf[1] << 16)|(buf[2] << 8)|buf[3]; | ||
1879 | b->page = (buf[4] << 8)|buf[5]; | ||
1880 | b->line = buf[6]; | ||
1881 | b->flag = buf[7]; | ||
1882 | |||
1883 | return true; | ||
1884 | } | ||
1885 | |||
1886 | static bool viewer_read_bookmark_infos(int bfd) | ||
1245 | { | 1887 | { |
1246 | int settings_fd, i; | 1888 | unsigned char c; |
1247 | struct bookmark_file_data *data; | 1889 | int i; |
1248 | struct bookmarked_file_info this_bookmark; | ||
1249 | 1890 | ||
1250 | /* read settings file */ | 1891 | if (rb->read(bfd, &c, 1) != 1) |
1251 | settings_fd=rb->open(SETTINGS_FILE, O_RDONLY); | ||
1252 | if ((settings_fd >= 0) && (rb->filesize(settings_fd) == sizeof(struct preferences))) | ||
1253 | { | 1892 | { |
1254 | rb->read(settings_fd, &prefs, sizeof(struct preferences)); | 1893 | bookmark_count = 0; |
1255 | rb->close(settings_fd); | 1894 | return false; |
1256 | } | 1895 | } |
1257 | else | 1896 | |
1897 | bookmark_count = c; | ||
1898 | if (bookmark_count > MAX_BOOKMARKS) | ||
1899 | bookmark_count = MAX_BOOKMARKS; | ||
1900 | |||
1901 | for (i = 0; i < bookmark_count; i++) | ||
1258 | { | 1902 | { |
1259 | /* load default settings if there is no settings file */ | 1903 | if (!viewer_read_bookmark_info(bfd, &bookmarks[i])) |
1260 | viewer_default_settings(); | 1904 | { |
1905 | bookmark_count = i; | ||
1906 | return false; | ||
1907 | } | ||
1261 | } | 1908 | } |
1909 | return true; | ||
1910 | } | ||
1262 | 1911 | ||
1263 | rb->memcpy(&old_prefs, &prefs, sizeof(struct preferences)); | 1912 | static bool viewer_write_bookmark_info(int bfd, struct bookmark_info *b) |
1913 | { | ||
1914 | unsigned char buf[BOOKMARK_SIZE]; | ||
1915 | unsigned char *p = buf; | ||
1916 | unsigned long ul; | ||
1917 | |||
1918 | ul = b->file_position; | ||
1919 | *p++ = ul >> 24; | ||
1920 | *p++ = ul >> 16; | ||
1921 | *p++ = ul >> 8; | ||
1922 | *p++ = ul; | ||
1264 | 1923 | ||
1265 | data = (struct bookmark_file_data*)buffer; /* grab the text buffer */ | 1924 | ul = b->page; |
1266 | data->bookmarked_files_count = 0; | 1925 | *p++ = ul >> 8; |
1926 | *p++ = ul; | ||
1267 | 1927 | ||
1268 | /* read bookmarks if file exists */ | 1928 | *p++ = b->line; |
1269 | settings_fd = rb->open(BOOKMARKS_FILE, O_RDONLY); | 1929 | *p = b->flag; |
1270 | if (settings_fd >= 0) | 1930 | |
1931 | return (rb->write(bfd, buf, sizeof(buf)) == sizeof(buf)); | ||
1932 | } | ||
1933 | |||
1934 | static bool viewer_write_bookmark_infos(int bfd) | ||
1935 | { | ||
1936 | unsigned char c = bookmark_count; | ||
1937 | int i; | ||
1938 | |||
1939 | if (rb->write(bfd, &c, 1) != 1) | ||
1940 | return false; | ||
1941 | |||
1942 | for (i = 0; i < bookmark_count; i++) | ||
1271 | { | 1943 | { |
1272 | /* figure out how many items to read */ | 1944 | if (!viewer_write_bookmark_info(bfd, &bookmarks[i])) |
1273 | rb->read(settings_fd, &data->bookmarked_files_count, sizeof(signed int)); | 1945 | return false; |
1274 | if (data->bookmarked_files_count > MAX_BOOKMARKED_FILES) | ||
1275 | data->bookmarked_files_count = MAX_BOOKMARKED_FILES; | ||
1276 | rb->read(settings_fd, data->bookmarks, | ||
1277 | sizeof(struct bookmarked_file_info) * data->bookmarked_files_count); | ||
1278 | rb->close(settings_fd); | ||
1279 | } | 1946 | } |
1280 | 1947 | ||
1281 | file_pos = 0; | 1948 | return true; |
1282 | screen_top_ptr = buffer; | 1949 | } |
1283 | 1950 | ||
1284 | /* check if current file is in list */ | 1951 | static bool viewer_load_global_settings(void) |
1285 | for (i=0; i < data->bookmarked_files_count; i++) | 1952 | { |
1286 | { | 1953 | unsigned buf[GLOBAL_SETTINGS_H_SIZE]; |
1287 | if (!rb->strcmp(file_name, data->bookmarks[i].filename)) | 1954 | int sfd = rb->open(GLOBAL_SETTINGS_FILE, O_RDONLY); |
1288 | { | 1955 | |
1289 | int screen_pos = data->bookmarks[i].file_position + data->bookmarks[i].top_ptr_pos; | 1956 | if (sfd < 0) |
1290 | int screen_top = screen_pos % buffer_size; | 1957 | return false; |
1291 | file_pos = screen_pos - screen_top; | 1958 | |
1292 | screen_top_ptr = buffer + screen_top; | 1959 | if ((rb->read(sfd, buf, GLOBAL_SETTINGS_H_SIZE) != GLOBAL_SETTINGS_H_SIZE) || |
1293 | break; | 1960 | rb->memcmp(buf, GLOBAL_SETTINGS_HEADER, GLOBAL_SETTINGS_H_SIZE) || |
1294 | } | 1961 | !viewer_read_preferences(sfd)) |
1962 | { | ||
1963 | rb->close(sfd); | ||
1964 | return false; | ||
1295 | } | 1965 | } |
1966 | rb->close(sfd); | ||
1967 | return true; | ||
1968 | } | ||
1296 | 1969 | ||
1297 | this_bookmark.file_position = file_pos; | 1970 | static bool viewer_save_global_settings(void) |
1298 | this_bookmark.top_ptr_pos = screen_top_ptr - buffer; | 1971 | { |
1972 | int sfd = rb->open(GLOBAL_SETTINGS_TMP_FILE, O_WRONLY|O_CREAT|O_TRUNC); | ||
1299 | 1973 | ||
1300 | rb->memset(&this_bookmark.filename[0],0,MAX_PATH); | 1974 | if (sfd < 0) |
1301 | rb->strcpy(this_bookmark.filename,file_name); | 1975 | return false; |
1302 | 1976 | ||
1303 | /* prevent potential slot overflow */ | 1977 | if (rb->write(sfd, &GLOBAL_SETTINGS_HEADER, GLOBAL_SETTINGS_H_SIZE) |
1304 | if (i >= data->bookmarked_files_count) | 1978 | != GLOBAL_SETTINGS_H_SIZE || |
1979 | !viewer_write_preferences(sfd)) | ||
1305 | { | 1980 | { |
1306 | if (i < MAX_BOOKMARKED_FILES) | 1981 | rb->close(sfd); |
1307 | data->bookmarked_files_count++; | 1982 | rb->remove(GLOBAL_SETTINGS_TMP_FILE); |
1308 | else | 1983 | return false; |
1309 | i = MAX_BOOKMARKED_FILES-1; | ||
1310 | } | 1984 | } |
1985 | rb->close(sfd); | ||
1986 | rb->remove(GLOBAL_SETTINGS_FILE); | ||
1987 | rb->rename(GLOBAL_SETTINGS_TMP_FILE, GLOBAL_SETTINGS_FILE); | ||
1988 | return true; | ||
1989 | } | ||
1311 | 1990 | ||
1312 | /* write bookmark file with spare slot in first position | 1991 | static void viewer_load_settings(void) |
1313 | to be filled in by viewer_save_settings */ | 1992 | { |
1314 | settings_fd = rb->open(BOOKMARKS_FILE, O_WRONLY|O_CREAT); | 1993 | unsigned char buf[MAX_PATH+2]; |
1315 | if (settings_fd >=0 ) | 1994 | unsigned int fcount; |
1995 | unsigned int i; | ||
1996 | bool res = false; | ||
1997 | int sfd; | ||
1998 | unsigned int size; | ||
1999 | |||
2000 | sfd = rb->open(SETTINGS_FILE, O_RDONLY); | ||
2001 | if (sfd < 0) | ||
2002 | goto read_end; | ||
2003 | |||
2004 | if ((rb->read(sfd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2) || | ||
2005 | rb->memcmp(buf, SETTINGS_HEADER, SETTINGS_H_SIZE)) | ||
1316 | { | 2006 | { |
1317 | /* write count */ | 2007 | /* illegal setting file */ |
1318 | rb->write (settings_fd, &data->bookmarked_files_count, sizeof(signed int)); | 2008 | rb->close(sfd); |
2009 | |||
2010 | if (rb->file_exists(SETTINGS_FILE)) | ||
2011 | rb->remove(SETTINGS_FILE); | ||
1319 | 2012 | ||
1320 | /* write the current bookmark */ | 2013 | goto read_end; |
1321 | rb->write (settings_fd, &this_bookmark, sizeof(struct bookmarked_file_info)); | 2014 | } |
2015 | |||
2016 | fcount = (buf[SETTINGS_H_SIZE] << 8) | buf[SETTINGS_H_SIZE+1]; | ||
2017 | for (i = 0; i < fcount; i++) | ||
2018 | { | ||
2019 | if (rb->read(sfd, buf, MAX_PATH+2) != MAX_PATH+2) | ||
2020 | break; | ||
1322 | 2021 | ||
1323 | /* write everything that was before this bookmark */ | 2022 | size = (buf[MAX_PATH] << 8) | buf[MAX_PATH+1]; |
1324 | rb->write (settings_fd, data->bookmarks, sizeof(struct bookmarked_file_info)*i); | 2023 | if (rb->strcmp(buf, file_name)) |
2024 | { | ||
2025 | if (rb->lseek(sfd, size, SEEK_CUR) < 0) | ||
2026 | break; | ||
2027 | continue; | ||
2028 | } | ||
2029 | if (!viewer_read_preferences(sfd)) | ||
2030 | break; | ||
1325 | 2031 | ||
1326 | rb->close(settings_fd); | 2032 | res = viewer_read_bookmark_infos(sfd); |
2033 | break; | ||
1327 | } | 2034 | } |
1328 | 2035 | ||
1329 | buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ | 2036 | rb->close(sfd); |
1330 | 2037 | ||
1331 | if (BUFFER_OOB(screen_top_ptr)) | 2038 | read_end: |
2039 | if (!res) | ||
1332 | { | 2040 | { |
2041 | /* load global settings */ | ||
2042 | if (!viewer_load_global_settings()) | ||
2043 | viewer_default_preferences(); | ||
2044 | |||
2045 | file_pos = 0; | ||
1333 | screen_top_ptr = buffer; | 2046 | screen_top_ptr = buffer; |
2047 | cpage = 1; | ||
2048 | cline = 1; | ||
2049 | bookmark_count = 0; | ||
2050 | } | ||
2051 | |||
2052 | rb->memcpy(&old_prefs, &prefs, sizeof(struct preferences)); | ||
2053 | calc_max_width(); | ||
2054 | |||
2055 | if (bookmark_count > 1) | ||
2056 | viewer_select_bookmark(-1); | ||
2057 | else if (bookmark_count == 1) | ||
2058 | { | ||
2059 | int screen_pos; | ||
2060 | int screen_top; | ||
2061 | |||
2062 | screen_pos = bookmarks[0].file_position; | ||
2063 | screen_top = screen_pos % buffer_size; | ||
2064 | file_pos = screen_pos - screen_top; | ||
2065 | screen_top_ptr = buffer + screen_top; | ||
2066 | cpage = bookmarks[0].page; | ||
2067 | cline = bookmarks[0].line; | ||
1334 | } | 2068 | } |
1335 | 2069 | ||
2070 | viewer_remove_last_read_bookmark(); | ||
2071 | |||
2072 | check_bom(); | ||
2073 | get_filesize(); | ||
2074 | |||
2075 | buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ | ||
2076 | |||
2077 | if (BUFFER_OOB(screen_top_ptr)) | ||
2078 | screen_top_ptr = buffer; | ||
2079 | |||
1336 | fill_buffer(file_pos, buffer, buffer_size); | 2080 | fill_buffer(file_pos, buffer, buffer_size); |
2081 | if (prefs.scroll_mode == PAGE && cline > 1) | ||
2082 | viewer_scroll_to_top_line(); | ||
1337 | 2083 | ||
1338 | /* remember the current position */ | 2084 | /* remember the current position */ |
1339 | start_position = file_pos + screen_top_ptr - buffer; | 2085 | start_position = file_pos + screen_top_ptr - buffer; |
1340 | 2086 | ||
2087 | #ifdef HAVE_LCD_BITMAP | ||
2088 | if (strcmp(prefs.font, rb->global_settings->font_file)) | ||
2089 | change_font(prefs.font); | ||
2090 | |||
1341 | init_need_scrollbar(); | 2091 | init_need_scrollbar(); |
2092 | init_header_and_footer(); | ||
2093 | #endif | ||
1342 | } | 2094 | } |
1343 | 2095 | ||
1344 | static void viewer_save_settings(void)/* same name as global, but not the same file.. */ | 2096 | static bool copy_bookmark_file(int sfd, int dfd, off_t start, off_t size) |
1345 | { | 2097 | { |
1346 | int settings_fd; | 2098 | off_t rsize; |
2099 | |||
2100 | if (rb->lseek(sfd, start, SEEK_SET) < 0) | ||
2101 | return false; | ||
1347 | 2102 | ||
1348 | /* save the viewer settings if they have been changed */ | 2103 | while (size > 0) |
1349 | if (rb->memcmp(&prefs, &old_prefs, sizeof(struct preferences))) | ||
1350 | { | 2104 | { |
1351 | settings_fd = rb->creat(SETTINGS_FILE); /* create the settings file */ | 2105 | if (size > buffer_size) |
2106 | rsize = buffer_size; | ||
2107 | else | ||
2108 | rsize = size; | ||
2109 | size -= rsize; | ||
1352 | 2110 | ||
1353 | if (settings_fd >= 0 ) | 2111 | if (rb->read(sfd, buffer, rsize) != rsize || |
1354 | { | 2112 | rb->write(dfd, buffer, rsize) != rsize) |
1355 | rb->write (settings_fd, &prefs, sizeof(struct preferences)); | 2113 | return false; |
1356 | rb->close(settings_fd); | 2114 | } |
1357 | } | 2115 | return true; |
2116 | } | ||
2117 | |||
2118 | static bool viewer_save_settings(void) | ||
2119 | { | ||
2120 | unsigned char buf[MAX_PATH+2]; | ||
2121 | unsigned int fcount = 0; | ||
2122 | unsigned int i; | ||
2123 | int idx; | ||
2124 | int ofd; | ||
2125 | int tfd; | ||
2126 | off_t first_copy_size = 0; | ||
2127 | off_t second_copy_start_pos = 0; | ||
2128 | off_t size; | ||
2129 | |||
2130 | /* add reading page to bookmarks */ | ||
2131 | idx = viewer_find_bookmark(cpage, cline); | ||
2132 | if (idx >= 0) | ||
2133 | bookmarks[idx].flag |= BOOKMARK_LAST; | ||
2134 | else | ||
2135 | { | ||
2136 | viewer_add_bookmark(); | ||
2137 | bookmarks[bookmark_count-1].flag = BOOKMARK_LAST; | ||
1358 | } | 2138 | } |
2139 | |||
2140 | tfd = rb->open(SETTINGS_TMP_FILE, O_WRONLY|O_CREAT|O_TRUNC); | ||
2141 | if (tfd < 0) | ||
2142 | return false; | ||
1359 | 2143 | ||
1360 | /* save the bookmark if the position has changed */ | 2144 | ofd = rb->open(SETTINGS_FILE, O_RDWR); |
1361 | if (file_pos + screen_top_ptr - buffer != start_position) | 2145 | if (ofd >= 0) |
1362 | { | 2146 | { |
1363 | settings_fd = rb->open(BOOKMARKS_FILE, O_WRONLY|O_CREAT); | 2147 | if ((rb->read(ofd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2) || |
2148 | rb->memcmp(buf, SETTINGS_HEADER, SETTINGS_H_SIZE)) | ||
2149 | { | ||
2150 | rb->close(ofd); | ||
2151 | goto save_err; | ||
2152 | } | ||
2153 | fcount = (buf[SETTINGS_H_SIZE] << 8) | buf[SETTINGS_H_SIZE+1]; | ||
2154 | |||
2155 | for (i = 0; i < fcount; i++) | ||
2156 | { | ||
2157 | if (rb->read(ofd, buf, MAX_PATH+2) != MAX_PATH+2) | ||
2158 | { | ||
2159 | rb->close(ofd); | ||
2160 | goto save_err; | ||
2161 | } | ||
2162 | size = (buf[MAX_PATH] << 8) | buf[MAX_PATH+1]; | ||
2163 | if (rb->strcmp(buf, file_name)) | ||
2164 | { | ||
2165 | if (rb->lseek(ofd, size, SEEK_CUR) < 0) | ||
2166 | { | ||
2167 | rb->close(ofd); | ||
2168 | goto save_err; | ||
2169 | } | ||
2170 | } | ||
2171 | else | ||
2172 | { | ||
2173 | first_copy_size = rb->lseek(ofd, 0, SEEK_CUR); | ||
2174 | if (first_copy_size < 0) | ||
2175 | { | ||
2176 | rb->close(ofd); | ||
2177 | goto save_err; | ||
2178 | } | ||
2179 | second_copy_start_pos = first_copy_size + size; | ||
2180 | first_copy_size -= MAX_PATH+2; | ||
2181 | fcount--; | ||
2182 | break; | ||
2183 | } | ||
2184 | } | ||
2185 | if (first_copy_size == 0) | ||
2186 | first_copy_size = rb->filesize(ofd); | ||
1364 | 2187 | ||
1365 | if (settings_fd >= 0 ) | 2188 | if (!copy_bookmark_file(ofd, tfd, 0, first_copy_size)) |
1366 | { | 2189 | { |
1367 | struct bookmarked_file_info b; | 2190 | rb->close(ofd); |
1368 | b.file_position = file_pos + screen_top_ptr - buffer; | 2191 | goto save_err; |
1369 | b.top_ptr_pos = 0; /* this is only kept for legassy reasons */ | 2192 | } |
1370 | rb->memset(&b.filename[0],0,MAX_PATH); | 2193 | if (second_copy_start_pos > 0) |
1371 | rb->strcpy(b.filename,file_name); | 2194 | { |
1372 | rb->lseek(settings_fd,sizeof(signed int),SEEK_SET); | 2195 | if (!copy_bookmark_file(ofd, tfd, second_copy_start_pos, |
1373 | rb->write (settings_fd, &b, sizeof(struct bookmarked_file_info)); | 2196 | rb->filesize(ofd) - second_copy_start_pos)) |
1374 | rb->close(settings_fd); | 2197 | { |
2198 | rb->close(ofd); | ||
2199 | goto save_err; | ||
2200 | } | ||
1375 | } | 2201 | } |
2202 | rb->close(ofd); | ||
1376 | } | 2203 | } |
2204 | else | ||
2205 | { | ||
2206 | rb->memcpy(buf, SETTINGS_HEADER, SETTINGS_H_SIZE); | ||
2207 | buf[SETTINGS_H_SIZE] = 0; | ||
2208 | buf[SETTINGS_H_SIZE+1] = 0; | ||
2209 | if (rb->write(tfd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2) | ||
2210 | goto save_err; | ||
2211 | } | ||
2212 | |||
2213 | /* copy to current read file's bookmarks */ | ||
2214 | rb->memset(buf, 0, MAX_PATH); | ||
2215 | rb->snprintf(buf, MAX_PATH, "%s", file_name); | ||
2216 | |||
2217 | size = PREFERENCES_SIZE + bookmark_count * BOOKMARK_SIZE + 1; | ||
2218 | buf[MAX_PATH] = size >> 8; | ||
2219 | buf[MAX_PATH+1] = size; | ||
2220 | |||
2221 | if (rb->write(tfd, buf, MAX_PATH+2) != MAX_PATH+2) | ||
2222 | goto save_err; | ||
2223 | |||
2224 | if (!viewer_write_preferences(tfd)) | ||
2225 | goto save_err; | ||
2226 | |||
2227 | if (!viewer_write_bookmark_infos(tfd)) | ||
2228 | goto save_err; | ||
2229 | |||
2230 | if (rb->lseek(tfd, SETTINGS_H_SIZE, SEEK_SET) < 0) | ||
2231 | goto save_err; | ||
2232 | |||
2233 | fcount++; | ||
2234 | buf[0] = fcount >> 8; | ||
2235 | buf[1] = fcount; | ||
2236 | |||
2237 | if (rb->write(tfd, buf, 2) != 2) | ||
2238 | goto save_err; | ||
2239 | |||
2240 | rb->close(tfd); | ||
2241 | |||
2242 | rb->remove(SETTINGS_FILE); | ||
2243 | rb->rename(SETTINGS_TMP_FILE, SETTINGS_FILE); | ||
2244 | |||
2245 | return true; | ||
2246 | |||
2247 | save_err: | ||
2248 | rb->close(tfd); | ||
2249 | rb->remove(SETTINGS_TMP_FILE); | ||
2250 | return false; | ||
1377 | } | 2251 | } |
1378 | 2252 | ||
1379 | static void viewer_exit(void *parameter) | 2253 | static void viewer_exit(void *parameter) |
1380 | { | 2254 | { |
1381 | (void)parameter; | 2255 | (void)parameter; |
1382 | 2256 | ||
1383 | viewer_save_settings(); | 2257 | /* save preference and bookmarks */ |
2258 | if (!viewer_save_settings()) | ||
2259 | rb->splash(HZ, "Can't save preference and bookmarks."); | ||
2260 | |||
1384 | rb->close(fd); | 2261 | rb->close(fd); |
2262 | #ifdef HAVE_LCD_BITMAP | ||
2263 | if (strcmp(prefs.font, rb->global_settings->font_file)) | ||
2264 | change_font(rb->global_settings->font_file); | ||
2265 | #endif | ||
2266 | } | ||
2267 | |||
2268 | static void calc_page(void) | ||
2269 | { | ||
2270 | int i; | ||
2271 | unsigned char *line_begin; | ||
2272 | unsigned char *line_end; | ||
2273 | off_t sfp; | ||
2274 | unsigned char *sstp; | ||
2275 | |||
2276 | rb->splash(0, "Calculating page/line number..."); | ||
2277 | |||
2278 | /* add reading page to bookmarks */ | ||
2279 | viewer_add_last_read_bookmark(); | ||
2280 | |||
2281 | rb->qsort(bookmarks, bookmark_count, sizeof(struct bookmark_info), | ||
2282 | bm_comp); | ||
2283 | |||
2284 | cpage = 1; | ||
2285 | cline = 1; | ||
2286 | file_pos = 0; | ||
2287 | screen_top_ptr = buffer; | ||
2288 | buffer_end = BUFFER_END(); | ||
2289 | |||
2290 | fill_buffer(file_pos, buffer, buffer_size); | ||
2291 | line_end = line_begin = buffer; | ||
2292 | |||
2293 | for (i = 0; i < bookmark_count; i++) | ||
2294 | { | ||
2295 | sfp = bookmarks[i].file_position; | ||
2296 | sstp = buffer; | ||
2297 | |||
2298 | while ((line_begin > sstp || sstp >= line_end) || | ||
2299 | (file_pos > sfp || sfp >= file_pos + BUFFER_END() - buffer)) | ||
2300 | { | ||
2301 | get_next_line_position(&line_begin, &line_end, NULL); | ||
2302 | if (line_end == NULL) | ||
2303 | break; | ||
2304 | |||
2305 | next_line_ptr = line_end; | ||
2306 | |||
2307 | if (sstp == buffer && | ||
2308 | file_pos <= sfp && sfp < file_pos + BUFFER_END() - buffer) | ||
2309 | sstp = sfp - file_pos + buffer; | ||
2310 | |||
2311 | increment_current_line(); | ||
2312 | } | ||
2313 | |||
2314 | decrement_current_line(); | ||
2315 | bookmarks[i].page = cpage; | ||
2316 | bookmarks[i].line = cline; | ||
2317 | bookmarks[i].file_position = file_pos + (line_begin - buffer); | ||
2318 | increment_current_line(); | ||
2319 | } | ||
2320 | |||
2321 | /* remove reading page's bookmark */ | ||
2322 | for (i = 0; i < bookmark_count; i++) | ||
2323 | { | ||
2324 | if (bookmarks[i].flag & BOOKMARK_LAST) | ||
2325 | { | ||
2326 | int screen_pos; | ||
2327 | int screen_top; | ||
2328 | |||
2329 | screen_pos = bookmarks[i].file_position; | ||
2330 | screen_top = screen_pos % buffer_size; | ||
2331 | file_pos = screen_pos - screen_top; | ||
2332 | screen_top_ptr = buffer + screen_top; | ||
2333 | |||
2334 | cpage = bookmarks[i].page; | ||
2335 | cline = bookmarks[i].line; | ||
2336 | bookmarks[i].flag ^= BOOKMARK_LAST; | ||
2337 | buffer_end = BUFFER_END(); | ||
2338 | |||
2339 | fill_buffer(file_pos, buffer, buffer_size); | ||
2340 | |||
2341 | if (bookmarks[i].flag == 0) | ||
2342 | viewer_remove_bookmark(i); | ||
2343 | |||
2344 | if (prefs.scroll_mode == PAGE && cline > 1) | ||
2345 | viewer_scroll_to_top_line(); | ||
2346 | break; | ||
2347 | } | ||
2348 | } | ||
1385 | } | 2349 | } |
1386 | 2350 | ||
1387 | static int col_limit(int col) | 2351 | static int col_limit(int col) |
@@ -1389,8 +2353,8 @@ static int col_limit(int col) | |||
1389 | if (col < 0) | 2353 | if (col < 0) |
1390 | col = 0; | 2354 | col = 0; |
1391 | else | 2355 | else |
1392 | if (col > max_line_len - 2*glyph_width('o')) | 2356 | if (col >= max_width) |
1393 | col = max_line_len - 2*glyph_width('o'); | 2357 | col = max_width - draw_columns; |
1394 | 2358 | ||
1395 | return col; | 2359 | return col; |
1396 | } | 2360 | } |
@@ -1401,6 +2365,8 @@ static bool encoding_setting(void) | |||
1401 | { | 2365 | { |
1402 | static struct opt_items names[NUM_CODEPAGES]; | 2366 | static struct opt_items names[NUM_CODEPAGES]; |
1403 | int idx; | 2367 | int idx; |
2368 | bool res; | ||
2369 | enum codepages oldenc = prefs.encoding; | ||
1404 | 2370 | ||
1405 | for (idx = 0; idx < NUM_CODEPAGES; idx++) | 2371 | for (idx = 0; idx < NUM_CODEPAGES; idx++) |
1406 | { | 2372 | { |
@@ -1408,8 +2374,21 @@ static bool encoding_setting(void) | |||
1408 | names[idx].voice_id = -1; | 2374 | names[idx].voice_id = -1; |
1409 | } | 2375 | } |
1410 | 2376 | ||
1411 | return rb->set_option("Encoding", &prefs.encoding, INT, names, | 2377 | res = rb->set_option("Encoding", &prefs.encoding, INT, names, |
1412 | sizeof(names) / sizeof(names[0]), NULL); | 2378 | sizeof(names) / sizeof(names[0]), NULL); |
2379 | |||
2380 | /* When prefs.encoding changes into UTF-8 or changes from UTF-8, | ||
2381 | * filesize (file_size) might change. | ||
2382 | * In addition, if prefs.encoding is UTF-8, then BOM does not read. | ||
2383 | */ | ||
2384 | if (oldenc != prefs.encoding && (oldenc == UTF_8 || prefs.encoding == UTF_8)) | ||
2385 | { | ||
2386 | check_bom(); | ||
2387 | get_filesize(); | ||
2388 | fill_buffer(file_pos, buffer, buffer_size); | ||
2389 | } | ||
2390 | |||
2391 | return res; | ||
1413 | } | 2392 | } |
1414 | 2393 | ||
1415 | static bool word_wrap_setting(void) | 2394 | static bool word_wrap_setting(void) |
@@ -1449,6 +2428,7 @@ static bool view_mode_setting(void) | |||
1449 | names , 2, NULL); | 2428 | names , 2, NULL); |
1450 | if (prefs.view_mode == NARROW) | 2429 | if (prefs.view_mode == NARROW) |
1451 | col = 0; | 2430 | col = 0; |
2431 | calc_max_width(); | ||
1452 | return ret; | 2432 | return ret; |
1453 | } | 2433 | } |
1454 | 2434 | ||
@@ -1485,6 +2465,152 @@ static bool scrollbar_setting(void) | |||
1485 | return rb->set_option("Show Scrollbar", &prefs.scrollbar_mode, INT, | 2465 | return rb->set_option("Show Scrollbar", &prefs.scrollbar_mode, INT, |
1486 | names, 2, NULL); | 2466 | names, 2, NULL); |
1487 | } | 2467 | } |
2468 | |||
2469 | static bool header_setting(void) | ||
2470 | { | ||
2471 | int len = (rb->global_settings->statusbar == STATUSBAR_TOP)? 4 : 2; | ||
2472 | struct opt_items names[len]; | ||
2473 | |||
2474 | names[0].string = "None"; | ||
2475 | names[0].voice_id = -1; | ||
2476 | names[1].string = "File path"; | ||
2477 | names[1].voice_id = -1; | ||
2478 | |||
2479 | if (rb->global_settings->statusbar == STATUSBAR_TOP) | ||
2480 | { | ||
2481 | names[2].string = "Status bar"; | ||
2482 | names[2].voice_id = -1; | ||
2483 | names[3].string = "Both"; | ||
2484 | names[3].voice_id = -1; | ||
2485 | } | ||
2486 | |||
2487 | return rb->set_option("Show Header", &prefs.header_mode, INT, | ||
2488 | names, len, NULL); | ||
2489 | } | ||
2490 | |||
2491 | static bool footer_setting(void) | ||
2492 | { | ||
2493 | int len = (rb->global_settings->statusbar == STATUSBAR_BOTTOM)? 4 : 2; | ||
2494 | struct opt_items names[len]; | ||
2495 | |||
2496 | names[0].string = "None"; | ||
2497 | names[0].voice_id = -1; | ||
2498 | names[1].string = "Page Num"; | ||
2499 | names[1].voice_id = -1; | ||
2500 | |||
2501 | if (rb->global_settings->statusbar == STATUSBAR_BOTTOM) | ||
2502 | { | ||
2503 | names[2].string = "Status bar"; | ||
2504 | names[2].voice_id = -1; | ||
2505 | names[3].string = "Both"; | ||
2506 | names[3].voice_id = -1; | ||
2507 | } | ||
2508 | |||
2509 | return rb->set_option("Show Footer", &prefs.footer_mode, INT, | ||
2510 | names, len, NULL); | ||
2511 | } | ||
2512 | |||
2513 | static int font_comp(const void *a, const void *b) | ||
2514 | { | ||
2515 | struct opt_items *pa; | ||
2516 | struct opt_items *pb; | ||
2517 | |||
2518 | pa = (struct opt_items *)a; | ||
2519 | pb = (struct opt_items *)b; | ||
2520 | |||
2521 | return rb->strcmp(pa->string, pb->string); | ||
2522 | } | ||
2523 | |||
2524 | static bool font_setting(void) | ||
2525 | { | ||
2526 | int count = 0; | ||
2527 | DIR *dir; | ||
2528 | struct dirent *entry; | ||
2529 | int i = 0; | ||
2530 | int len; | ||
2531 | int new_font = 0; | ||
2532 | int old_font; | ||
2533 | bool res; | ||
2534 | int size = 0; | ||
2535 | |||
2536 | dir = rb->opendir(FONT_DIR); | ||
2537 | if (!dir) | ||
2538 | { | ||
2539 | rb->splash(HZ/2, "font dir does not access."); | ||
2540 | return false; | ||
2541 | } | ||
2542 | |||
2543 | while (1) | ||
2544 | { | ||
2545 | entry = rb->readdir(dir); | ||
2546 | |||
2547 | if (entry == NULL) | ||
2548 | break; | ||
2549 | |||
2550 | len = rb->strlen(entry->d_name); | ||
2551 | if (len < 4 || rb->strcmp(entry->d_name + len-4, ".fnt")) | ||
2552 | continue; | ||
2553 | size += len-3; | ||
2554 | count++; | ||
2555 | } | ||
2556 | rb->closedir(dir); | ||
2557 | |||
2558 | struct opt_items names[count]; | ||
2559 | unsigned char font_names[size]; | ||
2560 | unsigned char *p = font_names; | ||
2561 | |||
2562 | dir = rb->opendir(FONT_DIR); | ||
2563 | if (!dir) | ||
2564 | { | ||
2565 | rb->splash(HZ/2, "font dir does not access."); | ||
2566 | return false; | ||
2567 | } | ||
2568 | |||
2569 | while (1) | ||
2570 | { | ||
2571 | entry = rb->readdir(dir); | ||
2572 | |||
2573 | if (entry == NULL) | ||
2574 | break; | ||
2575 | |||
2576 | len = rb->strlen(entry->d_name); | ||
2577 | if (len < 4 || rb->strcmp(entry->d_name + len-4, ".fnt")) | ||
2578 | continue; | ||
2579 | |||
2580 | rb->snprintf(p, len-3, "%s", entry->d_name); | ||
2581 | names[i].string = p; | ||
2582 | names[i].voice_id = -1; | ||
2583 | p += len-3; | ||
2584 | i++; | ||
2585 | if (i >= count) | ||
2586 | break; | ||
2587 | } | ||
2588 | rb->closedir(dir); | ||
2589 | |||
2590 | rb->qsort(names, count, sizeof(struct opt_items), font_comp); | ||
2591 | |||
2592 | for (i = 0; i < count; i++) | ||
2593 | { | ||
2594 | if (!rb->strcmp(names[i].string, prefs.font)) | ||
2595 | { | ||
2596 | new_font = i; | ||
2597 | break; | ||
2598 | } | ||
2599 | } | ||
2600 | old_font = new_font; | ||
2601 | |||
2602 | res = rb->set_option("Select Font", &new_font, INT, | ||
2603 | names, count, NULL); | ||
2604 | |||
2605 | if (new_font != old_font) | ||
2606 | { | ||
2607 | rb->memset(prefs.font, 0, MAX_PATH); | ||
2608 | rb->snprintf(prefs.font, MAX_PATH, "%s", names[new_font].string); | ||
2609 | change_font(prefs.font); | ||
2610 | } | ||
2611 | |||
2612 | return res; | ||
2613 | } | ||
1488 | #endif | 2614 | #endif |
1489 | 2615 | ||
1490 | static bool autoscroll_speed_setting(void) | 2616 | static bool autoscroll_speed_setting(void) |
@@ -1506,6 +2632,12 @@ MENUITEM_FUNCTION(scrollbar_item, 0, "Show Scrollbar", scrollbar_setting, | |||
1506 | NULL, NULL, Icon_NOICON); | 2632 | NULL, NULL, Icon_NOICON); |
1507 | MENUITEM_FUNCTION(page_mode_item, 0, "Overlap Pages", page_mode_setting, | 2633 | MENUITEM_FUNCTION(page_mode_item, 0, "Overlap Pages", page_mode_setting, |
1508 | NULL, NULL, Icon_NOICON); | 2634 | NULL, NULL, Icon_NOICON); |
2635 | MENUITEM_FUNCTION(header_item, 0, "Show Header", header_setting, | ||
2636 | NULL, NULL, Icon_NOICON); | ||
2637 | MENUITEM_FUNCTION(footer_item, 0, "Show Footer", footer_setting, | ||
2638 | NULL, NULL, Icon_NOICON); | ||
2639 | MENUITEM_FUNCTION(font_item, 0, "Font", font_setting, | ||
2640 | NULL, NULL, Icon_NOICON); | ||
1509 | #endif | 2641 | #endif |
1510 | MENUITEM_FUNCTION(scroll_mode_item, 0, "Scroll Mode", scroll_mode_setting, | 2642 | MENUITEM_FUNCTION(scroll_mode_item, 0, "Scroll Mode", scroll_mode_setting, |
1511 | NULL, NULL, Icon_NOICON); | 2643 | NULL, NULL, Icon_NOICON); |
@@ -1514,28 +2646,39 @@ MENUITEM_FUNCTION(autoscroll_speed_item, 0, "Auto-Scroll Speed", | |||
1514 | MAKE_MENU(option_menu, "Viewer Options", NULL, Icon_NOICON, | 2646 | MAKE_MENU(option_menu, "Viewer Options", NULL, Icon_NOICON, |
1515 | &encoding_item, &word_wrap_item, &line_mode_item, &view_mode_item, | 2647 | &encoding_item, &word_wrap_item, &line_mode_item, &view_mode_item, |
1516 | #ifdef HAVE_LCD_BITMAP | 2648 | #ifdef HAVE_LCD_BITMAP |
1517 | &scrollbar_item, &page_mode_item, | 2649 | &scrollbar_item, &page_mode_item, &header_item, &footer_item, &font_item, |
1518 | #endif | 2650 | #endif |
1519 | &scroll_mode_item, &autoscroll_speed_item); | 2651 | &scroll_mode_item, &autoscroll_speed_item); |
1520 | 2652 | ||
1521 | static bool viewer_options_menu(void) | 2653 | static bool viewer_options_menu(bool is_global) |
1522 | { | 2654 | { |
1523 | bool result; | 2655 | bool result; |
2656 | struct preferences tmp_prefs; | ||
2657 | |||
2658 | rb->memcpy(&tmp_prefs, &prefs, sizeof(struct preferences)); | ||
2659 | |||
1524 | result = (rb->do_menu(&option_menu, NULL, NULL, false) == MENU_ATTACHED_USB); | 2660 | result = (rb->do_menu(&option_menu, NULL, NULL, false) == MENU_ATTACHED_USB); |
1525 | 2661 | ||
2662 | if (!is_global && rb->memcmp(&tmp_prefs, &prefs, sizeof(struct preferences))) | ||
2663 | { | ||
2664 | /* Show-scrollbar mode for current view-width mode */ | ||
1526 | #ifdef HAVE_LCD_BITMAP | 2665 | #ifdef HAVE_LCD_BITMAP |
1527 | /* Show-scrollbar mode for current view-width mode */ | 2666 | init_need_scrollbar(); |
1528 | init_need_scrollbar(); | 2667 | init_header_and_footer(); |
1529 | #endif | 2668 | #endif |
2669 | calc_page(); | ||
2670 | } | ||
1530 | return result; | 2671 | return result; |
1531 | } | 2672 | } |
1532 | 2673 | ||
1533 | static void viewer_menu(void) | 2674 | static void viewer_menu(void) |
1534 | { | 2675 | { |
1535 | int result; | 2676 | int result; |
2677 | |||
1536 | MENUITEM_STRINGLIST(menu, "Viewer Menu", NULL, | 2678 | MENUITEM_STRINGLIST(menu, "Viewer Menu", NULL, |
1537 | "Return", "Viewer Options", | 2679 | "Return", "Viewer Options", |
1538 | "Show Playback Menu", "Quit"); | 2680 | "Show Playback Menu", "Select Bookmark", |
2681 | "Global Settings", "Quit"); | ||
1539 | 2682 | ||
1540 | result = rb->do_menu(&menu, NULL, NULL, false); | 2683 | result = rb->do_menu(&menu, NULL, NULL, false); |
1541 | switch (result) | 2684 | switch (result) |
@@ -1543,12 +2686,31 @@ static void viewer_menu(void) | |||
1543 | case 0: /* return */ | 2686 | case 0: /* return */ |
1544 | break; | 2687 | break; |
1545 | case 1: /* change settings */ | 2688 | case 1: /* change settings */ |
1546 | done = viewer_options_menu(); | 2689 | done = viewer_options_menu(false); |
1547 | break; | 2690 | break; |
1548 | case 2: /* playback control */ | 2691 | case 2: /* playback control */ |
1549 | playback_control(NULL); | 2692 | playback_control(NULL); |
1550 | break; | 2693 | break; |
1551 | case 3: /* quit */ | 2694 | case 3: /* select bookmark */ |
2695 | viewer_select_bookmark(viewer_add_last_read_bookmark()); | ||
2696 | viewer_remove_last_read_bookmark(); | ||
2697 | fill_buffer(file_pos, buffer, buffer_size); | ||
2698 | if (prefs.scroll_mode == PAGE && cline > 1) | ||
2699 | viewer_scroll_to_top_line(); | ||
2700 | break; | ||
2701 | case 4: /* change global settings */ | ||
2702 | { | ||
2703 | struct preferences orig_prefs; | ||
2704 | |||
2705 | rb->memcpy(&orig_prefs, &prefs, sizeof(struct preferences)); | ||
2706 | if (!viewer_load_global_settings()) | ||
2707 | viewer_default_preferences(); | ||
2708 | done = viewer_options_menu(true); | ||
2709 | viewer_save_global_settings(); | ||
2710 | rb->memcpy(&prefs, &orig_prefs, sizeof(struct preferences)); | ||
2711 | } | ||
2712 | break; | ||
2713 | case 5: /* quit */ | ||
1552 | viewer_exit(NULL); | 2714 | viewer_exit(NULL); |
1553 | done = true; | 2715 | done = true; |
1554 | break; | 2716 | break; |
@@ -1567,6 +2729,13 @@ enum plugin_status plugin_start(const void* file) | |||
1567 | 2729 | ||
1568 | /* get the plugin buffer */ | 2730 | /* get the plugin buffer */ |
1569 | buffer = rb->plugin_get_buffer((size_t *)&buffer_size); | 2731 | buffer = rb->plugin_get_buffer((size_t *)&buffer_size); |
2732 | if (buffer_size == 0) | ||
2733 | { | ||
2734 | rb->splash(HZ, "buffer does not allocate !!"); | ||
2735 | return PLUGIN_ERROR; | ||
2736 | } | ||
2737 | block_size = buffer_size / 3; | ||
2738 | buffer_size = 3 * block_size; | ||
1570 | 2739 | ||
1571 | if (!file) | 2740 | if (!file) |
1572 | return PLUGIN_ERROR; | 2741 | return PLUGIN_ERROR; |
@@ -1592,13 +2761,14 @@ enum plugin_status plugin_start(const void* file) | |||
1592 | { | 2761 | { |
1593 | if(old_tick <= *rb->current_tick - (110-prefs.autoscroll_speed*10)) | 2762 | if(old_tick <= *rb->current_tick - (110-prefs.autoscroll_speed*10)) |
1594 | { | 2763 | { |
1595 | viewer_scroll_down(); | 2764 | viewer_scroll_down(true); |
1596 | viewer_draw(col); | 2765 | viewer_draw(col); |
1597 | old_tick = *rb->current_tick; | 2766 | old_tick = *rb->current_tick; |
1598 | } | 2767 | } |
1599 | } | 2768 | } |
1600 | 2769 | ||
1601 | button = rb->button_get_w_tmo(HZ/10); | 2770 | button = rb->button_get_w_tmo(HZ/10); |
2771 | |||
1602 | switch (button) { | 2772 | switch (button) { |
1603 | case VIEWER_MENU: | 2773 | case VIEWER_MENU: |
1604 | #ifdef VIEWER_MENU2 | 2774 | #ifdef VIEWER_MENU2 |
@@ -1647,10 +2817,14 @@ enum plugin_status plugin_start(const void* file) | |||
1647 | { | 2817 | { |
1648 | /* Page down */ | 2818 | /* Page down */ |
1649 | if (next_screen_ptr != NULL) | 2819 | if (next_screen_ptr != NULL) |
2820 | { | ||
1650 | screen_top_ptr = next_screen_to_draw_ptr; | 2821 | screen_top_ptr = next_screen_to_draw_ptr; |
2822 | if (cpage < MAX_PAGE) | ||
2823 | cpage++; | ||
2824 | } | ||
1651 | } | 2825 | } |
1652 | else | 2826 | else |
1653 | viewer_scroll_down(); | 2827 | viewer_scroll_down(autoscroll); |
1654 | old_tick = *rb->current_tick; | 2828 | old_tick = *rb->current_tick; |
1655 | viewer_draw(col); | 2829 | viewer_draw(col); |
1656 | break; | 2830 | break; |
@@ -1697,8 +2871,8 @@ enum plugin_status plugin_start(const void* file) | |||
1697 | case VIEWER_LINE_DOWN: | 2871 | case VIEWER_LINE_DOWN: |
1698 | case VIEWER_LINE_DOWN | BUTTON_REPEAT: | 2872 | case VIEWER_LINE_DOWN | BUTTON_REPEAT: |
1699 | /* Scroll down one line */ | 2873 | /* Scroll down one line */ |
1700 | if (next_screen_ptr != NULL) | 2874 | viewer_scroll_down(autoscroll); |
1701 | screen_top_ptr = next_line_ptr; | 2875 | increment_current_line(); |
1702 | old_tick = *rb->current_tick; | 2876 | old_tick = *rb->current_tick; |
1703 | viewer_draw(col); | 2877 | viewer_draw(col); |
1704 | break; | 2878 | break; |
@@ -1736,6 +2910,29 @@ enum plugin_status plugin_start(const void* file) | |||
1736 | done = true; | 2910 | done = true; |
1737 | break; | 2911 | break; |
1738 | 2912 | ||
2913 | case VIEWER_BOOKMARK: | ||
2914 | { | ||
2915 | int idx = viewer_find_bookmark(cpage, cline); | ||
2916 | |||
2917 | if (idx < 0) | ||
2918 | { | ||
2919 | if (bookmark_count >= MAX_BOOKMARKS-1) | ||
2920 | rb->splash(HZ/2, "No more add bookmark."); | ||
2921 | else | ||
2922 | { | ||
2923 | viewer_add_bookmark(); | ||
2924 | rb->splash(HZ/2, "Bookmark add."); | ||
2925 | } | ||
2926 | } | ||
2927 | else | ||
2928 | { | ||
2929 | viewer_remove_bookmark(idx); | ||
2930 | rb->splash(HZ/2, "Bookmark remove."); | ||
2931 | } | ||
2932 | viewer_draw(col); | ||
2933 | } | ||
2934 | break; | ||
2935 | |||
1739 | default: | 2936 | default: |
1740 | if (rb->default_event_handler_ex(button, viewer_exit, NULL) | 2937 | if (rb->default_event_handler_ex(button, viewer_exit, NULL) |
1741 | == SYS_USB_CONNECTED) | 2938 | == SYS_USB_CONNECTED) |
@@ -1750,5 +2947,3 @@ enum plugin_status plugin_start(const void* file) | |||
1750 | } | 2947 | } |
1751 | return PLUGIN_OK; | 2948 | return PLUGIN_OK; |
1752 | } | 2949 | } |
1753 | |||
1754 | |||