-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy pathmsettings.c
166 lines (145 loc) · 3.95 KB
/
msettings.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <string.h>
#include "msettings.h"
///////////////////////////////////////
#define SETTINGS_VERSION 1
typedef struct Settings {
int version; // future proofing
int brightness;
int headphones;
int speaker;
int unused[2]; // for future use
// NOTE: doesn't really need to be persisted but still needs to be shared
int jack;
int hdmi;
} Settings;
static Settings DefaultSettings = {
.version = SETTINGS_VERSION,
.brightness = 2,
.headphones = 4,
.speaker = 8,
.jack = 0,
.hdmi = 0,
};
static Settings* settings;
#define SHM_KEY "/SharedSettings"
static char SettingsPath[256];
static int shm_fd = -1;
static int is_host = 0;
static int shm_size = sizeof(Settings);
void InitSettings(void) {
sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH"));
shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists
if (shm_fd==-1 && errno==EEXIST) { // already exists
puts("Settings client");
shm_fd = shm_open(SHM_KEY, O_RDWR, 0644);
settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
}
else { // host
puts("Settings host"); // should always be keymon
is_host = 1;
// we created it so set initial size and populate
ftruncate(shm_fd, shm_size);
settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
int fd = open(SettingsPath, O_RDONLY);
if (fd>=0) {
read(fd, settings, shm_size);
// TODO: use settings->version for future proofing?
close(fd);
}
else {
// load defaults
memcpy(settings, &DefaultSettings, shm_size);
}
// these shouldn't be persisted
// settings->jack = 0;
// settings->hdmi = 0;
}
printf("brightness: %i \nspeaker: %i\n", settings->brightness, settings->speaker); fflush(stdout);
SetVolume(GetVolume());
SetBrightness(GetBrightness());
// system("echo $(< " BRIGHTNESS_PATH ")");
}
void QuitSettings(void) {
munmap(settings, shm_size);
if (is_host) shm_unlink(SHM_KEY);
}
static inline void SaveSettings(void) {
int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644);
if (fd>=0) {
write(fd, settings, shm_size);
close(fd);
sync();
}
}
int GetBrightness(void) { // 0-10
return settings->brightness;
}
void SetBrightness(int value) {
if (settings->hdmi) return;
int raw;
switch (value) {
// TODO: redo
case 0: raw = 4; break;
case 1: raw = 28; break;
case 2: raw = 52; break;
case 3: raw = 76; break;
case 4: raw = 100; break;
case 5: raw = 124; break;
case 6: raw = 148; break;
case 7: raw = 172; break;
case 8: raw = 196; break;
case 9: raw = 220; break;
case 10: raw = 255; break;
}
SetRawBrightness(raw);
settings->brightness = value;
SaveSettings();
}
int GetVolume(void) { // 0-20
return settings->jack ? settings->headphones : settings->speaker;
}
void SetVolume(int value) {
if (settings->hdmi) return;
if (settings->jack) settings->headphones = value;
else settings->speaker = value;
int raw = value * 5;
if (raw>0) raw = 50 + (raw / 2); // v10 is quiet by default?
SetRawVolume(raw);
SaveSettings();
}
#define BRIGHTNESS_PATH "/sys/devices/platform/backlight/backlight/backlight/brightness"
void SetRawBrightness(int val) { // 0 - 255
if (settings->hdmi) return;
printf("SetRawBrightness(%i)\n", val); fflush(stdout);
// return;
char cmd[256];
sprintf(cmd, "echo %i > " BRIGHTNESS_PATH, val);
system(cmd);
}
void SetRawVolume(int val) { // 0 - 100
printf("SetRawVolume(%i)\n", val); fflush(stdout);
// return;
char cmd[256];
sprintf(cmd, "amixer -q sset 'Playback' %i%% > /dev/null 2>&1", val);
system(cmd);
}
// monitored and set by thread in keymon?
int GetJack(void) {
return settings->jack;
}
void SetJack(int value) {
settings->jack = value;
SetVolume(GetVolume());
}
int GetHDMI(void) { return 0; }
void SetHDMI(int value) { /* buh */ }