ui_net_sink 拆分为协议层与平台后端,新增 RemoDispBus 设计文档
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 模块名称:Simulator Display Port (SDL2 模拟器端口)
|
||||
* 模块功能:为 PC 模拟器提供 LVGL SDL2 显示与键盘输入端口
|
||||
* 适用平台:Windows / Linux / macOS (SDL2)
|
||||
* 说明:替代 MCU 端的 ui_port.c,用于 PC 上 UI 开发与调试
|
||||
*/
|
||||
#include "sim_port.h"
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
/* SDL 驱动头文件(由 lv_conf.h 中 LV_SDL_INCLUDE_PATH 指定) */
|
||||
#define SDL_MAIN_HANDLED
|
||||
#include <SDL.h>
|
||||
|
||||
/* 键盘输入设备句柄(全局,供 main.c SDL 事件循环读取) */
|
||||
static lv_indev_t *g_kbd_indev = NULL;
|
||||
|
||||
/*
|
||||
* 函数功能:初始化 SDL2 显示窗口与键盘输入设备
|
||||
* 入口参数:hor_res - 水平分辨率 int32_t
|
||||
* ver_res - 垂直分辨率 int32_t
|
||||
* 返回值:0 - 成功,-1 - 失败
|
||||
* 限定条件:lv_init() 已调用
|
||||
* 函数说明:1. 创建 SDL 窗口显示设备
|
||||
* 2. 创建键盘输入设备及默认输入组
|
||||
* 3. 不创建鼠标/触摸设备(模拟器仅用键盘导航)
|
||||
*/
|
||||
int sim_port_init(int32_t hor_res, int32_t ver_res)
|
||||
{
|
||||
/* 创建默认输入组 */
|
||||
lv_group_t *g = lv_group_create();
|
||||
if (g == NULL) {
|
||||
return -1;
|
||||
}
|
||||
lv_group_set_default(g);
|
||||
|
||||
/* 创建 SDL 窗口显示设备 */
|
||||
lv_display_t *disp = lv_sdl_window_create(hor_res, ver_res);
|
||||
if (disp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
lv_display_set_default(disp);
|
||||
|
||||
/* 初始化 mono 主题(1bpp 单色屏:白字黑底),并应用默认字体 */
|
||||
#if LV_USE_THEME_MONO
|
||||
lv_theme_t *th = lv_theme_mono_init(disp, true, LV_FONT_DEFAULT);
|
||||
if (th != NULL) {
|
||||
lv_display_set_theme(disp, th);
|
||||
}
|
||||
#endif
|
||||
/* 创建键盘输入设备(方向键/确认/返回 → LVGL keypad) */
|
||||
g_kbd_indev = lv_sdl_keyboard_create();
|
||||
if (g_kbd_indev == NULL) {
|
||||
return -1;
|
||||
}
|
||||
lv_indev_set_group(g_kbd_indev, lv_group_get_default());
|
||||
lv_indev_set_display(g_kbd_indev, disp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:获取 SDL 显示设备句柄
|
||||
* 入口参数:无
|
||||
* 返回值:显示设备指针 lv_display_t * 可能为 NULL
|
||||
* 限定条件:sim_port_init() 已成功调用
|
||||
*/
|
||||
void *sim_port_get_display(void)
|
||||
{
|
||||
return (void *)lv_display_get_default();
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:读取当前屏幕内容并转换为 1bpp 单色位图(MSB-first)
|
||||
* 入口参数:buf - 输出缓冲(调用方分配,≥ 宽*高/8 字节)
|
||||
* buf_size - buf 容量(字节)
|
||||
* 返回值:0 - 成功,-1 - 失败
|
||||
* 限定条件:sim_port_init() 已成功;须在 SDL 所属线程(主循环线程)调用
|
||||
* 函数说明:1. lv_sdl_window_get_renderer 取 SDL 渲染器
|
||||
* 2. SDL_RenderReadPixels 读回屏幕实际呈现的 ARGB8888 像素
|
||||
* 3. 按红通道阈值 128 判白(=1/墨)/黑(=0),逐行打包为 1bpp MSB-first
|
||||
* 窗口模式为 I1+PARTIAL,LVGL 显示缓冲系分块且经 I1→ARGB8888
|
||||
* 转换,直接读 get_buf_active 不可靠;读回屏幕呈现像素最稳,
|
||||
* 且完全避开快照离屏重渲染(SDL 驱动下会卡派发循环)
|
||||
*/
|
||||
int sim_port_get_screen_mono(uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
lv_display_t *disp = lv_display_get_default();
|
||||
if (disp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t w = lv_display_get_horizontal_resolution(disp);
|
||||
int32_t h = lv_display_get_vertical_resolution(disp);
|
||||
if (w <= 0 || h <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t stride = (uint32_t)(w + 7) / 8u;
|
||||
uint32_t need = stride * (uint32_t)h;
|
||||
if (buf_size < need) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_Renderer *renderer = (SDL_Renderer *)lv_sdl_window_get_renderer(disp);
|
||||
if (renderer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 读回屏幕实际呈现的像素(ARGB8888,4 字节/像素) */
|
||||
uint32_t pitch = (uint32_t)w * 4u;
|
||||
uint8_t *px = (uint8_t *)SDL_malloc((size_t)w * (size_t)h * 4u);
|
||||
if (px == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ARGB8888, px, (int)pitch);
|
||||
if (rc != 0) {
|
||||
SDL_free(px);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 先清零(黑像素=0),ARGB8888 内存序 [B,G,R,A],红通道在偏移 2 */
|
||||
lv_memset(buf, 0, need);
|
||||
for (int32_t y = 0; y < h; y++) {
|
||||
const uint8_t *row = px + (size_t)y * (size_t)pitch;
|
||||
uint8_t *out = buf + (size_t)y * (size_t)stride;
|
||||
for (int32_t x = 0; x < w; x++) {
|
||||
if (row[(size_t)x * 4u + 2u] >= 128u) {
|
||||
out[(uint32_t)x >> 3] |= (uint8_t)(0x80u >> (x & 7));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(px);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user