refactor(launcher): 拆分 meow_launcherd.c(9778行)→meow_launcherd/ 多文件(agent-149)

- 14 模块 .c + meow_launcher_internal.h(642): util/font_theme/fb_compositor/settings_page/power_menu/notif_center/app_launcher/main_menu/audio/backlight/net/keys/about/statusbar; meow_launcherd.c 已删
- 按行逐字搬移(0-diff), 118函数提升非static+47组extern(内部头), #if0退役区不编入(源码留.pre_split.bak)
- 关于本机小改: 作者 AskaEth/17 + info/item[13]防越界 + s_dd_modal 超高滚动(clamp/触摸滚动/音量键跟随/裁剪, 仅超高启用)
- build_launcher.sh 编译列表→模块; 文档/注释引用 meow_launcherd.c→模块/目录
- 编译0warning/-Wall -Wextra告警集与原文一致(77条无新增)/qemu-mipsel冒烟一致(--scan/--sysdump); launcher=c0799357(505KB; md5因多文件重编译与原文异,非回归依据)
- 备份 meow_launcherd.c.pre_split.bak/meow_launcherd.pre_split.bak; M2.69(0.7.64)已推卡并用户验证OK
This commit is contained in:
MeowOS committed 2026-08-30 21:38:30 +08:00
1 parent 1481ae00c4
commit e6f0b665e3
33 files changed
+9798 -9804

No files matched your search

+224
View File
@@ -0,0 +1,224 @@
/* audio.c — MeowOS launcher 拆分模块(LAUNCHER_SPLIT_PLAN 拆分)。*/
/* 本文件由拆分工具从 meow_launcherd.c 按职责搬移;逻辑与原文 0-diff(仅 static 可见性按跨模块需求调整)。*/
#include "meow_launcher_internal.h"
static int amixer_vol(int numid)
{
char cmd[96];
snprintf(cmd, sizeof cmd, "amixer -c 0 cget numid=%d 2>/dev/null", numid);
FILE *p = popen(cmd, "r");
if (!p) return -1;
char buf[128];
int v = -1;
while (fgets(buf, sizeof buf, p)) {
/* ": values=N" line — the other "values=1" on the type line is the
* element's value COUNT, not the actual volume */
char *s = strstr(buf, ": values=");
if (s) { v = atoi(s + 9); break; }
}
pclose(p);
return v;
}
static void amixer_set(int numid, int v)
{
if (v < 0) return;
char cmd[96];
snprintf(cmd, sizeof cmd, "amixer -c 0 cset numid=%d %d >/dev/null 2>&1",
numid, v);
system(cmd);
}
struct vol_snap vol_snapshot(void)
{
struct vol_snap s = { amixer_vol(1), amixer_vol(2) };
return s;
}
void vol_restore(struct vol_snap s)
{
logmsg("volume restore -> L=%d R=%d", s.l, s.r);
amixer_set(1, s.l);
amixer_set(2, s.r);
}
int settings_volume = MEOW_VOL_DEFAULT; /* 当前音量 0-100(= 写入 DAC 的映射值) */
int settings_volume_max = MEOW_VOL_MAX_DEFAULT; /* 最大音量上限 clamp */
int settings_volume_step = MEOW_VOL_STEP_DEFAULT; /* 跳步 */
/* M2.17/M2.16:把 meow_settings 当前值同步到本模块的缓存全局。读取方
* (DAC/状态栏/息屏/刷新率调度)统一从缓存取,避免散读 backend。 */
void settings_sync_cache_from_backend(void)
{
int v;
if (meow_settings_get_int("audio.volume", &v) == 0) settings_volume = v;
if (meow_settings_get_int("audio.volume_max", &v) == 0) settings_volume_max = v;
if (meow_settings_get_int("audio.volume_step", &v) == 0) settings_volume_step = v;
if (meow_settings_get_enum("display.refresh_rate", &v) == 0) /* names "60,30,15" */
refresh_rate_cfg = (v == 1) ? 30 : (v == 2) ? 15 : 60;
if (meow_settings_get_bool("display.refresh_always_max", &v) == 0) refresh_always_max = v;
if (meow_settings_get_int("display.screen_off_timeout", &v) == 0) screen_off_timeout = v;
if (meow_settings_get_enum("display.screen_off_mode", &v) == 0) screen_off_mode = v;
if (meow_settings_get_int("power.longpress_menu_ms", &v) == 0) power_longpress_menu_ms = v;
if (meow_settings_get_int("power.forceoff_ms", &v) == 0) power_forceoff_ms = v;
}
/* meow_settings 变更回调:set_*(如音量键)后同步缓存全局,保证既有引用
* settings_volume 等变量的代码与 backend 单点一致(SYSTEM_SETTINGS §3)。 */
void settings_sync_cache_listener(const char *key)
{
if (!strcmp(key, "audio.volume")) { int v; if (meow_settings_get_int("audio.volume", &v) == 0) settings_volume = v; }
else if (!strcmp(key, "audio.volume_max")) { int v; if (meow_settings_get_int("audio.volume_max", &v) == 0) settings_volume_max = v; }
else if (!strcmp(key, "audio.volume_step")) { int v; if (meow_settings_get_int("audio.volume_step", &v) == 0) settings_volume_step = v; }
else if (!strcmp(key, "display.refresh_rate")) { int v; if (meow_settings_get_enum("display.refresh_rate", &v) == 0) refresh_rate_cfg = (v == 1) ? 30 : (v == 2) ? 15 : 60; }
else if (!strcmp(key, "display.refresh_always_max")) { int v; if (meow_settings_get_bool("display.refresh_always_max", &v) == 0) refresh_always_max = v; }
else if (!strcmp(key, "display.screen_off_timeout")) { int v; if (meow_settings_get_int("display.screen_off_timeout", &v) == 0) screen_off_timeout = v; }
else if (!strcmp(key, "display.screen_off_mode")) { int v; if (meow_settings_get_enum("display.screen_off_mode", &v) == 0) screen_off_mode = v; }
else if (!strcmp(key, "power.longpress_menu_ms")) { int v; if (meow_settings_get_int("power.longpress_menu_ms", &v) == 0) power_longpress_menu_ms = v; }
else if (!strcmp(key, "power.forceoff_ms")) { int v; if (meow_settings_get_int("power.forceoff_ms", &v) == 0) power_forceoff_ms = v; }
}
/* 启动加载(M2.11/M2.24):统一由 meow_settings 后端读 settings.conf;
* 此处仅注册监听(一次性)+ 把 backend 当前值同步到缓存全局。重载(应用期
* watchdog 可能改音量)等价于 meow_settings_init() + 手动同步。 */
int settings_cache_registered = 0; /* M2.24:监听只注册一次 */
/* ---- MeowOS 真实 DAC 音量(CS43198,ANALYSIS §18.39)----
* HibyOS 播放器经 ioctl 直写 /dev/snd/controlC0 的 "Left/Right Playback
* Volume"(numid 1/2,0-255)→ codec 驱动 cs43198_vol_*_put → I2C 直写 CS43198
* 寄存器(0x9000-0x9002/0x7000-0x7001,双片 L/R)。我们复刻同路径(amixer
* cset = SNDRV_CTL_IOCTL_ELEM_WRITE),0-100 → 0-255 映射直写两声道。
* 读回不可用(驱动 get 为 dummy 恒 0;/dev/i2c-3 被驱动占用),故 meow_vol_get()
* 返回我们写入的跟踪值(= 真实 DAC 映射值)。 */
void meow_dac_vol_write(int pct)
{
int dac = pct * 255 / 100;
if (dac < 0) dac = 0;
if (dac > 255) dac = 255;
char cmd[160];
snprintf(cmd, sizeof cmd,
"amixer -c 0 cset numid=1 %d >/dev/null 2>&1; amixer -c 0 cset numid=2 %d >/dev/null 2>&1",
dac, dac);
system(cmd);
logmsg("DAC vol -> L/R=%d (pct %d)", dac, pct);
}
static unsigned long long vol_dac_last_ms = 0;
void meow_dac_vol_write_throttled(void)
{
unsigned long long now = now_ms();
if (now - vol_dac_last_ms < VOL_DRAG_DAC_MS) return; /* 节流窗口内跳过,等抬手统一写 */
vol_dac_last_ms = now;
meow_dac_vol_write(settings_volume);
}
/* 抬手/点击提交连 save 时调用:无条件直写一次真实 DAC(绕过节流,保证最终音量落 DAC/落盘)。 */
void meow_dac_vol_flush(void)
{
vol_dac_last_ms = now_ms();
meow_dac_vol_write(settings_volume);
}
/* clamp 集中:0..MEOW_VOL_MAX,再 clamp 到上限 settings_volume_max。 */
int vol_clamp(int v)
{
if (v < 0) v = 0;
if (v > MEOW_VOL_MAX) v = MEOW_VOL_MAX;
if (v > settings_volume_max) v = settings_volume_max;
return v;
}
static void settings_volume_set(int v)
{
v = vol_clamp(v); /* 0..MEOW_VOL_MAX,再 clamp 到上限 */
meow_settings_set_int("audio.volume", v); /* clamp 集中在 backend;listener 同步缓存 */
meow_dac_vol_write(settings_volume); /* 每次变更即直写真实 DAC(CS43198) */
meow_settings_save(); /* 单点变更即落盘 */
}
int settings_volume_get(void) { return settings_volume; }
int vol_ramp_dir = 0; /* +1 上 / -1 下 / 0 停 */
static int vol_ramp_target = -1; /* 目标值;-1=无 */
static unsigned long long vol_ramp_next_at = 0;
static unsigned long long vol_ramp_press_at = 0; /* M2.18 Bug 4:本方向键按下时刻(长按判据) */
static void vol_ramp_begin(int delta)
{
int target = vol_clamp(settings_volume + delta);
if (target == settings_volume) return;
vol_ramp_dir = (target > settings_volume) ? 1 : -1;
vol_ramp_target = target;
vol_ramp_press_at = now_ms(); /* M2.18 Bug 4:记录该方向键按下时刻,供 CLICK_MS 长按判定 */
vol_ramp_next_at = 0; /* 立即迈第一步,给即时反馈 */
}
/* 每主循环 tick 调;key_held=该方向按键是否仍按住(长按续爬)。返回 1=仍在渐变。
* M2.18 Bug 4 语义:单击(<CLICK_MS=400ms) 到 target 即停(只跳 step 格);长按(≥400ms) 才
* 续段连续爬。普通按压力 50-150ms 远大于 VOL_RAMP_MS(15ms),旧逻辑在到 target 后只要
* key_held=1 就续段 → 单击被当成长按,连爬 6~7 格(「点一下跳好几格」)。CLICK_MS 此前只
* 被 kd_tick 状态机使用,vol_ramp 路径从未接上。 */
int vol_ramp_tick(int key_held)
{
if (vol_ramp_dir == 0) return 0;
unsigned long long now = now_ms();
if (now < vol_ramp_next_at) return 1;
vol_ramp_next_at = now + VOL_RAMP_MS;
/* 先看是否已到「当前目标值」(settings_volume 等于 target,而非候选 v)——
* 因为一旦在 target 再取 v=settings_volume+dir 便越过 target,导致 hold_wait 失效继续爬。 */
if (settings_volume == vol_ramp_target) {
if (!key_held) { /* 松开 → 一段完成,结束(单击到 target 即停,只跳 step 格) */
vol_ramp_dir = 0; vol_ramp_target = -1;
meow_settings_save(); return 0;
}
if (now - vol_ramp_press_at < CLICK_MS) {
/* hold_wait:已到 target 但未到长按阈值 → 停在 target 不爬(保持待命不清 dir,
* 等长按激活或松开);若直接续段,长按第一次到 target 就断了。 */
return 1;
}
/* 长按激活:续段(在 target 基础上再 +step) */
vol_ramp_target = vol_clamp(vol_ramp_target + vol_ramp_dir * settings_volume_step);
if (vol_ramp_target == settings_volume) { /* 续段到上限无进展 → 结束 */
vol_ramp_dir = 0; vol_ramp_target = -1;
meow_settings_save(); return 0;
}
}
int v = vol_clamp(settings_volume + vol_ramp_dir);
if (v == settings_volume) { /* 已达上下限 */
vol_ramp_dir = 0; vol_ramp_target = -1;
meow_settings_save(); return 0;
}
meow_settings_set_int("audio.volume", v); /* 更新 backend 内存 + 同步缓存(不逐 1% 落盘) */
meow_dac_vol_write(settings_volume); /* 每 1% 写一次真实 DAC(settings_volume 已同步) */
return 1;
}
/* 步进调节(±settings_volume_step)→ 起线性渐变(1% 爬,见上)。 */
void settings_volume_adj(int delta) { vol_ramp_begin(delta); }
/* MeowOS 音量 API:get 返回当前(= 写入 DAC 的映射值);set 写真实 DAC + 持久化。 */
static void meow_vol_set(int pct) { settings_volume_set(pct); }
static int meow_vol_get(void) { return settings_volume; }