/*************************************************************************** * * __________ __ ___. * 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 #include #include #include #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=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