diff options
Diffstat (limited to 'apps/plugins/viewer.c')
-rw-r--r-- | apps/plugins/viewer.c | 140 |
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}; |
159 | static unsigned char *scrollbar_mode_str[] = {"off", "on", "scrollbar"}; | 161 | static unsigned char *scrollbar_mode_str[] = {"off", "on", "scrollbar"}; |
160 | static bool need_scrollbar; | 162 | static bool need_scrollbar; |
163 | |||
161 | enum { | 164 | enum { |
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 */ | |||
173 | static int draw_columns; /* number of (pixel) columns available for text */ | 176 | static int draw_columns; /* number of (pixel) columns available for text */ |
174 | static int par_indent_spaces; /* number of spaces to indent first paragraph */ | 177 | static int par_indent_spaces; /* number of spaces to indent first paragraph */ |
175 | static int fd; | 178 | static int fd; |
179 | static char *file_name; | ||
176 | static long file_size; | 180 | static long file_size; |
177 | static bool mac_text; | 181 | static bool mac_text; |
178 | static long file_pos; /* Position of the top of the buffer in the file */ | 182 | static 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 | ||
795 | static bool viewer_init(char* file) | 799 | static 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 | */ | ||
867 | typedef 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 | |||
876 | static 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 | |||
931 | static 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 | |||
859 | static void viewer_exit(void *parameter) | 975 | static 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) { |