/* 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.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)不去抢亮度——尊重播放器背光(§红线)。 */ void apply_user_brightness(void) { int v = meow_settings_brightness_clamped(); if (v <= 0) v = 60; /* 防御:clamp 后不可能 ≤0,仅兜底 */ write_brightness(v); g_sys.brightness = v; 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"); } }