diff --git a/apps/plugins/viewer.c b/apps/plugins/viewer.c index 9375959..4f0ff7b 100644 --- a/apps/plugins/viewer.c +++ b/apps/plugins/viewer.c @@ -25,30 +25,31 @@ PLUGIN_HEADER -#define SETTINGS_FILE VIEWERS_DIR "/viewer.dat" /* binary file, so dont use .cfg */ - -#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */ -#define MAX_COLUMNS 64 /* Max displayable string len (over-estimate) */ -#define MAX_WIDTH 910 /* Max line length in WIDE mode */ -#define READ_PREV_ZONE 910 /* Arbitrary number less than SMALL_BLOCK_SIZE */ -#define SMALL_BLOCK_SIZE 0x1000 /* 4k: Smallest file chunk we will read */ -#define LARGE_BLOCK_SIZE 0x2000 /* 8k: Preferable size of file chunk to read */ -#define TOP_SECTOR buffer -#define MID_SECTOR (buffer + SMALL_BLOCK_SIZE) -#define BOTTOM_SECTOR (buffer + 2*(SMALL_BLOCK_SIZE)) -#define SCROLLBAR_WIDTH 6 -#define MAX_PAGE 9999 - -/* - * Bookmark file format +/* preferences and bookmarks at each file + * binary file, so dont use .cfg + * + * setting file format * * part byte count * -------------------------------- - * 'TVB' 3 + * 'TVS' 3 * version 1 * file count 2 * [1st file] * file path MAX_PATH + * next file pos 2 + * [preferences] + * word_mode 1 + * line_mode 1 + * view_mode 1 + * encoding 1 + * scrollbar_mode 1 + * need_scrollbar 1 + * page_mode 1 + * page_number_mode 1 + * title_mode 1 + * scroll_mode 1 + * autoscroll_speed 1 * bookmark count 1 * [1st bookmark] * file_position 4 @@ -62,10 +63,26 @@ PLUGIN_HEADER * ... * [last file] */ -#define BOOKMARKS_FILE VIEWERS_DIR "/viewer_bookmarks.dat" -#define BOOKMARKS_TMP_FILE VIEWERS_DIR "/viewer_bookmarks.tmp" -#define BOOKMARKS_HEADER "\x54\x56\x42\x31" /* header="TVB", version=1 */ -#define BOOKMARKS_H_SIZE 4 +#define SETTINGS_FILE VIEWERS_DIR "/viewer_file.dat" + +/* temporary file */ +#define SETTINGS_TMP_FILE VIEWERS_DIR "/viewer_file.tmp" + +#define SETTINGS_HEADER "\x54\x56\x53\x31" /* header="TVS" version=1 */ +#define SETTINGS_H_SIZE 4 + +#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */ +#define MAX_COLUMNS 64 /* Max displayable string len (over-estimate) */ +#define MAX_WIDTH 910 /* Max line length in WIDE mode */ +#define READ_PREV_ZONE 910 /* Arbitrary number less than SMALL_BLOCK_SIZE */ +#define SMALL_BLOCK_SIZE 0x1000 /* 4k: Smallest file chunk we will read */ +#define LARGE_BLOCK_SIZE 0x2000 /* 8k: Preferable size of file chunk to read */ +#define TOP_SECTOR buffer +#define MID_SECTOR (buffer + SMALL_BLOCK_SIZE) +#define BOTTOM_SECTOR (buffer + 2*(SMALL_BLOCK_SIZE)) +#define SCROLLBAR_WIDTH 6 +#define MAX_PAGE 9999 + #define BOOKMARK_SIZE 8 #define MAX_BOOKMARKS 10 /* user setting bookmarks + last read page */ @@ -92,6 +109,8 @@ PLUGIN_HEADER #endif #endif +#define PREFERENCES_SIZE 11 + /* Out-Of-Bounds test for any pointer to data in the buffer */ #define BUFFER_OOB(p) ((p) < buffer || (p) >= buffer_end) @@ -458,7 +477,6 @@ struct preferences { enum codepages encoding; -#ifdef HAVE_LCD_BITMAP enum { SB_OFF=0, SB_ON, @@ -481,7 +499,6 @@ struct preferences { FT_OFF = 0, FT_ON } footer_mode; -#endif /* HAVE_LCD_BITMAP */ enum { PAGE=0, @@ -1447,11 +1464,7 @@ static int bm_comp(const void *a, const void *b) static void viewer_add_bookmark(void) { if (bookmark_count >= MAX_BOOKMARKS-1) - { - rb->splash(HZ/2, "No more add bookmark."); - viewer_draw(col); return; - } bookmarks[bookmark_count].file_position = file_pos + screen_top_ptr - buffer; @@ -1459,9 +1472,6 @@ static void viewer_add_bookmark(void) bookmarks[bookmark_count].line = cline; bookmarks[bookmark_count].flag = BOOKMARK_USER; bookmark_count++; - - rb->splash(HZ/2, "Bookmark add."); - viewer_draw(col); } static void viewer_remove_bookmark(int i) @@ -1476,8 +1486,6 @@ static void viewer_remove_bookmark(int i) sizeof(struct bookmark_info)); bookmark_count--; - rb->splash(HZ/2, "Bookmark remove."); - viewer_draw(col); } static void viewer_remove_last_bookmark(void) @@ -1541,28 +1549,74 @@ static void viewer_select_bookmark(void) screen_top = screen_pos % buffer_size; file_pos = screen_pos - screen_top; screen_top_ptr = buffer + screen_top; - cline = bookmarks[selected].line; cpage = bookmarks[selected].page; + cline = bookmarks[selected].line; } } -static void viewer_default_settings(void) +static void viewer_default_preferences(void) { prefs.word_mode = WRAP; prefs.line_mode = NORMAL; prefs.view_mode = NARROW; prefs.scroll_mode = PAGE; -#ifdef HAVE_LCD_BITMAP prefs.page_mode = NO_OVERLAP; prefs.scrollbar_mode = SB_OFF; +#ifdef HAVE_LCD_BITMAP prefs.header_mode = HD_BOTH; prefs.footer_mode = FT_ON; +#else + prefs.header_mode = HD_OFF; + prefs.footer_mode = FT_OFF; #endif prefs.autoscroll_speed = 1; /* Set codepage to system default */ prefs.encoding = rb->global_settings->default_codepage; } +static bool viewer_read_preferences(int pfd) +{ + unsigned char buf[PREFERENCES_SIZE]; + unsigned char *p = buf; + + if (rb->read(pfd, buf, sizeof(buf)) != sizeof(buf)) + return false; + + prefs.word_mode = *p++; + prefs.line_mode = *p++; + prefs.view_mode = *p++; + prefs.encoding = *p++; + prefs.scrollbar_mode = *p++; + prefs.need_scrollbar = *p++; + prefs.page_mode = *p++; + prefs.header_mode = *p++; + prefs.footer_mode = *p++; + prefs.scroll_mode = *p++; + prefs.autoscroll_speed = *p; + + return true; +} + +static bool viewer_write_preferences(int pfd) +{ + unsigned char buf[PREFERENCES_SIZE]; + unsigned char *p = buf; + + *p++ = prefs.word_mode; + *p++ = prefs.line_mode; + *p++ = prefs.view_mode; + *p++ = prefs.encoding; + *p++ = prefs.scrollbar_mode; + *p++ = prefs.need_scrollbar; + *p++ = prefs.page_mode; + *p++ = prefs.header_mode; + *p++ = prefs.footer_mode; + *p++ = prefs.scroll_mode; + *p = prefs.autoscroll_speed; + + return (rb->write(pfd, buf, sizeof(buf)) == sizeof(buf)); +} + static bool viewer_read_bookmark_info(int bfd, struct bookmark_info *b) { unsigned char buf[BOOKMARK_SIZE]; @@ -1628,22 +1682,9 @@ static bool viewer_write_bookmark_info(int bfd, struct bookmark_info *b) static bool viewer_write_bookmark_infos(int bfd) { - unsigned char c; - int i = viewer_find_bookmark(cpage, cline); - - if (i >= 0) - bookmarks[i].flag |= BOOKMARK_LAST; - else - { - i = bookmark_count++; - - bookmarks[i].file_position = file_pos + screen_top_ptr - buffer; - bookmarks[i].page = cpage; - bookmarks[i].line = cline; - bookmarks[i].flag = BOOKMARK_LAST; - } + unsigned char c = bookmark_count; + int i; - c = bookmark_count; if (rb->write(bfd, &c, 1) != 1) return false; @@ -1656,53 +1697,99 @@ static bool viewer_write_bookmark_infos(int bfd) return true; } -static bool viewer_load_bookmarks(void) +static void viewer_load_settings(void) { - int bfd; - unsigned char buf[MAX_PATH+1]; + unsigned char buf[MAX_PATH+2]; unsigned int fcount; unsigned int i; - bool res = true; - - bookmark_count = 0; + bool res = false; + int sfd; + unsigned int size; - bfd = rb->open(BOOKMARKS_FILE, O_RDONLY); - if (bfd < 0) - return false; + sfd = rb->open(SETTINGS_FILE, O_RDONLY); + if (sfd < 0) + goto read_end; - if ((rb->read(bfd, buf, BOOKMARKS_H_SIZE+2) != BOOKMARKS_H_SIZE+2) || - rb->memcmp(buf, BOOKMARKS_HEADER, BOOKMARKS_H_SIZE)) + if ((rb->read(sfd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2) || + rb->memcmp(buf, SETTINGS_HEADER, SETTINGS_H_SIZE)) { - rb->close(bfd); - return false; - } + /* illegal setting file */ + rb->close(sfd); - fcount = (buf[BOOKMARKS_H_SIZE] << 8) | buf[BOOKMARKS_H_SIZE+1]; + if (rb->file_exists(SETTINGS_FILE)) + rb->remove(SETTINGS_FILE); + goto read_end; + } + + fcount = (buf[SETTINGS_H_SIZE] << 8) | buf[SETTINGS_H_SIZE+1]; for (i = 0; i < fcount; i++) { - if (rb->read(bfd, buf, MAX_PATH+1) != MAX_PATH+1) - { - res = false; + if (rb->read(sfd, buf, MAX_PATH+2) != MAX_PATH+2) break; - } + size = (buf[MAX_PATH] << 8) | buf[MAX_PATH+1]; if (rb->strcmp(buf, file_name)) { - res = (rb->lseek(bfd, buf[MAX_PATH] * BOOKMARK_SIZE, SEEK_CUR)>=0); - if (!res) + if (rb->lseek(sfd, size, SEEK_CUR) < 0) break; continue; } - res = (rb->lseek(bfd, -1, SEEK_CUR) >= 0); - if (!res) + if (!viewer_read_preferences(sfd)) break; - res = viewer_read_bookmark_infos(bfd); + + res = viewer_read_bookmark_infos(sfd); break; } - rb->close(bfd); - return res; + rb->close(sfd); + +read_end: + if (!res) + { + /* set default preference */ + viewer_default_preferences(); + + file_pos = 0; + screen_top_ptr = buffer; + cpage = 1; + cline = 1; + bookmark_count = 0; + } + + rb->memcpy(&old_prefs, &prefs, sizeof(struct preferences)); + + if (bookmark_count > 1) + viewer_select_bookmark(); + else if (bookmark_count == 1) + { + int screen_pos; + int screen_top; + + screen_pos = bookmarks[0].file_position; + screen_top = screen_pos % buffer_size; + file_pos = screen_pos - screen_top; + screen_top_ptr = buffer + screen_top; + cpage = bookmarks[0].page; + cline = bookmarks[0].line; + } + + viewer_remove_last_bookmark(); + + buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ + + if (BUFFER_OOB(screen_top_ptr)) + screen_top_ptr = buffer; + + fill_buffer(file_pos, buffer, buffer_size); + if (prefs.scroll_mode == PAGE && cline > 1) + viewer_scroll_to_top_line(); + + /* remember the current position */ + start_position = file_pos + screen_top_ptr - buffer; + + init_need_scrollbar(); + init_header_and_footer(); } static bool copy_bookmark_file(int sfd, int dfd, off_t start, off_t size) @@ -1727,40 +1814,51 @@ static bool copy_bookmark_file(int sfd, int dfd, off_t start, off_t size) return true; } -static bool viewer_save_bookmarks(void) +static bool viewer_save_settings(void) { - unsigned char buf[MAX_PATH+1]; + unsigned char buf[MAX_PATH+2]; unsigned int fcount = 0; unsigned int i; + int idx; int ofd; int tfd; off_t first_copy_size = 0; off_t second_copy_start_pos = 0; off_t size; - tfd = rb->open(BOOKMARKS_TMP_FILE, O_WRONLY|O_CREAT|O_TRUNC); + /* add reading page to bookmarks */ + idx = viewer_find_bookmark(cpage, cline); + if (idx >= 0) + bookmarks[idx].flag |= BOOKMARK_LAST; + else + { + viewer_add_bookmark(); + bookmarks[bookmark_count-1].flag = BOOKMARK_LAST; + } + + tfd = rb->open(SETTINGS_TMP_FILE, O_WRONLY|O_CREAT|O_TRUNC); if (tfd < 0) return false; - ofd = rb->open(BOOKMARKS_FILE, O_RDWR); + ofd = rb->open(SETTINGS_FILE, O_RDWR); if (ofd >= 0) { - if ((rb->read(ofd, buf, BOOKMARKS_H_SIZE+2) != BOOKMARKS_H_SIZE+2) || - rb->memcmp(buf, BOOKMARKS_HEADER, BOOKMARKS_H_SIZE)) + if ((rb->read(ofd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2) || + rb->memcmp(buf, SETTINGS_HEADER, SETTINGS_H_SIZE)) { rb->close(ofd); goto save_err; } - fcount = (buf[BOOKMARKS_H_SIZE] << 8) | buf[BOOKMARKS_H_SIZE+1]; + fcount = (buf[SETTINGS_H_SIZE] << 8) | buf[SETTINGS_H_SIZE+1]; for (i = 0; i < fcount; i++) { - if (rb->read(ofd, buf, MAX_PATH+1) != MAX_PATH+1) + if (rb->read(ofd, buf, MAX_PATH+2) != MAX_PATH+2) { rb->close(ofd); goto save_err; } - size = buf[MAX_PATH] * BOOKMARK_SIZE; + size = (buf[MAX_PATH] << 8) | buf[MAX_PATH+1]; if (rb->strcmp(buf, file_name)) { if (rb->lseek(ofd, size, SEEK_CUR) < 0) @@ -1778,7 +1876,7 @@ static bool viewer_save_bookmarks(void) goto save_err; } second_copy_start_pos = first_copy_size + size; - first_copy_size -= MAX_PATH+1; + first_copy_size -= MAX_PATH+2; fcount--; break; } @@ -1804,10 +1902,10 @@ static bool viewer_save_bookmarks(void) } else { - rb->memcpy(buf, BOOKMARKS_HEADER, BOOKMARKS_H_SIZE); - buf[BOOKMARKS_H_SIZE] = 0; - buf[BOOKMARKS_H_SIZE+1] = 0; - if (rb->write(tfd, buf, BOOKMARKS_H_SIZE+2) != BOOKMARKS_H_SIZE+2) + rb->memcpy(buf, SETTINGS_HEADER, SETTINGS_H_SIZE); + buf[SETTINGS_H_SIZE] = 0; + buf[SETTINGS_H_SIZE+1] = 0; + if (rb->write(tfd, buf, SETTINGS_H_SIZE+2) != SETTINGS_H_SIZE+2) goto save_err; } @@ -1815,13 +1913,20 @@ static bool viewer_save_bookmarks(void) rb->memset(buf, 0, MAX_PATH); rb->snprintf(buf, MAX_PATH, "%s", file_name); - if (rb->write(tfd, buf, MAX_PATH) != MAX_PATH) + size = PREFERENCES_SIZE + bookmark_count * BOOKMARK_SIZE + 1; + buf[MAX_PATH] = size >> 8; + buf[MAX_PATH+1] = size; + + if (rb->write(tfd, buf, MAX_PATH+2) != MAX_PATH+2) + goto save_err; + + if (!viewer_write_preferences(tfd)) goto save_err; if (!viewer_write_bookmark_infos(tfd)) goto save_err; - if (rb->lseek(tfd, BOOKMARKS_H_SIZE, SEEK_SET) < 0) + if (rb->lseek(tfd, SETTINGS_H_SIZE, SEEK_SET) < 0) goto save_err; fcount++; @@ -1833,97 +1938,25 @@ static bool viewer_save_bookmarks(void) rb->close(tfd); - rb->remove(BOOKMARKS_FILE); - rb->rename(BOOKMARKS_TMP_FILE, BOOKMARKS_FILE); + rb->remove(SETTINGS_FILE); + rb->rename(SETTINGS_TMP_FILE, SETTINGS_FILE); return true; save_err: rb->close(tfd); - rb->remove(BOOKMARKS_TMP_FILE); + rb->remove(SETTINGS_TMP_FILE); return false; } -static void viewer_load_settings(void) /* same name as global, but not the same file.. */ -{ - int settings_fd; - - /* read settings file */ - settings_fd=rb->open(SETTINGS_FILE, O_RDONLY); - if ((settings_fd >= 0) && (rb->filesize(settings_fd) == sizeof(struct preferences))) - { - rb->read(settings_fd, &prefs, sizeof(struct preferences)); - rb->close(settings_fd); - } - else - { - /* load default settings if there is no settings file */ - viewer_default_settings(); - } - - rb->memcpy(&old_prefs, &prefs, sizeof(struct preferences)); - - file_pos = 0; - screen_top_ptr = buffer; - cpage = 1; - cline = 1; - bookmark_count = 0; - - if (!viewer_load_bookmarks()) - { - if (rb->file_exists(BOOKMARKS_FILE)) - rb->remove(BOOKMARKS_FILE); - } - - if (bookmark_count > 1) - viewer_select_bookmark(); - - viewer_remove_last_bookmark(); - - buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ - - if (BUFFER_OOB(screen_top_ptr)) - { - screen_top_ptr = buffer; - } - - fill_buffer(file_pos, buffer, buffer_size); - if (prefs.scroll_mode == PAGE && cline > 1) - viewer_scroll_to_top_line(); - - /* remember the current position */ - start_position = file_pos + screen_top_ptr - buffer; - - init_need_scrollbar(); - init_header_and_footer(); -} - -static void viewer_save_settings(void)/* same name as global, but not the same file.. */ -{ - int settings_fd; - - /* save the viewer settings if they have been changed */ - if (rb->memcmp(&prefs, &old_prefs, sizeof(struct preferences))) - { - settings_fd = rb->creat(SETTINGS_FILE); /* create the settings file */ - - if (settings_fd >= 0 ) - { - rb->write (settings_fd, &prefs, sizeof(struct preferences)); - rb->close(settings_fd); - } - } - - /* save the bookmark */ - if (!viewer_save_bookmarks()) - rb->splash(HZ, "Can't save bookmarks."); -} - static void viewer_exit(void *parameter) { (void)parameter; - viewer_save_settings(); + /* save preference and bookmarks */ + if (!viewer_save_settings()) + rb->splash(HZ, "Can't save preference and bookmarks."); + rb->close(fd); } @@ -2399,9 +2432,21 @@ enum plugin_status plugin_start(const void* file) int idx = viewer_find_bookmark(cpage, cline); if (idx < 0) - viewer_add_bookmark(); + { + if (bookmark_count >= MAX_BOOKMARKS-1) + rb->splash(HZ/2, "No more add bookmark."); + else + { + viewer_add_bookmark(); + rb->splash(HZ/2, "Bookmark add."); + } + } else + { viewer_remove_bookmark(idx); + rb->splash(HZ/2, "Bookmark remove."); + } + viewer_draw(col); } break;