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
This commit is contained in:
parent
ee4ea4266b
commit
990cbf302e
9 changed files with 131 additions and 64 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -125,6 +126,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
|
||||
*
|
||||
|
|
|
@ -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();
|
||||
|
@ -439,6 +450,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++)
|
||||
{
|
||||
if (rb->read(fd, buf, MAX_PATH+2) >= 0)
|
||||
|
@ -449,9 +462,14 @@ 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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -573,7 +573,7 @@ William Peters
|
|||
Li Jie
|
||||
Cristina Talpiga
|
||||
Ştefan Moisei
|
||||
|
||||
Alexander Meshcheryakov
|
||||
|
||||
The libmad team
|
||||
The wavpack team
|
||||
|
|
Loading…
Reference in a new issue