summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/textviewer/textviewer.c232
-rw-r--r--apps/plugins/textviewer/textviewer.h30
-rw-r--r--apps/plugins/textviewer/tv_bookmark.c338
-rw-r--r--apps/plugins/textviewer/tv_bookmark.h44
-rw-r--r--apps/plugins/textviewer/tv_button.h393
-rw-r--r--apps/plugins/textviewer/tv_menu.c384
-rw-r--r--apps/plugins/textviewer/tv_menu.h28
-rw-r--r--apps/plugins/textviewer/tv_readtext.c483
-rw-r--r--apps/plugins/textviewer/tv_readtext.h31
-rw-r--r--apps/plugins/textviewer/tv_screen.c468
-rw-r--r--apps/plugins/textviewer/tv_screen.h51
-rw-r--r--apps/plugins/textviewer/tv_settings.c464
-rw-r--r--apps/plugins/textviewer/tv_settings.h85
-rw-r--r--apps/plugins/textviewer/tv_text_processor.c505
14 files changed, 0 insertions, 3536 deletions
diff --git a/apps/plugins/textviewer/textviewer.c b/apps/plugins/textviewer/textviewer.c
deleted file mode 100644
index 289c741f96..0000000000
--- a/apps/plugins/textviewer/textviewer.c
+++ /dev/null
@@ -1,232 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "plugin.h"
24#include "textviewer.h"
25#include "tv_bookmark.h"
26#include "tv_button.h"
27#include "tv_menu.h"
28#include "tv_readtext.h"
29#include "tv_screen.h"
30#include "tv_settings.h"
31
32PLUGIN_HEADER
33
34static bool viewer_init(const unsigned char *file)
35{
36 viewer_init_screen();
37 viewer_init_buffer();
38
39 if (!viewer_open(file))
40 return false;
41
42 /* Init mac_text value used in processing buffer */
43 mac_text = false;
44
45 return true;
46}
47
48static void viewer_exit(void *parameter)
49{
50 (void)parameter;
51
52 /* save preference and bookmarks */
53 if (!viewer_save_settings())
54 rb->splash(HZ, "Can't save preference and bookmarks.");
55
56 viewer_close();
57 viewer_finalize_screen();
58}
59
60enum plugin_status plugin_start(const void* file)
61{
62 int button, i, ok;
63 int lastbutton = BUTTON_NONE;
64 bool autoscroll = false;
65 long old_tick;
66
67 old_tick = *rb->current_tick;
68
69 if (!file)
70 return PLUGIN_ERROR;
71
72 ok = viewer_init(file);
73 if (!ok) {
74 rb->splash(HZ, "Error opening file.");
75 return PLUGIN_ERROR;
76 }
77
78 viewer_load_settings(); /* load the preferences and bookmark */
79
80#if LCD_DEPTH > 1
81 rb->lcd_set_backdrop(NULL);
82#endif
83
84 viewer_draw();
85
86 while (!done) {
87
88 if (autoscroll)
89 {
90 if(old_tick <= *rb->current_tick - (110-prefs.autoscroll_speed*10))
91 {
92 viewer_scroll_down(VIEWER_SCROLL_LINE);
93 viewer_draw();
94 old_tick = *rb->current_tick;
95 }
96 }
97
98 button = rb->button_get_w_tmo(HZ/10);
99
100 switch (button) {
101 case VIEWER_MENU:
102#ifdef VIEWER_MENU2
103 case VIEWER_MENU2:
104#endif
105 viewer_menu();
106 break;
107
108 case VIEWER_AUTOSCROLL:
109#ifdef VIEWER_AUTOSCROLL_PRE
110 if (lastbutton != VIEWER_AUTOSCROLL_PRE)
111 break;
112#endif
113 autoscroll = !autoscroll;
114 break;
115
116 case VIEWER_SCROLL_UP:
117 case VIEWER_SCROLL_UP | BUTTON_REPEAT:
118#ifdef VIEWER_SCROLL_UP2
119 case VIEWER_SCROLL_UP2:
120 case VIEWER_SCROLL_UP2 | BUTTON_REPEAT:
121#endif
122 viewer_scroll_up(VIEWER_SCROLL_PREFS);
123 viewer_draw();
124 old_tick = *rb->current_tick;
125 break;
126
127 case VIEWER_SCROLL_DOWN:
128 case VIEWER_SCROLL_DOWN | BUTTON_REPEAT:
129#ifdef VIEWER_PAGE_DOWN2
130 case VIEWER_SCROLL_DOWN2:
131 case VIEWER_SCROLL_DOWN2 | BUTTON_REPEAT:
132#endif
133 viewer_scroll_down(VIEWER_SCROLL_PREFS);
134 viewer_draw();
135 old_tick = *rb->current_tick;
136 break;
137
138 case VIEWER_SCREEN_LEFT:
139 case VIEWER_SCREEN_LEFT | BUTTON_REPEAT:
140 if (prefs.view_mode == WIDE)
141 {
142 /* Screen left */
143 viewer_scroll_left(VIEWER_SCROLL_SCREEN);
144 }
145 else { /* prefs.view_mode == NARROW */
146 /* Top of file */
147 viewer_top();
148 }
149 viewer_draw();
150 break;
151
152 case VIEWER_SCREEN_RIGHT:
153 case VIEWER_SCREEN_RIGHT | BUTTON_REPEAT:
154 if (prefs.view_mode == WIDE)
155 {
156 /* Screen right */
157 viewer_scrol_right(VIEWER_SCROLL_SCREEN);
158 }
159 else { /* prefs.view_mode == NARROW */
160 /* Bottom of file */
161 viewer_bottom();
162 }
163 viewer_draw();
164 break;
165
166#ifdef VIEWER_LINE_UP
167 case VIEWER_LINE_UP:
168 case VIEWER_LINE_UP | BUTTON_REPEAT:
169 /* Scroll up one line */
170 viewer_scroll_up(VIEWER_SCROLL_LINE);
171 viewer_draw();
172 old_tick = *rb->current_tick;
173 break;
174
175 case VIEWER_LINE_DOWN:
176 case VIEWER_LINE_DOWN | BUTTON_REPEAT:
177 /* Scroll down one line */
178 viewer_scroll_down(VIEWER_SCROLL_LINE);
179 viewer_draw();
180 old_tick = *rb->current_tick;
181 break;
182#endif
183#ifdef VIEWER_COLUMN_LEFT
184 case VIEWER_COLUMN_LEFT:
185 case VIEWER_COLUMN_LEFT | BUTTON_REPEAT:
186 if (prefs.view_mode == WIDE)
187 {
188 viewer_scroll_left(VIEWER_SCROLL_COLUMN);
189 viewer_draw();
190 }
191 break;
192
193 case VIEWER_COLUMN_RIGHT:
194 case VIEWER_COLUMN_RIGHT | BUTTON_REPEAT:
195 if (prefs.view_mode == WIDE)
196 {
197 viewer_scroll_right(VIEWER_SCROLL_COLUMN);
198 viewer_draw();
199 }
200 break;
201#endif
202
203#ifdef VIEWER_RC_QUIT
204 case VIEWER_RC_QUIT:
205#endif
206 case VIEWER_QUIT:
207#ifdef VIEWER_QUIT2
208 case VIEWER_QUIT2:
209#endif
210 viewer_exit(NULL);
211 done = true;
212 break;
213
214 case VIEWER_BOOKMARK:
215 viewer_add_remove_bookmark(cpage, cline);
216 viewer_draw();
217 break;
218
219 default:
220 if (rb->default_event_handler_ex(button, viewer_exit, NULL)
221 == SYS_USB_CONNECTED)
222 return PLUGIN_USB_CONNECTED;
223 break;
224 }
225 if (button != BUTTON_NONE)
226 {
227 lastbutton = button;
228 rb->yield();
229 }
230 }
231 return PLUGIN_OK;
232}
diff --git a/apps/plugins/textviewer/textviewer.h b/apps/plugins/textviewer/textviewer.h
deleted file mode 100644
index 7c080f8cc0..0000000000
--- a/apps/plugins/textviewer/textviewer.h
+++ /dev/null
@@ -1,30 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#ifndef PLUGIN_TEXT_VIEWER_TEXTVIEWER_H
24#define PLUGIN_TEXT_VIEWER_TEXTVIEWER_H
25
26/* UTF-8 BOM */
27#define BOM "\xef\xbb\xbf"
28#define BOM_SIZE 3
29
30#endif
diff --git a/apps/plugins/textviewer/tv_bookmark.c b/apps/plugins/textviewer/tv_bookmark.c
deleted file mode 100644
index 261a319e26..0000000000
--- a/apps/plugins/textviewer/tv_bookmark.c
+++ /dev/null
@@ -1,338 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "plugin.h"
24#include "tv_bookmark.h"
25
26/* text viewer bookmark functions */
27
28enum
29{
30 BOOKMARK_LAST = 1,
31 BOOKMARK_USER,
32};
33
34#ifndef HAVE_LCD_BITMAP
35#define BOOKMARK_ICON "\xee\x84\x81\x00"
36#endif
37
38#define BOOKMARK_SIZE 8
39#define MAX_BOOKMARKS 10 /* user setting bookmarks + last read page */
40
41
42struct bookmark_info bookmarks[MAX_BOOKMARKS];
43static int bookmark_count;
44
45static int bm_comp(const void *a, const void *b)
46{
47 struct bookmark_info *pa;
48 struct bookmark_info *pb;
49
50 pa = (struct bookmark_info*)a;
51 pb = (struct bookmark_info*)b;
52
53 if (pa->page != pb->page)
54 return pa->page - pb->page;
55
56 return pa->line - pb->line;
57}
58
59int viewer_find_bookmark(int page, int line)
60{
61 int i;
62
63 for (i = 0; i < bookmark_count; i++)
64 {
65 if (bookmarks[i].page == page && bookmarks[i].line == line)
66 return i;
67 }
68 return -1;
69}
70
71void viewer_add_bookmark(int page, int line)
72{
73 if (bookmark_count >= MAX_BOOKMARKS-1)
74 return;
75
76 bookmarks[bookmark_count].file_position
77 = file_pos + screen_top_ptr - buffer;
78 bookmarks[bookmark_count].page = page;
79 bookmarks[bookmark_count].line = line;
80 bookmarks[bookmark_count].flag = BOOKMARK_USER;
81 bookmark_count++;
82}
83
84static int viewer_add_last_read_bookmark(void)
85{
86 int i;
87
88 i = viewer_find_bookmark(cpage, cline);
89 if (i >= 0)
90 bookmarks[i].flag |= BOOKMARK_LAST;
91 else
92 {
93 viewer_add_bookmark();
94 i = bookmark_count-1;
95 bookmarks[i].flag = BOOKMARK_LAST;
96 }
97 return i;
98}
99
100static void viewer_remove_bookmark(int i)
101{
102 int j;
103
104 if (i < 0 || i >= bookmark_count)
105 return;
106
107 for (j = i+1; j < bookmark_count; j++)
108 rb->memcpy(&bookmarks[j-1], &bookmarks[j],
109 sizeof(struct bookmark_info));
110
111 bookmark_count--;
112}
113
114void viewer_remove_last_read_bookmark(void)
115{
116 int i, j;
117
118 for (i = 0; i < bookmark_count; i++)
119 {
120 if (bookmarks[i].flag & BOOKMARK_LAST)
121 {
122 if (bookmarks[i].flag == BOOKMARK_LAST)
123 {
124 for (j = i+1; j < bookmark_count; j++)
125 rb->memcpy(&bookmarks[j-1], &bookmarks[j],
126 sizeof(struct bookmark_info));
127
128 bookmark_count--;
129 }
130 else
131 bookmarks[i].flag = BOOKMARK_USER;
132 break;
133 }
134 }
135}
136
137/*
138 * the function that a bookmark add when there is not a bookmark in the given position
139 * or the bookmark remove when there exist a bookmark in the given position.
140 *
141 */
142void viewer_add_remove_bookmark(int page, int line)
143{
144 int idx = viewer_find_bookmark(cpage, cline);
145
146 if (idx < 0)
147 {
148 if (bookmark_count >= MAX_BOOKMARKS-1)
149 rb->splash(HZ/2, "No more add bookmark.");
150 else
151 {
152 viewer_add_bookmark(page, line);
153 rb->splash(HZ/2, "Bookmark add.");
154 }
155 }
156 viewer_remove_bookmark(idx);
157 rb->splash(HZ/2, "Bookmark remove.");
158}
159
160static int viewer_get_last_read_bookmark(void)
161{
162 int i;
163
164 for (i = 0; i < bookmark_count; i++)
165 {
166 if (bookmarks[i].flag & BOOKMARK_LAST)
167 return i;
168 }
169 return -1;
170}
171
172void viewer_select_bookmark(int initval)
173{
174 int i;
175 int ipage = 0;
176 int iline = 0;
177 int screen_pos;
178 int screen_top;
179 int selected = -1;
180
181 struct opt_items items[bookmark_count];
182 unsigned char names[bookmark_count][38];
183
184 if (initval >= 0 && initval < bookmark_count)
185 {
186 ipage = bookmarks[initval].page;
187 iline = bookmarks[initval].line;
188 }
189
190 rb->qsort(bookmarks, bookmark_count, sizeof(struct bookmark_info),
191 bm_comp);
192
193 for (i = 0; i < bookmark_count; i++)
194 {
195 rb->snprintf(names[i], sizeof(names[0]),
196#if CONFIG_KEYPAD != PLAYER_PAD
197 "%sPage: %d Line: %d",
198#else
199 "%sP:%d L:%d",
200#endif
201 (bookmarks[i].flag&BOOKMARK_LAST)? "*":" ",
202 bookmarks[i].page,
203 bookmarks[i].line);
204 items[i].string = names[i];
205 items[i].voice_id = -1;
206 if (selected < 0 && bookmarks[i].page == ipage && bookmarks[i].line == iline)
207 selected = i;
208 }
209
210 rb->set_option("Select bookmark", &selected, INT, items,
211 sizeof(items) / sizeof(items[0]), NULL);
212
213 if (selected < 0 || selected >= bookmark_count)
214 {
215 if (initval < 0 || (selected = viewer_get_last_read_bookmark()) < 0)
216 {
217 if (initval < 0)
218 rb->splash(HZ, "Start the first page.");
219 file_pos = 0;
220 screen_top_ptr = buffer;
221 cpage = 1;
222 cline = 1;
223 buffer_end = BUFFER_END();
224 return;
225 }
226 }
227
228 screen_pos = bookmarks[selected].file_position;
229 screen_top = screen_pos % buffer_size;
230 file_pos = screen_pos - screen_top;
231 screen_top_ptr = buffer + screen_top;
232 cpage = bookmarks[selected].page;
233 cline = bookmarks[selected].line;
234 buffer_end = BUFFER_END();
235}
236
237
238static bool viewer_read_bookmark_info(int bfd, struct bookmark_info *b)
239{
240 unsigned char buf[BOOKMARK_SIZE];
241
242 if (rb->read(bfd, buf, sizeof(buf)) != sizeof(buf))
243 return false;
244
245 b->file_position = (buf[0] << 24)|(buf[1] << 16)|(buf[2] << 8)|buf[3];
246 b->page = (buf[4] << 8)|buf[5];
247 b->line = buf[6];
248 b->flag = buf[7];
249
250 return true;
251}
252
253bool viewer_read_bookmark_infos(int fd)
254{
255 unsigned char c;
256 int i;
257
258 if (rb->read(fd, &c, 1) != 1)
259 {
260 bookmark_count = 0;
261 return false;
262 }
263
264 bookmark_count = c;
265 if (bookmark_count > MAX_BOOKMARKS)
266 bookmark_count = MAX_BOOKMARKS;
267
268 for (i = 0; i < bookmark_count; i++)
269 {
270 if (!viewer_read_bookmark_info(fd, &bookmarks[i]))
271 {
272 bookmark_count = i;
273 return false;
274 }
275 }
276 return true;
277}
278
279static bool viewer_write_bookmark_info(int bfd, struct bookmark_info *b)
280{
281 unsigned char buf[BOOKMARK_SIZE];
282 unsigned char *p = buf;
283 unsigned long ul;
284
285 ul = b->file_position;
286 *p++ = ul >> 24;
287 *p++ = ul >> 16;
288 *p++ = ul >> 8;
289 *p++ = ul;
290
291 ul = b->page;
292 *p++ = ul >> 8;
293 *p++ = ul;
294
295 *p++ = b->line;
296 *p = b->flag;
297
298 return (rb->write(bfd, buf, sizeof(buf)) == sizeof(buf));
299}
300
301bool viewer_write_bookmark_infos(int fd)
302{
303 unsigned char c = bookmark_count;
304 int i;
305
306 if (rb->write(fd, &c, 1) != 1)
307 return false;
308
309 for (i = 0; i < bookmark_count; i++)
310 {
311 if (!viewer_write_bookmark_info(fd, &bookmarks[i]))
312 return false;
313 }
314
315 return true;
316}
317
318bool copy_bookmark_file(int sfd, int dfd, off_t start, off_t size)
319{
320 off_t rsize;
321
322 if (rb->lseek(sfd, start, SEEK_SET) < 0)
323 return false;
324
325 while (size > 0)
326 {
327 if (size > buffer_size)
328 rsize = buffer_size;
329 else
330 rsize = size;
331 size -= rsize;
332
333 if (rb->read(sfd, buffer, rsize) != rsize ||
334 rb->write(dfd, buffer, rsize) != rsize)
335 return false;
336 }
337 return true;
338}
diff --git a/apps/plugins/textviewer/tv_bookmark.h b/apps/plugins/textviewer/tv_bookmark.h
deleted file mode 100644
index 4d8e7fc3e8..0000000000
--- a/apps/plugins/textviewer/tv_bookmark.h
+++ /dev/null
@@ -1,44 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#ifndef PLUGIN_TEXT_VIEWER_BOOKMARK_H
24#define PLUGIN_TEXT_VIEWER_BOOKMARK_H
25
26/* stuff for the bookmarking */
27struct bookmark_info {
28 long file_position;
29 int page;
30 int line;
31 unsigned char flag;
32};
33
34int viewer_find_bookmark(int page, int line);
35void viewer_add_remove_bookmark(int page, int line);
36void viewer_add_bookmark(int page, int line);
37void viewer_remove_last_read_bookmark(void);
38void viewer_select_bookmark(int initval);
39
40bool viewer_read_bookmark_infos(int fd);
41bool viewer_write_bookmark_infos(int fd);
42bool copy_bookmark_file(int sfd, int dfd, off_t start, off_t size);
43
44#endif
diff --git a/apps/plugins/textviewer/tv_button.h b/apps/plugins/textviewer/tv_button.h
deleted file mode 100644
index 7728b9abc6..0000000000
--- a/apps/plugins/textviewer/tv_button.h
+++ /dev/null
@@ -1,393 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#ifndef PLUGIN_TEXT_VIEWER_BUTTON_H
24#define PLUGIN_TEXT_VIEWER_BUTTON_H
25
26/* variable button definitions */
27
28/* Recorder keys */
29#if CONFIG_KEYPAD == RECORDER_PAD
30#define VIEWER_QUIT BUTTON_OFF
31#define VIEWER_SCROLL_UP BUTTON_UP
32#define VIEWER_SCROLL_DOWN BUTTON_DOWN
33#define VIEWER_SCREEN_LEFT BUTTON_LEFT
34#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
35#define VIEWER_MENU BUTTON_F1
36#define VIEWER_AUTOSCROLL BUTTON_PLAY
37#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP)
38#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN)
39#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT)
40#define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT)
41#define VIEWER_BOOKMARK BUTTON_F2
42
43#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
44#define VIEWER_QUIT BUTTON_OFF
45#define VIEWER_SCROLL_UP BUTTON_UP
46#define VIEWER_SCROLL_DOWN BUTTON_DOWN
47#define VIEWER_SCREEN_LEFT BUTTON_LEFT
48#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
49#define VIEWER_MENU BUTTON_F1
50#define VIEWER_AUTOSCROLL BUTTON_SELECT
51#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP)
52#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN)
53#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT)
54#define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT)
55#define VIEWER_BOOKMARK BUTTON_F2
56
57/* Ondio keys */
58#elif CONFIG_KEYPAD == ONDIO_PAD
59#define VIEWER_QUIT BUTTON_OFF
60#define VIEWER_SCROLL_UP BUTTON_UP
61#define VIEWER_SCROLL_DOWN BUTTON_DOWN
62#define VIEWER_SCREEN_LEFT BUTTON_LEFT
63#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
64#define VIEWER_MENU (BUTTON_MENU|BUTTON_REPEAT)
65#define VIEWER_AUTOSCROLL_PRE BUTTON_MENU
66#define VIEWER_AUTOSCROLL (BUTTON_MENU|BUTTON_REL)
67#define VIEWER_BOOKMARK (BUTTON_MENU|BUTTON_OFF)
68
69/* Player keys */
70#elif CONFIG_KEYPAD == PLAYER_PAD
71#define VIEWER_QUIT BUTTON_STOP
72#define VIEWER_SCROLL_UP BUTTON_LEFT
73#define VIEWER_SCROLL_DOWN BUTTON_RIGHT
74#define VIEWER_SCREEN_LEFT (BUTTON_ON|BUTTON_LEFT)
75#define VIEWER_SCREEN_RIGHT (BUTTON_ON|BUTTON_RIGHT)
76#define VIEWER_MENU BUTTON_MENU
77#define VIEWER_AUTOSCROLL BUTTON_PLAY
78#define VIEWER_BOOKMARK BUTTON_ON
79
80/* iRiver H1x0 && H3x0 keys */
81#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
82 (CONFIG_KEYPAD == IRIVER_H300_PAD)
83#define VIEWER_QUIT BUTTON_OFF
84#define VIEWER_RC_QUIT BUTTON_RC_STOP
85#define VIEWER_SCROLL_UP BUTTON_UP
86#define VIEWER_SCROLL_DOWN BUTTON_DOWN
87#define VIEWER_SCREEN_LEFT BUTTON_LEFT
88#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
89#define VIEWER_MENU BUTTON_MODE
90#define VIEWER_AUTOSCROLL BUTTON_SELECT
91#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP)
92#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN)
93#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT)
94#define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT)
95#define VIEWER_BOOKMARK (BUTTON_ON | BUTTON_SELECT)
96
97/* iPods */
98#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
99 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
100 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
101#define VIEWER_QUIT_PRE BUTTON_SELECT
102#define VIEWER_QUIT (BUTTON_SELECT | BUTTON_MENU)
103#define VIEWER_SCROLL_UP BUTTON_SCROLL_BACK
104#define VIEWER_SCROLL_DOWN BUTTON_SCROLL_FWD
105#define VIEWER_SCREEN_LEFT BUTTON_LEFT
106#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
107#define VIEWER_MENU BUTTON_MENU
108#define VIEWER_AUTOSCROLL BUTTON_PLAY
109#define VIEWER_BOOKMARK BUTTON_SELECT
110
111/* iFP7xx keys */
112#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
113#define VIEWER_QUIT BUTTON_PLAY
114#define VIEWER_SCROLL_UP BUTTON_UP
115#define VIEWER_SCROLL_DOWN BUTTON_DOWN
116#define VIEWER_SCREEN_LEFT BUTTON_LEFT
117#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
118#define VIEWER_MENU BUTTON_MODE
119#define VIEWER_AUTOSCROLL BUTTON_SELECT
120#define VIEWER_BOOKMARK (BUTTON_LEFT|BUTTON_SELECT)
121
122/* iAudio X5 keys */
123#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
124#define VIEWER_QUIT BUTTON_POWER
125#define VIEWER_SCROLL_UP BUTTON_UP
126#define VIEWER_SCROLL_DOWN BUTTON_DOWN
127#define VIEWER_SCREEN_LEFT BUTTON_LEFT
128#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
129#define VIEWER_MENU BUTTON_SELECT
130#define VIEWER_AUTOSCROLL BUTTON_PLAY
131#define VIEWER_BOOKMARK BUTTON_REC
132
133/* GIGABEAT keys */
134#elif CONFIG_KEYPAD == GIGABEAT_PAD
135#define VIEWER_QUIT BUTTON_POWER
136#define VIEWER_SCROLL_UP BUTTON_UP
137#define VIEWER_SCROLL_DOWN BUTTON_DOWN
138#define VIEWER_SCREEN_LEFT BUTTON_LEFT
139#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
140#define VIEWER_MENU BUTTON_MENU
141#define VIEWER_AUTOSCROLL BUTTON_A
142#define VIEWER_BOOKMARK BUTTON_SELECT
143
144/* Sansa E200 keys */
145#elif CONFIG_KEYPAD == SANSA_E200_PAD
146#define VIEWER_QUIT BUTTON_POWER
147#define VIEWER_SCROLL_UP BUTTON_UP
148#define VIEWER_SCROLL_DOWN BUTTON_DOWN
149#define VIEWER_SCREEN_LEFT BUTTON_LEFT
150#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
151#define VIEWER_MENU BUTTON_SELECT
152#define VIEWER_AUTOSCROLL BUTTON_REC
153#define VIEWER_LINE_UP BUTTON_SCROLL_BACK
154#define VIEWER_LINE_DOWN BUTTON_SCROLL_FWD
155#define VIEWER_BOOKMARK (BUTTON_DOWN|BUTTON_SELECT)
156
157/* Sansa Fuze keys */
158#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
159#define VIEWER_QUIT (BUTTON_HOME|BUTTON_REPEAT)
160#define VIEWER_SCROLL_UP BUTTON_UP
161#define VIEWER_SCROLL_DOWN BUTTON_DOWN
162#define VIEWER_SCREEN_LEFT BUTTON_LEFT
163#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
164#define VIEWER_MENU BUTTON_SELECT|BUTTON_REPEAT
165#define VIEWER_AUTOSCROLL BUTTON_SELECT|BUTTON_DOWN
166#define VIEWER_LINE_UP BUTTON_SCROLL_BACK
167#define VIEWER_LINE_DOWN BUTTON_SCROLL_FWD
168#define VIEWER_BOOKMARK BUTTON_SELECT
169
170/* Sansa C200 keys */
171#elif CONFIG_KEYPAD == SANSA_C200_PAD
172#define VIEWER_QUIT BUTTON_POWER
173#define VIEWER_SCROLL_UP BUTTON_VOL_UP
174#define VIEWER_SCROLL_DOWN BUTTON_VOL_DOWN
175#define VIEWER_SCREEN_LEFT BUTTON_LEFT
176#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
177#define VIEWER_MENU BUTTON_SELECT
178#define VIEWER_AUTOSCROLL BUTTON_REC
179#define VIEWER_LINE_UP BUTTON_UP
180#define VIEWER_LINE_DOWN BUTTON_DOWN
181#define VIEWER_BOOKMARK (BUTTON_DOWN | BUTTON_SELECT)
182
183/* Sansa Clip keys */
184#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
185#define VIEWER_QUIT BUTTON_POWER
186#define VIEWER_SCROLL_UP BUTTON_VOL_UP
187#define VIEWER_SCROLL_DOWN BUTTON_VOL_DOWN
188#define VIEWER_SCREEN_LEFT BUTTON_LEFT
189#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
190#define VIEWER_MENU BUTTON_SELECT
191#define VIEWER_AUTOSCROLL BUTTON_HOME
192#define VIEWER_LINE_UP BUTTON_UP
193#define VIEWER_LINE_DOWN BUTTON_DOWN
194#define VIEWER_BOOKMARK (BUTTON_DOWN|BUTTON_SELECT)
195
196/* Sansa M200 keys */
197#elif CONFIG_KEYPAD == SANSA_M200_PAD
198#define VIEWER_QUIT BUTTON_POWER
199#define VIEWER_SCROLL_UP BUTTON_VOL_UP
200#define VIEWER_SCROLL_DOWN BUTTON_VOL_DOWN
201#define VIEWER_SCREEN_LEFT BUTTON_LEFT
202#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
203#define VIEWER_MENU (BUTTON_SELECT | BUTTON_UP)
204#define VIEWER_AUTOSCROLL (BUTTON_SELECT | BUTTON_REL)
205#define VIEWER_LINE_UP BUTTON_UP
206#define VIEWER_LINE_DOWN BUTTON_DOWN
207#define VIEWER_BOOKMARK (BUTTON_DOWN|BUTTON_SELECT)
208
209/* iriver H10 keys */
210#elif CONFIG_KEYPAD == IRIVER_H10_PAD
211#define VIEWER_QUIT BUTTON_POWER
212#define VIEWER_SCROLL_UP BUTTON_SCROLL_UP
213#define VIEWER_SCROLL_DOWN BUTTON_SCROLL_DOWN
214#define VIEWER_SCREEN_LEFT BUTTON_LEFT
215#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
216#define VIEWER_MENU BUTTON_REW
217#define VIEWER_AUTOSCROLL BUTTON_PLAY
218#define VIEWER_BOOKMARK BUTTON_FF
219
220/*M-Robe 500 keys */
221#elif CONFIG_KEYPAD == MROBE500_PAD
222#define VIEWER_QUIT BUTTON_POWER
223#define VIEWER_SCROLL_UP BUTTON_RC_PLAY
224#define VIEWER_SCROLL_DOWN BUTTON_RC_DOWN
225#define VIEWER_SCREEN_LEFT BUTTON_LEFT
226#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
227#define VIEWER_MENU BUTTON_RC_HEART
228#define VIEWER_AUTOSCROLL BUTTON_RC_MODE
229#define VIEWER_BOOKMARK BUTTON_CENTER
230
231/*Gigabeat S keys */
232#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
233#define VIEWER_QUIT BUTTON_BACK
234#define VIEWER_SCROLL_UP BUTTON_PREV
235#define VIEWER_SCROLL_DOWN BUTTON_NEXT
236#define VIEWER_SCREEN_LEFT (BUTTON_PLAY | BUTTON_LEFT)
237#define VIEWER_SCREEN_RIGHT (BUTTON_PLAY | BUTTON_RIGHT)
238#define VIEWER_MENU BUTTON_MENU
239#define VIEWER_AUTOSCROLL_PRE BUTTON_PLAY
240#define VIEWER_AUTOSCROLL (BUTTON_PLAY|BUTTON_REL)
241#define VIEWER_LINE_UP BUTTON_UP
242#define VIEWER_LINE_DOWN BUTTON_DOWN
243#define VIEWER_COLUMN_LEFT BUTTON_LEFT
244#define VIEWER_COLUMN_RIGHT BUTTON_RIGHT
245#define VIEWER_BOOKMARK BUTTON_SELECT
246
247/*M-Robe 100 keys */
248#elif CONFIG_KEYPAD == MROBE100_PAD
249#define VIEWER_QUIT BUTTON_POWER
250#define VIEWER_SCROLL_UP BUTTON_UP
251#define VIEWER_SCROLL_DOWN BUTTON_DOWN
252#define VIEWER_SCREEN_LEFT BUTTON_LEFT
253#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
254#define VIEWER_MENU BUTTON_MENU
255#define VIEWER_AUTOSCROLL BUTTON_DISPLAY
256#define VIEWER_BOOKMARK BUTTON_SELECT
257
258/* iAUdio M3 keys */
259#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
260#define VIEWER_QUIT BUTTON_REC
261#define VIEWER_RC_QUIT BUTTON_RC_REC
262#define VIEWER_SCROLL_UP BUTTON_RC_VOL_UP
263#define VIEWER_SCROLL_DOWN BUTTON_RC_VOL_DOWN
264#define VIEWER_SCREEN_LEFT BUTTON_RC_REW
265#define VIEWER_SCREEN_RIGHT BUTTON_RC_FF
266#define VIEWER_MENU BUTTON_RC_MENU
267#define VIEWER_AUTOSCROLL BUTTON_RC_MODE
268#define VIEWER_BOOKMARK BUTTON_RC_PLAY
269
270/* Cowon D2 keys */
271#elif CONFIG_KEYPAD == COWON_D2_PAD
272#define VIEWER_QUIT BUTTON_POWER
273#define VIEWER_MENU BUTTON_MENU
274#define VIEWER_SCROLL_UP BUTTON_MINUS
275#define VIEWER_SCROLL_DOWN BUTTON_PLUS
276#define VIEWER_BOOKMARK (BUTTON_MENU|BUTTON_PLUS)
277
278#elif CONFIG_KEYPAD == IAUDIO67_PAD
279#define VIEWER_QUIT BUTTON_POWER
280#define VIEWER_SCROLL_UP BUTTON_VOLUP
281#define VIEWER_SCROLL_DOWN BUTTON_VOLDOWN
282#define VIEWER_SCREEN_LEFT BUTTON_LEFT
283#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
284#define VIEWER_MENU BUTTON_MENU
285#define VIEWER_AUTOSCROLL BUTTON_PLAY
286#define VIEWER_RC_QUIT BUTTON_STOP
287#define VIEWER_BOOKMARK (BUTTON_LEFT|BUTTON_PLAY)
288
289/* Creative Zen Vision:M keys */
290#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
291#define VIEWER_QUIT BUTTON_BACK
292#define VIEWER_SCROLL_UP BUTTON_UP
293#define VIEWER_SCROLL_DOWN BUTTON_DOWN
294#define VIEWER_SCREEN_LEFT BUTTON_LEFT
295#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
296#define VIEWER_MENU BUTTON_MENU
297#define VIEWER_AUTOSCROLL BUTTON_SELECT
298#define VIEWER_BOOKMARK BUTTON_PLAY
299
300/* Philips HDD1630 keys */
301#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
302#define VIEWER_QUIT BUTTON_POWER
303#define VIEWER_SCROLL_UP BUTTON_UP
304#define VIEWER_SCROLL_DOWN BUTTON_DOWN
305#define VIEWER_SCREEN_LEFT BUTTON_LEFT
306#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
307#define VIEWER_MENU BUTTON_MENU
308#define VIEWER_AUTOSCROLL BUTTON_VIEW
309#define VIEWER_BOOKMARK BUTTON_SELECT
310
311/* Philips SA9200 keys */
312#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
313#define VIEWER_QUIT BUTTON_POWER
314#define VIEWER_SCROLL_UP BUTTON_UP
315#define VIEWER_SCROLL_DOWN BUTTON_DOWN
316#define VIEWER_SCREEN_LEFT BUTTON_PREV
317#define VIEWER_SCREEN_RIGHT BUTTON_NEXT
318#define VIEWER_MENU BUTTON_MENU
319#define VIEWER_AUTOSCROLL BUTTON_PLAY
320#define VIEWER_BOOKMARK BUTTON_RIGHT
321
322/* Onda VX747 keys */
323#elif CONFIG_KEYPAD == ONDAVX747_PAD
324#define VIEWER_QUIT BUTTON_POWER
325#define VIEWER_MENU BUTTON_MENU
326#define VIEWER_BOOKMARK (BUTTON_RIGHT|BUTTON_POWER)
327
328/* Onda VX777 keys */
329#elif CONFIG_KEYPAD == ONDAVX777_PAD
330#define VIEWER_QUIT BUTTON_POWER
331#define VIEWER_BOOKMARK (BUTTON_RIGHT|BUTTON_POWER)
332
333/* SAMSUNG YH-820 / YH-920 / YH-925 keys */
334#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
335#define VIEWER_QUIT BUTTON_REC
336#define VIEWER_SCROLL_UP BUTTON_UP
337#define VIEWER_SCROLL_DOWN BUTTON_DOWN
338#define VIEWER_SCREEN_LEFT BUTTON_LEFT
339#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
340#define VIEWER_MENU BUTTON_PLAY
341#define VIEWER_AUTOSCROLL BUTTON_REW
342#define VIEWER_BOOKMARK BUTTON_FFWD
343
344/* Packard Bell Vibe 500 keys */
345#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
346#define VIEWER_QUIT BUTTON_REC
347#define VIEWER_SCROLL_UP BUTTON_OK
348#define VIEWER_SCROLL_DOWN BUTTON_CANCEL
349#define VIEWER_LINE_UP BUTTON_UP
350#define VIEWER_LINE_DOWN BUTTON_DOWN
351#define VIEWER_SCREEN_LEFT BUTTON_PREV
352#define VIEWER_SCREEN_RIGHT BUTTON_NEXT
353#define VIEWER_MENU BUTTON_MENU
354#define VIEWER_AUTOSCROLL BUTTON_PLAY
355#define VIEWER_BOOKMARK BUTTON_POWER
356
357#else
358#error No keymap defined!
359#endif
360
361#ifdef HAVE_TOUCHSCREEN
362#ifdef VIEWER_QUIT
363#define VIEWER_QUIT2 BUTTON_TOPLEFT
364#else
365#define VIEWER_QUIT BUTTON_TOPLEFT
366#endif
367#ifdef VIEWER_SCROLL_UP
368#define VIEWER_SCROLL_UP2 BUTTON_TOPMIDDLE
369#else
370#define VIEWER_SCROLL_UP BUTTON_TOPMIDDLE
371#endif
372#ifdef VIEWER_SCROLL_DOWN
373#define VIEWER_SCROLL_DOWN2 BUTTON_BOTTOMMIDDLE
374#else
375#define VIEWER_SCROLL_DOWN BUTTON_BOTTOMMIDDLE
376#endif
377#ifndef VIEWER_SCREEN_LEFT
378#define VIEWER_SCREEN_LEFT BUTTON_MIDLEFT
379#endif
380#ifndef VIEWER_SCREEN_RIGHT
381#define VIEWER_SCREEN_RIGHT BUTTON_MIDRIGHT
382#endif
383#ifdef VIEWER_MENU
384#define VIEWER_MENU2 BUTTON_TOPRIGHT
385#else
386#define VIEWER_MENU BUTTON_TOPRIGHT
387#endif
388#ifndef VIEWER_AUTOSCROLL
389#define VIEWER_AUTOSCROLL BUTTON_CENTER
390#endif
391#endif
392
393#endif
diff --git a/apps/plugins/textviewer/tv_menu.c b/apps/plugins/textviewer/tv_menu.c
deleted file mode 100644
index aa1b8d615e..0000000000
--- a/apps/plugins/textviewer/tv_menu.c
+++ /dev/null
@@ -1,384 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "plugin.h"
24#include "lib/playback_control.h"
25
26
27/* settings helper functions */
28
29static bool encoding_setting(void)
30{
31 static struct opt_items names[NUM_CODEPAGES];
32 int idx;
33 bool res;
34 enum codepages oldenc = prefs.encoding;
35
36 for (idx = 0; idx < NUM_CODEPAGES; idx++)
37 {
38 names[idx].string = rb->get_codepage_name(idx);
39 names[idx].voice_id = -1;
40 }
41
42 res = rb->set_option("Encoding", &prefs.encoding, INT, names,
43 sizeof(names) / sizeof(names[0]), NULL);
44
45 /* When prefs.encoding changes into UTF-8 or changes from UTF-8,
46 * filesize (file_size) might change.
47 * In addition, if prefs.encoding is UTF-8, then BOM does not read.
48 */
49 if (oldenc != prefs.encoding && (oldenc == UTF_8 || prefs.encoding == UTF_8))
50 {
51 check_bom();
52 get_filesize();
53 fill_buffer(file_pos, buffer, buffer_size);
54 }
55
56 return res;
57}
58
59static bool word_wrap_setting(void)
60{
61 static const struct opt_items names[] = {
62 {"On", -1},
63 {"Off (Chop Words)", -1},
64 };
65
66 return rb->set_option("Word Wrap", &prefs.word_mode, INT,
67 names, 2, NULL);
68}
69
70static bool line_mode_setting(void)
71{
72 static const struct opt_items names[] = {
73 {"Normal", -1},
74 {"Join Lines", -1},
75 {"Expand Lines", -1},
76#ifdef HAVE_LCD_BITMAP
77 {"Reflow Lines", -1},
78#endif
79 };
80
81 return rb->set_option("Line Mode", &prefs.line_mode, INT, names,
82 sizeof(names) / sizeof(names[0]), NULL);
83}
84
85static bool view_mode_setting(void)
86{
87 static const struct opt_items names[] = {
88 {"No (Narrow)", -1},
89 {"Yes", -1},
90 };
91 bool ret;
92 ret = rb->set_option("Wide View", &prefs.view_mode, INT,
93 names , 2, NULL);
94 if (prefs.view_mode == NARROW)
95 col = 0;
96 calc_max_width();
97 return ret;
98}
99
100static bool scroll_mode_setting(void)
101{
102 static const struct opt_items names[] = {
103 {"Scroll by Page", -1},
104 {"Scroll by Line", -1},
105 };
106
107 return rb->set_option("Scroll Mode", &prefs.scroll_mode, INT,
108 names, 2, NULL);
109}
110
111#ifdef HAVE_LCD_BITMAP
112static bool page_mode_setting(void)
113{
114 static const struct opt_items names[] = {
115 {"No", -1},
116 {"Yes", -1},
117 };
118
119 return rb->set_option("Overlap Pages", &prefs.page_mode, INT,
120 names, 2, NULL);
121}
122
123static bool scrollbar_setting(void)
124{
125 static const struct opt_items names[] = {
126 {"Off", -1},
127 {"On", -1}
128 };
129
130 return rb->set_option("Show Scrollbar", &prefs.scrollbar_mode, INT,
131 names, 2, NULL);
132}
133
134static bool header_setting(void)
135{
136 int len = (rb->global_settings->statusbar == STATUSBAR_TOP)? 4 : 2;
137 struct opt_items names[len];
138
139 names[0].string = "None";
140 names[0].voice_id = -1;
141 names[1].string = "File path";
142 names[1].voice_id = -1;
143
144 if (rb->global_settings->statusbar == STATUSBAR_TOP)
145 {
146 names[2].string = "Status bar";
147 names[2].voice_id = -1;
148 names[3].string = "Both";
149 names[3].voice_id = -1;
150 }
151
152 return rb->set_option("Show Header", &prefs.header_mode, INT,
153 names, len, NULL);
154}
155
156static bool footer_setting(void)
157{
158 int len = (rb->global_settings->statusbar == STATUSBAR_BOTTOM)? 4 : 2;
159 struct opt_items names[len];
160
161 names[0].string = "None";
162 names[0].voice_id = -1;
163 names[1].string = "Page Num";
164 names[1].voice_id = -1;
165
166 if (rb->global_settings->statusbar == STATUSBAR_BOTTOM)
167 {
168 names[2].string = "Status bar";
169 names[2].voice_id = -1;
170 names[3].string = "Both";
171 names[3].voice_id = -1;
172 }
173
174 return rb->set_option("Show Footer", &prefs.footer_mode, INT,
175 names, len, NULL);
176}
177
178static int font_comp(const void *a, const void *b)
179{
180 struct opt_items *pa;
181 struct opt_items *pb;
182
183 pa = (struct opt_items *)a;
184 pb = (struct opt_items *)b;
185
186 return rb->strcmp(pa->string, pb->string);
187}
188
189static bool font_setting(void)
190{
191 int count = 0;
192 DIR *dir;
193 struct dirent *entry;
194 int i = 0;
195 int len;
196 int new_font = 0;
197 int old_font;
198 bool res;
199 int size = 0;
200
201 dir = rb->opendir(FONT_DIR);
202 if (!dir)
203 {
204 rb->splash(HZ/2, "font dir does not access.");
205 return false;
206 }
207
208 while (1)
209 {
210 entry = rb->readdir(dir);
211
212 if (entry == NULL)
213 break;
214
215 len = rb->strlen(entry->d_name);
216 if (len < 4 || rb->strcmp(entry->d_name + len-4, ".fnt"))
217 continue;
218 size += len-3;
219 count++;
220 }
221 rb->closedir(dir);
222
223 struct opt_items names[count];
224 unsigned char font_names[size];
225 unsigned char *p = font_names;
226
227 dir = rb->opendir(FONT_DIR);
228 if (!dir)
229 {
230 rb->splash(HZ/2, "font dir does not access.");
231 return false;
232 }
233
234 while (1)
235 {
236 entry = rb->readdir(dir);
237
238 if (entry == NULL)
239 break;
240
241 len = rb->strlen(entry->d_name);
242 if (len < 4 || rb->strcmp(entry->d_name + len-4, ".fnt"))
243 continue;
244
245 rb->snprintf(p, len-3, "%s", entry->d_name);
246 names[i].string = p;
247 names[i].voice_id = -1;
248 p += len-3;
249 i++;
250 if (i >= count)
251 break;
252 }
253 rb->closedir(dir);
254
255 rb->qsort(names, count, sizeof(struct opt_items), font_comp);
256
257 for (i = 0; i < count; i++)
258 {
259 if (!rb->strcmp(names[i].string, prefs.font))
260 {
261 new_font = i;
262 break;
263 }
264 }
265 old_font = new_font;
266
267 res = rb->set_option("Select Font", &new_font, INT,
268 names, count, NULL);
269
270 if (new_font != old_font)
271 {
272 rb->memset(prefs.font, 0, MAX_PATH);
273 rb->snprintf(prefs.font, MAX_PATH, "%s", names[new_font].string);
274 change_font(prefs.font);
275 }
276
277 return res;
278}
279#endif
280
281static bool autoscroll_speed_setting(void)
282{
283 return rb->set_int("Auto-scroll Speed", "", UNIT_INT,
284 &prefs.autoscroll_speed, NULL, 1, 1, 10, NULL);
285}
286
287MENUITEM_FUNCTION(encoding_item, 0, "Encoding", encoding_setting,
288 NULL, NULL, Icon_NOICON);
289MENUITEM_FUNCTION(word_wrap_item, 0, "Word Wrap", word_wrap_setting,
290 NULL, NULL, Icon_NOICON);
291MENUITEM_FUNCTION(line_mode_item, 0, "Line Mode", line_mode_setting,
292 NULL, NULL, Icon_NOICON);
293MENUITEM_FUNCTION(view_mode_item, 0, "Wide View", view_mode_setting,
294 NULL, NULL, Icon_NOICON);
295#ifdef HAVE_LCD_BITMAP
296MENUITEM_FUNCTION(scrollbar_item, 0, "Show Scrollbar", scrollbar_setting,
297 NULL, NULL, Icon_NOICON);
298MENUITEM_FUNCTION(page_mode_item, 0, "Overlap Pages", page_mode_setting,
299 NULL, NULL, Icon_NOICON);
300MENUITEM_FUNCTION(header_item, 0, "Show Header", header_setting,
301 NULL, NULL, Icon_NOICON);
302MENUITEM_FUNCTION(footer_item, 0, "Show Footer", footer_setting,
303 NULL, NULL, Icon_NOICON);
304MENUITEM_FUNCTION(font_item, 0, "Font", font_setting,
305 NULL, NULL, Icon_NOICON);
306#endif
307MENUITEM_FUNCTION(scroll_mode_item, 0, "Scroll Mode", scroll_mode_setting,
308 NULL, NULL, Icon_NOICON);
309MENUITEM_FUNCTION(autoscroll_speed_item, 0, "Auto-Scroll Speed",
310 autoscroll_speed_setting, NULL, NULL, Icon_NOICON);
311MAKE_MENU(option_menu, "Viewer Options", NULL, Icon_NOICON,
312 &encoding_item, &word_wrap_item, &line_mode_item, &view_mode_item,
313#ifdef HAVE_LCD_BITMAP
314 &scrollbar_item, &page_mode_item, &header_item, &footer_item, &font_item,
315#endif
316 &scroll_mode_item, &autoscroll_speed_item);
317
318static bool viewer_options_menu(bool is_global)
319{
320 bool result;
321 struct preferences tmp_prefs;
322
323 rb->memcpy(&tmp_prefs, &prefs, sizeof(struct preferences));
324
325 result = (rb->do_menu(&option_menu, NULL, NULL, false) == MENU_ATTACHED_USB);
326
327 if (!is_global && rb->memcmp(&tmp_prefs, &prefs, sizeof(struct preferences)))
328 {
329 /* Show-scrollbar mode for current view-width mode */
330#ifdef HAVE_LCD_BITMAP
331 init_need_scrollbar();
332 init_header_and_footer();
333#endif
334 calc_page();
335 }
336 return result;
337}
338
339void viewer_menu(void)
340{
341 int result;
342
343 MENUITEM_STRINGLIST(menu, "Viewer Menu", NULL,
344 "Return", "Viewer Options",
345 "Show Playback Menu", "Select Bookmark",
346 "Global Settings", "Quit");
347
348 result = rb->do_menu(&menu, NULL, NULL, false);
349 switch (result)
350 {
351 case 0: /* return */
352 break;
353 case 1: /* change settings */
354 done = viewer_options_menu(false);
355 break;
356 case 2: /* playback control */
357 playback_control(NULL);
358 break;
359 case 3: /* select bookmark */
360 viewer_select_bookmark(viewer_add_last_read_bookmark());
361 viewer_remove_last_read_bookmark();
362 fill_buffer(file_pos, buffer, buffer_size);
363 if (prefs.scroll_mode == PAGE && cline > 1)
364 viewer_scroll_to_top_line();
365 break;
366 case 4: /* change global settings */
367 {
368 struct preferences orig_prefs;
369
370 rb->memcpy(&orig_prefs, &prefs, sizeof(struct preferences));
371 if (!viewer_load_global_settings())
372 viewer_default_preferences();
373 done = viewer_options_menu(true);
374 viewer_save_global_settings();
375 rb->memcpy(&prefs, &orig_prefs, sizeof(struct preferences));
376 }
377 break;
378 case 5: /* quit */
379 viewer_exit(NULL);
380 done = true;
381 break;
382 }
383 viewer_draw(col);
384}
diff --git a/apps/plugins/textviewer/tv_menu.h b/apps/plugins/textviewer/tv_menu.h
deleted file mode 100644
index 68a635e22b..0000000000
--- a/apps/plugins/textviewer/tv_menu.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#ifndef PLUGIN_TEXT_VIEWER_MENU_H
24#define PLUGIN_TEXT_VIEWER_MENU_H
25
26void viewer_menu(void):
27
28#endif
diff --git a/apps/plugins/textviewer/tv_readtext.c b/apps/plugins/textviewer/tv_readtext.c
deleted file mode 100644
index 988ee637eb..0000000000
--- a/apps/plugins/textviewer/tv_readtext.c
+++ /dev/null
@@ -1,483 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "plugin.h"
24#include "tv_readtext.h"
25
26#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */
27#define NARROW_MAX_COLUMNS 64 /* Max displayable string len [narrow] (over-estimate) */
28#define WIDE_MAX_COLUMNS 128 /* Max displayable string len [wide] (over-estimate) */
29#define MAX_WIDTH 910 /* Max line length in WIDE mode */
30#define READ_PREV_ZONE (block_size*9/10) /* Arbitrary number less than SMALL_BLOCK_SIZE */
31#define SMALL_BLOCK_SIZE block_size /* Smallest file chunk we will read */
32#define LARGE_BLOCK_SIZE (block_size << 1) /* Preferable size of file chunk to read */
33#define TOP_SECTOR buffer
34#define MID_SECTOR (buffer + SMALL_BLOCK_SIZE)
35#define BOTTOM_SECTOR (buffer + (SMALL_BLOCK_SIZE << 1))
36#undef SCROLLBAR_WIDTH
37#define SCROLLBAR_WIDTH rb->global_settings->scrollbar_width
38#define MAX_PAGE 9999
39
40/* Out-Of-Bounds test for any pointer to data in the buffer */
41#define BUFFER_OOB(p) ((p) < buffer || (p) >= buffer_end)
42
43/* Does the buffer contain the beginning of the file? */
44#define BUFFER_BOF() (file_pos==0)
45
46/* Does the buffer contain the end of the file? */
47#define BUFFER_EOF() (file_size-file_pos <= buffer_size)
48
49/* Formula for the endpoint address outside of buffer data */
50#define BUFFER_END() \
51 ((BUFFER_EOF()) ? (file_size-file_pos+buffer) : (buffer+buffer_size))
52
53/* Is the entire file being shown in one screen? */
54#define ONE_SCREEN_FITS_ALL() \
55 (next_screen_ptr==NULL && screen_top_ptr==buffer && BUFFER_BOF())
56
57#define ADVANCE_COUNTERS(c) { width += glyph_width(c); k++; }
58#define LINE_IS_FULL ((k>=max_columns-1) ||( width >= max_width))
59#define LINE_IS_NOT_FULL ((k<max_columns-1) &&( width < max_width))
60
61
62static unsigned char file_name[MAX_PARH+1];
63static int fd = -1;
64
65static unsigned char *buffer;
66static long buffer_size;
67static long block_size = 0x1000;
68
69void viewer_init_buffer(void)
70{
71 /* get the plugin buffer */
72 buffer = rb->plugin_get_buffer((size_t *)&buffer_size);
73 if (buffer_size == 0)
74 {
75 rb->splash(HZ, "buffer does not allocate !!");
76 return PLUGIN_ERROR;
77 }
78 block_size = buffer_size / 3;
79 buffer_size = 3 * block_size;
80}
81
82static unsigned char* crop_at_width(const unsigned char* p)
83{
84 int k,width;
85 unsigned short ch;
86 const unsigned char *oldp = p;
87
88 k=width=0;
89
90 while (LINE_IS_NOT_FULL) {
91 oldp = p;
92 if (BUFFER_OOB(p))
93 break;
94 p = get_ucs(p, &ch);
95 ADVANCE_COUNTERS(ch);
96 }
97
98 return (unsigned char*)oldp;
99}
100
101static unsigned char* find_first_feed(const unsigned char* p, int size)
102{
103 int i;
104
105 for (i=0; i < size; i++)
106 if (p[i] == 0)
107 return (unsigned char*) p+i;
108
109 return NULL;
110}
111
112static unsigned char* find_last_feed(const unsigned char* p, int size)
113{
114 int i;
115
116 for (i=size-1; i>=0; i--)
117 if (p[i] == 0)
118 return (unsigned char*) p+i;
119
120 return NULL;
121}
122
123static unsigned char* find_last_space(const unsigned char* p, int size)
124{
125 int i, j, k;
126
127 k = (prefs.line_mode==JOIN) || (prefs.line_mode==REFLOW) ? 0:1;
128
129 if (!BUFFER_OOB(&p[size]))
130 for (j=k; j < ((int) sizeof(line_break)) - 1; j++)
131 if (p[size] == line_break[j])
132 return (unsigned char*) p+size;
133
134 for (i=size-1; i>=0; i--)
135 for (j=k; j < (int) sizeof(line_break); j++)
136 {
137 if (!((p[i] == '-') && (prefs.word_mode == WRAP)))
138 if (p[i] == line_break[j])
139 return (unsigned char*) p+i;
140 }
141
142 return NULL;
143}
144
145static unsigned char* find_next_line(const unsigned char* cur_line, bool *is_short)
146{
147 const unsigned char *next_line = NULL;
148 int size, i, j, k, width, search_len, spaces, newlines;
149 bool first_chars;
150 unsigned char c;
151
152 if (is_short != NULL)
153 *is_short = true;
154
155 if BUFFER_OOB(cur_line)
156 return NULL;
157
158 if (prefs.view_mode == WIDE) {
159 search_len = MAX_WIDTH;
160 }
161 else { /* prefs.view_mode == NARROW */
162 search_len = crop_at_width(cur_line) - cur_line;
163 }
164
165 size = BUFFER_OOB(cur_line+search_len) ? buffer_end-cur_line : search_len;
166
167 if ((prefs.line_mode == JOIN) || (prefs.line_mode == REFLOW)) {
168 /* Need to scan ahead and possibly increase search_len and size,
169 or possibly set next_line at second hard return in a row. */
170 next_line = NULL;
171 first_chars=true;
172 for (j=k=width=spaces=newlines=0; ; j++) {
173 if (BUFFER_OOB(cur_line+j))
174 return NULL;
175 if (LINE_IS_FULL) {
176 size = search_len = j;
177 break;
178 }
179
180 c = cur_line[j];
181 switch (c) {
182 case ' ':
183 if (prefs.line_mode == REFLOW) {
184 if (newlines > 0) {
185 size = j;
186 next_line = cur_line + size;
187 return (unsigned char*) next_line;
188 }
189 if (j==0) /* i=1 is intentional */
190 for (i=0; i<par_indent_spaces; i++)
191 ADVANCE_COUNTERS(' ');
192 }
193 if (!first_chars) spaces++;
194 break;
195
196 case 0:
197 if (newlines > 0) {
198 size = j;
199 next_line = cur_line + size - spaces;
200 if (next_line != cur_line)
201 return (unsigned char*) next_line;
202 break;
203 }
204
205 newlines++;
206 size += spaces -1;
207 if (BUFFER_OOB(cur_line+size) || size > 2*search_len)
208 return NULL;
209 search_len = size;
210 spaces = first_chars? 0:1;
211 break;
212
213 default:
214 if (prefs.line_mode==JOIN || newlines>0) {
215 while (spaces) {
216 spaces--;
217 ADVANCE_COUNTERS(' ');
218 if (LINE_IS_FULL) {
219 size = search_len = j;
220 break;
221 }
222 }
223 newlines=0;
224 } else if (spaces) {
225 /* REFLOW, multiple spaces between words: count only
226 * one. If more are needed, they will be added
227 * while drawing. */
228 search_len = size;
229 spaces=0;
230 ADVANCE_COUNTERS(' ');
231 if (LINE_IS_FULL) {
232 size = search_len = j;
233 break;
234 }
235 }
236 first_chars = false;
237 ADVANCE_COUNTERS(c);
238 break;
239 }
240 }
241 }
242 else {
243 /* find first hard return */
244 next_line = find_first_feed(cur_line, size);
245 }
246
247 if (next_line == NULL)
248 if (size == search_len) {
249 if (prefs.word_mode == WRAP) /* Find last space */
250 next_line = find_last_space(cur_line, size);
251
252 if (next_line == NULL)
253 next_line = crop_at_width(cur_line);
254 else
255 if (prefs.word_mode == WRAP)
256 for (i=0;
257 i<WRAP_TRIM && isspace(next_line[0]) && !BUFFER_OOB(next_line);
258 i++)
259 next_line++;
260 }
261
262 if (prefs.line_mode == EXPAND)
263 if (!BUFFER_OOB(next_line)) /* Not Null & not out of bounds */
264 if (next_line[0] == 0)
265 if (next_line != cur_line)
266 return (unsigned char*) next_line;
267
268 /* If next_line is pointing to a zero, increment it; i.e.,
269 leave the terminator at the end of cur_line. If pointing
270 to a hyphen, increment only if there is room to display
271 the hyphen on current line (won't apply in WIDE mode,
272 since it's guarenteed there won't be room). */
273 if (!BUFFER_OOB(next_line)) /* Not Null & not out of bounds */
274 if (next_line[0] == 0)/* ||
275 (next_line[0] == '-' && next_line-cur_line < draw_columns)) */
276 next_line++;
277
278 if (BUFFER_OOB(next_line))
279 {
280 if (BUFFER_EOF() && next_line != cur_line)
281 return (unsigned char*) next_line;
282 return NULL;
283 }
284
285 if (is_short)
286 *is_short = false;
287
288 return (unsigned char*) next_line;
289}
290
291static unsigned char* find_prev_line(const unsigned char* cur_line)
292{
293 const unsigned char *prev_line = NULL;
294 const unsigned char *p;
295
296 if BUFFER_OOB(cur_line)
297 return NULL;
298
299 /* To wrap consistently at the same places, we must
300 start with a known hard return, then work downwards.
301 We can either search backwards for a hard return,
302 or simply start wrapping downwards from top of buffer.
303 If current line is not near top of buffer, this is
304 a file with long lines (paragraphs). We would need to
305 read earlier sectors before we could decide how to
306 properly wrap the lines above the current line, but
307 it probably is not worth the disk access. Instead,
308 start with top of buffer and wrap down from there.
309 This may result in some lines wrapping at different
310 points from where they wrap when scrolling down.
311 If buffer is at top of file, start at top of buffer. */
312
313 if ((prefs.line_mode == JOIN) || (prefs.line_mode == REFLOW))
314 prev_line = p = NULL;
315 else
316 prev_line = p = find_last_feed(buffer, cur_line-buffer-1);
317 /* Null means no line feeds in buffer above current line. */
318
319 if (prev_line == NULL)
320 if (BUFFER_BOF() || cur_line - buffer > READ_PREV_ZONE)
321 prev_line = p = buffer;
322 /* (else return NULL and read previous block) */
323
324 /* Wrap downwards until too far, then use the one before. */
325 while (p != NULL && p < cur_line) {
326 prev_line = p;
327 p = find_next_line(prev_line, NULL);
328 }
329
330 if (BUFFER_OOB(prev_line))
331 return NULL;
332
333 return (unsigned char*) prev_line;
334}
335
336static void check_bom(void)
337{
338 unsigned char bom[BOM_SIZE];
339 off_t orig = rb->lseek(fd, 0, SEEK_CUR);
340
341 is_bom = false;
342
343 rb->lseek(fd, 0, SEEK_SET);
344
345 if (rb->read(fd, bom, BOM_SIZE) == BOM_SIZE)
346 is_bom = !memcmp(bom, BOM, BOM_SIZE);
347
348 rb->lseek(fd, orig, SEEK_SET);
349}
350
351static void fill_buffer(long pos, unsigned char* buf, unsigned size)
352{
353 /* Read from file and preprocess the data */
354 /* To minimize disk access, always read on sector boundaries */
355 unsigned numread, i;
356 bool found_CR = false;
357 off_t offset = rb->lseek(fd, pos, SEEK_SET);
358
359 if (offset == 0 && prefs.encoding == UTF_8 && is_bom)
360 rb->lseek(fd, BOM_SIZE, SEEK_SET);
361
362 numread = rb->read(fd, buf, size);
363 buf[numread] = 0;
364 rb->button_clear_queue(); /* clear button queue */
365
366 for(i = 0; i < numread; i++) {
367 switch(buf[i]) {
368 case '\r':
369 if (mac_text) {
370 buf[i] = 0;
371 }
372 else {
373 buf[i] = ' ';
374 found_CR = true;
375 }
376 break;
377
378 case '\n':
379 buf[i] = 0;
380 found_CR = false;
381 break;
382
383 case 0: /* No break between case 0 and default, intentionally */
384 buf[i] = ' ';
385 default:
386 if (found_CR) {
387 buf[i - 1] = 0;
388 found_CR = false;
389 mac_text = true;
390 }
391 break;
392 }
393 }
394}
395
396static int read_and_synch(int direction)
397{
398/* Read next (or prev) block, and reposition global pointers. */
399/* direction: 1 for down (i.e., further into file), -1 for up */
400 int move_size, move_vector, offset;
401 unsigned char *fill_buf;
402
403 if (direction == -1) /* up */ {
404 move_size = SMALL_BLOCK_SIZE;
405 offset = 0;
406 fill_buf = TOP_SECTOR;
407 rb->memcpy(BOTTOM_SECTOR, MID_SECTOR, SMALL_BLOCK_SIZE);
408 rb->memcpy(MID_SECTOR, TOP_SECTOR, SMALL_BLOCK_SIZE);
409 }
410 else /* down */ {
411 if (prefs.view_mode == WIDE) {
412 /* WIDE mode needs more buffer so we have to read smaller blocks */
413 move_size = SMALL_BLOCK_SIZE;
414 offset = LARGE_BLOCK_SIZE;
415 fill_buf = BOTTOM_SECTOR;
416 rb->memcpy(TOP_SECTOR, MID_SECTOR, SMALL_BLOCK_SIZE);
417 rb->memcpy(MID_SECTOR, BOTTOM_SECTOR, SMALL_BLOCK_SIZE);
418 }
419 else {
420 move_size = LARGE_BLOCK_SIZE;
421 offset = SMALL_BLOCK_SIZE;
422 fill_buf = MID_SECTOR;
423 rb->memcpy(TOP_SECTOR, BOTTOM_SECTOR, SMALL_BLOCK_SIZE);
424 }
425 }
426 move_vector = direction * move_size;
427 screen_top_ptr -= move_vector;
428 file_pos += move_vector;
429 buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
430 fill_buffer(file_pos + offset, fill_buf, move_size);
431 return move_vector;
432}
433
434static void get_next_line_position(unsigned char **line_begin,
435 unsigned char **line_end,
436 bool *is_short)
437{
438 int resynch_move;
439
440 *line_begin = *line_end;
441 *line_end = find_next_line(*line_begin, is_short);
442
443 if (*line_end == NULL && !BUFFER_EOF())
444 {
445 resynch_move = read_and_synch(1); /* Read block & move ptrs */
446 *line_begin -= resynch_move;
447 if (next_line_ptr > buffer)
448 next_line_ptr -= resynch_move;
449
450 *line_end = find_next_line(*line_begin, is_short);
451 }
452}
453
454/* open, close, get file size functions */
455
456bool viewer_open(const unsigned char *fname)
457{
458 if (fname == 0)
459 return false;
460
461 rb->strlcpy(file_name, fname, MAX_PATH+1);
462 fd = rb->open(fname, O_RDONLY);
463 return (fd >= 0);
464}
465
466void viewer_close(void)
467{
468 if (fd >= 0)
469 rb->close(fd);
470}
471
472/* When a file is UTF-8 file with BOM, if prefs.encoding is UTF-8,
473 * then file size decreases only BOM_SIZE.
474 */
475static void get_filesize(void)
476{
477 file_size = rb->filesize(fd);
478 if (file_size == -1)
479 return;
480
481 if (prefs.encoding == UTF_8 && is_bom)
482 file_size -= BOM_SIZE;
483}
diff --git a/apps/plugins/textviewer/tv_readtext.h b/apps/plugins/textviewer/tv_readtext.h
deleted file mode 100644
index 774ebabd64..0000000000
--- a/apps/plugins/textviewer/tv_readtext.h
+++ /dev/null
@@ -1,31 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#ifndef PLUGIN_TEXT_VIEWER_READTEXT_H
24#define PLUGIN_TEXT_VIEWER_READTEXT_H
25
26void viewer_init_buffer(void);
27
28bool viewer_open(const unsigned char *fname);
29void viewer_close(void);
30
31#endif
diff --git a/apps/plugins/textviewer/tv_screen.c b/apps/plugins/textviewer/tv_screen.c
deleted file mode 100644
index ce2d82d59f..0000000000
--- a/apps/plugins/textviewer/tv_screen.c
+++ /dev/null
@@ -1,468 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux, 2003 Garrett Derner
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "plugin.h"
22#include "tv_screen.h"
23#include "tv_settings.h"
24
25static int draw_columns; /* number of (pixel) columns available for text */
26static int par_indent_spaces; /* number of spaces to indent first paragraph */
27
28#ifdef HAVE_LCD_BITMAP
29static struct font *pf;
30static int header_height = 0;
31static int footer_height = 0;
32#endif
33
34void viewer_init_screen(void)
35{
36#ifdef HAVE_LCD_BITMAP
37 /* initialize fonts */
38 pf = rb->font_get(FONT_UI);
39 draw_columns = display_columns = LCD_WIDTH;
40#else
41 /* REAL fixed pitch :) all chars use up 1 cell */
42 display_lines = 2;
43 draw_columns = display_columns = 11;
44 par_indent_spaces = 2;
45#endif
46}
47
48void viewer_finalize_screen(void)
49{
50 change_font(rb->global_settings->font_file);
51}
52
53void viewer_draw(void)
54{
55}
56
57void viewer_top(void)
58{
59 /* Read top of file into buffer
60 and point screen pointer to top */
61 if (file_pos != 0)
62 {
63 rb->splash(0, "Loading...");
64
65 file_pos = 0;
66 buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
67 fill_buffer(0, buffer, buffer_size);
68 }
69
70 screen_top_ptr = buffer;
71 cpage = 1;
72 cline = 1;
73}
74
75void viewer_bottom(void)
76{
77 unsigned char *line_begin;
78 unsigned char *line_end;
79
80 rb->splash(0, "Loading...");
81
82 if (last_screen_top_ptr)
83 {
84 cpage = lpage;
85 cline = 1;
86 screen_top_ptr = last_screen_top_ptr;
87 file_pos = last_file_pos;
88 fill_buffer(file_pos, buffer, buffer_size);
89 buffer_end = BUFFER_END();
90 return;
91 }
92
93 line_end = screen_top_ptr;
94
95 while (!BUFFER_EOF() || !BUFFER_OOB(line_end))
96 {
97 get_next_line_position(&line_begin, &line_end, NULL);
98 if (line_end == NULL)
99 break;
100
101 increment_current_line();
102 if (cline == 1)
103 screen_top_ptr = line_end;
104 }
105 lpage = cpage;
106 cline = 1;
107 last_screen_top_ptr = screen_top_ptr;
108 last_file_pos = file_pos;
109 buffer_end = BUFFER_END();
110}
111
112static void increment_current_line(void)
113{
114 if (cline < display_lines)
115 cline++;
116 else if (cpage < MAX_PAGE)
117 {
118 cpage++;
119 cline = 1;
120 }
121}
122
123static void decrement_current_line(void)
124{
125 if (cline > 1)
126 cline--;
127 else if (cpage > 1)
128 {
129 cpage--;
130 cline = display_lines;
131 }
132}
133
134static void viewer_line_scroll_up(void)
135{
136 unsigned char *p;
137
138 p = find_prev_line(screen_top_ptr);
139 if (p == NULL && !BUFFER_BOF()) {
140 read_and_synch(-1);
141 p = find_prev_line(screen_top_ptr);
142 }
143 if (p != NULL)
144 screen_top_ptr = p;
145
146 decrement_current_line();
147}
148
149static void viewer_line_scroll_down(void)
150{
151 if (cpage == lpage)
152 return;
153
154 if (next_line_ptr != NULL)
155 screen_top_ptr = next_line_ptr;
156
157 increment_current_line();
158}
159
160static void viewer_scroll_to_top_line(void)
161{
162 int line;
163
164 for (line = cline; line > 1; line--)
165 viewer_scroll_up();
166}
167
168void viewer_scroll_up(int mode)
169{
170 int i;
171 int line_count = 1;
172 struct viewer_preference *prefs = viewer_get_preference();
173
174 if ((mode == VIEWER_SCROLL_PAGE) ||
175 (mode == VIEWER_SCROLL_PREFS && prefs->scroll_mode == PAGE))
176 {
177#ifdef HAVE_LCD_BITMAP
178 line_count = display_lines - ((prefs->page_mode==OVERLAP)? 1:0);
179#else
180 line_count = display_lines;
181#endif
182 }
183
184 for (i = 0; i < line_count; i++)
185 viewer_line_scroll_up();
186}
187
188void viewer_scroll_down(int mode)
189{
190 struct viewer_preference *prefs = viewer_get_preference();
191
192 if ((mode == VIEWER_SCROLL_PAGE) ||
193 (mode == VIEWER_SCROLL_PREFS && prefs->scroll_mode == PAGE))
194 {
195 /* Page down */
196 if (next_screen_ptr != NULL)
197 {
198 screen_top_ptr = next_screen_to_draw_ptr;
199 if (cpage < MAX_PAGE)
200 cpage++;
201 }
202 }
203 else
204 viewer_line_scroll_down();
205}
206
207#ifdef HAVE_LCD_BITMAP
208static void viewer_scrollbar(void) {
209 int items, min_shown, max_shown, sb_begin_y, sb_height;
210
211 items = (int) file_size; /* (SH1 int is same as long) */
212 min_shown = (int) file_pos + (screen_top_ptr - buffer);
213
214 if (next_screen_ptr == NULL)
215 max_shown = items;
216 else
217 max_shown = min_shown + (next_screen_ptr - screen_top_ptr);
218
219 sb_begin_y = header_height;
220 sb_height = LCD_HEIGHT - header_height - footer_height;
221
222 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, sb_begin_y,
223 SCROLLBAR_WIDTH-1, sb_height,
224 items, min_shown, max_shown, VERTICAL);
225}
226
227static void viewer_show_header(void)
228{
229 struct viewer_preference *prefs = viewer_get_preference();
230
231 if (prefs->header_mode == HD_SBAR || prefs->header_mode == HD_BOTH)
232 rb->gui_syncstatusbar_draw(rb->statusbars, true);
233
234 if (prefs->header_mode == HD_PATH || prefs->header_mode == HD_BOTH)
235 rb->lcd_putsxy(0, header_height - pf->height, file_name);
236}
237
238static void viewer_show_footer(void)
239{
240 struct viewer_preference *prefs = viewer_get_preference();
241
242 if (prefs->footer_mode == FT_SBAR || prefs->footer_mode == FT_BOTH)
243 rb->gui_syncstatusbar_draw(rb->statusbars, true);
244
245 if (prefs->footer_mode == FT_PAGE || prefs->footer_mode == FT_BOTH)
246 {
247 unsigned char buf[12];
248
249 if (cline == 1)
250 rb->snprintf(buf, sizeof(buf), "%d", cpage);
251 else
252 rb->snprintf(buf, sizeof(buf), "%d - %d", cpage, cpage+1);
253
254 rb->lcd_putsxy(0, LCD_HEIGHT - footer_height, buf);
255 }
256}
257
258static bool need_scrollbar(void)
259{
260 struct viewer_preference *prefs = viewer_get_preference();
261
262 return prefs->need_scrollbar;
263}
264
265static void init_need_scrollbar(void) {
266 draw_columns = need_scrollbar()? display_columns-SCROLLBAR_WIDTH : display_columns;
267 par_indent_spaces = draw_columns/(5*glyph_width(' '));
268 calc_max_width();
269}
270
271static void init_header_and_footer(void)
272{
273 struct viewer_preference *prefs = viewer_get_preference();
274
275 header_height = 0;
276 footer_height = 0;
277 if (rb->global_settings->statusbar == STATUSBAR_TOP)
278 {
279 if (prefs->header_mode == HD_SBAR || prefs->header_mode == HD_BOTH)
280 header_height = STATUSBAR_HEIGHT;
281
282 if (prefs->footer_mode == FT_SBAR)
283 prefs->footer_mode = FT_NONE;
284 else if (prefs->footer_mode == FT_BOTH)
285 prefs->footer_mode = FT_PAGE;
286 }
287 else if (rb->global_settings->statusbar == STATUSBAR_BOTTOM)
288 {
289 if (prefs->footer_mode == FT_SBAR || prefs->footer_mode == FT_BOTH)
290 footer_height = STATUSBAR_HEIGHT;
291
292 if (prefs->header_mode == HD_SBAR)
293 prefs->header_mode = HD_NONE;
294 else if (prefs->header_mode == HD_BOTH)
295 prefs->header_mode = HD_PATH;
296 }
297 else /* STATUSBAR_OFF || STATUSBAR_CUSTOM */
298 {
299 if (prefs->header_mode == HD_SBAR)
300 prefs->header_mode = HD_NONE;
301 else if (prefs->header_mode == HD_BOTH)
302 prefs->header_mode = HD_PATH;
303
304 if (prefs->footer_mode == FT_SBAR)
305 prefs->footer_mode = FT_NONE;
306 else if (prefs->footer_mode == FT_BOTH)
307 prefs->footer_mode = FT_PAGE;
308 }
309
310 if (prefs->header_mode == HD_NONE || prefs->header_mode == HD_PATH ||
311 prefs->footer_mode == FT_NONE || prefs->footer_mode == FT_PAGE)
312 rb->gui_syncstatusbar_draw(rb->statusbars, false);
313
314 if (prefs->header_mode == HD_PATH || prefs->header_mode == HD_BOTH)
315 header_height += pf->height;
316 if (prefs->footer_mode == FT_PAGE || prefs->footer_mode == FT_BOTH)
317 footer_height += pf->height;
318
319 display_lines = (LCD_HEIGHT - header_height - footer_height) / pf->height;
320
321 lpage = 0;
322 last_file_pos = 0;
323 last_screen_top_ptr = NULL;
324}
325
326void change_font(unsigned char *font)
327{
328 unsigned char buf[MAX_PATH];
329 struct viewer_preference *prefs = viewer_get_preference();
330
331 if (font == NULL || *font == '\0')
332 return;
333
334 if (rb->strcmp(prefs->font, rb->global_settings->font_file) == 0)
335 return;
336
337 rb->snprintf(buf, MAX_PATH, "%s/%s.fnt", FONT_DIR, font);
338 if (rb->font_load(NULL, buf) < 0)
339 rb->splash(HZ/2, "font load failed.");
340}
341#else
342#define change_font(f)
343#endif
344
345static void calc_page(void)
346{
347 int i;
348 unsigned char *line_begin;
349 unsigned char *line_end;
350 off_t sfp;
351 unsigned char *sstp;
352 struct viewer_preference *prefs = viewer_get_preference();
353
354 rb->splash(0, "Calculating page/line number...");
355
356 /* add reading page to bookmarks */
357 viewer_add_last_read_bookmark();
358
359 rb->qsort(bookmarks, bookmark_count, sizeof(struct bookmark_info),
360 bm_comp);
361
362 cpage = 1;
363 cline = 1;
364 file_pos = 0;
365 screen_top_ptr = buffer;
366 buffer_end = BUFFER_END();
367
368 fill_buffer(file_pos, buffer, buffer_size);
369 line_end = line_begin = buffer;
370
371 for (i = 0; i < bookmark_count; i++)
372 {
373 sfp = bookmarks[i].file_position;
374 sstp = buffer;
375
376 while ((line_begin > sstp || sstp >= line_end) ||
377 (file_pos > sfp || sfp >= file_pos + BUFFER_END() - buffer))
378 {
379 get_next_line_position(&line_begin, &line_end, NULL);
380 if (line_end == NULL)
381 break;
382
383 next_line_ptr = line_end;
384
385 if (sstp == buffer &&
386 file_pos <= sfp && sfp < file_pos + BUFFER_END() - buffer)
387 sstp = sfp - file_pos + buffer;
388
389 increment_current_line();
390 }
391
392 decrement_current_line();
393 bookmarks[i].page = cpage;
394 bookmarks[i].line = cline;
395 bookmarks[i].file_position = file_pos + (line_begin - buffer);
396 increment_current_line();
397 }
398
399 /* remove reading page's bookmark */
400 for (i = 0; i < bookmark_count; i++)
401 {
402 if (bookmarks[i].flag & BOOKMARK_LAST)
403 {
404 int screen_pos;
405 int screen_top;
406
407 screen_pos = bookmarks[i].file_position;
408 screen_top = screen_pos % buffer_size;
409 file_pos = screen_pos - screen_top;
410 screen_top_ptr = buffer + screen_top;
411
412 cpage = bookmarks[i].page;
413 cline = bookmarks[i].line;
414 bookmarks[i].flag ^= BOOKMARK_LAST;
415 buffer_end = BUFFER_END();
416
417 fill_buffer(file_pos, buffer, buffer_size);
418
419 if (bookmarks[i].flag == 0)
420 viewer_remove_bookmark(i);
421
422 if (prefs->scroll_mode == PAGE && cline > 1)
423 viewer_scroll_to_top_line();
424 break;
425 }
426 }
427}
428
429static int col_limit(int col)
430{
431 if (col < 0)
432 col = 0;
433 else
434 if (col >= max_width)
435 col = max_width - draw_columns;
436
437 return col;
438}
439
440void viewer_scroll_left(int mode)
441{
442 if (mode == VIEWER_SCROLL_COLUMN)
443 {
444 /* Scroll left one column */
445 col -= glyph_width('o');
446 }
447 else
448 {
449 /* Screen left */
450 col -= draw_columns;
451 }
452 col = col_limit(col);
453}
454
455void viewer_scroll_right(int mode)
456{
457 if (mode == VIEWER_SCROLL_COLUMN)
458 {
459 /* Scroll right one column */
460 col += glyph_width('o');
461 }
462 else
463 {
464 /* Screen right */
465 col += draw_columns;
466 }
467 col = col_limit(col);
468}
diff --git a/apps/plugins/textviewer/tv_screen.h b/apps/plugins/textviewer/tv_screen.h
deleted file mode 100644
index db29640e42..0000000000
--- a/apps/plugins/textviewer/tv_screen.h
+++ /dev/null
@@ -1,51 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#ifndef PLUGIN_TEXT_VIEWER_SCREEN_H
24#define PLUGIN_TEXT_VIEWER_SCREEN_H
25
26/* scroll mode */
27enum
28{
29 VIEWER_SCROLL_LINE, /* up/down one line */
30 VIEWER_SCROLL_PAGE, /* up/down one page */
31 VIEWER_SCROLL_COLUMN, /* left/right one column */
32 VIEWER_SCROLL_SCREEN, /* left/right one screen */
33 VIEWER_SCROLL_PREFS, /*up/down/left/right follows the settings. */
34};
35
36void viewer_init_screen(void);
37void viewer_finalize_screen(void);
38
39void viewer_draw(void);
40
41void viewer_top(void);
42void viewer_bottom(void);
43
44void viewer_scroll_up(int mode);
45void viewer_scroll_down(int mode);
46void viewer_scroll_left(int mode);
47void viewer_scroll_right(int mode);
48
49void change_font(unsigned char *font);
50
51#endif
diff --git a/apps/plugins/textviewer/tv_settings.c b/apps/plugins/textviewer/tv_settings.c
deleted file mode 100644
index 463e6a42de..0000000000
--- a/apps/plugins/textviewer/tv_settings.c
+++ /dev/null
@@ -1,464 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "plugin.h"
24#include <ctype.h>
25
26/* global settings file
27 * binary file, so dont use .cfg
28 *
29 * setting file format
30 *
31 * part byte count
32 * --------------------------------
33 * 'TVGS' 4
34 * version 1
35 * word_mode 1
36 * line_mode 1
37 * view_mode 1
38 * encoding 1
39 * scrollbar_mode 1
40 * need_scrollbar 1
41 * page_mode 1
42 * page_number_mode 1
43 * title_mode 1
44 * scroll_mode 1
45 * autoscroll_speed 1
46 * font name MAX_PATH
47 */
48#define GLOBAL_SETTINGS_FILE VIEWERS_DIR "/viewer.dat"
49
50/* temporary file */
51#define GLOBAL_SETTINGS_TMP_FILE VIEWERS_DIR "/viewer_file.tmp"
52
53#define GLOBAL_SETTINGS_HEADER "\x54\x56\x47\x53\x31" /* header="TVGS" version=1 */
54#define GLOBAL_SETTINGS_H_SIZE 5
55
56/* preferences and bookmarks at each file
57 * binary file, so dont use .cfg
58 *
59 * setting file format
60 *
61 * part byte count
62 * --------------------------------
63 * 'TVS' 3
64 * version 1
65 * file count 2
66 * [1st file]
67 * file path MAX_PATH
68 * next file pos 2
69 * [preferences]
70 * word_mode 1
71 * line_mode 1
72 * view_mode 1
73 * encoding 1
74 * scrollbar_mode 1
75 * need_scrollbar 1
76 * page_mode 1
77 * header_mode 1
78 * footer_mode 1
79 * scroll_mode 1
80 * autoscroll_speed 1
81 * font name MAX_PATH
82 * bookmark count 1
83 * [1st bookmark]
84 * file_position 4
85 * page 2
86 * line 1
87 * flag 1
88 * [2nd bookmark]
89 * ...
90 * [last bookmark]
91 * [2nd file]
92 * ...
93 * [last file]
94 */
95#define SETTINGS_FILE VIEWERS_DIR "/viewer_file.dat"
96
97/* temporary file */
98#define SETTINGS_TMP_FILE VIEWERS_DIR "/viewer_file.tmp"
99
100#define SETTINGS_HEADER "\x54\x56\x53\x32" /* header="TVS" version=2 */
101#define SETTINGS_H_SIZE 4
102
103#ifndef HAVE_LCD_BITMAP
104#define BOOKMARK_ICON "\xee\x84\x81\x00"
105#endif
106
107#define PREFERENCES_SIZE (11 + MAX_PATH)
108
109
110struct preferences prefs;
111struct preferences old_prefs;
112
113static int fd;
114static const char *file_name;
115static int cline = 1;
116static int cpage = 1;
117static int lpage = 0;
118
119static void viewer_default_preferences(void)
120{
121 prefs.word_mode = WRAP;
122 prefs.line_mode = NORMAL;
123 prefs.view_mode = NARROW;
124 prefs.scroll_mode = PAGE;
125 prefs.page_mode = NO_OVERLAP;
126 prefs.scrollbar_mode = SB_OFF;
127 rb->memset(prefs.font, 0, MAX_PATH);
128#ifdef HAVE_LCD_BITMAP
129 prefs.header_mode = HD_BOTH;
130 prefs.footer_mode = FT_BOTH;
131 rb->snprintf(prefs.font, MAX_PATH, "%s", rb->global_settings->font_file);
132#else
133 prefs.header_mode = HD_NONE;
134 prefs.footer_mode = FT_NONE;
135#endif
136 prefs.autoscroll_speed = 1;
137 /* Set codepage to system default */
138 prefs.encoding = rb->global_settings->default_codepage;
139}
140
141static bool viewer_read_preferences(int pfd)
142{
143 unsigned char buf[PREFERENCES_SIZE];
144 unsigned char *p = buf;
145
146 if (rb->read(pfd, buf, sizeof(buf)) != sizeof(buf))
147 return false;
148
149 prefs.word_mode = *p++;
150 prefs.line_mode = *p++;
151 prefs.view_mode = *p++;
152 prefs.encoding = *p++;
153 prefs.scrollbar_mode = *p++;
154 prefs.need_scrollbar = *p++;
155 prefs.page_mode = *p++;
156 prefs.header_mode = *p++;
157 prefs.footer_mode = *p++;
158 prefs.scroll_mode = *p++;
159 prefs.autoscroll_speed = *p++;
160 rb->memcpy(prefs.font, p, MAX_PATH);
161
162 return true;
163}
164
165static bool viewer_write_preferences(int pfd)
166{
167 unsigned char buf[PREFERENCES_SIZE];
168 unsigned char *p = buf;
169
170 *p++ = prefs.word_mode;
171 *p++ = prefs.line_mode;
172 *p++ = prefs.view_mode;
173 *p++ = prefs.encoding;
174 *p++ = prefs.scrollbar_mode;
175 *p++ = prefs.need_scrollbar;
176 *p++ = prefs.page_mode;
177 *p++ = prefs.header_mode;
178 *p++ = prefs.footer_mode;
179 *p++ = prefs.scroll_mode;
180 *p++ = prefs.autoscroll_speed;
181 rb->memcpy(p, prefs.font, MAX_PATH);
182
183 return (rb->write(pfd, buf, sizeof(buf)) == sizeof(buf));
184}
185
186static bool viewer_load_global_settings(void)
187{
188 unsigned buf[GLOBAL_SETTINGS_H_SIZE];
189 int sfd = rb->open(GLOBAL_SETTINGS_FILE, O_RDONLY);
190
191 if (sfd < 0)
192 return false;
193
194 if ((rb->read(sfd, buf, GLOBAL_SETTINGS_H_SIZE) != GLOBAL_SETTINGS_H_SIZE) ||
195 rb->memcmp(buf, GLOBAL_SETTINGS_HEADER, GLOBAL_SETTINGS_H_SIZE) ||
196 !viewer_read_preferences(sfd))
197 {
198 rb->close(sfd);
199 return false;
200 }
201 rb->close(sfd);
202 return true;
203}
204
205static bool viewer_save_global_settings(void)
206{
207 int sfd = rb->open(GLOBAL_SETTINGS_TMP_FILE, O_WRONLY|O_CREAT|O_TRUNC);
208
209 if (sfd < 0)
210 return false;
211
212 if (rb->write(sfd, &GLOBAL_SETTINGS_HEADER, GLOBAL_SETTINGS_H_SIZE)
213 != GLOBAL_SETTINGS_H_SIZE ||
214 !viewer_write_preferences(sfd))
215 {
216 rb->close(sfd);
217 rb->remove(GLOBAL_SETTINGS_TMP_FILE);
218 return false;
219 }
220 rb->close(sfd);
221 rb->remove(GLOBAL_SETTINGS_FILE);
222 rb->rename(GLOBAL_SETTINGS_TMP_FILE, GLOBAL_SETTINGS_FILE);
223 return true;
224}
225
226void viewer_load_settings(void)
227{
228 unsigned char buf[MAX_PATH+2];
229 unsigned int fcount;
230 unsigned int i;
231 bool res = false;
232 int sfd;
233 unsigned int size;
234
235 sfd = rb->open(SETTINGS_FILE, O_RDONLY);
236 if (sfd < 0)
237 goto read_end;
238
239 if ((rb->read(sfd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2) ||
240 rb->memcmp(buf, SETTINGS_HEADER, SETTINGS_H_SIZE))
241 {
242 /* illegal setting file */
243 rb->close(sfd);
244
245 if (rb->file_exists(SETTINGS_FILE))
246 rb->remove(SETTINGS_FILE);
247
248 goto read_end;
249 }
250
251 fcount = (buf[SETTINGS_H_SIZE] << 8) | buf[SETTINGS_H_SIZE+1];
252 for (i = 0; i < fcount; i++)
253 {
254 if (rb->read(sfd, buf, MAX_PATH+2) != MAX_PATH+2)
255 break;
256
257 size = (buf[MAX_PATH] << 8) | buf[MAX_PATH+1];
258 if (rb->strcmp(buf, file_name))
259 {
260 if (rb->lseek(sfd, size, SEEK_CUR) < 0)
261 break;
262 continue;
263 }
264 if (!viewer_read_preferences(sfd))
265 break;
266
267 res = viewer_read_bookmark_infos(sfd);
268 break;
269 }
270
271 rb->close(sfd);
272
273read_end:
274 if (!res)
275 {
276 /* load global settings */
277 if (!viewer_load_global_settings())
278 viewer_default_preferences();
279
280 file_pos = 0;
281 screen_top_ptr = buffer;
282 cpage = 1;
283 cline = 1;
284 bookmark_count = 0;
285 }
286
287 rb->memcpy(&old_prefs, &prefs, sizeof(struct preferences));
288 calc_max_width();
289
290 if (bookmark_count > 1)
291 viewer_select_bookmark(-1);
292 else if (bookmark_count == 1)
293 {
294 int screen_pos;
295 int screen_top;
296
297 screen_pos = bookmarks[0].file_position;
298 screen_top = screen_pos % buffer_size;
299 file_pos = screen_pos - screen_top;
300 screen_top_ptr = buffer + screen_top;
301 cpage = bookmarks[0].page;
302 cline = bookmarks[0].line;
303 }
304
305 viewer_remove_last_read_bookmark();
306
307 check_bom();
308 get_filesize();
309
310 buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
311
312 if (BUFFER_OOB(screen_top_ptr))
313 screen_top_ptr = buffer;
314
315 fill_buffer(file_pos, buffer, buffer_size);
316 if (prefs.scroll_mode == PAGE && cline > 1)
317 viewer_scroll_to_top_line();
318
319 /* remember the current position */
320 start_position = file_pos + screen_top_ptr - buffer;
321
322#ifdef HAVE_LCD_BITMAP
323 if (rb->strcmp(prefs.font, rb->global_settings->font_file))
324 change_font(prefs.font);
325
326 init_need_scrollbar();
327 init_header_and_footer();
328#endif
329}
330
331bool viewer_save_settings(void)
332{
333 unsigned char buf[MAX_PATH+2];
334 unsigned int fcount = 0;
335 unsigned int i;
336 int idx;
337 int ofd;
338 int tfd;
339 off_t first_copy_size = 0;
340 off_t second_copy_start_pos = 0;
341 off_t size;
342
343 /* add reading page to bookmarks */
344 idx = viewer_find_bookmark(cpage, cline);
345 if (idx >= 0)
346 bookmarks[idx].flag |= BOOKMARK_LAST;
347 else
348 {
349 viewer_add_bookmark(cpage, cline);
350 bookmarks[bookmark_count-1].flag = BOOKMARK_LAST;
351 }
352
353 tfd = rb->open(SETTINGS_TMP_FILE, O_WRONLY|O_CREAT|O_TRUNC);
354 if (tfd < 0)
355 return false;
356
357 ofd = rb->open(SETTINGS_FILE, O_RDWR);
358 if (ofd >= 0)
359 {
360 if ((rb->read(ofd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2) ||
361 rb->memcmp(buf, SETTINGS_HEADER, SETTINGS_H_SIZE))
362 {
363 rb->close(ofd);
364 goto save_err;
365 }
366 fcount = (buf[SETTINGS_H_SIZE] << 8) | buf[SETTINGS_H_SIZE+1];
367
368 for (i = 0; i < fcount; i++)
369 {
370 if (rb->read(ofd, buf, MAX_PATH+2) != MAX_PATH+2)
371 {
372 rb->close(ofd);
373 goto save_err;
374 }
375 size = (buf[MAX_PATH] << 8) | buf[MAX_PATH+1];
376 if (rb->strcmp(buf, file_name))
377 {
378 if (rb->lseek(ofd, size, SEEK_CUR) < 0)
379 {
380 rb->close(ofd);
381 goto save_err;
382 }
383 }
384 else
385 {
386 first_copy_size = rb->lseek(ofd, 0, SEEK_CUR);
387 if (first_copy_size < 0)
388 {
389 rb->close(ofd);
390 goto save_err;
391 }
392 second_copy_start_pos = first_copy_size + size;
393 first_copy_size -= MAX_PATH+2;
394 fcount--;
395 break;
396 }
397 }
398 if (first_copy_size == 0)
399 first_copy_size = rb->filesize(ofd);
400
401 if (!copy_bookmark_file(ofd, tfd, 0, first_copy_size))
402 {
403 rb->close(ofd);
404 goto save_err;
405 }
406 if (second_copy_start_pos > 0)
407 {
408 if (!copy_bookmark_file(ofd, tfd, second_copy_start_pos,
409 rb->filesize(ofd) - second_copy_start_pos))
410 {
411 rb->close(ofd);
412 goto save_err;
413 }
414 }
415 rb->close(ofd);
416 }
417 else
418 {
419 rb->memcpy(buf, SETTINGS_HEADER, SETTINGS_H_SIZE);
420 buf[SETTINGS_H_SIZE] = 0;
421 buf[SETTINGS_H_SIZE+1] = 0;
422 if (rb->write(tfd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2)
423 goto save_err;
424 }
425
426 /* copy to current read file's bookmarks */
427 rb->memset(buf, 0, MAX_PATH);
428 rb->snprintf(buf, MAX_PATH, "%s", file_name);
429
430 size = PREFERENCES_SIZE + bookmark_count * BOOKMARK_SIZE + 1;
431 buf[MAX_PATH] = size >> 8;
432 buf[MAX_PATH+1] = size;
433
434 if (rb->write(tfd, buf, MAX_PATH+2) != MAX_PATH+2)
435 goto save_err;
436
437 if (!viewer_write_preferences(tfd))
438 goto save_err;
439
440 if (!viewer_write_bookmark_infos(tfd))
441 goto save_err;
442
443 if (rb->lseek(tfd, SETTINGS_H_SIZE, SEEK_SET) < 0)
444 goto save_err;
445
446 fcount++;
447 buf[0] = fcount >> 8;
448 buf[1] = fcount;
449
450 if (rb->write(tfd, buf, 2) != 2)
451 goto save_err;
452
453 rb->close(tfd);
454
455 rb->remove(SETTINGS_FILE);
456 rb->rename(SETTINGS_TMP_FILE, SETTINGS_FILE);
457
458 return true;
459
460save_err:
461 rb->close(tfd);
462 rb->remove(SETTINGS_TMP_FILE);
463 return false;
464}
diff --git a/apps/plugins/textviewer/tv_settings.h b/apps/plugins/textviewer/tv_settings.h
deleted file mode 100644
index 317d6aa211..0000000000
--- a/apps/plugins/textviewer/tv_settings.h
+++ /dev/null
@@ -1,85 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#ifndef PLUGIN_TEXT_VIEWER_PREFERENCE_H
24#define PLUGIN_TEXT_VIEWER_PREFERENCE_H
25
26struct viewer_preferences {
27 enum {
28 WRAP=0,
29 CHOP,
30 } word_mode;
31
32 enum {
33 NORMAL=0,
34 JOIN,
35 EXPAND,
36 REFLOW, /* won't be set on charcell LCD, must be last */
37 } line_mode;
38
39 enum {
40 NARROW=0,
41 WIDE,
42 } view_mode;
43
44 enum codepages encoding;
45
46 enum {
47 SB_OFF=0,
48 SB_ON,
49 } scrollbar_mode;
50 bool need_scrollbar;
51
52 enum {
53 NO_OVERLAP=0,
54 OVERLAP,
55 } page_mode;
56
57 enum {
58 HD_NONE = 0,
59 HD_PATH,
60 HD_SBAR,
61 HD_BOTH,
62 } header_mode;
63
64 enum {
65 FT_NONE = 0,
66 FT_PAGE,
67 FT_SBAR,
68 FT_BOTH,
69 } footer_mode;
70
71 enum {
72 PAGE=0,
73 LINE,
74 } scroll_mode;
75
76 int autoscroll_speed;
77
78 unsigned char font[MAX_PATH];
79};
80
81struct viewer_preferences *viewer_get_preference(void);
82void viewer_load_settings(void);
83bool viewer_save_settings(void);
84
85#endif
diff --git a/apps/plugins/textviewer/tv_text_processor.c b/apps/plugins/textviewer/tv_text_processor.c
deleted file mode 100644
index 3ad80db585..0000000000
--- a/apps/plugins/textviewer/tv_text_processor.c
+++ /dev/null
@@ -1,505 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux, 2003 Garrett Derner
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "plugin.h"
22#include "tv_drawtext.h"
23
24#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */
25#define NARROW_MAX_COLUMNS 64 /* Max displayable string len [narrow] (over-estimate) */
26#define WIDE_MAX_COLUMNS 128 /* Max displayable string len [wide] (over-estimate) */
27#define MAX_WIDTH 910 /* Max line length in WIDE mode */
28#define READ_PREV_ZONE (block_size*9/10) /* Arbitrary number less than SMALL_BLOCK_SIZE */
29#define SMALL_BLOCK_SIZE block_size /* Smallest file chunk we will read */
30#define LARGE_BLOCK_SIZE (block_size << 1) /* Preferable size of file chunk to read */
31#define TOP_SECTOR buffer
32#define MID_SECTOR (buffer + SMALL_BLOCK_SIZE)
33#define BOTTOM_SECTOR (buffer + (SMALL_BLOCK_SIZE << 1))
34#undef SCROLLBAR_WIDTH
35#define SCROLLBAR_WIDTH rb->global_settings->scrollbar_width
36#define MAX_PAGE 9999
37
38/* Is a scrollbar called for on the current screen? */
39#define NEED_SCROLLBAR() \
40 ((!(ONE_SCREEN_FITS_ALL())) && (prefs.scrollbar_mode==SB_ON))
41
42static void increment_current_line(void)
43{
44 if (cline < display_lines)
45 cline++;
46 else if (cpage < MAX_PAGE)
47 {
48 cpage++;
49 cline = 1;
50 }
51}
52
53static void decrement_current_line(void)
54{
55 if (cline > 1)
56 cline--;
57 else if (cpage > 1)
58 {
59 cpage--;
60 cline = display_lines;
61 }
62}
63
64static void viewer_scroll_up(void)
65{
66 unsigned char *p;
67
68 p = find_prev_line(screen_top_ptr);
69 if (p == NULL && !BUFFER_BOF()) {
70 read_and_synch(-1);
71 p = find_prev_line(screen_top_ptr);
72 }
73 if (p != NULL)
74 screen_top_ptr = p;
75
76 decrement_current_line();
77}
78
79static void viewer_scroll_down(bool autoscroll)
80{
81 if (cpage == lpage)
82 return;
83
84 if (next_line_ptr != NULL)
85 screen_top_ptr = next_line_ptr;
86
87 if (prefs.scroll_mode == LINE || autoscroll)
88 increment_current_line();
89}
90
91static void viewer_scroll_to_top_line(void)
92{
93 int line;
94
95 for (line = cline; line > 1; line--)
96 viewer_scroll_up();
97}
98
99#ifdef HAVE_LCD_BITMAP
100static void viewer_scrollbar(void) {
101 int items, min_shown, max_shown, sb_begin_y, sb_height;
102
103 items = (int) file_size; /* (SH1 int is same as long) */
104 min_shown = (int) file_pos + (screen_top_ptr - buffer);
105
106 if (next_screen_ptr == NULL)
107 max_shown = items;
108 else
109 max_shown = min_shown + (next_screen_ptr - screen_top_ptr);
110
111 sb_begin_y = header_height;
112 sb_height = LCD_HEIGHT - header_height - footer_height;
113
114 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, sb_begin_y,
115 SCROLLBAR_WIDTH-1, sb_height,
116 items, min_shown, max_shown, VERTICAL);
117}
118
119static void viewer_show_header(void)
120{
121 if (prefs.header_mode == HD_SBAR || prefs.header_mode == HD_BOTH)
122 rb->gui_syncstatusbar_draw(rb->statusbars, true);
123
124 if (prefs.header_mode == HD_PATH || prefs.header_mode == HD_BOTH)
125 rb->lcd_putsxy(0, header_height - pf->height, file_name);
126}
127
128static void viewer_show_footer(void)
129{
130 if (prefs.footer_mode == FT_SBAR || prefs.footer_mode == FT_BOTH)
131 rb->gui_syncstatusbar_draw(rb->statusbars, true);
132
133 if (prefs.footer_mode == FT_PAGE || prefs.footer_mode == FT_BOTH)
134 {
135 unsigned char buf[12];
136
137 if (cline == 1)
138 rb->snprintf(buf, sizeof(buf), "%d", cpage);
139 else
140 rb->snprintf(buf, sizeof(buf), "%d - %d", cpage, cpage+1);
141
142 rb->lcd_putsxy(0, LCD_HEIGHT - footer_height, buf);
143 }
144}
145#endif
146
147void viewer_draw(int col)
148{
149 int i, j, k, line_len, line_width, spaces, left_col=0;
150 int width, extra_spaces, indent_spaces, spaces_per_word;
151 bool multiple_spacing, line_is_short;
152 unsigned short ch;
153 unsigned char *str, *oldstr;
154 unsigned char *line_begin;
155 unsigned char *line_end;
156 unsigned char c;
157 unsigned char scratch_buffer[max_columns + 1];
158 unsigned char utf8_buffer[max_columns*4 + 1];
159 unsigned char *endptr;
160
161 /* If col==-1 do all calculations but don't display */
162 if (col != -1) {
163#ifdef HAVE_LCD_BITMAP
164 left_col = prefs.need_scrollbar? SCROLLBAR_WIDTH:0;
165#else
166 left_col = 0;
167#endif
168 rb->lcd_clear_display();
169 }
170 max_line_len = 0;
171 line_begin = line_end = screen_top_ptr;
172
173 for (i = 0; i < display_lines; i++) {
174 if (BUFFER_OOB(line_end))
175 {
176 if (lpage == cpage)
177 break; /* Happens after display last line at BUFFER_EOF() */
178
179 if (lpage == 0 && cline == 1)
180 {
181 lpage = cpage;
182 last_screen_top_ptr = screen_top_ptr;
183 last_file_pos = file_pos;
184 }
185 }
186
187 get_next_line_position(&line_begin, &line_end, &line_is_short);
188 if (line_end == NULL)
189 {
190 if (BUFFER_OOB(line_begin))
191 break;
192 line_end = buffer_end + 1;
193 }
194
195 line_len = line_end - line_begin;
196
197 /* calculate line_len */
198 str = oldstr = line_begin;
199 j = -1;
200 while (str < line_end) {
201 oldstr = str;
202 str = crop_at_width(str);
203 j++;
204 }
205 line_width = j*draw_columns;
206 while (oldstr < line_end) {
207 oldstr = get_ucs(oldstr, &ch);
208 line_width += glyph_width(ch);
209 }
210
211 if (prefs.line_mode == JOIN) {
212 if (line_begin[0] == 0) {
213 line_begin++;
214 if (prefs.word_mode == CHOP)
215 line_end++;
216 else
217 line_len--;
218 }
219 for (j=k=spaces=0; j < line_len; j++) {
220 if (k == max_columns)
221 break;
222
223 c = line_begin[j];
224 switch (c) {
225 case ' ':
226 spaces++;
227 break;
228 case 0:
229 spaces = 0;
230 scratch_buffer[k++] = ' ';
231 break;
232 default:
233 while (spaces) {
234 spaces--;
235 scratch_buffer[k++] = ' ';
236 if (k == max_columns - 1)
237 break;
238 }
239 scratch_buffer[k++] = c;
240 break;
241 }
242 }
243 if (col != -1) {
244 scratch_buffer[k] = 0;
245 endptr = decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns);
246 *endptr = 0;
247 }
248 }
249 else if (prefs.line_mode == REFLOW) {
250 if (line_begin[0] == 0) {
251 line_begin++;
252 if (prefs.word_mode == CHOP)
253 line_end++;
254 else
255 line_len--;
256 }
257
258 indent_spaces = 0;
259 if (!line_is_short) {
260 multiple_spacing = false;
261 width=spaces=0;
262 for (str = line_begin; str < line_end; ) {
263 str = get_ucs(str, &ch);
264 switch (ch) {
265 case ' ':
266 case 0:
267 if ((str == line_begin) && (prefs.word_mode==WRAP))
268 /* special case: indent the paragraph,
269 * don't count spaces */
270 indent_spaces = par_indent_spaces;
271 else if (!multiple_spacing)
272 spaces++;
273 multiple_spacing = true;
274 break;
275 default:
276 multiple_spacing = false;
277 width += glyph_width(ch);
278 break;
279 }
280 }
281 if (multiple_spacing) spaces--;
282
283 if (spaces) {
284 /* total number of spaces to insert between words */
285 extra_spaces = (max_width-width)/glyph_width(' ')
286 - indent_spaces;
287 /* number of spaces between each word*/
288 spaces_per_word = extra_spaces / spaces;
289 /* number of words with n+1 spaces (to fill up) */
290 extra_spaces = extra_spaces % spaces;
291 if (spaces_per_word > 2) { /* too much spacing is awful */
292 spaces_per_word = 3;
293 extra_spaces = 0;
294 }
295 } else { /* this doesn't matter much... no spaces anyway */
296 spaces_per_word = extra_spaces = 0;
297 }
298 } else { /* end of a paragraph: don't fill line */
299 spaces_per_word = 1;
300 extra_spaces = 0;
301 }
302
303 multiple_spacing = false;
304 for (j=k=spaces=0; j < line_len; j++) {
305 if (k == max_columns)
306 break;
307
308 c = line_begin[j];
309 switch (c) {
310 case ' ':
311 case 0:
312 if (j==0 && prefs.word_mode==WRAP) { /* indent paragraph */
313 for (j=0; j<par_indent_spaces; j++)
314 scratch_buffer[k++] = ' ';
315 j=0;
316 }
317 else if (!multiple_spacing) {
318 for (width = spaces<extra_spaces ? -1:0; width < spaces_per_word; width++)
319 scratch_buffer[k++] = ' ';
320 spaces++;
321 }
322 multiple_spacing = true;
323 break;
324 default:
325 scratch_buffer[k++] = c;
326 multiple_spacing = false;
327 break;
328 }
329 }
330 if (col != -1) {
331 scratch_buffer[k] = 0;
332 endptr = decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns);
333 *endptr = 0;
334 }
335 }
336 else { /* prefs.line_mode != JOIN && prefs.line_mode != REFLOW */
337 if (col != -1)
338 if (line_width > col) {
339 str = oldstr = line_begin;
340 k = col;
341 width = 0;
342 while( (width<draw_columns) && (oldstr<line_end) )
343 {
344 oldstr = get_ucs(oldstr, &ch);
345 if (k > 0) {
346 k -= glyph_width(ch);
347 line_begin = oldstr;
348 } else {
349 width += glyph_width(ch);
350 }
351 }
352
353 if(prefs.view_mode==WIDE)
354 endptr = rb->iso_decode(line_begin, utf8_buffer,
355 prefs.encoding, oldstr-line_begin);
356 else
357 endptr = rb->iso_decode(line_begin, utf8_buffer,
358 prefs.encoding, line_end-line_begin);
359 *endptr = 0;
360 }
361 }
362 if (col != -1 && line_width > col)
363 {
364 int dpage = (cline+i <= display_lines)?cpage:cpage+1;
365 int dline = cline+i - ((cline+i <= display_lines)?0:display_lines);
366 bool bflag = (viewer_find_bookmark(dpage, dline) >= 0);
367#ifdef HAVE_LCD_BITMAP
368 int dy = i * pf->height + header_height;
369#endif
370 if (bflag)
371#ifdef HAVE_LCD_BITMAP
372 {
373 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_FG);
374 rb->lcd_fillrect(left_col, dy, LCD_WIDTH, pf->height);
375 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
376 }
377 rb->lcd_putsxy(left_col, dy, utf8_buffer);
378 rb->lcd_set_drawmode(DRMODE_SOLID);
379#else
380 {
381 rb->lcd_puts(left_col, i, BOOKMARK_ICON);
382 }
383 rb->lcd_puts(left_col+1, i, utf8_buffer);
384#endif
385 }
386 if (line_width > max_line_len)
387 max_line_len = line_width;
388
389 if (i == 0)
390 next_line_ptr = line_end;
391 }
392 next_screen_ptr = line_end;
393 if (BUFFER_OOB(next_screen_ptr))
394 next_screen_ptr = NULL;
395
396#ifdef HAVE_LCD_BITMAP
397 next_screen_to_draw_ptr = prefs.page_mode==OVERLAP? line_begin: next_screen_ptr;
398
399 if (prefs.need_scrollbar)
400 viewer_scrollbar();
401#else
402 next_screen_to_draw_ptr = next_screen_ptr;
403#endif
404
405#ifdef HAVE_LCD_BITMAP
406 /* show header */
407 viewer_show_header();
408
409 /* show footer */
410 viewer_show_footer();
411#endif
412
413 if (col != -1)
414 rb->lcd_update();
415}
416
417#ifdef HAVE_LCD_BITMAP
418static void init_need_scrollbar(void) {
419 /* Call viewer_draw in quiet mode to initialize next_screen_ptr,
420 and thus ONE_SCREEN_FITS_ALL(), and thus NEED_SCROLLBAR() */
421 viewer_draw(-1);
422 prefs.need_scrollbar = NEED_SCROLLBAR();
423 draw_columns = prefs.need_scrollbar? display_columns-SCROLLBAR_WIDTH : display_columns;
424 par_indent_spaces = draw_columns/(5*glyph_width(' '));
425 calc_max_width();
426}
427
428static void init_header_and_footer(void)
429{
430 header_height = 0;
431 footer_height = 0;
432 if (rb->global_settings->statusbar == STATUSBAR_TOP)
433 {
434 if (prefs.header_mode == HD_SBAR || prefs.header_mode == HD_BOTH)
435 header_height = STATUSBAR_HEIGHT;
436
437 if (prefs.footer_mode == FT_SBAR)
438 prefs.footer_mode = FT_NONE;
439 else if (prefs.footer_mode == FT_BOTH)
440 prefs.footer_mode = FT_PAGE;
441 }
442 else if (rb->global_settings->statusbar == STATUSBAR_BOTTOM)
443 {
444 if (prefs.footer_mode == FT_SBAR || prefs.footer_mode == FT_BOTH)
445 footer_height = STATUSBAR_HEIGHT;
446
447 if (prefs.header_mode == HD_SBAR)
448 prefs.header_mode = HD_NONE;
449 else if (prefs.header_mode == HD_BOTH)
450 prefs.header_mode = HD_PATH;
451 }
452 else /* STATUSBAR_OFF || STATUSBAR_CUSTOM */
453 {
454 if (prefs.header_mode == HD_SBAR)
455 prefs.header_mode = HD_NONE;
456 else if (prefs.header_mode == HD_BOTH)
457 prefs.header_mode = HD_PATH;
458
459 if (prefs.footer_mode == FT_SBAR)
460 prefs.footer_mode = FT_NONE;
461 else if (prefs.footer_mode == FT_BOTH)
462 prefs.footer_mode = FT_PAGE;
463 }
464
465 if (prefs.header_mode == HD_NONE || prefs.header_mode == HD_PATH ||
466 prefs.footer_mode == FT_NONE || prefs.footer_mode == FT_PAGE)
467 rb->gui_syncstatusbar_draw(rb->statusbars, false);
468
469 if (prefs.header_mode == HD_PATH || prefs.header_mode == HD_BOTH)
470 header_height += pf->height;
471 if (prefs.footer_mode == FT_PAGE || prefs.footer_mode == FT_BOTH)
472 footer_height += pf->height;
473
474 display_lines = (LCD_HEIGHT - header_height - footer_height) / pf->height;
475
476 lpage = 0;
477 last_file_pos = 0;
478 last_screen_top_ptr = NULL;
479}
480
481static void change_font(unsigned char *font)
482{
483 unsigned char buf[MAX_PATH];
484
485 if (font == NULL || *font == '\0')
486 return;
487
488 rb->snprintf(buf, MAX_PATH, "%s/%s.fnt", FONT_DIR, font);
489 if (rb->font_load(NULL, buf) < 0)
490 rb->splash(HZ/2, "font load failed.");
491}
492#endif
493
494/* When a file is UTF-8 file with BOM, if prefs.encoding is UTF-8,
495 * then file size decreases only BOM_SIZE.
496 */
497static void get_filesize(void)
498{
499 file_size = rb->filesize(fd);
500 if (file_size == -1)
501 return;
502
503 if (prefs.encoding == UTF_8 && is_bom)
504 file_size -= BOM_SIZE;
505}