159 lines
6.7 KiB
C
159 lines
6.7 KiB
C
/* test_sdk_fixes.c — M2.71 修复项宿主验证(离屏 480x720,16bpp)。
|
||
* 覆盖:
|
||
* bug4 disabled 按钮圆角外无灰方块(角点 = 页面背景而非叠暗);
|
||
* bug1 圆形进度环带确实画到 = 半径+thk/2 处(bbox 与真实像素一致,漏刷修复的几何前提);
|
||
* bug3 modal(Dialog)open→cancel 后背景还原(scrim 不累积/无残影);
|
||
* bug7 IME 回显实时同步(on_change 随键入触发)+ 关闭后键盘区背景还原。
|
||
*
|
||
* 编译(宿主 gcc,链真实 gfx/sys/theme/vol/log/widget/input/activity/dialog/ime + 打桩 font/global):
|
||
* gcc -Wall -o test_sdk_fixes test_sdk_fixes.c test_host_stub.c \
|
||
* meow_ui_gfx.c meow_ui_sys.c meow_ui_theme.c meow_ui_vol.c meow_ui_log.c \
|
||
* meow_ui_widget.c meow_ui_input.c meow_ui_activity.c meow_ui_dialog.c meow_ui_ime.c \
|
||
* -I. -I../meow_launcherd -DMEOW_UI_HOST_TEST -pthread
|
||
*/
|
||
#include "meow_ui.h"
|
||
#include "meow_ui_internal.h"
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <assert.h>
|
||
#include <unistd.h>
|
||
#include <pthread.h>
|
||
|
||
static void rd_px(int x, int y, int *r, int *g, int *b)
|
||
{
|
||
unsigned char *bb = meow_ui_back_buf();
|
||
int line = meow_ui_back_buf_pitch(), bpp = meow_ui_back_buf_bpp();
|
||
assert(bb && line > 0);
|
||
if (bpp == 16) {
|
||
uint16_t px = *(uint16_t *)(bb + (size_t)y * line + (size_t)x * 2);
|
||
*r = (((px >> 11) & 0x1F) << 3) | ((px >> 11) & 0x1F) >> 2;
|
||
*g = (((px >> 5) & 0x3F) << 2) | ((px >> 5) & 0x3F) >> 4;
|
||
*b = ((px & 0x1F) << 3) | ((px & 0x1F) >> 2);
|
||
} else {
|
||
uint32_t px = *(uint32_t *)(bb + (size_t)y * line + (size_t)x * 4);
|
||
*r = (px >> 16) & 0xFF; *g = (px >> 8) & 0xFF; *b = px & 0xFF;
|
||
}
|
||
}
|
||
static int near(int a, int b) { int d = a - b; if (d < 0) d = -d; return d <= 12; }
|
||
|
||
/* ---- 为阻塞模态/IME 在后台注入事件 ---- */
|
||
static int g_inj_tap_x = 0, g_inj_tap_y = 0, g_inj_delay = 0;
|
||
static void *inject_thread(void *arg)
|
||
{
|
||
(void)arg;
|
||
usleep((useconds_t)g_inj_delay);
|
||
meow_input_inject(MEOW_EV_TAP, g_inj_tap_x, g_inj_tap_y);
|
||
return NULL;
|
||
}
|
||
static void inject_after(int ms, int x, int y)
|
||
{
|
||
pthread_t th; g_inj_tap_x = x; g_inj_tap_y = y; g_inj_delay = ms;
|
||
pthread_create(&th, NULL, inject_thread, NULL);
|
||
pthread_detach(th);
|
||
}
|
||
|
||
static void test_disabled_corner(void)
|
||
{
|
||
const meow_theme *th = meow_theme_get();
|
||
meow_ui_clear(th->bg);
|
||
meow_widget *b = meow_btn_create(100, 100, 200, 60, "DISABLED");
|
||
meow_widget_set_enabled(b, 0); /* 禁用:old 用方形 α 盖整 bbox → 圆角外露灰 */
|
||
meow_widget_draw(b);
|
||
meow_ui_flush();
|
||
int r, g, bb;
|
||
rd_px(100, 100, &r, &g, &bb); /* bbox 左上角(圆角外):应为页面背景 */
|
||
printf("[bug4] disabled corner rgb=%02X%02X%02X (bg=%02X%02X%02X) ",
|
||
r, g, bb, (th->bg >> 16) & 0xFF, (th->bg >> 8) & 0xFF, th->bg & 0xFF);
|
||
assert(near(r, (th->bg >> 16) & 0xFF) && near(g, (th->bg >> 8) & 0xFF) && near(bb, th->bg & 0xFF));
|
||
printf("PASS\n");
|
||
meow_widget_free(b);
|
||
}
|
||
|
||
static void test_circular_extent(void)
|
||
{
|
||
const meow_theme *th = meow_theme_get();
|
||
meow_ui_clear(th->bg);
|
||
/* r=30, thk=4 → 环外缘 = r+thk/2 = 32;create 几何外接框 = 中心±(r+margin)=±33 */
|
||
int cx = 240, cy = 200, r = 30;
|
||
meow_widget *pg = meow_progress_circular_create(cx, cy, r, 100);
|
||
meow_widget_draw(pg);
|
||
meow_ui_flush();
|
||
int rd, g, b;
|
||
rd_px(cx - 32, cy, &rd, &g, &b); /* 最左环外缘:应被画(非背景) */
|
||
int bg_r = (th->bg >> 16) & 0xFF, bg_g = (th->bg >> 8) & 0xFF, bg_b = th->bg & 0xFF;
|
||
printf("[bug1] ring-left-extent rgb=%02X%02X%02X bg=%02X%02X%02X ", rd, g, b, bg_r, bg_g, bg_b);
|
||
assert(!(near(rd, bg_r) && near(g, bg_g) && near(b, bg_b))); /* 环带已画到外缘 */
|
||
printf("PASS\n"); fflush(stdout);
|
||
meow_widget_free(pg);
|
||
}
|
||
|
||
static void test_modal_restore(void)
|
||
{
|
||
const meow_theme *th = meow_theme_get();
|
||
meow_ui_clear(th->bg);
|
||
meow_ui_flush();
|
||
meow_dialog *d = meow_dialog_create(MEOW_DLG_CONFIRM, "Sure?");
|
||
/* 两次 open→cancel:背景应两次均还原(scrim 不累积、无残影) */
|
||
for (int i = 0; i < 2; i++) {
|
||
inject_after(30, 1, 1); /* (1,1) 在居中卡片外 → 取消 */
|
||
meow_dialog_show(d);
|
||
int r, g, b;
|
||
rd_px(400, 100, &r, &g, &b); /* 卡片外右上:应 == 背景 */
|
||
printf("[bug3] open%d cancel bg rgb=%02X%02X%02X bg=%02X%02X%02X ", i, r, g, b,
|
||
(th->bg >> 16) & 0xFF, (th->bg >> 8) & 0xFF, th->bg & 0xFF);
|
||
assert(near(r, (th->bg >> 16) & 0xFF) && near(g, (th->bg >> 8) & 0xFF) && near(b, th->bg & 0xFF));
|
||
}
|
||
printf("PASS\n");
|
||
meow_dialog_free(d);
|
||
}
|
||
|
||
/* IME 回显同步回调 */
|
||
static char g_echo[64] = "";
|
||
static void ime_cb(const char *t, void *ctx) { (void)ctx; snprintf(g_echo, sizeof g_echo, "%s", t); }
|
||
|
||
static void test_ime_echo_and_restore(void)
|
||
{
|
||
const meow_theme *th = meow_theme_get();
|
||
meow_ui_clear(th->bg);
|
||
meow_ui_flush();
|
||
meow_ime_ctx c; memset(&c, 0, sizeof c);
|
||
c.mode = MEOW_IME_ASCII; c.maxlen = 32; c.on_change = ime_cb;
|
||
/* --- 异步:验『回显/输入框实时同步(on_change 随键入触发)』--- */
|
||
meow_ui_text_input_async(&c);
|
||
assert(meow_ime_active() == 1);
|
||
meow_input_inject(MEOW_EV_TAP, 20, 580); /* ASCII 第3行第1键 = 'A'(shift 关 → 缓冲 'A') */
|
||
meow_ime_handle_tap(20, 580);
|
||
assert(strcmp(g_echo, "A") == 0 && strcmp(meow_ime_text(), "A") == 0);
|
||
printf("[bug7] ime echo live-sync after 'A' -> \"%s\" (on_change fired) PASS\n", g_echo); fflush(stdout);
|
||
meow_input_inject(MEOW_EV_TAP, 20, 680); /* ESC(X) → 取消 */
|
||
meow_ime_handle_tap(20, 680);
|
||
assert(meow_ime_active() == 0);
|
||
/* --- 阻塞:验『关闭后键盘区背景还原』--- */
|
||
meow_ui_clear(th->bg);
|
||
meow_ui_flush();
|
||
inject_after(30, 20, 680); /* ESC 关闭 */
|
||
int rc = meow_ui_text_input(&c);
|
||
assert(rc == 0); /* 取消 */
|
||
int r, g, b;
|
||
rd_px(240, 600, &r, &g, &b); /* 键盘区内一点:应 == 背景 */
|
||
printf("[bug7] ime close restore px rgb=%02X%02X%02X bg=%02X%02X%02X ", r, g, b,
|
||
(th->bg >> 16) & 0xFF, (th->bg >> 8) & 0xFF, th->bg & 0xFF);
|
||
assert(near(r, (th->bg >> 16) & 0xFF) && near(g, (th->bg >> 8) & 0xFF) && near(b, th->bg & 0xFF));
|
||
printf("PASS\n");
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
setenv("MEOW_UI_DUMP", "/tmp/fixes.ppm", 1);
|
||
meow_ui_opts o = { 480, 720 };
|
||
assert(meow_ui_init(&o) == 0);
|
||
test_disabled_corner();
|
||
test_circular_extent();
|
||
test_modal_restore();
|
||
test_ime_echo_and_restore();
|
||
meow_ui_shutdown();
|
||
printf("ALL PASS\n");
|
||
return 0;
|
||
}
|