Files
AskaEth 2826c1e905 feat: M6.40批 — 阅读器UI改版(书架list·grid+空态骨架+界面设置+App设置页+header·footer+背景黑默认) + 系统级音量翻页映射 + P1 MD3(select面板28/对话框按钮胶囊) + MeowPanel写端点护栏 + SDK公开仓·文档同步
- reader: app.c/shelf.c/reader.c 全套UI; 新增 reader_conf(reader.conf)/settings(App设置页)/reader_ipc(音量翻页IPC响应); app.json加volume_page
- launcher: keys.c meow_volpage_*门 + util.c app_id→fd映射(HELLO记fd/断开清) + app_launcher.c 前台三处接线(进入sink/按键路径volpage_key/离开clear) → 前台声明volume_page的App音量键→MSG_KEY_PAGEUP/PAGEDOWN翻页(非阅读器前台音量照旧)
- sdk: meow_select.c 底部面板28 + meow_ui_dialog.c 对话框按钮胶囊(h/2) + test_meow_ui_select.c修采样
- meowpanel: /api/net/policy·/api/power/policy 加防自锁+policy默认关两条护栏(panel.policy_enabled默认0)
- 文档: MEOW_APP_SDK.md §12.6 + meowpanel README端点表

0warning;宿主测试全过;二进制留批量批次未入库
2026-09-04 18:13:18 +08:00

118 lines
4.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* app/reader_conf.c — 阅读器 App 私有配置实现(见 app/reader_conf.h)。 */
#include "reader_conf.h"
#include "meow_ui.h" /* meow_config_dir() */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
/* 从 MEOW_DATA_DIR(<TF>/MeowData/<pkg>/data)剥掉尾 "/data",得到 <TF>/MeowData/<pkg>。 */
static void strip_data_suffix(const char *d, char *out, int outsz)
{
if (!d || !d[0]) { strncpy(out, "/tmp", (size_t)outsz - 1); out[outsz - 1] = 0; return; }
size_t n = strlen(d);
const char *suffix = "/data";
size_t sl = strlen(suffix);
size_t keep;
if (n >= sl && strcmp(d + n - sl, suffix) == 0) keep = n - sl;
else keep = n;
if (keep >= (size_t)outsz) keep = (size_t)outsz - 1;
memcpy(out, d, keep);
out[keep] = 0;
}
static void conf_path(char *out, int outsz)
{
const char *data = meow_config_dir();
char base[360];
strip_data_suffix(data ? data : "", base, sizeof base);
if (snprintf(out, (size_t)outsz, "%s/reader.conf", base) >= outsz) out[0] = 0;
/* mkdir -p base */
char tmp[400];
strncpy(tmp, base, sizeof tmp - 1); tmp[sizeof tmp - 1] = 0;
for (char *p = tmp + 1; *p; p++) {
if (*p == '/') { *p = 0; mkdir(tmp, 0755); *p = '/'; }
}
mkdir(tmp, 0755);
}
static void conf_defaults(rdconf *c)
{
c->fs = 20;
c->ls = 130;
strcpy(c->bg, "black"); /* B 定案:默认纯黑 */
strcpy(c->theme, "auto");
strcpy(c->shelf, "list"); /* A 定案:默认 list */
c->header = 1;
c->footer = 1;
c->font[0] = 0;
}
static void clamp_str(char *v, size_t sz)
{
v[sz - 1] = 0;
}
rdconf *rdconf_get(void)
{
static rdconf g;
static int loaded = 0;
if (loaded) return &g;
conf_defaults(&g);
char path[440];
conf_path(path, sizeof path);
FILE *f = path[0] ? fopen(path, "r") : NULL;
if (f) {
char line[512];
while (fgets(line, sizeof line, f)) {
line[strcspn(line, "\r\n")] = 0;
char *eq = strchr(line, '=');
if (!eq) continue;
*eq = 0;
const char *k = line, *v = eq + 1;
if (!strcmp(k, "ui.shelf_layout")) { strncpy(g.shelf, v, sizeof g.shelf - 1); g.shelf[sizeof g.shelf - 1] = 0; }
else if (!strcmp(k, "rd.fs")) { int t = atoi(v); if (t >= 14 && t <= 40) g.fs = t; }
else if (!strcmp(k, "rd.ls")) { int t = atoi(v); if (t >= 100 && t <= 200) g.ls = t; }
else if (!strcmp(k, "rd.bg")) { strncpy(g.bg, v, sizeof g.bg - 1); g.bg[sizeof g.bg - 1] = 0; }
else if (!strcmp(k, "rd.theme")) { strncpy(g.theme, v, sizeof g.theme - 1); g.theme[sizeof g.theme - 1] = 0; }
else if (!strcmp(k, "rd.header")) { g.header = atoi(v) ? 1 : 0; }
else if (!strcmp(k, "rd.footer")) { g.footer = atoi(v) ? 1 : 0; }
else if (!strcmp(k, "rd.font")) { strncpy(g.font, v, sizeof g.font - 1); g.font[sizeof g.font - 1] = 0; }
}
fclose(f);
}
/* 校验合法取值(越界回默认/回退),避免脏档破坏 UI */
if (strcmp(g.shelf, "grid") && strcmp(g.shelf, "list")) strcpy(g.shelf, "list");
if (strcmp(g.bg, "black") && strcmp(g.bg, "white") &&
strcmp(g.bg, "sepia") && strcmp(g.bg, "auto")) strcpy(g.bg, "black");
if (strcmp(g.theme, "light") && strcmp(g.theme, "dark") &&
strcmp(g.theme, "auto")) strcpy(g.theme, "auto");
clamp_str(g.shelf, sizeof g.shelf);
clamp_str(g.bg, sizeof g.bg);
clamp_str(g.theme, sizeof g.theme);
clamp_str(g.font, sizeof g.font);
loaded = 1;
return &g;
}
int rdconf_persist(void)
{
rdconf *c = rdconf_get();
char path[440];
conf_path(path, sizeof path);
if (!path[0]) return -1;
FILE *f = fopen(path, "wb");
if (!f) return -5;
fprintf(f, "ui.shelf_layout=%s\n", c->shelf);
fprintf(f, "rd.fs=%d\n", c->fs);
fprintf(f, "rd.ls=%d\n", c->ls);
fprintf(f, "rd.bg=%s\n", c->bg);
fprintf(f, "rd.theme=%s\n", c->theme);
fprintf(f, "rd.header=%d\n", c->header);
fprintf(f, "rd.footer=%d\n", c->footer);
fprintf(f, "rd.font=%s\n", c->font);
fclose(f);
return 0;
}