Gilles Roux's text viewer
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2452 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
ad911c0ac8
commit
773e7a70cc
3 changed files with 386 additions and 0 deletions
20
apps/tree.c
20
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);
|
||||
}
|
||||
|
|
342
apps/viewer.c
Normal file
342
apps/viewer.c
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
apps/viewer.h
Normal file
24
apps/viewer.h
Normal file
|
@ -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
|
Loading…
Reference in a new issue