- 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
112 lines
6.3 KiB
C
112 lines
6.3 KiB
C
/* statusbar.c — MeowOS launcher 拆分模块(LAUNCHER_SPLIT_PLAN 拆分)。*/
|
||
/* 本文件由拆分工具从 meow_launcherd.c 按职责搬移;逻辑与原文 0-diff(仅 static 可见性按跨模块需求调整)。*/
|
||
#include "meow_launcher_internal.h"
|
||
|
||
int g_sb_icon_cy = SB_ICON_CY;
|
||
|
||
|
||
/* 状态栏文字垂直锚 y(行首升线顶):(栏高-行高)/2 把文字垂直居中于 28px 栏;
|
||
* 下限 1 防极端行高(>栏高)时算出负 y 溢出顶端(不越界优先)。 */
|
||
|
||
/* 状态栏 MD3 图标 blit:把 sb_icons.h 的 32x32 单通道 alpha 位图画进状态栏(fb = SDK back_buf)。
|
||
* x = 图标槽左缘(槽宽 SB_ICON_SIZE);fg = 24-bit RGB 前景色(主题 on_surface / on_surface_variant)。
|
||
* M2.46-2 视觉对齐(音量图标小一圈/下边距、图标与文字垂直中心):
|
||
* - 先求该位图 ink 边界(阈值 32,忽略近透明抗锯齿);按 ink 边界在槽内水平居中,并把 ink 垂直
|
||
* 中心对齐到全局 g_sb_icon_cy(==状态栏文字中心),→ 所有图标共用同一光学中线,不再「偏下」。
|
||
* - ink_h>0 时对 ink 做等比缩放(绘制时最近邻采样,源位图不变)到该 ink 高:主图标统一用
|
||
* SB_ICON_INK,音量(volume_up ink 较矮)随之放大到与电量/亮度一致 → 不显「小一圈」。
|
||
* - ink_h==0 保持位图自然 ink 尺寸(仅居中):用于 WiFi 强弱档——较短 ink(少一格)本身即
|
||
* 「信号弱」语义,不可被等比拉大。
|
||
* 像素 = 前景与背景按 alpha 软边混合(a<8 跳过透明;a>=240 直写前景;其余按 a>>4 在 565 空间
|
||
* 插值),与 blit_pm_icon 同构——暗/亮主题下图标随状态栏底色一起换色。 */
|
||
void sb_blit_icon(int icon_idx, int x, uint32_t fg, int ink_h)
|
||
{
|
||
const unsigned char *src = sb_icons[icon_idx].data;
|
||
uint16_t col = rgb565(fg);
|
||
/* 1) ink 边界(含空图兜底) */
|
||
int minx = SB_ICON_SIZE, miny = SB_ICON_SIZE, maxx = -1, maxy = -1;
|
||
for (int i = 0; i < SB_ICON_SIZE * SB_ICON_SIZE; i++) {
|
||
if (src[i] >= 32) {
|
||
int xx = i % SB_ICON_SIZE, yy = i / SB_ICON_SIZE;
|
||
if (xx < minx) minx = xx; if (xx > maxx) maxx = xx;
|
||
if (yy < miny) miny = yy; if (yy > maxy) maxy = yy;
|
||
}
|
||
}
|
||
if (maxx < minx || maxy < miny) { minx = miny = 0; maxx = maxy = SB_ICON_SIZE - 1; }
|
||
int ink_w = maxx - minx + 1, ink_h_n = maxy - miny + 1;
|
||
int t_h = (ink_h > 0) ? ink_h : ink_h_n; /* 目标 ink 高 */
|
||
int t_w = ink_w * t_h / ink_h_n; if (t_w < 1) t_w = 1;
|
||
if (t_w > SB_ICON_SIZE * 2) t_w = SB_ICON_SIZE * 2; /* 防御:等比极端上限 */
|
||
/* 2) 目标框左上:水平居中于 32px 槽;垂直中心 = g_sb_icon_cy */
|
||
int x0 = x + (SB_ICON_SIZE - t_w) / 2;
|
||
int y0 = g_sb_icon_cy - t_h / 2;
|
||
/* 3) 最近邻采样映射:目标 (dx,dy) ← 源 ink (minx+dx*ink_w/t_w, miny+dy*ink_h_n/t_h) */
|
||
for (int dy = 0; dy < t_h; dy++) {
|
||
int ty = y0 + dy;
|
||
if (ty < 0 || ty >= fb_yres) continue;
|
||
int sy = miny + (dy * ink_h_n) / t_h;
|
||
uint16_t *row = (uint16_t *)fb + ty * (fb_line / 2);
|
||
for (int dx = 0; dx < t_w; dx++) {
|
||
int tx = x0 + dx;
|
||
if (tx < 0 || tx >= fb_xres) continue;
|
||
int sx = minx + (dx * ink_w) / t_w;
|
||
int a = src[sy * SB_ICON_SIZE + sx];
|
||
if (a < 8) continue; /* 透明像素跳过 */
|
||
uint16_t bg = row[tx];
|
||
if (a >= 240) { row[tx] = col; continue; }
|
||
int a4 = a >> 4; /* 0..15 */
|
||
int r = ((col >> 11) * a4 + ((bg >> 11) & 0x1F) * (16 - a4)) >> 4;
|
||
int g = (((col >> 5) & 0x3F) * a4 + ((bg >> 5) & 0x3F) * (16 - a4)) >> 4;
|
||
int b = ((col & 0x1F) * a4 + (bg & 0x1F) * (16 - a4)) >> 4;
|
||
row[tx] = (uint16_t)((r << 11) | (g << 5) | b);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/* ---- Stage-One 状态栏收敛:launcher 不再自绘状态栏,统一由 SDK 全局状态栏绘制 ----
|
||
* launcher 系统界面(主界面/设置页/电源菜单/通知中心)顶部 28px 状态栏改由 SDK 的
|
||
* meow_ui_sys_statusbar_render()(present() 时合成,z 最顶)绘制。launcher 侧只保留三个
|
||
* 入口(paint_sb_clock/paint_sb_right/draw_statusbar,调用点遍布主界面/设置页/通知中心/
|
||
* 音量/亮度/主题变更/1s 时钟),其职责从「自绘」改为「把权威状态喂进 SDK + 标脏顶条」。
|
||
* 依据(devdocs/plan/LAUNCHER_SDK_REWRITE.md):
|
||
* - launcher 不跑 SDK 事件循环 → SDK 的 meow_ui_sys_refresh() 不在 launcher 触发,数据
|
||
* 必须由 launcher 喂。g_sys(meow_sys_refresh/light + 事件路径维护)是权威源,尤其
|
||
* 亮度/音量(写入方=launcher)。
|
||
* - SDK 主题是缓存的 → 喂前 meow_theme_reload() 逼重读 settings,状态栏跟手 launcher 换肤。
|
||
* - 标脏顶条 (0,0,xres,28) → present() 时 SDK 重画顶条;SDK 只在「数据变(force)/顶条被触及/
|
||
* 收合过渡」才重画,天然满足「状态栏只在变化时重绘」。 */
|
||
static void sb_sdk_refresh(void)
|
||
{
|
||
meow_theme_reload(); /* SDK 状态栏主题随 launcher 换肤(重读 settings) */
|
||
meow_ui_feed f;
|
||
f.batt = g_sys.batt;
|
||
f.charging = g_sys.charging;
|
||
f.wifi_on = g_sys.wifi_on;
|
||
f.wifi_connected = g_sys.wifi_connected;
|
||
f.wifi_level = g_sys.wifi_level;
|
||
f.bt_seen = g_sys.bt_seen;
|
||
f.bt_on = g_sys.bt_on;
|
||
f.vol = g_sys.vol;
|
||
f.brightness = g_sys.brightness;
|
||
meow_ui_sys_feed(&f); /* 权威快照喂入 + 置 force(顶条必重画) */
|
||
meow_dirty_add(0, SB_BAR_Y, fb_xres, SB_BAR_H); /* 标脏顶条 → present() 时 SDK 重画 */
|
||
}
|
||
|
||
|
||
/* 三个入口(调用点不动):现在驱动 SDK 全局状态栏(唯一绘制者),不再自绘。 */
|
||
void paint_sb_clock(void) { sb_sdk_refresh(); }
|
||
|
||
void paint_sb_right(void) { sb_sdk_refresh(); }
|
||
|
||
|
||
void draw_statusbar(void) { sb_sdk_refresh(); } /* 对齐原语义:整条状态栏 → SDK 绘制 */
|
||
|
||
|
||
/* 上次读到的 App 顶条模式(用于在 launch_app waitpid 循环里判「模式新变 → 立即叠一次」)。
|
||
* 高整文件作用域;每次启动 App 前重置为 -1(强制首帧同步一次)。 */
|
||
int g_sb_mode_last = -1;
|
||
|