Files
ViperOS/vpsdk/window.vp
T

108 lines
3.7 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.
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)