嵌入式终端模拟器:单元格网格、ANSI 转义序列解析、滚动缓冲、颜色配置。
Terminal 控件是完整的终端模拟器:
• 单元格网格:Columns × Rows 的字符矩阵
• ANSI 解析:支持 SGR/光标移动/清屏等转义序列
• Scrollback:历史行缓冲区,可配置上限
• 输入回调:用户键入数据通过回调传递给进程
• 颜色主题:16 色 + 前景/背景/光标/选区颜色
| 函数 | 说明 |
|---|---|
int xuiTerminalCreate(xui_context pCtx, xui_widget* ppW, const xui_terminal_desc_t* pDesc) | 创建终端 |
int xuiTerminalWrite(pW, pData, iSize) | 写入二进制数据 |
int xuiTerminalWriteText(pW, sText) | 写入文本 |
int xuiTerminalFlush(pW) | 刷新渲染 |
int xuiTerminalClear(pW) | 清屏 |
int xuiTerminalSetScrollbackLimit(pW, iLimit) | 滚动缓冲行数 |
int xuiTerminalSetFont(pW, pFont) | 等宽字体 |
int xuiTerminalSetMetrics(pW, fCellW, fCellH, fPad) | 单元格尺寸 |
int xuiTerminalSetColors(pW, iBg, iFg, iCursor, ...) | 颜色配置 |
int xuiTerminalResize(pW, iCols, iRows) | 调整尺寸 |
int xuiTerminalSetInputCallback(pW, onData, pUser) | 输入回调 |
gcc -O2 -I. -o ch178.exe ch178_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch178.exe
xui_terminal_desc_t desc = { 0 };
xui_widget pTerm;
xuiTerminalCreate(pCtx, &pTerm, &desc);
// 等宽字体
xuiTerminalSetFont(pTerm, pMonoFont);
// 80×24 标准终端
xuiTerminalResize(pTerm, 80, 24);
// 暗色主题
xuiTerminalSetColors(pTerm,
0x1E1E1EFF, 0xD4D4D4FF, 0x569CD6FF,
0x264F78FF, 0xFFFFFFFF, 0xFFFF00FF,
0x007ACCFF, 0x4FC1FFFF);
// 滚动缓冲 5000 行
xuiTerminalSetScrollbackLimit(pTerm, 5000);
// 写入欢迎信息
xuiTerminalWriteText(pTerm, "XGE Terminal v2.0\r\n");
xuiTerminalFlush(pTerm);
xuiWidgetAddChild(pDock, pTerm);将以下代码保存为 ch178_main.c,编译后运行即可看到一个嵌入式终端模拟器:
#include "xge.h"
#include "xui.h"
static xui_context g_pCtx;
static xui_widget g_pTerm;
static void onTermInput(const char* pData, int iSize, void* pUser) {
(void)pUser;
// 回显用户输入
xuiTerminalWrite(g_pTerm, pData, iSize);
xuiTerminalFlush(g_pTerm);
}
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x1E1E1EFF);
xui_vec2_t pos;
xgeMouseGet(&pos.x, &pos.y);
xuiInputPointerMove(g_pCtx, pos.x, pos.y);
if (xgeMouseDown(XGE_MOUSE_LEFT))
xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
else
xuiInputPointerUp(g_pCtx, pos.x, pos.y, 0);
xuiUpdate(g_pCtx, xgeGetDelta());
xuiLayout(g_pCtx);
xuiRender(g_pCtx, NULL, NULL, 0);
return XGE_OK;
}
int main(void) {
xge_desc_t d = { 0 };
d.iWidth = 800; d.iHeight = 600;
d.sTitle = "ch178 - Terminal";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
xuiCreate(&g_pCtx);
extern const xui_proxy_t tXgeProxy;
xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
xuiSetViewportSize(g_pCtx, 800, 600);
// 创建终端
xui_terminal_desc_t desc = { 0 };
xuiTerminalCreate(g_pCtx, &g_pTerm, &desc);
// 80×24 标准终端
xuiTerminalResize(g_pTerm, 80, 24);
// 暗色主题
xuiTerminalSetColors(g_pTerm,
0x1E1E1EFF, 0xD4D4D4FF, 0x569CD6FF,
0x264F78FF, 0xFFFFFFFF, 0xFFFF00FF,
0x007ACCFF, 0x4FC1FFFF);
// 滚动缓冲 5000 行
xuiTerminalSetScrollbackLimit(g_pTerm, 5000);
// 输入回调
xuiTerminalSetInputCallback(g_pTerm, onTermInput, NULL);
// 写入欢迎信息
xuiTerminalWriteText(g_pTerm, "XGE Terminal v2.0\r\n");
xuiTerminalWriteText(g_pTerm, "Type something...\r\n");
xuiTerminalFlush(g_pTerm);
xui_widget pRoot = xuiGetRootWidget(g_pCtx);
xuiWidgetAddChild(pRoot, g_pTerm);
xuiWidgetSetRect(g_pTerm, (xui_rect_t){0, 0, 800, 600});
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}