1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by wavey@wavey.org
11 * RTC config saving code (C) 2002 by hessu@hes.iki.fi
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
35 #include "backlight.h"
36 #include "powermgmt.h"
38 #ifdef HAVE_LCD_BITMAP
42 struct user_settings global_settings
;
43 char rockboxdir
[] = "/.rockbox/"; /* config/font/data file directory */
45 #define CONFIG_BLOCK_VERSION 1
46 #define CONFIG_BLOCK_SIZE 512
47 #define RTC_BLOCK_SIZE 44
49 /********************************************
51 Config block as saved on the battery-packed RTC user RAM memory block
52 of 44 bytes, starting at offset 0x14 of the RTC memory space.
55 0x00 0x14 "Roc" header signature: 0x52 0x6f 0x63
56 0x03 0x17 <version byte: 0x0>
57 0x04 0x18 <volume byte>
58 0x05 0x19 <balance byte>
60 0x07 0x1b <treble byte>
61 0x08 0x1c <loudness byte>
62 0x09 0x1d <bass boost byte>
63 0x0a 0x1e <contrast byte>
64 0x0b 0x1f <backlight byte>
65 0x0c 0x20 <poweroff timer byte>
66 0x0d 0x21 <resume settings byte>
67 0x0e 0x22 <shuffle,mp3filter,sort_case,discharge,statusbar,show_hidden>
68 0x0f 0x23 <scroll speed & WPS display byte>
69 0x10 0x24 <ff/rewind accleration rate>
71 0x12 0x26 <(int) Resume playlist index, or -1 if no playlist resume>
72 0x16 0x2a <(int) Byte offset into resume file>
73 0x1a 0x2e <time until disk spindown>
75 <all unused space filled with 0xff>
77 the geeky but useless statistics part:
78 0x24 <total uptime in seconds: 32 bits uint, actually unused for now>
80 0x2a <checksum 2 bytes: xor of 0x0-0x29>
82 Config memory is reset to 0xff and initialized with 'factory defaults' if
83 a valid header & checksum is not found. Config version number is only
84 increased when information is _relocated_ or space is _reused_ so that old
85 versions can read and modify configuration changed by new versions. New
86 versions should check for the value of '0xff' in each config memory
87 location used, and reset the setting in question with a factory default if
88 needed. Memory locations not used by a given version should not be
89 modified unless the header & checksum test fails.
92 Rest of config block, only saved to disk:
94 0xF8 (int) Playlist shuffle seed
95 0xFC (char[260]) Resume playlist (path/to/dir or path/to/playlist.m3u)
97 *************************************/
100 static unsigned char config_block
[CONFIG_BLOCK_SIZE
];
103 * Calculates the checksum for the config block and returns it
106 static unsigned short calculate_config_checksum(unsigned char* buf
)
109 unsigned char cksum
[2];
110 cksum
[0] = cksum
[1] = 0;
112 for (i
=0; i
< RTC_BLOCK_SIZE
- 2; i
+=2 ) {
114 cksum
[1] ^= buf
[i
+1];
117 return (cksum
[0] << 8) | cksum
[1];
121 * initialize the config block buffer
123 static void init_config_buffer( void )
125 DEBUGF( "init_config_buffer()\n" );
127 /* reset to 0xff - all unused */
128 memset(config_block
, 0xff, CONFIG_BLOCK_SIZE
);
130 config_block
[0] = 'R';
131 config_block
[1] = 'o';
132 config_block
[2] = 'c';
133 config_block
[3] = CONFIG_BLOCK_VERSION
;
137 * save the config block buffer to disk or RTC RAM
139 static int save_config_buffer( void )
141 unsigned short chksum
;
146 DEBUGF( "save_config_buffer()\n" );
148 /* update the checksum in the end of the block before saving */
149 chksum
= calculate_config_checksum(config_block
);
150 config_block
[ RTC_BLOCK_SIZE
- 2 ] = chksum
>> 8;
151 config_block
[ RTC_BLOCK_SIZE
- 1 ] = chksum
& 0xff;
154 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
155 that it would write a number of bytes at a time since the RTC chip
156 supports that, but this will have to do for now 8-) */
157 for (i
=0; i
< RTC_BLOCK_SIZE
; i
++ ) {
158 int r
= rtc_write(0x14+i
, config_block
[i
]);
160 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", 14+i
, r
);
167 if (fat_startsector() != 0)
168 ata_delayed_write( 61, config_block
);
176 * load the config block buffer from disk or RTC RAM
178 static int load_config_buffer( void )
180 unsigned short chksum
;
181 bool correct
= false;
185 unsigned char rtc_block
[RTC_BLOCK_SIZE
];
188 DEBUGF( "load_config_buffer()\n" );
190 if (fat_startsector() != 0) {
191 ata_read_sectors( 61, 1, config_block
);
193 /* calculate the checksum, check it and the header */
194 chksum
= calculate_config_checksum(config_block
);
196 if (config_block
[0] == 'R' &&
197 config_block
[1] == 'o' &&
198 config_block
[2] == 'c' &&
199 config_block
[3] == CONFIG_BLOCK_VERSION
&&
200 (chksum
>> 8) == config_block
[RTC_BLOCK_SIZE
- 2] &&
201 (chksum
& 0xff) == config_block
[RTC_BLOCK_SIZE
- 1])
203 DEBUGF( "load_config_buffer: header & checksum test ok\n" );
210 for (i
=0; i
< RTC_BLOCK_SIZE
; i
++ )
211 rtc_block
[i
] = rtc_read(0x14+i
);
213 chksum
= calculate_config_checksum(rtc_block
);
215 /* if rtc block is ok, use that */
216 if (rtc_block
[0] == 'R' &&
217 rtc_block
[1] == 'o' &&
218 rtc_block
[2] == 'c' &&
219 rtc_block
[3] == CONFIG_BLOCK_VERSION
&&
220 (chksum
>> 8) == rtc_block
[RTC_BLOCK_SIZE
- 2] &&
221 (chksum
& 0xff) == rtc_block
[RTC_BLOCK_SIZE
- 1])
223 memcpy(config_block
, rtc_block
, RTC_BLOCK_SIZE
);
229 /* if checksum is not valid, clear the config buffer */
230 DEBUGF( "load_config_buffer: header & checksum test failed\n" );
231 init_config_buffer();
239 * persist all runtime user settings to disk or RTC RAM
241 int settings_save( void )
243 DEBUGF( "settings_save()\n" );
245 /* update the config block buffer with current
246 settings and save the block in the RTC */
247 config_block
[0x4] = (unsigned char)global_settings
.volume
;
248 config_block
[0x5] = (unsigned char)global_settings
.balance
;
249 config_block
[0x6] = (unsigned char)global_settings
.bass
;
250 config_block
[0x7] = (unsigned char)global_settings
.treble
;
251 config_block
[0x8] = (unsigned char)global_settings
.loudness
;
252 config_block
[0x9] = (unsigned char)global_settings
.bass_boost
;
254 config_block
[0xa] = (unsigned char)global_settings
.contrast
;
255 config_block
[0xb] = (unsigned char)global_settings
.backlight
;
256 config_block
[0xc] = (unsigned char)global_settings
.poweroff
;
257 config_block
[0xd] = (unsigned char)global_settings
.resume
;
259 config_block
[0xe] = (unsigned char)
260 ((global_settings
.playlist_shuffle
& 1) |
261 ((global_settings
.mp3filter
& 1) << 1) |
262 ((global_settings
.sort_case
& 1) << 2) |
263 ((global_settings
.discharge
& 1) << 3) |
264 ((global_settings
.statusbar
& 1) << 4) |
265 ((global_settings
.show_hidden_files
& 1) << 5));
267 config_block
[0xf] = (unsigned char)
268 ((global_settings
.scroll_speed
<< 3) |
269 (global_settings
.wps_display
& 7));
271 config_block
[0x10] = (unsigned char)global_settings
.ff_rewind_accel
;
272 config_block
[0x11] = (unsigned char)global_settings
.avc
;
273 config_block
[0x1a] = (unsigned char)global_settings
.disk_spindown
;
275 memcpy(&config_block
[0x12], &global_settings
.resume_index
, 4);
276 memcpy(&config_block
[0x16], &global_settings
.resume_offset
, 4);
277 memcpy(&config_block
[0xF8], &global_settings
.resume_seed
, 4);
279 memcpy(&config_block
[0x24], &global_settings
.total_uptime
, 4);
280 strncpy(&config_block
[0xFC], global_settings
.resume_file
, MAX_PATH
);
282 DEBUGF("+Resume file %s\n",global_settings
.resume_file
);
283 DEBUGF("+Resume index %X offset %X\n",
284 global_settings
.resume_index
,
285 global_settings
.resume_offset
);
286 DEBUGF("+Resume shuffle %s seed %X\n",
287 global_settings
.playlist_shuffle
?"on":"off",
288 global_settings
.resume_seed
);
290 if(save_config_buffer())
293 #ifdef HAVE_LCD_CHARCELLS
294 lcd_puts(0, 0, "Save failed");
295 lcd_puts(0, 1, "Batt. low?");
297 lcd_puts(4, 2, "Save failed");
298 lcd_puts(2, 4, "Is battery low?");
308 * load settings from disk or RTC RAM
310 void settings_load(void)
314 DEBUGF( "reload_all_settings()\n" );
316 /* populate settings with default values */
319 /* load the buffer from the RTC (resets it to all-unused if the block
320 is invalid) and decode the settings which are set in the block */
321 if (!load_config_buffer()) {
322 if (config_block
[0x4] != 0xFF)
323 global_settings
.volume
= config_block
[0x4];
324 if (config_block
[0x5] != 0xFF)
325 global_settings
.balance
= config_block
[0x5];
326 if (config_block
[0x6] != 0xFF)
327 global_settings
.bass
= config_block
[0x6];
328 if (config_block
[0x7] != 0xFF)
329 global_settings
.treble
= config_block
[0x7];
330 if (config_block
[0x8] != 0xFF)
331 global_settings
.loudness
= config_block
[0x8];
332 if (config_block
[0x9] != 0xFF)
333 global_settings
.bass_boost
= config_block
[0x9];
335 if (config_block
[0xa] != 0xFF) {
336 global_settings
.contrast
= config_block
[0xa];
337 if ( global_settings
.contrast
< MIN_CONTRAST_SETTING
)
338 global_settings
.contrast
= DEFAULT_CONTRAST_SETTING
;
340 if (config_block
[0xb] != 0xFF)
341 global_settings
.backlight
= config_block
[0xb];
342 if (config_block
[0xc] != 0xFF)
343 global_settings
.poweroff
= config_block
[0xc];
344 if (config_block
[0xd] != 0xFF)
345 global_settings
.resume
= config_block
[0xd];
346 if (config_block
[0xe] != 0xFF) {
347 global_settings
.playlist_shuffle
= config_block
[0xe] & 1;
348 global_settings
.mp3filter
= (config_block
[0xe] >> 1) & 1;
349 global_settings
.sort_case
= (config_block
[0xe] >> 2) & 1;
350 global_settings
.discharge
= (config_block
[0xe] >> 3) & 1;
351 global_settings
.statusbar
= (config_block
[0xe] >> 4) & 1;
352 global_settings
.show_hidden_files
= (config_block
[0xe] >> 5) & 1;
355 c
= config_block
[0xf] >> 3;
357 global_settings
.scroll_speed
= c
;
359 c
= config_block
[0xf] & 7;
361 global_settings
.wps_display
= c
;
363 if (config_block
[0x10] != 0xFF)
364 global_settings
.ff_rewind_accel
= config_block
[0x10];
366 if (config_block
[0x11] != 0xFF)
367 global_settings
.avc
= config_block
[0x11];
369 if (config_block
[0x12] != 0xFF)
370 memcpy(&global_settings
.resume_index
, &config_block
[0x12], 4);
372 if (config_block
[0x16] != 0xFF)
373 memcpy(&global_settings
.resume_offset
, &config_block
[0x16], 4);
375 if (config_block
[0x1a] != 0xFF)
376 global_settings
.disk_spindown
= config_block
[0x1a];
378 memcpy(&global_settings
.resume_seed
, &config_block
[0xF8], 4);
380 if (config_block
[0x24] != 0xFF)
381 memcpy(&global_settings
.total_uptime
, &config_block
[0x24], 4);
383 strncpy(global_settings
.resume_file
, &config_block
[0xFC], MAX_PATH
);
384 global_settings
.resume_file
[MAX_PATH
]=0;
386 lcd_set_contrast(global_settings
.contrast
);
387 lcd_scroll_speed(global_settings
.scroll_speed
);
388 backlight_time(global_settings
.backlight
);
389 ata_spindown(global_settings
.disk_spindown
);
390 #ifdef HAVE_CHARGE_CTRL
391 charge_restart_level
= global_settings
.discharge
? CHARGE_RESTART_LO
: CHARGE_RESTART_HI
;
396 * reset all settings to their default value
398 void settings_reset(void) {
400 DEBUGF( "settings_reset()\n" );
402 global_settings
.volume
= mpeg_sound_default(SOUND_VOLUME
);
403 global_settings
.balance
= mpeg_sound_default(SOUND_BALANCE
);
404 global_settings
.bass
= mpeg_sound_default(SOUND_BASS
);
405 global_settings
.treble
= mpeg_sound_default(SOUND_TREBLE
);
406 global_settings
.loudness
= mpeg_sound_default(SOUND_LOUDNESS
);
407 global_settings
.bass_boost
= mpeg_sound_default(SOUND_SUPERBASS
);
408 global_settings
.avc
= mpeg_sound_default(SOUND_AVC
);
409 global_settings
.resume
= RESUME_ASK
;
410 global_settings
.contrast
= DEFAULT_CONTRAST_SETTING
;
411 global_settings
.poweroff
= DEFAULT_POWEROFF_SETTING
;
412 global_settings
.backlight
= DEFAULT_BACKLIGHT_SETTING
;
413 global_settings
.wps_display
= DEFAULT_WPS_DISPLAY
;
414 global_settings
.mp3filter
= true;
415 global_settings
.sort_case
= false;
416 global_settings
.statusbar
= true;
417 global_settings
.loop_playlist
= true;
418 global_settings
.playlist_shuffle
= false;
419 global_settings
.discharge
= 0;
420 global_settings
.total_uptime
= 0;
421 global_settings
.scroll_speed
= 8;
422 global_settings
.show_hidden_files
= false;
423 global_settings
.ff_rewind_accel
= DEFAULT_FF_REWIND_ACCEL_SETTING
;
424 global_settings
.resume_index
= -1;
425 global_settings
.resume_offset
= -1;
426 global_settings
.disk_spindown
= 5;
431 * dump the list of current settings
433 void settings_display(void)
436 DEBUGF( "\nsettings_display()\n" );
438 DEBUGF( "\nvolume:\t\t%d\nbalance:\t%d\nbass:\t\t%d\ntreble:\t\t%d\nloudness:\t%d\nbass boost:\t%d\n",
439 global_settings
.volume
,
440 global_settings
.balance
,
441 global_settings
.bass
,
442 global_settings
.treble
,
443 global_settings
.loudness
,
444 global_settings
.bass_boost
);
446 DEBUGF( "contrast:\t%d\npoweroff:\t%d\nbacklight:\t%d\n",
447 global_settings
.contrast
,
448 global_settings
.poweroff
,
449 global_settings
.backlight
);
453 void set_bool(char* string
, bool* variable
)
458 #ifdef HAVE_LCD_BITMAP
459 if(global_settings
.statusbar
)
460 lcd_setmargins(0, STATUSBAR_HEIGHT
);
462 lcd_setmargins(0, 0);
465 lcd_puts_scroll(0, 0, string
);
468 lcd_puts(0, 1, *variable
? "on " : "off");
469 #ifdef HAVE_LCD_BITMAP
474 button
= button_get_w_tmo(HZ
/2);
476 #ifdef HAVE_RECORDER_KEYPAD
485 #ifdef HAVE_RECORDER_KEYPAD
492 if(!(button
& BUTTON_REL
))
493 *variable
= !*variable
;
496 #ifdef HAVE_RECORDER_KEYPAD
498 #ifdef HAVE_LCD_BITMAP
499 global_settings
.statusbar
= !global_settings
.statusbar
;
501 if(global_settings
.statusbar
)
502 lcd_setmargins(0, STATUSBAR_HEIGHT
);
504 lcd_setmargins(0, 0);
506 lcd_puts_scroll(0, 0, string
);
515 void set_int(char* string
,
518 void (*function
)(int),
525 #ifdef HAVE_LCD_BITMAP
526 if(global_settings
.statusbar
)
527 lcd_setmargins(0, STATUSBAR_HEIGHT
);
529 lcd_setmargins(0, 0);
532 lcd_puts_scroll(0, 0, string
);
536 snprintf(str
,sizeof str
,"%d %s ", *variable
, unit
);
538 #ifdef HAVE_LCD_BITMAP
543 switch( button_get_w_tmo(HZ
/2) ) {
544 #ifdef HAVE_RECORDER_KEYPAD
546 case BUTTON_UP
| BUTTON_REPEAT
:
549 case BUTTON_RIGHT
| BUTTON_REPEAT
:
556 #ifdef HAVE_RECORDER_KEYPAD
558 case BUTTON_DOWN
| BUTTON_REPEAT
:
561 case BUTTON_LEFT
| BUTTON_REPEAT
:
568 #ifdef HAVE_RECORDER_KEYPAD
577 #ifdef HAVE_RECORDER_KEYPAD
579 #ifdef HAVE_LCD_BITMAP
580 global_settings
.statusbar
= !global_settings
.statusbar
;
582 if(global_settings
.statusbar
)
583 lcd_setmargins(0, STATUSBAR_HEIGHT
);
585 lcd_setmargins(0, 0);
587 lcd_puts_scroll(0, 0, string
);
598 void set_option(char* string
, int* variable
, char* options
[], int numoptions
)
602 #ifdef HAVE_LCD_BITMAP
603 if(global_settings
.statusbar
)
604 lcd_setmargins(0, STATUSBAR_HEIGHT
);
606 lcd_setmargins(0, 0);
609 lcd_puts_scroll(0, 0, string
);
612 lcd_puts(0, 1, options
[*variable
]);
613 #ifdef HAVE_LCD_BITMAP
618 switch ( button_get_w_tmo(HZ
/2) ) {
619 #ifdef HAVE_RECORDER_KEYPAD
621 case BUTTON_UP
| BUTTON_REPEAT
:
624 case BUTTON_RIGHT
| BUTTON_REPEAT
:
626 if ( *variable
< (numoptions
-1) )
630 #ifdef HAVE_RECORDER_KEYPAD
632 case BUTTON_DOWN
| BUTTON_REPEAT
:
635 case BUTTON_LEFT
| BUTTON_REPEAT
:
641 #ifdef HAVE_RECORDER_KEYPAD
650 #ifdef HAVE_RECORDER_KEYPAD
652 #ifdef HAVE_LCD_BITMAP
653 global_settings
.statusbar
= !global_settings
.statusbar
;
655 if(global_settings
.statusbar
)
656 lcd_setmargins(0, STATUSBAR_HEIGHT
);
658 lcd_setmargins(0, 0);
660 lcd_puts_scroll(0, 0, string
);
672 #define INDEX_WIDTH 2
673 char *dayname
[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
674 char *monthname
[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
675 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
676 char cursor
[][3] = {{ 0, 8, 12}, {18, 8, 12}, {36, 8, 12},
677 {24, 16, 24}, {54, 16, 18}, {78, 16, 12}};
678 char daysinmonth
[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
680 void set_time(char* string
, int timedate
[])
684 int min
= 0, steps
= 0;
686 int lastcursorpos
= !cursorpos
;
687 unsigned char buffer
[19];
691 #if defined(LOADABLE_FONTS) || defined(LCD_PROPFONTS)
692 unsigned char reffub
[5];
693 unsigned int width
, height
;
694 unsigned int separator_width
, weekday_width
;
695 unsigned int line_height
, prev_line_height
;
696 #if defined(LOADABLE_FONTS)
697 unsigned char *font
= lcd_getcurrentldfont();
701 #ifdef HAVE_LCD_BITMAP
702 if(global_settings
.statusbar
)
703 lcd_setmargins(0, STATUSBAR_HEIGHT
);
705 lcd_setmargins(0, 0);
708 lcd_puts_scroll(0, 0, string
);
711 /* calculate the number of days in febuary */
712 realyear
= timedate
[3] + 2000;
713 if((realyear
% 4 == 0 && !(realyear
% 100 == 0)) || realyear
% 400 == 0)
718 /* fix day if month or year changed */
719 if (timedate
[5] > daysinmonth
[timedate
[4] - 1])
720 timedate
[5] = daysinmonth
[timedate
[4] - 1];
722 /* calculate day of week */
724 for(i
= 0; i
< timedate
[4] - 1; i
++) {
725 julianday
+= daysinmonth
[i
];
727 julianday
+= timedate
[5];
728 timedate
[6] = (realyear
+ julianday
+ (realyear
- 1) / 4 -
729 (realyear
- 1) / 100 + (realyear
- 1) / 400 + 7 - 1) % 7;
731 snprintf(buffer
, sizeof(buffer
), "%02d:%02d:%02d ",
735 lcd_puts(0, 1, buffer
);
736 #if defined(LCD_PROPFONTS)
737 /* recalculate the positions and offsets */
738 lcd_getstringsize(string
, 0, &width
, &prev_line_height
);
739 lcd_getstringsize(buffer
, 0, &width
, &line_height
);
740 lcd_getstringsize(":", 0, &separator_width
, &height
);
742 strncpy(reffub
, buffer
, 2);
744 lcd_getstringsize(reffub
, 0, &width
, &height
);
745 cursor
[0][INDEX_X
] = 0;
746 cursor
[0][INDEX_Y
] = 1 + prev_line_height
+ 1;
747 cursor
[0][INDEX_WIDTH
] = width
;
749 strncpy(reffub
, buffer
+ 3, 2);
751 lcd_getstringsize(reffub
, 0, &width
, &height
);
752 cursor
[1][INDEX_X
] = cursor
[0][INDEX_WIDTH
] + separator_width
;
753 cursor
[1][INDEX_Y
] = 1 + prev_line_height
+ 1;
754 cursor
[1][INDEX_WIDTH
] = width
;
756 strncpy(reffub
, buffer
+ 6, 2);
758 lcd_getstringsize(reffub
, 0, &width
, &height
);
759 cursor
[2][INDEX_X
] = cursor
[0][INDEX_WIDTH
] + separator_width
+
760 cursor
[1][INDEX_WIDTH
] + separator_width
;
761 cursor
[2][INDEX_Y
] = 1 + prev_line_height
+ 1;
762 cursor
[2][INDEX_WIDTH
] = width
;
764 lcd_getstringsize(buffer
, 0, &width
, &prev_line_height
);
765 #elif defined(LOADABLE_FONTS)
766 /* recalculate the positions and offsets */
767 lcd_getstringsize(string
, font
, &width
, &prev_line_height
);
768 lcd_getstringsize(buffer
, font
, &width
, &line_height
);
769 lcd_getstringsize(":", font
, &separator_width
, &height
);
771 strncpy(reffub
, buffer
, 2);
773 lcd_getstringsize(reffub
, font
, &width
, &height
);
774 cursor
[0][INDEX_X
] = 0;
775 cursor
[0][INDEX_Y
] = prev_line_height
;
776 cursor
[0][INDEX_WIDTH
] = width
;
778 strncpy(reffub
, buffer
+ 3, 2);
780 lcd_getstringsize(reffub
, font
, &width
, &height
);
781 cursor
[1][INDEX_X
] = cursor
[0][INDEX_WIDTH
] + separator_width
;
782 cursor
[1][INDEX_Y
] = prev_line_height
;
783 cursor
[1][INDEX_WIDTH
] = width
;
785 strncpy(reffub
, buffer
+ 6, 2);
787 lcd_getstringsize(reffub
, font
, &width
, &height
);
788 cursor
[2][INDEX_X
] = cursor
[0][INDEX_WIDTH
] + separator_width
+
789 cursor
[1][INDEX_WIDTH
] + separator_width
;
790 cursor
[2][INDEX_Y
] = prev_line_height
;
791 cursor
[2][INDEX_WIDTH
] = width
;
793 lcd_getstringsize(buffer
, font
, &width
, &prev_line_height
);
796 snprintf(buffer
, sizeof(buffer
), "%s 20%02d %s %02d ",
797 dayname
[timedate
[6]],
799 monthname
[timedate
[4] - 1],
801 lcd_puts(0, 2, buffer
);
802 #if defined(LCD_PROPFONTS)
803 /* recalculate the positions and offsets */
804 lcd_getstringsize(buffer
, 0, &width
, &line_height
);
805 strncpy(reffub
, buffer
, 3);
807 lcd_getstringsize(reffub
, 0, &weekday_width
, &height
);
808 lcd_getstringsize(" ", 0, &separator_width
, &height
);
810 strncpy(reffub
, buffer
+ 4, 4);
812 lcd_getstringsize(reffub
, 0, &width
, &height
);
813 cursor
[3][INDEX_X
] = weekday_width
+ separator_width
;
814 cursor
[3][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
+ 1;
815 cursor
[3][INDEX_WIDTH
] = width
;
817 strncpy(reffub
, buffer
+ 9, 3);
819 lcd_getstringsize(reffub
, 0, &width
, &height
);
820 cursor
[4][INDEX_X
] = weekday_width
+ separator_width
+
821 cursor
[3][INDEX_WIDTH
] + separator_width
;
822 cursor
[4][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
+ 1;
823 cursor
[4][INDEX_WIDTH
] = width
;
825 strncpy(reffub
, buffer
+ 13, 2);
827 lcd_getstringsize(reffub
, 0, &width
, &height
);
828 cursor
[5][INDEX_X
] = weekday_width
+ separator_width
+
829 cursor
[3][INDEX_WIDTH
] + separator_width
+
830 cursor
[4][INDEX_WIDTH
] + separator_width
;
831 cursor
[5][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
+ 1;
832 cursor
[5][INDEX_WIDTH
] = width
;
834 lcd_invertrect(cursor
[cursorpos
][INDEX_X
],
835 cursor
[cursorpos
][INDEX_Y
] + lcd_getymargin(),
836 cursor
[cursorpos
][INDEX_WIDTH
],
838 #elif defined(LOADABLE_FONTS)
839 /* recalculate the positions and offsets */
840 lcd_getstringsize(buffer
, font
, &width
, &line_height
);
841 strncpy(reffub
, buffer
, 3);
843 lcd_getstringsize(reffub
, font
, &weekday_width
, &height
);
844 lcd_getstringsize(" ", font
, &separator_width
, &height
);
846 strncpy(reffub
, buffer
+ 4, 4);
848 lcd_getstringsize(reffub
, font
, &width
, &height
);
849 cursor
[3][INDEX_X
] = weekday_width
+ separator_width
;
850 cursor
[3][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
;
851 cursor
[3][INDEX_WIDTH
] = width
;
853 strncpy(reffub
, buffer
+ 9, 3);
855 lcd_getstringsize(reffub
, font
, &width
, &height
);
856 cursor
[4][INDEX_X
] = weekday_width
+ separator_width
+
857 cursor
[3][INDEX_WIDTH
] + separator_width
;
858 cursor
[4][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
;
859 cursor
[4][INDEX_WIDTH
] = width
;
861 strncpy(reffub
, buffer
+ 13, 2);
863 lcd_getstringsize(reffub
, font
, &width
, &height
);
864 cursor
[5][INDEX_X
] = weekday_width
+ separator_width
+
865 cursor
[3][INDEX_WIDTH
] + separator_width
+
866 cursor
[4][INDEX_WIDTH
] + separator_width
;
867 cursor
[5][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
;
868 cursor
[5][INDEX_WIDTH
] = width
;
870 lcd_invertrect(cursor
[cursorpos
][INDEX_X
],
871 cursor
[cursorpos
][INDEX_Y
] + lcd_getymargin(),
872 cursor
[cursorpos
][INDEX_WIDTH
],
875 lcd_invertrect(cursor
[cursorpos
][INDEX_X
],
876 cursor
[cursorpos
][INDEX_Y
] + lcd_getymargin(),
877 cursor
[cursorpos
][INDEX_WIDTH
],
880 lcd_puts(0, 4, "ON to set");
881 lcd_puts(0, 5, "OFF to revert");
882 #ifdef HAVE_LCD_BITMAP
887 /* calculate the minimum and maximum for the number under cursor */
888 if(cursorpos
!=lastcursorpos
) {
889 lastcursorpos
=cursorpos
;
910 steps
= daysinmonth
[timedate
[4] - 1];
915 button
= button_get_w_tmo(HZ
/2);
918 cursorpos
= (cursorpos
+ 6 - 1) % 6;
921 cursorpos
= (cursorpos
+ 6 + 1) % 6;
924 case BUTTON_UP
| BUTTON_REPEAT
:
925 timedate
[cursorpos
] = (timedate
[cursorpos
] + steps
- min
+ 1) % steps
+ min
;
926 if(timedate
[cursorpos
] == 0)
927 timedate
[cursorpos
] += min
;
930 case BUTTON_DOWN
| BUTTON_REPEAT
:
931 timedate
[cursorpos
]=(timedate
[cursorpos
]+steps
- min
- 1) % steps
+ min
;
932 if(timedate
[cursorpos
] == 0)
933 timedate
[cursorpos
] += min
;
937 if (timedate
[6] == 0) /* rtc needs 1 .. 7 */
944 #ifdef HAVE_RECORDER_KEYPAD
946 #ifdef HAVE_LCD_BITMAP
947 global_settings
.statusbar
= !global_settings
.statusbar
;
949 if(global_settings
.statusbar
)
950 lcd_setmargins(0, STATUSBAR_HEIGHT
);
952 lcd_setmargins(0, 0);
954 lcd_puts_scroll(0, 0, string
);