/* * meow_ui_internal.h — SDK 内部各 TU 共享声明(不随 meow_ui.h 发布给应用)。 * 仅供 meow_ui_*.c 之间协作:渲染后端底层能力 + 输入事件队列 + 主题取用。 */ #ifndef MEOW_UI_INTERNAL_H #define MEOW_UI_INTERNAL_H #include #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 #define MEOW_SB_ICON_BATT_CHG 14 /* 状态栏右下布局常量(与 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); /* §10.5 叠加让位:present 因 /tmp/meow_notif_active 存在而被自抑的累计次数 * (仅 App 进程会自抑;宿主单测断言用,设备上无调用方)。 */ unsigned long long meow_gfx_overlay_suppressed_count(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 */