146 lines
6.1 KiB
C
146 lines
6.1 KiB
C
/* backlight.c — MeowOS launcher 拆分模块(LAUNCHER_SPLIT_PLAN 拆分)。*/
|
||
/* 本文件由拆分工具从 meow_launcherd.c 按职责搬移;逻辑与原文 0-diff(仅 static 可见性按跨模块需求调整)。*/
|
||
#include "meow_launcher_internal.h"
|
||
|
||
|
||
/* ---- MeowOS 面板自持(M2.6:播放器已死,MeowOS 拥有面板/背光,无拔河)----
|
||
* 电源键按时长三分:单击(短按松开)= 息屏/亮屏;3s=电源菜单;8s=强制关机。
|
||
* 息屏 = 亮度0 + FBIOBLANK(4)(面板下电,同时挂起 goodix 触摸,无误触);
|
||
* 亮屏 = FBIOBLANK(0) + 恢复亮度。 */
|
||
int meow_screen_on = 1;
|
||
|
||
int meow_saved_brightness = 60;
|
||
|
||
int meow_auto_slept = 0; /* M2.17:当前是否「超时自动息屏」置位(手动电源息屏不置位) */
|
||
|
||
|
||
/* brightness save/restore (defined below, used by run_menu) */
|
||
int saved_brightness = -1;
|
||
|
||
/* M2.86:亮度「待补应用」挂起标志。launcher 被 sysui 在 S70 早拉起,早于 /usr/data(UBIFS) 就绪,
|
||
* settings_load 读到的是纯默认值(display.brightness=101→clamp 100);此时 apply_user_brightness
|
||
* 若照写 100 即「开机遇 100 满亮」。修:设置未真正读到盘上时挂起,待 run_menu 轮询 settings_load
|
||
* 成功(meow_settings_loaded()==1)后补应用真实用户亮度。 */
|
||
int meow_brightness_pending = 0;
|
||
|
||
|
||
/* M2.53:MeowOS 主屏接管时把亮度强制压回用户设置值(display.brightness,经
|
||
* meow_settings_brightness_clamped() —— 下限 brightness_min 默认 1、上限 100),
|
||
* 覆盖 HibyOS 播放器写入 sysfs 的背光下限(16/25)。仅应在「MeowOS 真正接管画面」
|
||
* (播放器已死、主屏常驻,即 run_menu 的 had_player==0)时调用;播放器会话期间的
|
||
* 覆盖菜单(had_player==1)不去抢亮度——尊重播放器背光(§红线)。
|
||
* M2.86:设置未读到(meow_settings_loaded()==0,S70 早启动 /usr/data 未就绪)时不盲目写 100 ——
|
||
* 挂起 meow_brightness_pending,待设置就绪后由 settings_load()(run_menu 每 2s 重试)补应用。 */
|
||
void apply_user_brightness(void)
|
||
{
|
||
if (!meow_settings_loaded()) {
|
||
if (!meow_brightness_pending)
|
||
logmsg("apply user brightness: settings unloaded, defer (not forcing 100)");
|
||
meow_brightness_pending = 1;
|
||
return;
|
||
}
|
||
int v = meow_settings_brightness_clamped();
|
||
if (v <= 0) v = 60; /* 防御:clamp 后不可能 ≤0,仅兜底 */
|
||
write_brightness(v);
|
||
g_sys.brightness = v;
|
||
meow_brightness_pending = 0;
|
||
logmsg("apply user brightness (MeowOS takeover) -> %d", v);
|
||
}
|
||
|
||
|
||
/* ---- backlight save/restore ---- */
|
||
int read_brightness(void)
|
||
{
|
||
int fd = open(BACKLIGHT, O_RDONLY);
|
||
if (fd < 0) return -1;
|
||
char buf[16];
|
||
int n = read(fd, buf, sizeof buf - 1);
|
||
close(fd);
|
||
if (n <= 0) return -1;
|
||
buf[n] = 0;
|
||
return atoi(buf);
|
||
}
|
||
|
||
|
||
static void write_file(const char *path, const char *val)
|
||
{
|
||
int fd = open(path, O_WRONLY);
|
||
if (fd < 0) return;
|
||
int l = strlen(val);
|
||
if (write(fd, val, l) < 0)
|
||
logmsg("write %s <- %s: %s", path, val, strerror(errno));
|
||
close(fd);
|
||
}
|
||
|
||
|
||
void write_brightness(int val)
|
||
{
|
||
char buf[8];
|
||
int l = snprintf(buf, sizeof buf, "%d\n", val);
|
||
int fd = open(BACKLIGHT, O_WRONLY);
|
||
if (fd < 0) { logmsg("backlight open fail: %s", strerror(errno)); return; }
|
||
if (write(fd, buf, l) < 0) logmsg("backlight write %d: %s", val, strerror(errno));
|
||
close(fd);
|
||
}
|
||
|
||
|
||
/* Bring the panel up for the menu, but ONLY when it is actually dark:
|
||
* brightness 0 (the player's own screen-off/standby writes brightness 0
|
||
* then FBIOBLANK(4); on this device bl_power stays 0, so brightness==0 is
|
||
* the reliable indicator — keep the bl_power check as a belt-and-suspenders
|
||
* for other states). A normal brightness is left completely untouched so
|
||
* the menu never yanks the brightness up (Bug A).
|
||
*
|
||
* CRITICAL (2026-08-28 hotfix): we NEVER touch FBIOBLANK here — the panel
|
||
* blank state belongs to the player's display state machine. fb_open()
|
||
* already unblanks for the menu (the menu must be visible); forcibly
|
||
* unblanking while the player thinks the screen is blanked leaves the
|
||
* player's state machine inconsistent (it stops drawing, UI freezes —
|
||
* this is the Bug B keeper deadlock, do not reintroduce). */
|
||
void ensure_backlight(void)
|
||
{
|
||
int cur = read_brightness();
|
||
int blp = read_file_int(BACKLIGHT_POWER);
|
||
if (cur > 0 && blp <= 0) {
|
||
logmsg("backlight: screen on (%d), leave untouched", cur);
|
||
return;
|
||
}
|
||
int target = (saved_brightness > 0) ? saved_brightness : 60;
|
||
logmsg("backlight off (cur=%d bl_power=%d) -> %d", cur, blp, target);
|
||
if (cur <= 0) write_brightness(target);
|
||
if (blp > 0) write_file(BACKLIGHT_POWER, "0\n");
|
||
}
|
||
|
||
|
||
/* Restore the backlight after the player resumes (app exit / SIGTERM).
|
||
* Minimal duty after the 2026-08-28 hotfix:
|
||
* - if the menu opened while the player had blanked the panel (screen
|
||
* timeout), re-blank it (brightness 0 + FBIOBLANK(4)) so the physical
|
||
* panel matches the player's display state machine — no frozen frame,
|
||
* and the player still owns the blank state;
|
||
* - otherwise only write brightness back when it reads 0, and never
|
||
* unblank (unblanking behind the player's back wedges its display state
|
||
* machine — see ensure_backlight). A normal brightness is left
|
||
* completely untouched (Bug A: no forced brightness raise). */
|
||
void restore_backlight(void)
|
||
{
|
||
if (menu_opened_blank) {
|
||
logmsg("restore: panel was blanked at menu open, re-blank (0 + FBIOBLANK 4)");
|
||
write_brightness(0);
|
||
int fbfd = open(FB_DEV, O_RDWR);
|
||
if (fbfd >= 0) { ioctl(fbfd, FBIOBLANK, 4); close(fbfd); }
|
||
menu_opened_blank = 0;
|
||
return;
|
||
}
|
||
int cur = read_brightness();
|
||
int blp = read_file_int(BACKLIGHT_POWER);
|
||
if (cur <= 0 || blp > 0) {
|
||
int target = (saved_brightness > 0) ? saved_brightness : 60;
|
||
logmsg("restore backlight (cur=%d bl_power=%d) -> %d (saved=%d)",
|
||
cur, blp, target, saved_brightness);
|
||
if (cur <= 0) write_brightness(target);
|
||
if (blp > 0) write_file(BACKLIGHT_POWER, "0\n");
|
||
}
|
||
}
|
||
|