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) |
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 @@ #include "rolo.h" #include "icons.h" #include "lang.h" +#include "viewer.h" #include "language.h" #include "screens.h" @@ -141,6 +142,7 @@ extern unsigned char bitmap_icons_6x8[LastIcon][6]; #define TREE_ATTR_WPS 0x100 /* wps config file */ #define TREE_ATTR_MOD 0x200 /* firmware file */ #define TREE_ATTR_EQ 0x400 /* EQ config file */ +#define TREE_ATTR_TXT 0x500 /* text file */ #define TREE_ATTR_FONT 0x800 /* font file */ #define TREE_ATTR_LNG 0x1000 /* binary lang file */ #define TREE_ATTR_MASK 0xffd0 /* which bits tree.c uses (above + DIR) */ @@ -258,6 +260,8 @@ static int showdir(char *path, int start) dptr->attr |= TREE_ATTR_EQ; else if (!strcasecmp(&entry->d_name[len-4], ".wps")) dptr->attr |= TREE_ATTR_WPS; + else if (!strcasecmp(&entry->d_name[len-4], ".txt")) + dptr->attr |= TREE_ATTR_TXT; else if (!strcasecmp(&entry->d_name[len-4], ".lng")) dptr->attr |= TREE_ATTR_LNG; #ifdef HAVE_RECORDER_KEYPAD @@ -383,6 +387,10 @@ static int showdir(char *path, int start) icon_type = Wps; break; + case TREE_ATTR_TXT: + icon_type = Wps; + break; + case TREE_ATTR_LNG: icon_type = Language; break; @@ -801,6 +809,13 @@ bool dirbrowse(char *root) restore = true; break; + case TREE_ATTR_TXT: + snprintf(buf, sizeof buf, "%s/%s", + currdir, file->name); + viewer_run(buf); + restore = true; + break; + case TREE_ATTR_LNG: snprintf(buf, sizeof buf, "%s/%s", currdir, file->name); @@ -1031,6 +1046,11 @@ bool dirbrowse(char *root) dirstart++; dircursor--; } +#ifdef HAVE_LCD_BITMAP + /* the sub-screen might've ruined the margins */ + lcd_setmargins(MARGIN_X,MARGIN_Y); /* leave room for cursor and + icon */ +#endif numentries = showdir(currdir, dirstart); put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true); } 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 @@ +/*************************************************************************** + * + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Gilles Roux + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdbool.h> + +#include "file.h" +#include "lcd.h" +#include "button.h" +#include "kernel.h" +#include "font.h" +#include "settings.h" +#include "icons.h" +#include "screens.h" + +#define BUFFER_SIZE 1024 + +#define OUTSIDE_BUFFER -10 +#define OUTSIDE_FILE -11 + +static int fd; +static int file_size; + +static char buffer[BUFFER_SIZE+1]; +static int buffer_pos; /* Position of the buffer in the file */ + +static int begin_line; /* Index of the first line displayed on the lcd */ +static int end_line; /* Index of the last line displayed on the lcd */ +static int begin_line_pos; /* Position of the first_line in the bufffer */ +static int end_line_pos; /* Position of the last_line in the buffer */ + +/* + * Known issue: The caching algorithm will fail (display incoherent data) if + * the total space of the lines that are displayed on the screen exceeds the + * buffer size (only happens with very long lines). + */ + +static int display_line_count(void) +{ +#ifdef HAVE_LCD_BITMAP + int fh; + fh = font_get(FONT_UI)->height; + if (global_settings.statusbar) + return (LCD_HEIGHT - STATUSBAR_HEIGHT) / fh; + else + return LCD_HEIGHT/fh; +#else + return 2; +#endif +} + +static int find_next_line(int pos) +{ + int i; + + if (pos==OUTSIDE_BUFFER || pos==OUTSIDE_FILE) + return pos; + + i = pos; + if (buffer_pos+i>=file_size) { + return OUTSIDE_FILE; + } + while (1) { + i++; + if (buffer_pos+i==file_size) { + return i; + } + if (i>=BUFFER_SIZE) { + return OUTSIDE_BUFFER; + } + if (buffer[i]==0) { + return i; + } + } +} + +static int find_prev_line(int pos) +{ + int i; + + if (pos==OUTSIDE_BUFFER || pos==OUTSIDE_FILE) + return pos; + + i = pos; + if (buffer_pos+i<0) { + return OUTSIDE_FILE; + } + while (1) { + i--; + if (buffer_pos+i<0) { + return i; + } + if (i<0) { + return OUTSIDE_BUFFER; + } + if (buffer[i]==0) { + return i; + } + } +} + +static void viewer_draw(int col) +{ + int i, j; + char* str; + int line_pos; + + lcd_clear_display(); + + line_pos = begin_line_pos; + + for (i=0; + i<=end_line-begin_line && + line_pos!=OUTSIDE_BUFFER && + line_pos!=OUTSIDE_FILE; + i++) { + str = buffer + line_pos + 1; + for (j=0; j<col && *str!=0; ++j) + str++; + lcd_puts(0, i, str); + line_pos = find_next_line(line_pos); + } + + lcd_update(); +} + +static void fill_buffer(int pos) +{ + int i; + int numread; + + if (pos>=file_size-BUFFER_SIZE) + pos = file_size-BUFFER_SIZE; + if (pos<0) + pos = 0; + + lseek(fd, pos, SEEK_SET); + numread = read(fd, buffer, BUFFER_SIZE); + + begin_line_pos -= pos - buffer_pos; + end_line_pos -= pos - buffer_pos; + buffer_pos = pos; + + buffer[numread] = 0; + for(i=0;i<numread;i++) { + switch(buffer[i]) { + case '\r': + buffer[i] = ' '; + break; + case '\n': + buffer[i] = 0; + break; + default: + break; + } + } +} + +static bool viewer_init(char* file) +{ + int i; + int ret; + int disp_lines; + + fd = open(file, O_RDONLY); + if (fd==-1) + return false; + + file_size = lseek(fd, 0, SEEK_END); + + buffer_pos = 0; + begin_line = 0; + begin_line_pos = -1; + end_line = -1; + end_line_pos = -1; + fill_buffer(0); + disp_lines = display_line_count(); + for (i=0; i<disp_lines; ++i) { + ret = find_next_line(end_line_pos); + if (ret!=OUTSIDE_FILE && ret!=OUTSIDE_BUFFER) { + end_line_pos = ret; + end_line++; + } + } + + return true; +} + +static void viewer_exit(void) +{ + close(fd); +} + +static void viewer_scroll_down(void) +{ + int ret; + + ret = find_next_line(end_line_pos); + if (ret==OUTSIDE_BUFFER) { + begin_line_pos = find_next_line(begin_line_pos); + fill_buffer(begin_line_pos+buffer_pos); + end_line_pos = find_next_line(end_line_pos); + } else if (ret==OUTSIDE_FILE) { + return; + } else { + begin_line_pos = find_next_line(begin_line_pos); + end_line_pos = ret; + } + begin_line++; + end_line++; +} + +static void viewer_scroll_up(void) +{ + int ret; + + ret = find_prev_line(begin_line_pos); + if (ret==OUTSIDE_BUFFER) { + end_line_pos = find_prev_line(end_line_pos); + fill_buffer(buffer_pos+end_line_pos-BUFFER_SIZE); + begin_line_pos = find_prev_line(begin_line_pos); + } else if (ret==OUTSIDE_FILE) { + return; + } else { + end_line_pos = find_prev_line(end_line_pos); + begin_line_pos = ret; + } + begin_line--; + end_line--; +} + +bool viewer_run(char* file) +{ + int button; + int col = 0; + int ok; + +#ifdef HAVE_LCD_BITMAP + /* no margins */ + lcd_setmargins(0, 0); +#endif + + ok = viewer_init(file); + if (!ok) { + lcd_clear_display(); + lcd_puts(0, 0, "Error"); + lcd_update(); + sleep(HZ); + viewer_exit(); + return false; + } + + viewer_draw(col); + while(1) { + button = button_get(true); + + switch ( button ) { + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_F1: + case BUTTON_ON: +#else + case BUTTON_STOP: + case BUTTON_ON: +#endif + viewer_exit(); + return true; + break; + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_UP: + case BUTTON_UP | BUTTON_REPEAT: +#else + case BUTTON_LEFT: + case BUTTON_LEFT | BUTTON_REPEAT: +#endif + viewer_scroll_up(); + viewer_draw(col); + break; + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_DOWN: + case BUTTON_DOWN | BUTTON_REPEAT: +#else + case BUTTON_RIGHT: + case BUTTON_RIGHT | BUTTON_REPEAT: +#endif + viewer_scroll_down(); + viewer_draw(col); + break; + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_LEFT: + case BUTTON_LEFT | BUTTON_REPEAT: +#else + case BUTTON_MENU | BUTTON_LEFT: + case BUTTON_MENU | BUTTON_LEFT | BUTTON_REPEAT: +#endif + col--; + viewer_draw(col); + break; + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_RIGHT: + case BUTTON_RIGHT | BUTTON_REPEAT: +#else + case BUTTON_MENU | BUTTON_RIGHT: + case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REPEAT: +#endif + col++; + viewer_draw(col); + break; + + case SYS_USB_CONNECTED: + usb_screen(); +#ifdef HAVE_LCD_CHARCELLS + lcd_icon(ICON_PARAM, false); +#endif + viewer_exit(); + return true; + } + } +} + 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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Jerome Kuptz + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _VIEWER_H +#define _VIEWER_H + +bool viewer_run(char* file); + +#endif |