summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/tree.c20
-rw-r--r--apps/viewer.c342
-rw-r--r--apps/viewer.h24
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
39static int fd;
40static int file_size;
41
42static char buffer[BUFFER_SIZE+1];
43static int buffer_pos; /* Position of the buffer in the file */
44
45static int begin_line; /* Index of the first line displayed on the lcd */
46static int end_line; /* Index of the last line displayed on the lcd */
47static int begin_line_pos; /* Position of the first_line in the bufffer */
48static 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
56static 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
70static 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
95static 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
120static 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
145static 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
177static 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
207static void viewer_exit(void)
208{
209 close(fd);
210}
211
212static 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
231static 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
250bool 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
22bool viewer_run(char* file);
23
24#endif