diff options
author | Daniel Stenberg <daniel@haxx.se> | 2002-09-30 19:05:03 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2002-09-30 19:05:03 +0000 |
commit | 773e7a70cc94fc6b6a0f9406ab99b828bea5bd42 (patch) | |
tree | a8d5789ab3544147d726d04b2a5a9399dd0eed2d | |
parent | ad911c0ac82f409251230b39b39fc3e8c2b83ff9 (diff) | |
download | rockbox-773e7a70cc94fc6b6a0f9406ab99b828bea5bd42.tar.gz rockbox-773e7a70cc94fc6b6a0f9406ab99b828bea5bd42.zip |
Gilles Roux's text viewer
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2452 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/tree.c | 20 | ||||
-rw-r--r-- | apps/viewer.c | 342 | ||||
-rw-r--r-- | apps/viewer.h | 24 |
3 files changed, 386 insertions, 0 deletions
diff --git a/apps/tree.c b/apps/tree.c index a9b62e0beb..653b6afa2a 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include "rolo.h" | 46 | #include "rolo.h" |
47 | #include "icons.h" | 47 | #include "icons.h" |
48 | #include "lang.h" | 48 | #include "lang.h" |
49 | #include "viewer.h" | ||
49 | #include "language.h" | 50 | #include "language.h" |
50 | #include "screens.h" | 51 | #include "screens.h" |
51 | 52 | ||
@@ -141,6 +142,7 @@ extern unsigned char bitmap_icons_6x8[LastIcon][6]; | |||
141 | #define TREE_ATTR_WPS 0x100 /* wps config file */ | 142 | #define TREE_ATTR_WPS 0x100 /* wps config file */ |
142 | #define TREE_ATTR_MOD 0x200 /* firmware file */ | 143 | #define TREE_ATTR_MOD 0x200 /* firmware file */ |
143 | #define TREE_ATTR_EQ 0x400 /* EQ config file */ | 144 | #define TREE_ATTR_EQ 0x400 /* EQ config file */ |
145 | #define TREE_ATTR_TXT 0x500 /* text file */ | ||
144 | #define TREE_ATTR_FONT 0x800 /* font file */ | 146 | #define TREE_ATTR_FONT 0x800 /* font file */ |
145 | #define TREE_ATTR_LNG 0x1000 /* binary lang file */ | 147 | #define TREE_ATTR_LNG 0x1000 /* binary lang file */ |
146 | #define TREE_ATTR_MASK 0xffd0 /* which bits tree.c uses (above + DIR) */ | 148 | #define TREE_ATTR_MASK 0xffd0 /* which bits tree.c uses (above + DIR) */ |
@@ -258,6 +260,8 @@ static int showdir(char *path, int start) | |||
258 | dptr->attr |= TREE_ATTR_EQ; | 260 | dptr->attr |= TREE_ATTR_EQ; |
259 | else if (!strcasecmp(&entry->d_name[len-4], ".wps")) | 261 | else if (!strcasecmp(&entry->d_name[len-4], ".wps")) |
260 | dptr->attr |= TREE_ATTR_WPS; | 262 | dptr->attr |= TREE_ATTR_WPS; |
263 | else if (!strcasecmp(&entry->d_name[len-4], ".txt")) | ||
264 | dptr->attr |= TREE_ATTR_TXT; | ||
261 | else if (!strcasecmp(&entry->d_name[len-4], ".lng")) | 265 | else if (!strcasecmp(&entry->d_name[len-4], ".lng")) |
262 | dptr->attr |= TREE_ATTR_LNG; | 266 | dptr->attr |= TREE_ATTR_LNG; |
263 | #ifdef HAVE_RECORDER_KEYPAD | 267 | #ifdef HAVE_RECORDER_KEYPAD |
@@ -383,6 +387,10 @@ static int showdir(char *path, int start) | |||
383 | icon_type = Wps; | 387 | icon_type = Wps; |
384 | break; | 388 | break; |
385 | 389 | ||
390 | case TREE_ATTR_TXT: | ||
391 | icon_type = Wps; | ||
392 | break; | ||
393 | |||
386 | case TREE_ATTR_LNG: | 394 | case TREE_ATTR_LNG: |
387 | icon_type = Language; | 395 | icon_type = Language; |
388 | break; | 396 | break; |
@@ -801,6 +809,13 @@ bool dirbrowse(char *root) | |||
801 | restore = true; | 809 | restore = true; |
802 | break; | 810 | break; |
803 | 811 | ||
812 | case TREE_ATTR_TXT: | ||
813 | snprintf(buf, sizeof buf, "%s/%s", | ||
814 | currdir, file->name); | ||
815 | viewer_run(buf); | ||
816 | restore = true; | ||
817 | break; | ||
818 | |||
804 | case TREE_ATTR_LNG: | 819 | case TREE_ATTR_LNG: |
805 | snprintf(buf, sizeof buf, "%s/%s", | 820 | snprintf(buf, sizeof buf, "%s/%s", |
806 | currdir, file->name); | 821 | currdir, file->name); |
@@ -1031,6 +1046,11 @@ bool dirbrowse(char *root) | |||
1031 | dirstart++; | 1046 | dirstart++; |
1032 | dircursor--; | 1047 | dircursor--; |
1033 | } | 1048 | } |
1049 | #ifdef HAVE_LCD_BITMAP | ||
1050 | /* the sub-screen might've ruined the margins */ | ||
1051 | lcd_setmargins(MARGIN_X,MARGIN_Y); /* leave room for cursor and | ||
1052 | icon */ | ||
1053 | #endif | ||
1034 | numentries = showdir(currdir, dirstart); | 1054 | numentries = showdir(currdir, dirstart); |
1035 | put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true); | 1055 | put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true); |
1036 | } | 1056 | } |
diff --git a/apps/viewer.c b/apps/viewer.c new file mode 100644 index 0000000000..d986ce2dcf --- /dev/null +++ b/apps/viewer.c | |||
@@ -0,0 +1,342 @@ | |||
1 | /*************************************************************************** | ||
2 | * | ||
3 | * __________ __ ___. | ||
4 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
5 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
6 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
7 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
8 | * \/ \/ \/ \/ \/ | ||
9 | * $Id$ | ||
10 | * | ||
11 | * Copyright (C) 2002 Gilles Roux | ||
12 | * | ||
13 | * All files in this archive are subject to the GNU General Public License. | ||
14 | * See the file COPYING in the source tree root for full license agreement. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | #include <stdio.h> | ||
21 | #include <string.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <stdbool.h> | ||
24 | |||
25 | #include "file.h" | ||
26 | #include "lcd.h" | ||
27 | #include "button.h" | ||
28 | #include "kernel.h" | ||
29 | #include "font.h" | ||
30 | #include "settings.h" | ||
31 | #include "icons.h" | ||
32 | #include "screens.h" | ||
33 | |||
34 | #define BUFFER_SIZE 1024 | ||
35 | |||
36 | #define OUTSIDE_BUFFER -10 | ||
37 | #define OUTSIDE_FILE -11 | ||
38 | |||
39 | static int fd; | ||
40 | static int file_size; | ||
41 | |||
42 | static char buffer[BUFFER_SIZE+1]; | ||
43 | static int buffer_pos; /* Position of the buffer in the file */ | ||
44 | |||
45 | static int begin_line; /* Index of the first line displayed on the lcd */ | ||
46 | static int end_line; /* Index of the last line displayed on the lcd */ | ||
47 | static int begin_line_pos; /* Position of the first_line in the bufffer */ | ||
48 | static int end_line_pos; /* Position of the last_line in the buffer */ | ||
49 | |||
50 | /* | ||
51 | * Known issue: The caching algorithm will fail (display incoherent data) if | ||
52 | * the total space of the lines that are displayed on the screen exceeds the | ||
53 | * buffer size (only happens with very long lines). | ||
54 | */ | ||
55 | |||
56 | static int display_line_count(void) | ||
57 | { | ||
58 | #ifdef HAVE_LCD_BITMAP | ||
59 | int fh; | ||
60 | fh = font_get(FONT_UI)->height; | ||
61 | if (global_settings.statusbar) | ||
62 | return (LCD_HEIGHT - STATUSBAR_HEIGHT) / fh; | ||
63 | else | ||
64 | return LCD_HEIGHT/fh; | ||
65 | #else | ||
66 | return 2; | ||
67 | #endif | ||
68 | } | ||
69 | |||
70 | static int find_next_line(int pos) | ||
71 | { | ||
72 | int i; | ||
73 | |||
74 | if (pos==OUTSIDE_BUFFER || pos==OUTSIDE_FILE) | ||
75 | return pos; | ||
76 | |||
77 | i = pos; | ||
78 | if (buffer_pos+i>=file_size) { | ||
79 | return OUTSIDE_FILE; | ||
80 | } | ||
81 | while (1) { | ||
82 | i++; | ||
83 | if (buffer_pos+i==file_size) { | ||
84 | return i; | ||
85 | } | ||
86 | if (i>=BUFFER_SIZE) { | ||
87 | return OUTSIDE_BUFFER; | ||
88 | } | ||
89 | if (buffer[i]==0) { | ||
90 | return i; | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static int find_prev_line(int pos) | ||
96 | { | ||
97 | int i; | ||
98 | |||
99 | if (pos==OUTSIDE_BUFFER || pos==OUTSIDE_FILE) | ||
100 | return pos; | ||
101 | |||
102 | i = pos; | ||
103 | if (buffer_pos+i<0) { | ||
104 | return OUTSIDE_FILE; | ||
105 | } | ||
106 | while (1) { | ||
107 | i--; | ||
108 | if (buffer_pos+i<0) { | ||
109 | return i; | ||
110 | } | ||
111 | if (i<0) { | ||
112 | return OUTSIDE_BUFFER; | ||
113 | } | ||
114 | if (buffer[i]==0) { | ||
115 | return i; | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static void viewer_draw(int col) | ||
121 | { | ||
122 | int i, j; | ||
123 | char* str; | ||
124 | int line_pos; | ||
125 | |||
126 | lcd_clear_display(); | ||
127 | |||
128 | line_pos = begin_line_pos; | ||
129 | |||
130 | for (i=0; | ||
131 | i<=end_line-begin_line && | ||
132 | line_pos!=OUTSIDE_BUFFER && | ||
133 | line_pos!=OUTSIDE_FILE; | ||
134 | i++) { | ||
135 | str = buffer + line_pos + 1; | ||
136 | for (j=0; j<col && *str!=0; ++j) | ||
137 | str++; | ||
138 | lcd_puts(0, i, str); | ||
139 | line_pos = find_next_line(line_pos); | ||
140 | } | ||
141 | |||
142 | lcd_update(); | ||
143 | } | ||
144 | |||
145 | static void fill_buffer(int pos) | ||
146 | { | ||
147 | int i; | ||
148 | int numread; | ||
149 | |||
150 | if (pos>=file_size-BUFFER_SIZE) | ||
151 | pos = file_size-BUFFER_SIZE; | ||
152 | if (pos<0) | ||
153 | pos = 0; | ||
154 | |||
155 | lseek(fd, pos, SEEK_SET); | ||
156 | numread = read(fd, buffer, BUFFER_SIZE); | ||
157 | |||
158 | begin_line_pos -= pos - buffer_pos; | ||
159 | end_line_pos -= pos - buffer_pos; | ||
160 | buffer_pos = pos; | ||
161 | |||
162 | buffer[numread] = 0; | ||
163 | for(i=0;i<numread;i++) { | ||
164 | switch(buffer[i]) { | ||
165 | case '\r': | ||
166 | buffer[i] = ' '; | ||
167 | break; | ||
168 | case '\n': | ||
169 | buffer[i] = 0; | ||
170 | break; | ||
171 | default: | ||
172 | break; | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static bool viewer_init(char* file) | ||
178 | { | ||
179 | int i; | ||
180 | int ret; | ||
181 | int disp_lines; | ||
182 | |||
183 | fd = open(file, O_RDONLY); | ||
184 | if (fd==-1) | ||
185 | return false; | ||
186 | |||
187 | file_size = lseek(fd, 0, SEEK_END); | ||
188 | |||
189 | buffer_pos = 0; | ||
190 | begin_line = 0; | ||
191 | begin_line_pos = -1; | ||
192 | end_line = -1; | ||
193 | end_line_pos = -1; | ||
194 | fill_buffer(0); | ||
195 | disp_lines = display_line_count(); | ||
196 | for (i=0; i<disp_lines; ++i) { | ||
197 | ret = find_next_line(end_line_pos); | ||
198 | if (ret!=OUTSIDE_FILE && ret!=OUTSIDE_BUFFER) { | ||
199 | end_line_pos = ret; | ||
200 | end_line++; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | return true; | ||
205 | } | ||
206 | |||
207 | static void viewer_exit(void) | ||
208 | { | ||
209 | close(fd); | ||
210 | } | ||
211 | |||
212 | static void viewer_scroll_down(void) | ||
213 | { | ||
214 | int ret; | ||
215 | |||
216 | ret = find_next_line(end_line_pos); | ||
217 | if (ret==OUTSIDE_BUFFER) { | ||
218 | begin_line_pos = find_next_line(begin_line_pos); | ||
219 | fill_buffer(begin_line_pos+buffer_pos); | ||
220 | end_line_pos = find_next_line(end_line_pos); | ||
221 | } else if (ret==OUTSIDE_FILE) { | ||
222 | return; | ||
223 | } else { | ||
224 | begin_line_pos = find_next_line(begin_line_pos); | ||
225 | end_line_pos = ret; | ||
226 | } | ||
227 | begin_line++; | ||
228 | end_line++; | ||
229 | } | ||
230 | |||
231 | static void viewer_scroll_up(void) | ||
232 | { | ||
233 | int ret; | ||
234 | |||
235 | ret = find_prev_line(begin_line_pos); | ||
236 | if (ret==OUTSIDE_BUFFER) { | ||
237 | end_line_pos = find_prev_line(end_line_pos); | ||
238 | fill_buffer(buffer_pos+end_line_pos-BUFFER_SIZE); | ||
239 | begin_line_pos = find_prev_line(begin_line_pos); | ||
240 | } else if (ret==OUTSIDE_FILE) { | ||
241 | return; | ||
242 | } else { | ||
243 | end_line_pos = find_prev_line(end_line_pos); | ||
244 | begin_line_pos = ret; | ||
245 | } | ||
246 | begin_line--; | ||
247 | end_line--; | ||
248 | } | ||
249 | |||
250 | bool viewer_run(char* file) | ||
251 | { | ||
252 | int button; | ||
253 | int col = 0; | ||
254 | int ok; | ||
255 | |||
256 | #ifdef HAVE_LCD_BITMAP | ||
257 | /* no margins */ | ||
258 | lcd_setmargins(0, 0); | ||
259 | #endif | ||
260 | |||
261 | ok = viewer_init(file); | ||
262 | if (!ok) { | ||
263 | lcd_clear_display(); | ||
264 | lcd_puts(0, 0, "Error"); | ||
265 | lcd_update(); | ||
266 | sleep(HZ); | ||
267 | viewer_exit(); | ||
268 | return false; | ||
269 | } | ||
270 | |||
271 | viewer_draw(col); | ||
272 | while(1) { | ||
273 | button = button_get(true); | ||
274 | |||
275 | switch ( button ) { | ||
276 | |||
277 | #ifdef HAVE_RECORDER_KEYPAD | ||
278 | case BUTTON_F1: | ||
279 | case BUTTON_ON: | ||
280 | #else | ||
281 | case BUTTON_STOP: | ||
282 | case BUTTON_ON: | ||
283 | #endif | ||
284 | viewer_exit(); | ||
285 | return true; | ||
286 | break; | ||
287 | |||
288 | #ifdef HAVE_RECORDER_KEYPAD | ||
289 | case BUTTON_UP: | ||
290 | case BUTTON_UP | BUTTON_REPEAT: | ||
291 | #else | ||
292 | case BUTTON_LEFT: | ||
293 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
294 | #endif | ||
295 | viewer_scroll_up(); | ||
296 | viewer_draw(col); | ||
297 | break; | ||
298 | |||
299 | #ifdef HAVE_RECORDER_KEYPAD | ||
300 | case BUTTON_DOWN: | ||
301 | case BUTTON_DOWN | BUTTON_REPEAT: | ||
302 | #else | ||
303 | case BUTTON_RIGHT: | ||
304 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
305 | #endif | ||
306 | viewer_scroll_down(); | ||
307 | viewer_draw(col); | ||
308 | break; | ||
309 | |||
310 | #ifdef HAVE_RECORDER_KEYPAD | ||
311 | case BUTTON_LEFT: | ||
312 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
313 | #else | ||
314 | case BUTTON_MENU | BUTTON_LEFT: | ||
315 | case BUTTON_MENU | BUTTON_LEFT | BUTTON_REPEAT: | ||
316 | #endif | ||
317 | col--; | ||
318 | viewer_draw(col); | ||
319 | break; | ||
320 | |||
321 | #ifdef HAVE_RECORDER_KEYPAD | ||
322 | case BUTTON_RIGHT: | ||
323 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
324 | #else | ||
325 | case BUTTON_MENU | BUTTON_RIGHT: | ||
326 | case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REPEAT: | ||
327 | #endif | ||
328 | col++; | ||
329 | viewer_draw(col); | ||
330 | break; | ||
331 | |||
332 | case SYS_USB_CONNECTED: | ||
333 | usb_screen(); | ||
334 | #ifdef HAVE_LCD_CHARCELLS | ||
335 | lcd_icon(ICON_PARAM, false); | ||
336 | #endif | ||
337 | viewer_exit(); | ||
338 | return true; | ||
339 | } | ||
340 | } | ||
341 | } | ||
342 | |||
diff --git a/apps/viewer.h b/apps/viewer.h new file mode 100644 index 0000000000..ed9f64ca49 --- /dev/null +++ b/apps/viewer.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Jerome Kuptz | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef _VIEWER_H | ||
20 | #define _VIEWER_H | ||
21 | |||
22 | bool viewer_run(char* file); | ||
23 | |||
24 | #endif | ||