summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2005-05-17 13:14:09 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2005-05-17 13:14:09 +0000
commit7ee41033b9ed547cd8b8ff4ff33528058c664382 (patch)
tree0d463ab5f4d3064c78b530e19d7f41a6aeedf64f /apps
parent8b8593f37aa43d0b34f52719a29645abd6d302d3 (diff)
downloadrockbox-7ee41033b9ed547cd8b8ff4ff33528058c664382.tar.gz
rockbox-7ee41033b9ed547cd8b8ff4ff33528058c664382.zip
Patch #1202120 by Luca Burelli - autobookmark for text viewer
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6483 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/viewer.c140
1 files changed, 130 insertions, 10 deletions
diff --git a/apps/plugins/viewer.c b/apps/plugins/viewer.c
index 514854db97..aadcd2f1db 100644
--- a/apps/plugins/viewer.c
+++ b/apps/plugins/viewer.c
@@ -24,6 +24,8 @@
24#error Scrollbar function requires PLUGIN_API_VERSION 3 at least 24#error Scrollbar function requires PLUGIN_API_VERSION 3 at least
25#endif 25#endif
26 26
27#define SETTINGS_FILE "/.rockbox/viewers/viewer.dat"
28
27#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */ 29#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */
28#define MAX_COLUMNS 64 /* Max displayable string len (over-estimate) */ 30#define MAX_COLUMNS 64 /* Max displayable string len (over-estimate) */
29#define MAX_WIDTH 910 /* Max line length in WIDE mode */ 31#define MAX_WIDTH 910 /* Max line length in WIDE mode */
@@ -53,10 +55,12 @@
53 (next_screen_ptr==NULL && screen_top_ptr==buffer && BUFFER_BOF()) 55 (next_screen_ptr==NULL && screen_top_ptr==buffer && BUFFER_BOF())
54 56
55/* Is a scrollbar called for on the current screen? */ 57/* Is a scrollbar called for on the current screen? */
56#define NEED_SCROLLBAR() ((!(ONE_SCREEN_FITS_ALL())) && \ 58#define NEED_SCROLLBAR() \
57 (view_mode==WIDE? scrollbar_mode[WIDE]==SB_ON: scrollbar_mode[NARROW]==SB_ON)) 59 ((!(ONE_SCREEN_FITS_ALL())) && (scrollbar_mode[view_mode]==SB_ON))
58 60
59/* variable button definitions */ 61/* variable button definitions */
62
63/* Recorder keys */
60#if CONFIG_KEYPAD == RECORDER_PAD 64#if CONFIG_KEYPAD == RECORDER_PAD
61#define VIEWER_QUIT BUTTON_OFF 65#define VIEWER_QUIT BUTTON_OFF
62#define VIEWER_PAGE_UP BUTTON_UP 66#define VIEWER_PAGE_UP BUTTON_UP
@@ -66,15 +70,14 @@
66#define VIEWER_MODE_WRAP BUTTON_F1 70#define VIEWER_MODE_WRAP BUTTON_F1
67#define VIEWER_MODE_LINE BUTTON_F2 71#define VIEWER_MODE_LINE BUTTON_F2
68#define VIEWER_MODE_WIDTH BUTTON_F3 72#define VIEWER_MODE_WIDTH BUTTON_F3
69/* Recorder, Ondio, iRiver */
70#define VIEWER_MODE_PAGE (BUTTON_ON | BUTTON_F1) 73#define VIEWER_MODE_PAGE (BUTTON_ON | BUTTON_F1)
71#define VIEWER_MODE_SCROLLBAR (BUTTON_ON | BUTTON_F3) 74#define VIEWER_MODE_SCROLLBAR (BUTTON_ON | BUTTON_F3)
72/* Recorder, iRiver */
73#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP) 75#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP)
74#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) 76#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN)
75#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) 77#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT)
76#define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT) 78#define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT)
77 79
80/* Ondio keys */
78#elif CONFIG_KEYPAD == ONDIO_PAD 81#elif CONFIG_KEYPAD == ONDIO_PAD
79#define VIEWER_QUIT BUTTON_OFF 82#define VIEWER_QUIT BUTTON_OFF
80#define VIEWER_PAGE_UP BUTTON_UP 83#define VIEWER_PAGE_UP BUTTON_UP
@@ -84,10 +87,10 @@
84#define VIEWER_MODE_WRAP (BUTTON_MENU | BUTTON_LEFT) 87#define VIEWER_MODE_WRAP (BUTTON_MENU | BUTTON_LEFT)
85#define VIEWER_MODE_LINE (BUTTON_MENU | BUTTON_UP) 88#define VIEWER_MODE_LINE (BUTTON_MENU | BUTTON_UP)
86#define VIEWER_MODE_WIDTH (BUTTON_MENU | BUTTON_RIGHT) 89#define VIEWER_MODE_WIDTH (BUTTON_MENU | BUTTON_RIGHT)
87/* Recorder, Ondio, iRiver */
88#define VIEWER_MODE_PAGE (BUTTON_MENU | BUTTON_DOWN) 90#define VIEWER_MODE_PAGE (BUTTON_MENU | BUTTON_DOWN)
89#define VIEWER_MODE_SCROLLBAR (BUTTON_MENU | BUTTON_OFF) 91#define VIEWER_MODE_SCROLLBAR (BUTTON_MENU | BUTTON_OFF)
90 92
93/* Player keys */
91#elif CONFIG_KEYPAD == PLAYER_PAD 94#elif CONFIG_KEYPAD == PLAYER_PAD
92#define VIEWER_QUIT BUTTON_STOP 95#define VIEWER_QUIT BUTTON_STOP
93#define VIEWER_PAGE_UP BUTTON_LEFT 96#define VIEWER_PAGE_UP BUTTON_LEFT
@@ -98,6 +101,7 @@
98#define VIEWER_MODE_LINE (BUTTON_ON | BUTTON_MENU | BUTTON_RIGHT) 101#define VIEWER_MODE_LINE (BUTTON_ON | BUTTON_MENU | BUTTON_RIGHT)
99#define VIEWER_MODE_WIDTH (BUTTON_ON | BUTTON_RIGHT) 102#define VIEWER_MODE_WIDTH (BUTTON_ON | BUTTON_RIGHT)
100 103
104/* iRiver H1x0 keys */
101#elif CONFIG_KEYPAD == IRIVER_H100_PAD 105#elif CONFIG_KEYPAD == IRIVER_H100_PAD
102#define VIEWER_QUIT BUTTON_OFF 106#define VIEWER_QUIT BUTTON_OFF
103#define VIEWER_PAGE_UP BUTTON_UP 107#define VIEWER_PAGE_UP BUTTON_UP
@@ -107,10 +111,8 @@
107#define VIEWER_MODE_WRAP BUTTON_REC 111#define VIEWER_MODE_WRAP BUTTON_REC
108#define VIEWER_MODE_LINE BUTTON_MODE 112#define VIEWER_MODE_LINE BUTTON_MODE
109#define VIEWER_MODE_WIDTH BUTTON_SELECT 113#define VIEWER_MODE_WIDTH BUTTON_SELECT
110/* Recorder, Ondio, iRiver */
111#define VIEWER_MODE_PAGE (BUTTON_ON | BUTTON_MODE) 114#define VIEWER_MODE_PAGE (BUTTON_ON | BUTTON_MODE)
112#define VIEWER_MODE_SCROLLBAR (BUTTON_ON | BUTTON_REC) 115#define VIEWER_MODE_SCROLLBAR (BUTTON_ON | BUTTON_REC)
113/* Recorder, iRiver */
114#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP) 116#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP)
115#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) 117#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN)
116#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) 118#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT)
@@ -158,6 +160,7 @@ enum {
158} scrollbar_mode[VIEW_MODES] = {SB_OFF, SB_ON}; 160} scrollbar_mode[VIEW_MODES] = {SB_OFF, SB_ON};
159static unsigned char *scrollbar_mode_str[] = {"off", "on", "scrollbar"}; 161static unsigned char *scrollbar_mode_str[] = {"off", "on", "scrollbar"};
160static bool need_scrollbar; 162static bool need_scrollbar;
163
161enum { 164enum {
162 NO_OVERLAP=0, 165 NO_OVERLAP=0,
163 OVERLAP, 166 OVERLAP,
@@ -173,6 +176,7 @@ static int display_lines; /* number of lines on the display */
173static int draw_columns; /* number of (pixel) columns available for text */ 176static int draw_columns; /* number of (pixel) columns available for text */
174static int par_indent_spaces; /* number of spaces to indent first paragraph */ 177static int par_indent_spaces; /* number of spaces to indent first paragraph */
175static int fd; 178static int fd;
179static char *file_name;
176static long file_size; 180static long file_size;
177static bool mac_text; 181static bool mac_text;
178static long file_pos; /* Position of the top of the buffer in the file */ 182static long file_pos; /* Position of the top of the buffer in the file */
@@ -792,7 +796,7 @@ static void init_need_scrollbar(void) {
792} 796}
793#endif 797#endif
794 798
795static bool viewer_init(char* file) 799static bool viewer_init(void)
796{ 800{
797#ifdef HAVE_LCD_BITMAP 801#ifdef HAVE_LCD_BITMAP
798 int idx, ch; 802 int idx, ch;
@@ -833,7 +837,7 @@ static bool viewer_init(char* file)
833#endif 837#endif
834 **********************/ 838 **********************/
835 839
836 fd = rb->open(file, O_RDONLY); 840 fd = rb->open(file_name, O_RDONLY);
837 if (fd==-1) 841 if (fd==-1)
838 return false; 842 return false;
839 843
@@ -856,10 +860,123 @@ static bool viewer_init(char* file)
856 return true; 860 return true;
857} 861}
858 862
863/* in the viewer settings file, the line format is:
864 * - file name (variable length)
865 * - settings (fixed length strings appended, EOL included)
866 */
867typedef struct {
868 char word_mode[2], line_mode[2], view_mode[2];
869 char file_pos[11], screen_top_ptr[11];
870#ifdef HAVE_LCD_BITMAP
871 char scrollbar_mode[VIEW_MODES][2], page_mode[2];
872#endif
873 char EOL;
874} viewer_settings_string;
875
876static void viewer_load_settings(void)
877{
878 int settings_fd, file_name_len, req_line_len, line_len;
879 char line[1024];
880
881 settings_fd=rb->open(SETTINGS_FILE, O_RDONLY);
882 rb->splash(HZ, true, "load %s %d", SETTINGS_FILE, settings_fd);
883 if (settings_fd < 0) return;
884
885 file_name_len = rb->strlen(file_name);
886 req_line_len = file_name_len + sizeof(viewer_settings_string);
887 while ((line_len = rb->read_line(settings_fd, line, sizeof(line))) > 0) {
888 if ((line_len == req_line_len) &&
889 (rb->strncasecmp(line, file_name, file_name_len) == 0)) {
890 /* found a match, load stored values */
891 viewer_settings_string *prefs = (void*) &line[file_name_len];
892
893#ifdef HAVE_LCD_BITMAP
894 /* view mode will be initialized later anyways */
895 for (view_mode=0; view_mode<VIEW_MODES; ++view_mode)
896 scrollbar_mode[view_mode] =
897 rb->atoi(prefs->scrollbar_mode[view_mode]);
898
899 page_mode = rb->atoi(prefs->page_mode);
900#endif
901
902 word_mode = rb->atoi(prefs->word_mode);
903 line_mode = rb->atoi(prefs->line_mode);
904 view_mode = rb->atoi(prefs->view_mode);
905
906#ifdef HAVE_LCD_BITMAP
907 init_need_scrollbar();
908#endif
909 /* the following settings are safety checked
910 * (file may have changed on disk)
911 */
912 file_pos = rb->atoi(prefs->file_pos); /* should be atol() */
913 if (file_pos > file_size) {
914 file_pos = 0;
915 break;
916 }
917 buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
918
919 screen_top_ptr = buffer + rb->atoi(prefs->screen_top_ptr);
920 if (BUFFER_OOB(screen_top_ptr)) {
921 screen_top_ptr = buffer;
922 break;
923 }
924 }
925 }
926 rb->close(settings_fd);
927
928 fill_buffer(file_pos, buffer, BUFFER_SIZE);
929}
930
931static void viewer_save_settings(void)
932{
933 int settings_fd, file_name_len, req_line_len, line_len;
934 char line[1024];
935 viewer_settings_string prefs;
936
937 settings_fd=rb->open(SETTINGS_FILE, O_RDWR | O_CREAT);
938 DEBUGF("SETTINGS_FILE: %d\n", settings_fd);
939 if (settings_fd < 0) return;
940
941 file_name_len = rb->strlen(file_name);
942 req_line_len = file_name_len + sizeof(viewer_settings_string);
943 while ((line_len = rb->read_line(settings_fd, line, sizeof(line))) > 0) {
944 if ((line_len == req_line_len) &&
945 (rb->strncasecmp(line, file_name, file_name_len) == 0)) {
946 /* found a match, reposition file pointer to overwrite this line */
947 rb->lseek(settings_fd, -line_len, SEEK_CUR);
948 break;
949 }
950 }
951
952 /* fill structure in order to prevent overwriting with 0s (snprintf
953 * intentionally overflows so that no terminating NULLs are written
954 * to disk). */
955 rb->snprintf(prefs.word_mode, 3, "%2d", word_mode);
956 rb->snprintf(prefs.line_mode, 3, "%2d", line_mode);
957 rb->snprintf(prefs.view_mode, 3, "%2d", view_mode);
958 rb->snprintf(prefs.file_pos, 12, "%11d", file_pos);
959 rb->snprintf(prefs.screen_top_ptr, 12, "%11d", screen_top_ptr-buffer);
960#ifdef HAVE_LCD_BITMAP
961 /* view_mode is not needed anymore */
962 for (view_mode=0; view_mode<VIEW_MODES; ++view_mode)
963 rb->snprintf(prefs.scrollbar_mode[view_mode], 3,
964 "%2d", scrollbar_mode[view_mode]);
965
966 rb->snprintf(prefs.page_mode, 3, "%2d", page_mode);
967#endif
968 prefs.EOL = '\n';
969
970 rb->write(settings_fd, file_name, file_name_len);
971 rb->write(settings_fd, &prefs, sizeof(prefs));
972 rb->close(settings_fd);
973}
974
859static void viewer_exit(void *parameter) 975static void viewer_exit(void *parameter)
860{ 976{
861 (void)parameter; 977 (void)parameter;
862 978
979 viewer_save_settings();
863 rb->close(fd); 980 rb->close(fd);
864} 981}
865 982
@@ -888,13 +1005,16 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file)
888 if (!file) 1005 if (!file)
889 return PLUGIN_ERROR; 1006 return PLUGIN_ERROR;
890 1007
891 ok = viewer_init(file); 1008 file_name = file;
1009 ok = viewer_init();
892 if (!ok) { 1010 if (!ok) {
893 rb->splash(HZ, false, "Error"); 1011 rb->splash(HZ, false, "Error");
894 viewer_exit(NULL); 1012 viewer_exit(NULL);
895 return PLUGIN_OK; 1013 return PLUGIN_OK;
896 } 1014 }
897 1015
1016 viewer_load_settings();
1017
898 viewer_draw(col); 1018 viewer_draw(col);
899 1019
900 while (!exit) { 1020 while (!exit) {