Files
ViperOS/Apps/Explorer/main.vp
T
TermiNexus 1633769534 feat(explorer): S3c —— explorer 窗口服务端与合成器(请求环 + 输入 + 逐行合成)
Apps/Explorer/desk_server.vp(新增):窗口槽分配(含 arena 像素缓冲切分与底色预清)、Z 序与焦点、逐脏行合成(背景整行 memcpy → 各窗口按 Z 序只重画落在该行的那一段 → 光标)、请求处理(CREATE/DESTROY/MOVE/RESIZE/FLUSH/ACTIVATE)、事件投递(CREATED/CLOSE/KEY)、输入轮询(读 /dev/input/keyboard 的 ASCII 与 /dev/input/mouse 的按键+x/y,做命中测试、点击聚焦、标题栏右侧关闭按钮发 CLOSE、按住拖动移窗)。

main.vp:fb/desk/输入三者就绪后交给 DeskServer.serve() 主循环;去掉 S2 的渐变条演示(像素通路已由 fb 映射日志与合成器本身证明)。desk.vp:删掉写错且无人使用 的 DESK_MSG_SIZE 常量。

注意:本切片尚未实现标题文字(需用户态字体表)、任务栏、最小化/缩放、窗口侧边框与样式;且此过渡态下内核 desktop 与 explorer 同时在画屏幕,会互相覆盖 —— S3d(app 改走协议)与 S3e(删内核 UI)收口。
2026-10-16 18:56:30 +08:00

79 lines
2.8 KiB
Plaintext

import vpsdk.devfs as devfs
import vpsdk.desk as desk
import vpsdk.process as process
import vpsdk.syscall as syscall
from stdint import *
import viperlib
import desk_server
def _dbg(msg: const str):
syscall._syscall1(uint64(syscall.Syscall.SERIAL_PUTS), uint64(msg))
@__attribute__(section(".text.startup"), aligned(16))
export def _start() -> int:
_dbg("[explorer] start\n")
# 1) 打开 framebuffer 设备,问几何,再映射成线性地址
fb_fd: int = devfs.fb_open()
if fb_fd < 0:
_dbg("[explorer] open /dev/fb0 FAILED\n")
process.exit(1)
return 0
info: devfs.FbInfo = devfs.fb_get_info(fb_fd)
buf: [160]char
viperlib.snprintf(&buf, 160,
"[explorer] fb %ux%u pitch=%u fmt=%u size=%lu phys=0x%lx\n",
info.width, info.height, info.pitch, info.format, info.size, info.phys)
_dbg(&buf)
fb_va: uint64 = devfs.fb_map(fb_fd, info.size)
if fb_va == 0:
_dbg("[explorer] mmap /dev/fb0 FAILED\n")
process.exit(1)
return 0
buf2: [96]char
viperlib.snprintf(&buf2, 96, "[explorer] fb mapped at 0x%lx\n", fb_va)
_dbg(&buf2)
# 2) 屏幕几何/映射地址已打印(上面两行),像素通路由此验证;真正的绘制在服务端。
fb: uint32* = uint32*(fb_va)
# 4) 输入设备可达性:能 open 到就说明 /dev/* 通路已打通
# (真正读事件、接管窗口合成放到 S3 —— 内核桌面此刻还在抢同一个 PS/2 口)。
kfd: int = devfs.kbd_open()
mfd: int = devfs.mouse_open()
buf3: [96]char
viperlib.snprintf(&buf3, 96, "[explorer] input: kbd=%d mouse=%d\n", kfd, mfd)
_dbg(&buf3)
# 5) 挂上 /dev/desk 共享区并格式化 —— explorer 是图形壳,共享区由它初始化,
# app 侧只 desk_ready() 校验。这里先把头打出来证明 IPC 底座可用。
desk_fd: int = devfs.desk_open()
if desk_fd < 0:
_dbg("[explorer] open /dev/desk FAILED\n")
process.exit(1)
return 0
shm: uint64 = devfs.desk_map(desk_fd)
if shm == 0:
_dbg("[explorer] mmap /dev/desk FAILED\n")
process.exit(1)
return 0
desk.desk_format(shm, info.width, info.height, info.pitch)
hdr: desk.DeskHeader* = desk.DeskHeader*(shm + desk.desk_header_off())
buf4: [144]char
viperlib.snprintf(&buf4, 144,
"[explorer] desk shm=0x%lx ready=%d slot=%lu arena=%u\n",
shm, hdr.ready, uint64(desk.desk_slot_size()), hdr.arena_off)
_dbg(&buf4)
# 6) 进入窗口服务端主循环(永不返回):请求环 + 输入 + 合成。
srv: desk_server.DeskServer = desk_server.DeskServer()
srv.init(fb, int(info.width), int(info.height), int(info.pitch), info.format, shm, kfd, mfd)
_dbg("[explorer] desk server running\n")
srv.serve()
return 0