A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare based on Zakk Roberts's work
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "clock.h"
23#include "clock_bitmaps.h"
24#include "clock_draw.h"
25#include "clock_settings.h"
26#include "lib/picture.h"
27
28static int max_skin[]={
29 [ANALOG]=2,
30 [BINARY]=3,
31 [DIGITAL]=2,
32};
33
34enum message{
35 MESSAGE_LOADING,
36 MESSAGE_LOADED,
37 MESSAGE_ERRLOAD,
38 MESSAGE_SAVING,
39 MESSAGE_SAVED,
40 MESSAGE_ERRSAVE
41};
42
43enum settings_file_status{
44 LOADED, ERRLOAD,
45 SAVED, ERRSAVE
46};
47
48struct clock_settings clock_settings;
49bool show_counter;
50
51/* The settings as they exist on the hard disk, so that
52 * we can know at saving time if changes have been made */
53struct clock_settings hdd_clock_settings;
54
55static bool settings_needs_saving(struct clock_settings* settings){
56 return(rb->memcmp(settings, &hdd_clock_settings, sizeof(*settings)));
57}
58
59void clock_settings_reset(struct clock_settings* settings){
60 settings->mode = ANALOG;
61 settings->general.date_format = EUROPEAN;
62 settings->skin[ANALOG] = 1; /* round */
63 settings->skin[DIGITAL] = 1; /* LCD-style */
64 settings->skin[BINARY] = 2; /* LCD-style */
65 for (const char *ptr = rb->str(LANG_VOICED_DATE_FORMAT) ; *ptr; ptr++)
66 {
67 if (*ptr == 'd')
68 break;
69 else if (*ptr == 'Y')
70 {
71 settings->general.date_format = JAPANESE;
72 break;
73 }
74 else if (*ptr == 'A' || *ptr == 'm')
75 {
76 settings->general.date_format = ENGLISH;
77 break;
78 }
79 }
80 settings->general.save_settings = true;
81 settings->general.idle_poweroff=true;
82 settings->general.backlight = ROCKBOX_SETTING;
83
84 settings->analog.show_date = false;
85 settings->analog.show_seconds = true;
86 settings->analog.show_border = true;
87
88 settings->digital.show_seconds = true;
89 settings->digital.blinkcolon = false;
90 apply_backlight_setting(settings->general.backlight);
91}
92
93void apply_backlight_setting(int backlight_setting)
94{
95 if(backlight_setting == ALWAS_OFF)
96 rb->backlight_set_timeout(-1);
97 else if(backlight_setting == ROCKBOX_SETTING)
98 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
99 else if(backlight_setting == ALWAYS_ON)
100 rb->backlight_set_timeout(0);
101}
102
103void clock_settings_skin_next(struct clock_settings* settings){
104 settings->skin[settings->mode]++;
105 if(settings->skin[settings->mode]>=max_skin[settings->mode])
106 settings->skin[settings->mode]=0;
107}
108
109void clock_settings_skin_previous(struct clock_settings* settings){
110 settings->skin[settings->mode]--;
111 if(settings->skin[settings->mode]<0)
112 settings->skin[settings->mode]=max_skin[settings->mode]-1;
113}
114
115static enum settings_file_status clock_settings_load(
116 struct clock_settings* settings,char* filename){
117 int fd = rb->open(filename, O_RDONLY);
118 if(fd >= 0)
119 {
120 /* basic consistency check */
121 if(rb->filesize(fd) != sizeof(*settings))
122 rb->close(fd);
123 else
124 {
125 rb->read(fd, settings, sizeof(*settings));
126 rb->close(fd);
127 apply_backlight_setting(settings->general.backlight);
128 rb->memcpy(&hdd_clock_settings, settings, sizeof(*settings));
129 return(LOADED);
130 }
131 }
132 /* Initializes the settings with default values at least */
133 clock_settings_reset(settings);
134 return(ERRLOAD);
135}
136
137static enum settings_file_status clock_settings_save(
138 struct clock_settings* settings, char* filename){
139 int fd = rb->creat(filename, 0666);
140 if(fd >= 0){ /* does file exist? */
141 rb->write (fd, settings, sizeof(*settings));
142 rb->close(fd);
143 return(SAVED);
144 }
145 return(ERRSAVE);
146}
147
148static void draw_logo(struct screen* display){
149#ifdef HAVE_LCD_COLOR
150 if(display->is_color){
151 display->set_foreground(LCD_BLACK);
152 display->set_background(LCD_RGBPACK(180,200,230));
153 }
154#endif
155
156 const struct picture* logo = &(logos[display->screen_type]);
157 display->clear_display();
158 picture_draw(display, logo, 0, 0);
159}
160
161static void draw_message(struct screen* display, int msg, int y){
162 const struct picture* message = &(messages[display->screen_type]);
163 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
164 display->fillrect(0, display->getheight()-message->slide_height,
165 display->getwidth(), message->slide_height);
166 display->set_drawmode(DRMODE_SOLID);
167 vertical_picture_draw_sprite(display, message, msg,
168 0, display->getheight() -
169 (message->slide_height*y));
170}
171
172void load_settings(void)
173{
174 struct screen* display;
175 enum settings_file_status load_status = LOADED;
176
177 if (rb->file_exists(settings_filename))
178 load_status = clock_settings_load(&clock_settings, settings_filename);
179 else
180 clock_settings_reset(&clock_settings);
181
182 if (load_status != LOADED)
183 {
184 FOR_NB_SCREENS(i)
185 {
186 display = rb->screens[i];
187 display->clear_display();
188 draw_logo(display);
189 draw_message(display, MESSAGE_ERRLOAD, 1);
190 display->update();
191 }
192 rb->sleep(HZ);
193 }
194 rb->storage_sleep();
195}
196
197void save_settings(void)
198{
199 struct screen* display;
200 enum settings_file_status save_status = SAVED;
201
202 if (settings_needs_saving(&clock_settings))
203 save_status = clock_settings_save(&clock_settings, settings_filename);
204
205 if (save_status != SAVED)
206 {
207 FOR_NB_SCREENS(i)
208 {
209 display = rb->screens[i];
210 display->clear_display();
211 draw_logo(display);
212 draw_message(display, MESSAGE_ERRSAVE, 1);
213 display->update();
214 }
215 rb->sleep(HZ);
216 }
217}
218
219void save_settings_wo_gui(void){
220 clock_settings_save(&clock_settings, settings_filename);
221}