summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Giacomelli <giac2000@hotmail.com>2010-12-14 21:33:45 +0000
committerMichael Giacomelli <giac2000@hotmail.com>2010-12-14 21:33:45 +0000
commit990cbf302eb04f80174c50040492fa7db6fbad6d (patch)
tree8a0340d9aeb299a954aa63bb1895a23cebfbe1d9
parentee4ea4266b2eae7a78680a722054a68a83840ec5 (diff)
downloadrockbox-990cbf302eb04f80174c50040492fa7db6fbad6d.zip
rockbox-990cbf302eb04f80174c50040492fa7db6fbad6d.tar.gz
rockbox-990cbf302eb04f80174c50040492fa7db6fbad6d.tar.bz2
rockbox-990cbf302eb04f80174c50040492fa7db6fbad6d.tar.xz
Commit FS#11799 by Alexander Meshcheryakov. Improves the text viewer plugin to write to the disk less often, and correct several minor bugs.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28833 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/text_viewer/tv_action.c27
-rw-r--r--apps/plugins/text_viewer/tv_bookmark.c16
-rw-r--r--apps/plugins/text_viewer/tv_bookmark.h3
-rw-r--r--apps/plugins/text_viewer/tv_menu.c2
-rw-r--r--apps/plugins/text_viewer/tv_preferences.c7
-rw-r--r--apps/plugins/text_viewer/tv_preferences.h10
-rw-r--r--apps/plugins/text_viewer/tv_settings.c127
-rw-r--r--apps/plugins/text_viewer/tv_settings.h1
-rw-r--r--docs/CREDITS2
9 files changed, 131 insertions, 64 deletions
diff --git a/apps/plugins/text_viewer/tv_action.c b/apps/plugins/text_viewer/tv_action.c
index 54cec38..3a0d895 100644
--- a/apps/plugins/text_viewer/tv_action.c
+++ b/apps/plugins/text_viewer/tv_action.c
@@ -28,6 +28,9 @@
#include "tv_settings.h"
#include "tv_window.h"
+bool bookmarks_changed = false;
+bool scrolled = false;
+
bool tv_init_action(unsigned char **buf, size_t *size)
{
/* initialize bookmarks and window modules */
@@ -36,10 +39,6 @@ bool tv_init_action(unsigned char **buf, size_t *size)
static void tv_finalize_action(void)
{
- /* save preference and bookmarks */
- if (!tv_save_settings())
- rb->splash(HZ, "Can't save preferences and bookmarks");
-
/* finalize bookmark modules */
tv_finalize_bookmark();
@@ -50,8 +49,19 @@ static void tv_finalize_action(void)
void tv_exit(void)
{
/* save preference and bookmarks */
- if (!tv_save_settings())
- rb->splash(HZ, "Can't save preferences and bookmarks");
+ DEBUGF("preferences_changed=%d\tbookmarks_changed=%d\tscrolled=%d\n",preferences_changed,bookmarks_changed,scrolled);
+ if ( preferences_changed || bookmarks_changed
+#ifndef HAVE_DISK_STORAGE
+ || scrolled
+#endif
+ )
+ {
+ DEBUGF("Saving settings\n");
+ if (!tv_save_settings())
+ rb->splash(HZ, "Can't save preferences and bookmarks");
+ }
+ else
+ DEBUGF("Skip saving settings\n");
/* finalize modules */
tv_finalize_action();
@@ -95,6 +105,7 @@ void tv_scroll_up(unsigned mode)
#endif
}
tv_move_screen(offset_page, offset_line, SEEK_CUR);
+ scrolled = true;
}
void tv_scroll_down(unsigned mode)
@@ -111,6 +122,7 @@ void tv_scroll_down(unsigned mode)
#endif
}
tv_move_screen(offset_page, offset_line, SEEK_CUR);
+ scrolled = true;
}
void tv_scroll_left(unsigned mode)
@@ -130,6 +142,7 @@ void tv_scroll_left(unsigned mode)
offset_window--;
}
tv_move_window(offset_window, offset_column);
+ scrolled = true;
}
void tv_scroll_right(unsigned mode)
@@ -149,6 +162,7 @@ void tv_scroll_right(unsigned mode)
offset_window++;
}
tv_move_window(offset_window, offset_column);
+ scrolled = true;
}
void tv_top(void)
@@ -186,4 +200,5 @@ unsigned tv_menu(void)
void tv_add_or_remove_bookmark(void)
{
tv_toggle_bookmark();
+ bookmarks_changed = true;
}
diff --git a/apps/plugins/text_viewer/tv_bookmark.c b/apps/plugins/text_viewer/tv_bookmark.c
index 815e7a1..5f77d2a 100644
--- a/apps/plugins/text_viewer/tv_bookmark.c
+++ b/apps/plugins/text_viewer/tv_bookmark.c
@@ -32,7 +32,6 @@ enum {
TV_BOOKMARK_USER = 2,
};
-#define SERIALIZE_BOOKMARK_SIZE 8
struct tv_bookmark_info {
struct tv_screen_pos pos;
@@ -287,11 +286,8 @@ bool tv_deserialize_bookmarks(int fd)
return res;
}
-static bool tv_write_bookmark_info(int fd, const struct tv_bookmark_info *b)
+static void tv_write_bookmark_info(unsigned char *p, const struct tv_bookmark_info *b)
{
- unsigned char buf[SERIALIZE_BOOKMARK_SIZE];
- unsigned char *p = buf;
-
*p++ = b->pos.file_pos >> 24;
*p++ = b->pos.file_pos >> 16;
*p++ = b->pos.file_pos >> 8;
@@ -302,21 +298,17 @@ static bool tv_write_bookmark_info(int fd, const struct tv_bookmark_info *b)
*p++ = b->pos.line;
*p = b->flag;
-
- return (rb->write(fd, buf, SERIALIZE_BOOKMARK_SIZE) >= 0);
}
-int tv_serialize_bookmarks(int fd)
+int tv_serialize_bookmarks(unsigned char *buf)
{
int i;
- if (rb->write(fd, &bookmark_count, 1) < 0)
- return 0;
+ buf[0] = bookmark_count;
for (i = 0; i < bookmark_count; i++)
{
- if (!tv_write_bookmark_info(fd, &bookmarks[i]))
- break;
+ tv_write_bookmark_info(buf + i * SERIALIZE_BOOKMARK_SIZE + 1, &bookmarks[i]);
}
return i * SERIALIZE_BOOKMARK_SIZE + 1;
}
diff --git a/apps/plugins/text_viewer/tv_bookmark.h b/apps/plugins/text_viewer/tv_bookmark.h
index b0b9107..85b52b2 100644
--- a/apps/plugins/text_viewer/tv_bookmark.h
+++ b/apps/plugins/text_viewer/tv_bookmark.h
@@ -29,6 +29,7 @@
/* Maximum amount of register possible bookmarks */
#define TV_MAX_BOOKMARKS 16
+#define SERIALIZE_BOOKMARK_SIZE 8
/*
* initialize the bookmark module
@@ -83,7 +84,7 @@ void tv_create_system_bookmark(void);
* Return
* the size of the result
*/
-int tv_serialize_bookmarks(int fd);
+int tv_serialize_bookmarks(unsigned char *buf);
/*
* deserialize the bookmark array
diff --git a/apps/plugins/text_viewer/tv_menu.c b/apps/plugins/text_viewer/tv_menu.c
index 5e79fd4..9be8312 100644
--- a/apps/plugins/text_viewer/tv_menu.c
+++ b/apps/plugins/text_viewer/tv_menu.c
@@ -329,6 +329,8 @@ unsigned tv_display_menu(void)
case 1: /* change settings */
tv_copy_preferences(&new_prefs);
result = tv_options_menu();
+ if (tv_compare_preferences(&new_prefs))
+ preferences_changed = true;
if (!tv_set_preferences(&new_prefs))
result = TV_MENU_RESULT_ERROR;
break;
diff --git a/apps/plugins/text_viewer/tv_preferences.c b/apps/plugins/text_viewer/tv_preferences.c
index 5e6677e..6d5c112 100644
--- a/apps/plugins/text_viewer/tv_preferences.c
+++ b/apps/plugins/text_viewer/tv_preferences.c
@@ -28,6 +28,8 @@ static struct tv_preferences prefs;
/* read-only preferences pointer, for access by other files */
const struct tv_preferences * const preferences = &prefs;
+bool preferences_changed = false;
+
static int listner_count = 0;
#define TV_MAX_LISTNERS 5
@@ -91,6 +93,11 @@ void tv_copy_preferences(struct tv_preferences *copy_prefs)
rb->memcpy(copy_prefs, preferences, sizeof(struct tv_preferences));
}
+bool tv_compare_preferences(struct tv_preferences *copy_prefs)
+{
+ return rb->memcmp(copy_prefs, preferences, sizeof(struct tv_preferences)) != 0;
+}
+
void tv_set_default_preferences(struct tv_preferences *p)
{
p->word_mode = WM_WRAP;
diff --git a/apps/plugins/text_viewer/tv_preferences.h b/apps/plugins/text_viewer/tv_preferences.h
index bc871a7..bb448b0 100644
--- a/apps/plugins/text_viewer/tv_preferences.h
+++ b/apps/plugins/text_viewer/tv_preferences.h
@@ -104,6 +104,7 @@ struct tv_preferences {
* global pointer to the preferences (read-only)
*/
extern const struct tv_preferences * const preferences;
+extern bool preferences_changed;
/*
* change the preferences
@@ -126,6 +127,15 @@ bool tv_set_preferences(const struct tv_preferences *new_prefs);
void tv_copy_preferences(struct tv_preferences *copy_prefs);
/*
+ * compare the preferences structs (binary)
+ *
+ * return
+ * true differs
+ * false identical
+ */
+bool tv_compare_preferences(struct tv_preferences *copy_prefs);
+
+/*
* set the default settings
*
* [Out] p
diff --git a/apps/plugins/text_viewer/tv_settings.c b/apps/plugins/text_viewer/tv_settings.c
index 3004ac3..20e8212 100644
--- a/apps/plugins/text_viewer/tv_settings.c
+++ b/apps/plugins/text_viewer/tv_settings.c
@@ -120,6 +120,10 @@
#define TV_SETTINGS_FIRST_VERSION 0x32
#define TV_PREFERENCES_SIZE (28 + MAX_PATH)
+#define TV_MAX_FILE_RECORD_SIZE (MAX_PATH+2 + TV_PREFERENCES_SIZE + TV_MAX_BOOKMARKS*SERIALIZE_BOOKMARK_SIZE+1)
+
+static off_t stored_preferences_offset = 0;
+static int stored_preferences_size = 0;
/* ----------------------------------------------------------------------------
* read/write the preferences
@@ -220,9 +224,8 @@ static bool tv_read_preferences(int pfd, int version, struct tv_preferences *pre
return true;
}
-static bool tv_write_preferences(int pfd, const struct tv_preferences *prefs)
+static void tv_serialize_preferences(unsigned char *buf, const struct tv_preferences *prefs)
{
- unsigned char buf[TV_PREFERENCES_SIZE];
unsigned char *p = buf;
rb->memset(buf, 0, TV_PREFERENCES_SIZE);
@@ -248,6 +251,13 @@ static bool tv_write_preferences(int pfd, const struct tv_preferences *prefs)
#ifdef HAVE_LCD_BITMAP
rb->strlcpy(buf + 28, prefs->font_name, MAX_PATH);
#endif
+}
+
+static bool tv_write_preferences(int pfd, const struct tv_preferences *prefs)
+{
+ unsigned char buf[TV_PREFERENCES_SIZE];
+
+ tv_serialize_preferences(buf, prefs);
return (rb->write(pfd, buf, TV_PREFERENCES_SIZE) >= 0);
}
@@ -427,6 +437,7 @@ bool tv_load_settings(const unsigned char *file_name)
int version;
unsigned int size;
struct tv_preferences prefs;
+ off_t current_pref_offset;
if (!rb->file_exists(TV_SETTINGS_FILE))
tv_convert_settings_file();
@@ -438,6 +449,8 @@ bool tv_load_settings(const unsigned char *file_name)
{
version = buf[TV_SETTINGS_HEADER_SIZE - 1] - TV_SETTINGS_FIRST_VERSION;
fcount = (buf[TV_SETTINGS_HEADER_SIZE] << 8) | buf[TV_SETTINGS_HEADER_SIZE+1];
+
+ current_pref_offset = rb->lseek(fd, 0, SEEK_CUR);
for (i = 0; i < fcount; i++)
{
@@ -448,10 +461,15 @@ bool tv_load_settings(const unsigned char *file_name)
{
if (tv_read_preferences(fd, version, &prefs))
res = tv_deserialize_bookmarks(fd);
+
+ if (res) {
+ stored_preferences_offset = current_pref_offset;
+ stored_preferences_size = size;
+ }
break;
}
- rb->lseek(fd, size, SEEK_CUR);
+ current_pref_offset = rb->lseek(fd, size, SEEK_CUR);
}
}
rb->close(fd);
@@ -473,38 +491,74 @@ bool tv_load_settings(const unsigned char *file_name)
return tv_set_preferences(&prefs);
}
-static bool tv_copy_settings(int sfd, int dfd, int size)
-{
- unsigned char buf[MAX_PATH];
- int i = size / MAX_PATH;
-
- size %= MAX_PATH;
-
- while (i--)
- {
- if ((rb->read(sfd, buf, MAX_PATH) < 0) || (rb->write(dfd, buf, MAX_PATH) < 0))
- return false;
- }
-
- return ((rb->read(sfd, buf, size) >= 0) && (rb->write(dfd, buf, size) >= 0));
-}
-
bool tv_save_settings(void)
{
- unsigned char buf[MAX_PATH+2];
+ unsigned char buf[TV_MAX_FILE_RECORD_SIZE];
+ unsigned char preferences_buf[TV_MAX_FILE_RECORD_SIZE];
unsigned int fcount = 0;
+ unsigned int new_fcount = 0;
unsigned int i;
int ofd = -1;
int tfd;
off_t size;
+ off_t preferences_buf_size;
bool res = true;
/* add reading page to bookmarks */
tv_create_system_bookmark();
+ /* storing preferences record in memory */
+ rb->memset(preferences_buf, 0, MAX_PATH);
+ rb->strlcpy(preferences_buf, preferences->file_name, MAX_PATH);
+ preferences_buf_size = MAX_PATH + 2;
+
+ tv_serialize_preferences(preferences_buf + preferences_buf_size, preferences);
+ preferences_buf_size += TV_PREFERENCES_SIZE;
+ preferences_buf_size += tv_serialize_bookmarks(preferences_buf + preferences_buf_size);
+ size = preferences_buf_size - (MAX_PATH + 2);
+ preferences_buf[MAX_PATH + 0] = size >> 8;
+ preferences_buf[MAX_PATH + 1] = size;
+
+
+ /* Just overwrite preferences if possible*/
+ if ( (stored_preferences_offset > 0) && (stored_preferences_size == size) )
+ {
+ DEBUGF("Saving preferences: overwriting\n");
+ if ((tfd = rb->open(TV_SETTINGS_FILE, O_WRONLY)) < 0)
+ return false;
+ rb->lseek(tfd, stored_preferences_offset, SEEK_SET);
+ res = (rb->write(tfd, preferences_buf, preferences_buf_size) >= 0);
+ rb->close(tfd);
+ return res;
+ }
+
+
if (!rb->file_exists(TV_SETTINGS_FILE))
tv_convert_settings_file();
+
+ /* Try appending preferences */
+ if ( (stored_preferences_offset == 0) &&
+ ( (tfd = rb->open(TV_SETTINGS_FILE, O_RDWR)) >= 0) )
+ {
+ DEBUGF("Saving preferences: appending\n");
+ rb->lseek(tfd, 0, SEEK_END);
+ if (rb->write(tfd, preferences_buf, preferences_buf_size) < 0)
+ return false;
+
+ rb->lseek(tfd, TV_SETTINGS_HEADER_SIZE, SEEK_SET);
+ rb->read(tfd, buf, 2);
+ fcount = (buf[0] << 8) | buf[1];
+ fcount ++;
+ buf[0] = fcount >> 8;
+ buf[1] = fcount;
+ rb->lseek(tfd, TV_SETTINGS_HEADER_SIZE, SEEK_SET);
+ res = rb->write(tfd, buf, 2) >= 0;
+
+ rb->close(tfd);
+ return res;
+ }
+
/* create header for the temporary file */
rb->memcpy(buf, TV_SETTINGS_HEADER, TV_SETTINGS_HEADER_SIZE - 1);
buf[TV_SETTINGS_HEADER_SIZE - 1] = TV_SETTINGS_VERSION;
@@ -539,12 +593,13 @@ bool tv_save_settings(void)
rb->lseek(ofd, size, SEEK_CUR);
else
{
- if ((rb->write(tfd, buf, MAX_PATH + 2) < 0) ||
- (!tv_copy_settings(ofd, tfd, size)))
+ if ((rb->read(ofd, buf + (MAX_PATH + 2), size) < 0) ||
+ (rb->write(tfd, buf, size + MAX_PATH + 2) < 0))
{
res = false;
break;
}
+ new_fcount++;
}
}
}
@@ -555,31 +610,15 @@ bool tv_save_settings(void)
{
/* save to current read file's preferences and bookmarks */
res = false;
- rb->memset(buf, 0, MAX_PATH);
- rb->strlcpy(buf, preferences->file_name, MAX_PATH);
- if (rb->write(tfd, buf, MAX_PATH + 2) >= 0)
+ if (rb->write(tfd, preferences_buf, preferences_buf_size) >= 0)
{
- if (tv_write_preferences(tfd, preferences))
- {
- size = tv_serialize_bookmarks(tfd);
- if (size > 0)
- {
- size += TV_PREFERENCES_SIZE;
- rb->lseek(tfd, -size - 2, SEEK_CUR);
- buf[0] = size >> 8;
- buf[1] = size;
- if (rb->write(tfd, buf, 2) >= 0)
- {
- rb->lseek(tfd, TV_SETTINGS_HEADER_SIZE, SEEK_SET);
+ rb->lseek(tfd, TV_SETTINGS_HEADER_SIZE, SEEK_SET);
- fcount++;
- buf[0] = fcount >> 8;
- buf[1] = fcount;
- res = (rb->write(tfd, buf, 2) >= 0);
- }
- }
- }
+ new_fcount++;
+ buf[0] = new_fcount >> 8;
+ buf[1] = new_fcount;
+ res = (rb->write(tfd, buf, 2) >= 0);
}
}
rb->close(tfd);
diff --git a/apps/plugins/text_viewer/tv_settings.h b/apps/plugins/text_viewer/tv_settings.h
index 65b31ec..afcf532 100644
--- a/apps/plugins/text_viewer/tv_settings.h
+++ b/apps/plugins/text_viewer/tv_settings.h
@@ -63,6 +63,7 @@ bool tv_load_settings(const unsigned char *file_name);
/*
* save the settings at each file
+ * supposed to be called only once at plugin exit
*
* return
* true success
diff --git a/docs/CREDITS b/docs/CREDITS
index 422a228..54f21ca 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -573,7 +573,7 @@ William Peters
Li Jie
Cristina Talpiga
Ştefan Moisei
-
+Alexander Meshcheryakov
The libmad team
The wavpack team