Files
MeowOS-SDK/meow_ui_internal.h
T
MeowOS cdaa51a541 perf(sdk): clip_contains 逐像素函数调用→内联 (agent-235, MIPS汇编实证每像素省34指令,修demo滑动卡顿) + invalidate 分支加 clip 窗口收敛 overdraw
meow_ui.a→4ac08c6e; 三App重链已部署; 宿主四套件全PASS+视觉正确性验证; launcher不重链(不含绘制受影响路径,语义等价)
2026-08-31 18:59:54 +08:00

261 lines
17 KiB
C
Raw 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.
/*
* meow_ui_internal.h — SDK 内部各 TU 共享声明(不随 meow_ui.h 发布给应用)。
* 仅供 meow_ui_*.c 之间协作:渲染后端底层能力 + 输入事件队列 + 主题取用。
*/
#ifndef MEOW_UI_INTERNAL_H
#define MEOW_UI_INTERNAL_H
#include <stdint.h>
#include "meow_ui.h"
/* ---- 系统状态喂入(Stage-One 状态栏收敛;meow_ui_sys.c 提供)----
* launcher(系统进程)不跑 SDK 事件循环(无 meow_ui_run),SDK 的 meow_ui_sys_refresh()
* 不会在 launcher 里自动触发;且电量/音量/亮度等权威值本就在 launcher 的 g_sys 快照里
* (launcher 是背光/音量写入方)。故此 API 让 launcher 把权威快照喂进 SDK 的系统状态,
* 喂入即置状态栏 force,下一次 present() 重画顶条。SDK 自身 meow_ui_sys_refresh() 仍按
* 同源兜底(供 App 流程 meow_ui_run 使用)。只填 SDK 快照所需最小字段,与 launcher 的
* meow_sys_state(util.c)字段名交叉映射,二者是不同 TU 的异名类型,故用此
* 专用喂入结构,避免 launcher 引入 meow_ui_sys.h 造成 typedef 重定义。 */
typedef struct meow_ui_feed {
int batt; /* 电量 %,-1 未知 */
int charging; /* 1 充电/满 0 放电 */
int wifi_on; /* 1 网卡 up(射频开) */
int wifi_connected;/* 1 已关联 AP(operstate up);WiFi 图标分档用 */
int wifi_level; /* 信号 dBm(<-1000=未知);≥-60 强 / -75 中 / 更弱弱 */
int bt_seen; /* hci0 节点存在 */
int bt_on; /* 实际上电 */
int vol; /* 音量 0-100 */
int brightness; /* 背光 1-100;<=0 视为未知/屏关不入顶条 */
} meow_ui_feed;
void meow_ui_sys_feed(const meow_ui_feed *f); /* 喂权威快照 + 置 force 重绘顶条 */
/* ---- 系统 UI 模式(「同一个状态栏」闭环,§3.1 / FRAMEWORK_DESIGN §10.2)----
* 状态栏 = 系统级组件,仅系统进程(launcher)渲染。SDK 在 App 进程与 launcher 进程都链接,
* 但顶条/提示线的**渲染**仅当本进程为系统 UI(launcher 置 system_mode=1)才进行;App 进程
* 不渲染(meow_ui_sys_statusbar_active()/meow_ui_statusbar_height() 不受此开关影响 → App 仍
* inset 28、热区可用,只是不画顶条、由 launcher 叠加)。launcher init 后调
* meow_ui_sys_set_system_mode(1);App 保持默认 0。 */
void meow_ui_sys_set_system_mode(int on); /* 1=本进程为系统 UI(渲染顶条/提示线) */
int meow_ui_sys_render_enabled(void); /* 当前进程是否渲染系统顶条 */
/* 把全局状态栏画进本进程 back_buf 顶部 MUI_SBAR_H 行(仅系统进程调用,见 render_enabled)。
* launcher 的 App 前台叠加(launch_app 循环)直接调它 + 标脏顶条上屏。实现见 meow_ui_sys.c。 */
void meow_ui_sys_statusbar_render(void);
/* 收合「上移出屏」过渡渲染:把顶条内容整体上移 yoff 像素并裁顶(y<0 处自然剪裁,meow_font/图标
* blit 已带边界钳制),仅画可见条高 [0, MUI_SBAR_H-yoff) 行(其上为 App 内容、由 launcher 保留)。
* yoff=0 等价 meow_ui_sys_statusbar_render()。实现见 meow_ui_sys.c。 */
void meow_ui_sys_statusbar_render_off(int yoff);
/* ---- 状态栏 MD3 图标簇(meow_ui_sys.c 渲染右侧;位图在 SDK 侧 sb_icons.h)----
* meow_ui_gfx.c 的 meow_gfx_blit_icon(idx,...) 用这些索引查 sb_icons[]。
* 索引值与 launcher sb_icons.h 的 SB_I_* 一一对应(位图同源,勿改序)。 */
#define MEOW_SB_ICON_WIFI 0
#define MEOW_SB_ICON_BT 1
#define MEOW_SB_ICON_BATT 2
#define MEOW_SB_ICON_VOL 3
#define MEOW_SB_ICON_BRIGHT 4
#define MEOW_SB_ICON_WIFI_STRONG 5
#define MEOW_SB_ICON_WIFI_MEDIUM 6
#define MEOW_SB_ICON_WIFI_WEAK 7
#define MEOW_SB_ICON_WIFI_NO 8
#define MEOW_SB_ICON_WIFI_OFF 9
#define MEOW_SB_ICON_BT_NO 10
#define MEOW_SB_ICON_BT_CONN 11
#define MEOW_SB_ICON_BT_DIS 12
#define MEOW_SB_ICON_BT_SEARCH 13
/* 状态栏右下布局常量(与 launcher SB_* 对齐):图标右缘↔文字间隙 / 相邻项间隙 / 图标目标 ink 高 /
* 右簇左缘相对时钟右缘安全间距 / 图标 ink 垂直中心(=状态栏文字中心,28px 栏约 14)。 */
#define MEOW_SB_TGAP 6
#define MEOW_SB_XGAP 10
#define MEOW_SB_ICON_INK 16
#define MEOW_SB_CLK_MARGIN 14
#define MEOW_SB_ICON_CY 14
#define MEOW_SB_ICON_SIZE 32 /* 图标槽宽(= sb_icons.h SB_ICON_SIZE,勿改序) */
/* 把第 idx 个 MD3 图标(sb_icons[])按 ink 等比 blit 进 back_buf;x=槽左缘、ink_h=目标 ink 高
* (0=自然 ink,WiFi 强弱档用)、fg=24bit 前景、cy=ink 垂直中心线。见 meow_ui_gfx.c。 */
void meow_gfx_blit_icon(int idx, int x, int y, int ink_h, uint32_t fg, int cy);
/* ---- 顶级主题风格族(§8.1.2,minimal):状态栏图标集/配色随 ui.style(md3/miuix)----
* meow_ui_theme.c 实现:读 settings.conf 的 ui.style(md3→0 / miuix→1),缓存,随
* meow_theme_reload() 重读。launcher settings 改 ui.style 后经 sb_sdk_refresh→theme_reload
* →本值更新 → 状态栏图标集跟手切。公共版见 meow_ui.h(meow_ui_set_style/meow_ui_style)。 */
int meow_ui_style(void);
/* ---- 主题(meow_ui_theme.c 提供)----
* 重置主题缓存,使下一次 meow_theme_get() 重读 settings.conf(display.theme /
* display.theme_mode / display.theme_dark_start|end)。launcher 在 statusbar 刷新前调用,
* 让 SDK 状态栏(其主题是缓存的)跟手 launcher 侧主题变更,避免「launcher 界面已换肤、
* 状态栏滞留旧主题」。App 无需调用(主题变更本就由 Settings 改 settings.conf,下一个
* set_mode/get 自然读到——缓存仅挡「同会话内 settings 被外部改写」的即时反映)。 */
void meow_theme_reload(void);
/* ---- 渲染后端(meow_ui_gfx.c)提供 ---- */
/* 把 RGBA 像素(stb_image 输出,4 通道 straight alpha)blit 进 back_buf;
* alpha 为全局不透明度 0-255(255 时仍用像素自身 alpha 做逐像素混合)。 */
void meow_gfx_blit_rgba(int x, int y, int w, int h, const uint8_t *rgba, int alpha);
/* 标记一个区域脏(供非标准绘制使用)。 */
void meow_gfx_mark_dirty(int x, int y, int w, int h);
/* flush 挂起(IME/模态阻塞循环用):on=1 期间 meow_ui_flush/flush_region 只记脏不上屏,
* 解除后由调用方一次 flush 原子上屏,避免覆盖层与 App on_tick 重绘同帧两刷频闪。 */
void meow_gfx_flush_hold(int on);
/* M2.78:安装 SIGTERM/SIGINT 退出日志兜底处理器(meow_ui_log.c;meow_ui_init 调用)。 */
void meow_log_install_exit_handler(void);
/* M2.87:安装 SIGUSR1 无害护栏处理器(meow_ui_log.c;meow_ui_init 调用)。
* SDK 框架 App 的左缘返回由 SDK on_swipe 处理,watchdog 对框架 App 不再发 SIGUSR1;
* 此护栏兜底任何漏进的 SIGUSR1(看门狗判定误差/竞态/测试路径):记日志+忽略,绝不杀 App。 */
void meow_ui_install_sigusr1_guard(void);
/* 绘制期裁剪(MEOW_APP_SDK.md §3,2026-08-31):当前 clip 矩形内才写像素,默认全屏。
* meow_widget_draw(w) 画任何控件前 push 该控件矩形、画完 pop——任何控件(含 W_CUSTOM)
* 画不出自身边界,根治自定义画布越界脏区。可嵌套(入栈/出栈,push 与当前 clip 求交)。
* 顶层 clip=全屏,故 IME/模态(snapshot+整帧路径)经 gfx 原语直绘全屏 scrim 时不受裁剪;
* meow_gfx_flush_hold 语义不依赖 clip(flush 只在解除后原子上屏)。 */
void meow_gfx_clip_push(int x, int y, int w, int h);
void meow_gfx_clip_pop(void);
/* 标记整帧脏(launcher 手动脏模型桥接:自绘 raw 像素后标全屏,present 走 SDK)。 */
void meow_gfx_mark_full(void);
/* 清空脏区(含整帧标记)。用于 App 前台叠加路径:meow_ui_statusbar_set_collapsed 会标整帧脏,
* 但 launcher 在 App 上只应 blit 顶条(可见条高),绝不能整帧 blit(会把自身 back_buf 的 stale
* 菜单内容盖到 App 内容上)——叠加前用本函数撤销整帧脏,再按需标局部脏(agent-146)。 */
void meow_gfx_dirty_reset(void);
/* 返回离屏 back_buf 指针(launcher 系统组件与 SDK 共用同一 back_buf 用)。 */
unsigned char *meow_ui_back_buf(void);
/* back_buf 的每行字节数(pitch)与位深(16/32)。M2.71-bug3:模态/IME 快照恢复用。 */
int meow_ui_back_buf_pitch(void);
int meow_ui_back_buf_bpp(void);
/* 实心圆角矩形(控件按钮底色用;公共 §3 只有空心 draw_rect_round)。[D3] */
void meow_gfx_fill_round(int x, int y, int w, int h, int r, uint32_t color);
/* 圆角矩形半透明填充(M2.71-bug4):禁用变暗等状态层用,圆角外不叠色(防灰方块)。 */
void meow_gfx_fill_round_alpha(int x, int y, int w, int h, int r, uint32_t color, int alpha);
/* §5.8.6 batch2:软渲圆形/线段/圆弧环原语(无 GPU、无 -lm,内部整数/查表实现)。
* 供 Radio(外圈/内点)、Badge(红点)、ProgressBar(环形轨道/进度弧)、Checkbox(勾线段)使用。 */
void meow_gfx_fill_circle(int cx, int cy, int r, uint32_t color); /* 实心圆(bbox 距离测试) */
void meow_gfx_line(int x0, int y0, int x1, int y1, int th, uint32_t color); /* 粗线(Bresenham + 圆帽) */
void meow_gfx_ring_arc(int cx, int cy, int r, int th, int start_deg,
int sweep_deg, uint32_t color); /* 圆弧环(查表采样成粗线) */
/* 是否运行于真实 fb 之上(0 = 头less/离屏,qemu/宿主)。 */
int meow_gfx_is_device(void);
/* 中文/日文字库(mfont)是否已加载(状态栏「蓝牙」CJK 与回退 "BT" 二选一)。 */
int meow_gfx_mfont_ready(void);
/* ---- 输入层(meow_ui_input.c)---- */
/* 语义事件:由输入线程解析后压入队列,run/IME 循环弹出。 */
#define MEOW_EV_KEY 1 /* a=keycode, b=1 按下 / 0 抬起 */
#define MEOW_EV_TAP 2 /* a=x, b=y(触摸抬起落点) */
#define MEOW_EV_SWIPE 3 /* a=MEOW_SWIPE_*, b=距离(px) */
#define MEOW_EV_SWIPE_PROGRESS 4 /* a=按下X(t_dx), b=当前X(t_cx);dx=b-a(>0=左缘向内划=返回手势) */
#define MEOW_EV_TOUCH_DOWN 6 /* a=x, b=y:按下后首个有效坐标(拖动起点,M2.71-bug2/6) */
#define MEOW_EV_TOUCH_MOVE 7 /* a=x, b=y:拖动过程坐标变化(坐标变才入队;跟手用) */
#define MEOW_EV_LONG_PRESS 8 /* a=x, b=y:按下 ≥ 阈值未抬手(长按触发;其抬手不再产生 TAP/SWIPE) */
typedef struct meow_input_ev {
uint8_t type;
int a, b;
} meow_input_ev;
/* 启动输入线程(幂等)。无设备时仅空转。 */
void meow_input_start(void);
/* 从队列弹出一个事件;无事件返回 0。 */
int meow_input_pop(meow_input_ev *ev);
/* 注入一条语义事件(宿主验证手势分发/进度条用;设备上无调用方)。 */
void meow_input_inject(int type, int a, int b);
/* 清空队列(IME 打开前丢弃残留触摸,避免误敲)。 */
void meow_input_drain(void);
/* ---- M2.71-bug5:App 活动 → 通知 launcher 重置息屏计时 ----
* launcher 前台 app 会话的 app_last_input 只在物理键边沿重置(它看不到应用内触摸)。SDK 在
* 收到任意交互事件(tap/swipe/拖动/IME/模态)时节流 touch 出 /tmp/meow_app_activity 标记;
* launcher app 循环探测到即 unlink + 重置计时(若已自动息屏则照 key-wake 路径唤醒)。 */
void meow_ui_activity_ping(void);
/* ---- 实时触摸态(供控件绘制按压/按住视觉;输入线程写、app 主线读)----
* 与语义事件队列无关:这些直接读输入线程的触摸状态机当前值,让 meow_widget_draw
* 在「手指按下期间」能如实反映按钮的按下/按住视觉,而无需 app 自行追踪按下。 */
int meow_input_touch_down(void); /* 当前是否有触摸按下 */
int meow_input_touch_x(void); /* 当前 X(无按下=-1) */
int meow_input_touch_y(void); /* 当前 Y(无按下=-1) */
unsigned int meow_input_touch_hold_ms(void); /* 按下已持续毫秒(抬起后 0) */
/* 宿主单测/内部注入:模拟一次按压。down=1 时 x,y 为压点、hold_ms 可指定「已按住时长」
* (把按下时刻回拨),便于测按住态;down=0 复位。设备运行时无调用方。 */
void meow_input_touch_set(int down, int x, int y, unsigned hold_ms);
/* ---- 通用长按(§6.3,2026-08-31)----
* 主循环/宿主调用:检测「按下 ≥ 阈值且位移 ≤ 容忍」的跨越;触发则入队 MEOW_EV_LONG_PRESS
* 并返回 1(幂等:一次按压只触发一次)。供 meow_ui_run 每帧调用与宿主单测模拟时序。 */
int meow_input_long_press_poll(void);
/* 宿主单测/内部注入:模拟一次抬手(真实 touch_release;含长按后抑制 TAP/SWIPE)。设备运行时无调用方。 */
void meow_input_touch_release(void);
/* 宿主单测/内部注入:模拟按下后移动到 (x,y)(保原点、更新当前坐标;位移超长按容忍即取消)。设备运行时无调用方。 */
void meow_input_touch_move(int x, int y);
/* ---- 控件层实时刷新(meow_ui_widget.c)----
* 每帧由 meow_ui_run 调用(主线程):实时触摸按下/释放/按住达阈值时,重绘命中的按钮区
* 并局部上屏,让按压/按住/释放视觉即时反映,无需 app 在 on_tick/on_tap 重绘(agent-119)。
* 仅作用于 SDK 控件按钮(meow_widget_draw 的 W_BTN);app 纯自绘不适用。 */
void meow_widget_touch_refresh(void);
/* ---- App 跨 Activity 全局控件(meow_ui_global.c,§6.1 ②骨架)----
* 渲染帧(meow_ui_gfx present())在 active activity 内容之上、全局状态栏之下调用
* meow_ui_global_render;触摸 TAP 分发先给 meow_ui_global_hit(命中返回 1=消费,
* 否则落到 active activity 页面控件)。跨 Activity 常驻,由 SDK 调度。 */
void meow_ui_global_render(void);
int meow_ui_global_hit(int x, int y);
/* ---- 绘制物注册表(meow_ui_draw.c,§6.2 绘制物注册表/z序/区域重画)----
* 内部协作接口:widget.c 在 create 末尾自动注册、meow_widget_free 自动注销;view.c 在
* meow_view_add_widget/meow_view_free 挂/摘 widget 与 view 的 z 深度源;live_btn 收敛查询
* 是否已注册(已注册→走 invalidate 区域重画,否则回退单控件 flush)。 */
struct meow_view; /* 仅前向声明;完整类型在 meow_ui_view.h */
void meow_draw_widget_register(struct meow_widget *w); /* create 末尾:自动注册(幂等) */
void meow_draw_widget_unregister(struct meow_widget *w); /* meow_widget_free:自动注销 */
int meow_draw_widget_registered(const struct meow_widget *w);/* 是否在注册表(live_btn 收敛用) */
void meow_draw_widget_set_view(struct meow_widget *w, struct meow_view *v); /* 挂 view:重算 auto z */
void meow_draw_view_register(struct meow_view *v); /* view create:注册绘制物(on_draw 用) */
void meow_draw_view_unregister(struct meow_view *v); /* view free:注销 */
int meow_draw_view_entered(const struct meow_view *v); /* view 是否已进入(绘制过滤参考) */
void meow_draw_view_set_z(struct meow_view *v, int z); /* view 显式 z(z<=0=清除回退自动) */
/* 控件布局深度反推(meow_ui_draw.c 用;widget.c 实现,读 struct meow_widget 内部字段)。
* 让绘制注册表在「无 meow_view 时」仍能从 W_LAYOUT children 反推子>父深度。 */
int meow_widget_is_layout(const struct meow_widget *w); /* 1 = W_LAYOUT */
int meow_widget_nchild(const struct meow_widget *w); /* 布局子项数 */
const struct meow_widget *meow_widget_child_at(const struct meow_widget *w, int idx);
/* 控件几何/归属访问器(meow_ui_draw.c 用:绘制物 rect 实时读 + owner 过滤)。 */
int meow_widget_owner(const struct meow_widget *w); /* 创建时绑定的 Activity */
void meow_widget_rect(const struct meow_widget *w, int out[4]); /* x,y,w,h */
/* ---- IME(meow_ui_ime.c)---- */
/* 当前是否显示软键盘。 */
int meow_ime_active(void);
/* 软键盘拦截一次触摸。返回 1=已消费(供 IME 转键/提交),0=未命中(透传给 app)。 */
int meow_ime_handle_tap(int x, int y);
/* 软键盘绘制覆盖层(每次 flush 前调用;覆盖底部约 40%)。 */
void meow_ime_draw(void);
/* 关闭 IME 并交付最终结果(result: 1=确认 0=取消)。 */
void meow_ime_close(int result);
/* 拼音 IME 事件钩子(meow_ui_input.c 主循环 / meow_ui_ime.c 阻塞循环调用,IME 打开时):
* 统一分发 TAP/TOUCH_DOWN/SWIPE/LONG_PRESS 给拼音模式(组合/候选栏翻页/长按清空)。
* 非拼音(ASCII/NUM)模式:TAP 走 meow_ime_handle_tap,其余事件返回 0(沿用既有英文行为,零回归)。
* 返回 1=已消费(调用方 continue),0=透传。 */
int meow_ime_handle_event(const meow_input_ev *e);
/* 当前 IME 是否拼音模式(供 meow_ui_input.c 决定是否喂长按轮询)。 */
int meow_ime_mode_pinyin(void);
#endif /* MEOW_UI_INTERNAL_H */