Files
ViperOS/vpsdk/window.vp
T

125 lines
4.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import t, c
from . import syscall as syscall
import vpsdk.stdlib as stdlib
from stdint import *
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
@c.Attribute(t.attr.packed)
@t.Object
class 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: t.CArray[uint64, 64]
# [临时探针] 窗口缓冲指针形态:高半非 0 即根因现场(定位后删除)
_win_dbg: int = 0
def _dbg_puts(s: const str):
syscall._syscall1(uint64(syscall.SERIAL_PUTS), uint64(s))
def get_winbuf(win_id: int) -> UINT32PTR:
global _win_dbg
if win_id < 0 or win_id >= 64: return None
if _winbufs[win_id] == 0:
p: t.CPtr = stdlib.malloc(WINBUF_MAX_BYTES)
if p is None: return None
_winbufs[win_id] = uint64(p)
if _win_dbg < 4:
_win_dbg = _win_dbg + 1
_dbg_puts("[win] first malloc\n")
# [临时探针] 高半非 0 ⇒ 这里返回的指针就已被污染(上限 12 行)
if (_winbufs[win_id] >> 32) != 0:
if _win_dbg < 12:
_win_dbg = _win_dbg + 1
_dbg_puts("[win] BAD winbuf high half != 0\n")
return t.CPtr(_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: UINT32PTR = 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)