108 lines
3.7 KiB
Plaintext
108 lines
3.7 KiB
Plaintext
from . import syscall as syscall
|
||
import vpsdk.stdlib as stdlib
|
||
|
||
|
||
define STYLE_CLASSIC = 0
|
||
define STYLE_WIN10 = 1
|
||
define STYLE_WIN11 = 2
|
||
define STYLE_WIN7 = 3
|
||
define STYLE_WINXP = 4
|
||
|
||
define EVENT_TYPE_NONE = 0
|
||
define EVENT_TYPE_CLICK = 1
|
||
define EVENT_TYPE_HOVER = 2
|
||
define EVENT_TYPE_RELEASE = 3
|
||
define EVENT_TYPE_HOVER_LEAVE = 4
|
||
define EVENT_TYPE_KEY = 5
|
||
define EVENT_TYPE_KEY_RELEASE = 6
|
||
define EVENT_TYPE_PING = 7
|
||
define EVENT_TYPE_RESIZE = 8
|
||
|
||
define KEY_STATE_PRESS = 1
|
||
define KEY_STATE_RELEASE = 2
|
||
define KEY_STATE_REPEAT = 3
|
||
|
||
define CURSOR_DEFAULT = 0
|
||
define CURSOR_IBEAM = 1
|
||
define CURSOR_RESIZE_EW = 2
|
||
define CURSOR_RESIZE_NS = 3
|
||
define CURSOR_RESIZE_NWSE = 4
|
||
|
||
define VK_LEFT = -1
|
||
define VK_RIGHT = -2
|
||
define VK_UP = -3
|
||
define VK_DOWN = -4
|
||
define VK_HOME = -5
|
||
define VK_END = -6
|
||
define VK_DELETE = -7
|
||
define VK_PRIOR = -8
|
||
define VK_NEXT = -9
|
||
|
||
@__attribute__(packed)
|
||
struct InputEvent:
|
||
type: uint32
|
||
win_id: int
|
||
x: int
|
||
y: int
|
||
button: uint8
|
||
_pad0: uint8
|
||
_pad1: uint8
|
||
_pad2: uint8
|
||
|
||
def create_window(x: int, y: int, w: int, h: int, title: const str, style: int) -> int:
|
||
return int(syscall._syscall6(uint64(syscall.CREATE_WINDOW), uint64(x), uint64(y), uint64(w), uint64(h), uint64(title), uint64(style)))
|
||
|
||
def draw_text(win_id: int, x: int, y: int, text: const str, color: uint32) -> int:
|
||
return int(syscall._syscall5(uint64(syscall.DRAW_TEXT), uint64(win_id), uint64(x), uint64(y), uint64(text), uint64(color)))
|
||
|
||
# 每窗口一份**用户态**后备缓冲(stdlib.malloc → MMAP → 0x20000000 用户堆)。
|
||
# 旧实现用 GET_WINBUF 把内核窗口缓冲地址直接交给 app,那片页 U=0 → app 一画就 #PF(err=0x7);
|
||
# 现在 app 画在自己的用户缓冲里,flush(win_id) 交给内核拷进窗口缓冲(WIN_FLUSH(win_id, src))。
|
||
# 注意:这里必须写成**单个字面量** —— `1024*1024*4` 会按最小宽度(i16)做算术而回绕成 0,
|
||
# 让缓冲只有几字节,随后内核 memcpy 240KB 就会越界读(三重故障的根)。4MB。
|
||
define WINBUF_MAX_BYTES = 4194304
|
||
|
||
_winbufs: [64]uint64
|
||
|
||
def get_winbuf(win_id: int) -> uint32*:
|
||
if win_id < 0 or win_id >= 64: return None
|
||
if _winbufs[win_id] == 0:
|
||
p: rawptr = stdlib.malloc(WINBUF_MAX_BYTES)
|
||
if p is None: return None
|
||
_winbufs[win_id] = uint64(p)
|
||
return uint32*(_winbufs[win_id])
|
||
|
||
def get_win_size(win_id: int) -> int:
|
||
return int(syscall._syscall2(uint64(syscall.GET_WIN_SIZE), uint64(win_id), 0))
|
||
|
||
def flush(win_id: int):
|
||
buf: uint32* = get_winbuf(win_id)
|
||
syscall._syscall3(uint64(syscall.WIN_FLUSH), uint64(win_id), uint64(buf))
|
||
|
||
def mainloop(win_id: int):
|
||
syscall._syscall1(uint64(syscall.WAIT_WINDOW), uint64(win_id))
|
||
|
||
def poll_event(evt: InputEvent*) -> int:
|
||
return int(syscall._syscall1(uint64(syscall.POLL_EVENT), uint64(evt)))
|
||
|
||
def is_active(win_id: int) -> int:
|
||
return int(syscall._syscall2(uint64(syscall.WAIT_WINDOW), uint64(win_id), 1))
|
||
|
||
def set_cursor_type(win_id: int, cursor_t: int):
|
||
syscall._syscall2(uint64(syscall.SET_CURSOR), uint64(win_id), uint64(cursor_t))
|
||
|
||
def set_title(win_id: int, title: const str) -> int:
|
||
return int(syscall._syscall2(uint64(syscall.SET_TITLE), uint64(win_id), uint64(title)))
|
||
|
||
def set_geometry(win_id: int, x: int, y: int, w: int, h: int) -> int:
|
||
return int(syscall._syscall5(uint64(syscall.SET_GEOMETRY), uint64(win_id), uint64(x), uint64(y), uint64(w), uint64(h)))
|
||
|
||
def set_resizable(win_id: int, rw: int, rh: int) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.SET_RESIZABLE), uint64(win_id), uint64(rw), uint64(rh)))
|
||
|
||
#class Window:
|
||
# HWND: int
|
||
# def __init__(self):
|
||
# self.HWND = create_window(100, 100, 100, 100)
|
||
|