1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Gilles Roux
12 * 2010 Yoshihisa Uchida
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
24 #include "tv_bookmark.h"
25 #include "tv_reader.h"
26 #include "tv_settings.h"
28 /* global settings file
29 * binary file, so dont use .cfg
34 * -------------------------------
39 * windows 1 (when version <= 0x32, this value is view_mode)
42 * vertical_scrollbar 1
43 * (unused) 1 (for compatibility)
49 * horizontal_scrollbar 1
50 * horizontal_scroll_mode 1
55 #define VIEWER_GLOBAL_SETTINGS_FILE VIEWERS_DIR "/viewer.dat"
56 #define TV_GLOBAL_SETTINGS_FILE VIEWERS_DIR "/tv_global.dat"
58 #define TV_GLOBAL_SETTINGS_HEADER "\x54\x56\x47\x53" /* "TVGS" */
59 #define TV_GLOBAL_SETTINGS_VERSION 0x35
60 #define TV_GLOBAL_SETTINGS_HEADER_SIZE 5
61 #define TV_GLOBAL_SETTINGS_FIRST_VERSION 0x31
63 /* preferences and bookmarks at each file
64 * binary file, so dont use .cfg
69 * -----------------------------------
75 * next file pos 2 (prefences size + bookmark count * bookmark size + 1)
79 * windows 1 (when version <= 0x33, this value is view_mode)
82 * vertical_scrollbar 1
83 * (unused) 1 (for compatibility)
89 * horizontal_scrollbar 1
90 * horizontal_scroll_mode 1
106 #define VIEWER_SETTINGS_FILE VIEWERS_DIR "/viewer_file.dat"
107 #define TV_SETTINGS_FILE VIEWERS_DIR "/tv_file.dat"
110 #define TV_SETTINGS_TMP_FILE VIEWERS_DIR "/tv_file.tmp"
112 #define TV_SETTINGS_HEADER "\x54\x56\x53" /* "TVS" */
113 #define TV_SETTINGS_VERSION 0x36
114 #define TV_SETTINGS_HEADER_SIZE 4
115 #define TV_SETTINGS_FIRST_VERSION 0x32
117 #define TV_PREFERENCES_SIZE (28 + MAX_PATH)
119 /* ----------------------------------------------------------------------------
120 * read/write the preferences
121 * ----------------------------------------------------------------------------
124 static bool tv_read_preferences(int pfd
, int version
, struct tv_preferences
*prefs
)
126 unsigned char buf
[TV_PREFERENCES_SIZE
];
127 const unsigned char *p
= buf
;
128 int read_size
= TV_PREFERENCES_SIZE
;
132 else if (version
== 1)
135 if (rb
->read(pfd
, buf
, read_size
) < 0)
138 prefs
->word_mode
= *p
++;
139 prefs
->line_mode
= *p
++;
141 prefs
->windows
= *p
++;
146 prefs
->alignment
= *p
++;
148 prefs
->alignment
= LEFT
;
150 prefs
->encoding
= *p
++;
151 prefs
->vertical_scrollbar
= *p
++;
152 /* skip need_scrollbar */
154 prefs
->page_mode
= *p
++;
155 prefs
->header_mode
= *p
++;
156 prefs
->footer_mode
= *p
++;
157 prefs
->vertical_scroll_mode
= *p
++;
158 prefs
->autoscroll_speed
= *p
++;
161 prefs
->horizontal_scrollbar
= *p
;
163 prefs
->horizontal_scrollbar
= SB_OFF
;
166 prefs
->horizontal_scroll_mode
= *p
++;
168 prefs
->horizontal_scroll_mode
= SCREEN
;
170 rb
->memcpy(prefs
->font_name
, buf
+ read_size
- MAX_PATH
, MAX_PATH
);
172 #ifdef HAVE_LCD_BITMAP
173 prefs
->font
= rb
->font_get(FONT_UI
);
179 static bool tv_write_preferences(int pfd
, const struct tv_preferences
*prefs
)
181 unsigned char buf
[TV_PREFERENCES_SIZE
];
182 unsigned char *p
= buf
;
184 *p
++ = prefs
->word_mode
;
185 *p
++ = prefs
->line_mode
;
186 *p
++ = prefs
->windows
;
187 *p
++ = prefs
->alignment
;
188 *p
++ = prefs
->encoding
;
189 *p
++ = prefs
->vertical_scrollbar
;
190 /* skip need_scrollbar */
192 *p
++ = prefs
->page_mode
;
193 *p
++ = prefs
->header_mode
;
194 *p
++ = prefs
->footer_mode
;
195 *p
++ = prefs
->vertical_scroll_mode
;
196 *p
++ = prefs
->autoscroll_speed
;
197 *p
++ = prefs
->horizontal_scrollbar
;
198 *p
++ = prefs
->horizontal_scroll_mode
;
200 rb
->memcpy(buf
+ 28, prefs
->font_name
, MAX_PATH
);
202 return (rb
->write(pfd
, buf
, TV_PREFERENCES_SIZE
) >= 0);
205 /* ----------------------------------------------------------------------------
206 * convert vewer.rock's settings file to text_viewer.rock's settings file
207 * ----------------------------------------------------------------------------
210 static bool tv_convert_settings(int sfd
, int dfd
, int old_ver
)
212 struct tv_preferences new_prefs
;
215 unsigned char buf
[MAX_PATH
+ 2];
218 rb
->read(sfd
, buf
, MAX_PATH
+ 2);
219 rb
->write(dfd
, buf
, MAX_PATH
+ 2);
221 settings_size
= (buf
[MAX_PATH
] << 8) | buf
[MAX_PATH
+ 1];
223 old_pos
= rb
->lseek(sfd
, 0, SEEK_CUR
);
224 new_pos
= rb
->lseek(dfd
, 0, SEEK_CUR
);
227 * when the settings size != preferences size + bookmarks size,
228 * settings data are considered to be old version.
230 if (old_ver
> 0 && ((settings_size
- TV_PREFERENCES_SIZE
) % 8) == 0)
233 if (!tv_read_preferences(sfd
, old_ver
, &new_prefs
))
236 if (!tv_write_preferences(dfd
, &new_prefs
))
239 settings_size
-= (rb
->lseek(sfd
, 0, SEEK_CUR
) - old_pos
);
241 if (settings_size
> 0)
243 rb
->read(sfd
, buf
, settings_size
);
244 rb
->write(dfd
, buf
, settings_size
);
247 settings_size
= rb
->lseek(dfd
, 0, SEEK_CUR
) - new_pos
;
248 buf
[0] = settings_size
>> 8;
249 buf
[1] = settings_size
;
250 rb
->lseek(dfd
, new_pos
- 2, SEEK_SET
);
251 rb
->write(dfd
, buf
, 2);
252 rb
->lseek(dfd
, settings_size
, SEEK_CUR
);
256 static void tv_convert_settings_file(void)
258 unsigned char buf
[TV_SETTINGS_HEADER_SIZE
+ 2];
266 if ((sfd
= rb
->open(VIEWER_SETTINGS_FILE
, O_RDONLY
)) < 0)
269 if ((tfd
= rb
->open(TV_SETTINGS_TMP_FILE
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0666)) < 0)
275 if (rb
->read(sfd
, buf
, TV_SETTINGS_HEADER_SIZE
+ 2) >= 0)
277 version
= buf
[TV_SETTINGS_HEADER_SIZE
- 1] - TV_SETTINGS_FIRST_VERSION
;
278 fcount
= (buf
[TV_SETTINGS_HEADER_SIZE
] << 8) | buf
[TV_SETTINGS_HEADER_SIZE
+ 1];
279 buf
[TV_SETTINGS_HEADER_SIZE
- 1] = TV_SETTINGS_VERSION
;
281 if (rb
->write(tfd
, buf
, TV_SETTINGS_HEADER_SIZE
+ 2) >= 0)
284 for (i
= 0; i
< fcount
; i
++)
286 if (!tv_convert_settings(sfd
, tfd
, version
))
299 rb
->rename(TV_SETTINGS_TMP_FILE
, TV_SETTINGS_FILE
);
301 rb
->remove(TV_SETTINGS_TMP_FILE
);
306 /* ----------------------------------------------------------------------------
307 * load/save the global settings
308 * ----------------------------------------------------------------------------
311 bool tv_load_global_settings(struct tv_preferences
*prefs
)
313 unsigned char buf
[TV_GLOBAL_SETTINGS_HEADER_SIZE
];
319 * the viewer.rock's setting file read when the text_viewer.rock's setting file
322 if ((fd
= rb
->open(TV_GLOBAL_SETTINGS_FILE
, O_RDONLY
)) < 0)
323 fd
= rb
->open(VIEWER_GLOBAL_SETTINGS_FILE
, O_RDONLY
);
327 if ((rb
->read(fd
, buf
, TV_GLOBAL_SETTINGS_HEADER_SIZE
) > 0) &&
328 (rb
->memcmp(buf
, TV_GLOBAL_SETTINGS_HEADER
, TV_GLOBAL_SETTINGS_HEADER_SIZE
- 1) == 0))
330 version
= buf
[TV_GLOBAL_SETTINGS_HEADER_SIZE
- 1] - TV_GLOBAL_SETTINGS_FIRST_VERSION
;
331 res
= tv_read_preferences(fd
, version
, prefs
);
338 bool tv_save_global_settings(const struct tv_preferences
*prefs
)
340 unsigned char buf
[TV_GLOBAL_SETTINGS_HEADER_SIZE
];
344 if ((fd
= rb
->open(TV_SETTINGS_TMP_FILE
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0666)) < 0)
347 rb
->memcpy(buf
, TV_GLOBAL_SETTINGS_HEADER
, TV_GLOBAL_SETTINGS_HEADER_SIZE
- 1);
348 buf
[TV_GLOBAL_SETTINGS_HEADER_SIZE
- 1] = TV_GLOBAL_SETTINGS_VERSION
;
350 res
= (rb
->write(fd
, buf
, TV_GLOBAL_SETTINGS_HEADER_SIZE
) >= 0) &&
351 (tv_write_preferences(fd
, prefs
));
356 rb
->remove(TV_GLOBAL_SETTINGS_FILE
);
357 rb
->rename(TV_SETTINGS_TMP_FILE
, TV_GLOBAL_SETTINGS_FILE
);
360 rb
->remove(TV_SETTINGS_TMP_FILE
);
365 /* ----------------------------------------------------------------------------
366 * load/save the settings
367 * ----------------------------------------------------------------------------
370 void tv_load_settings(const unsigned char *file_name
)
372 unsigned char buf
[MAX_PATH
+2];
379 struct tv_preferences prefs
;
381 if (!rb
->file_exists(TV_SETTINGS_FILE
))
382 tv_convert_settings_file();
384 if ((fd
= rb
->open(TV_SETTINGS_FILE
, O_RDONLY
)) >= 0)
386 if ((rb
->read(fd
, buf
, TV_SETTINGS_HEADER_SIZE
+ 2) >= 0) &&
387 (rb
->memcmp(buf
, TV_SETTINGS_HEADER
, TV_SETTINGS_HEADER_SIZE
- 1) == 0))
389 version
= buf
[TV_SETTINGS_HEADER_SIZE
- 1] - TV_SETTINGS_FIRST_VERSION
;
390 fcount
= (buf
[TV_SETTINGS_HEADER_SIZE
] << 8) | buf
[TV_SETTINGS_HEADER_SIZE
+1];
392 for (i
= 0; i
< fcount
; i
++)
394 if (rb
->read(fd
, buf
, MAX_PATH
+2) >= 0)
396 size
= (buf
[MAX_PATH
] << 8) | buf
[MAX_PATH
+1];
397 if (rb
->strcmp(buf
, file_name
) == 0)
399 if (tv_read_preferences(fd
, version
, &prefs
))
400 res
= tv_deserialize_bookmarks(fd
);
404 rb
->lseek(fd
, size
, SEEK_CUR
);
411 /* when the settings file is illegal, removes it */
413 rb
->remove(TV_SETTINGS_FILE
);
418 /* specifications are acquired from the global settings */
419 if (!tv_load_global_settings(&prefs
))
420 tv_set_default_preferences(&prefs
);
422 rb
->strlcpy(prefs
.file_name
, file_name
, MAX_PATH
);
423 tv_set_preferences(&prefs
);
426 static bool tv_copy_settings(int sfd
, int dfd
, int size
)
428 unsigned char buf
[MAX_PATH
];
429 int i
= size
/ MAX_PATH
;
435 if ((rb
->read(sfd
, buf
, MAX_PATH
) < 0) || (rb
->write(dfd
, buf
, MAX_PATH
) < 0))
439 return ((rb
->read(sfd
, buf
, size
) >= 0) && (rb
->write(dfd
, buf
, size
) >= 0));
442 bool tv_save_settings(void)
444 const struct tv_preferences
*prefs
= tv_get_preferences();
445 unsigned char buf
[MAX_PATH
+2];
446 unsigned int fcount
= 0;
453 /* add reading page to bookmarks */
454 tv_create_system_bookmark();
456 if (!rb
->file_exists(TV_SETTINGS_FILE
))
457 tv_convert_settings_file();
459 /* create header for the temporary file */
460 rb
->memcpy(buf
, TV_SETTINGS_HEADER
, TV_SETTINGS_HEADER_SIZE
- 1);
461 buf
[TV_SETTINGS_HEADER_SIZE
- 1] = TV_SETTINGS_VERSION
;
463 if ((tfd
= rb
->open(TV_SETTINGS_TMP_FILE
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0666)) < 0)
466 if (rb
->write(tfd
, buf
, TV_SETTINGS_HEADER_SIZE
+ 2) < 0)
472 if ((ofd
= rb
->open(TV_SETTINGS_FILE
, O_RDONLY
)) >= 0)
474 res
= ((rb
->read(ofd
, buf
, TV_SETTINGS_HEADER_SIZE
+ 2) >= 0) &&
475 (rb
->memcmp(buf
, TV_SETTINGS_HEADER
, TV_SETTINGS_HEADER_SIZE
- 1) == 0));
479 fcount
= (buf
[TV_SETTINGS_HEADER_SIZE
] << 8) | buf
[TV_SETTINGS_HEADER_SIZE
+ 1];
480 for (i
= 0; i
< fcount
; i
++)
482 if (rb
->read(ofd
, buf
, MAX_PATH
+ 2) < 0)
488 size
= (buf
[MAX_PATH
] << 8) | buf
[MAX_PATH
+ 1];
489 if (rb
->strcmp(buf
, prefs
->file_name
) == 0)
490 rb
->lseek(ofd
, size
, SEEK_CUR
);
493 if ((rb
->write(tfd
, buf
, MAX_PATH
+ 2) < 0) ||
494 (!tv_copy_settings(ofd
, tfd
, size
)))
507 /* save to current read file's preferences and bookmarks */
509 rb
->memset(buf
, 0, MAX_PATH
);
510 rb
->strlcpy(buf
, prefs
->file_name
, MAX_PATH
);
512 if (rb
->write(tfd
, buf
, MAX_PATH
+ 2) >= 0)
514 if (tv_write_preferences(tfd
, prefs
))
516 size
= tv_serialize_bookmarks(tfd
);
519 size
+= TV_PREFERENCES_SIZE
;
520 rb
->lseek(tfd
, -size
- 2, SEEK_CUR
);
523 if (rb
->write(tfd
, buf
, 2) >= 0)
525 rb
->lseek(tfd
, TV_SETTINGS_HEADER_SIZE
, SEEK_SET
);
528 buf
[0] = fcount
>> 8;
530 res
= (rb
->write(tfd
, buf
, 2) >= 0);
540 rb
->remove(TV_SETTINGS_FILE
);
541 rb
->rename(TV_SETTINGS_TMP_FILE
, TV_SETTINGS_FILE
);
544 rb
->remove(TV_SETTINGS_TMP_FILE
);