1use core::mem::MaybeUninit;
2
3pub use kernel_user_link::graphics::{FrameBufferInfo, GraphicsCommand};
4use kernel_user_link::{
5 call_syscall,
6 syscalls::{SyscallError, SYS_GRAPHICS},
7};
8
9pub struct BlitCommand<'a> {
10 pub memory: &'a [u8],
11 pub src_framebuffer_info: FrameBufferInfo,
12 pub src: (usize, usize),
13 pub dst: (usize, usize),
14 pub size: (usize, usize),
15}
16
17impl BlitCommand<'_> {
18 fn is_buffer_valid(&self) -> bool {
19 let buf_expected_len = self.src_framebuffer_info.memory_size();
21 if self.memory.len() != buf_expected_len {
22 return false;
23 }
24
25 if self.src.0 >= self.src_framebuffer_info.width
27 || self.src.1 >= self.src_framebuffer_info.height
28 || self.src.0 + self.size.0 > self.src_framebuffer_info.width
29 || self.src.1 + self.size.1 > self.src_framebuffer_info.height
30 {
31 return false;
32 }
33
34 true
37 }
38}
39
40unsafe fn graphics(command: GraphicsCommand, extra: u64) -> Result<(), SyscallError> {
44 unsafe {
45 call_syscall!(
46 SYS_GRAPHICS,
47 command as u64, extra, )
50 .map(|e| assert!(e == 0))
51 }
52}
53
54pub fn take_ownership() -> Result<(), SyscallError> {
55 unsafe { graphics(GraphicsCommand::TakeOwnership, 0) }
57}
58
59pub fn release_ownership() -> Result<(), SyscallError> {
60 unsafe { graphics(GraphicsCommand::ReleaseOwnership, 0) }
62}
63
64pub fn get_framebuffer_info() -> Result<FrameBufferInfo, SyscallError> {
65 let mut info = MaybeUninit::<FrameBufferInfo>::uninit();
66
67 unsafe {
70 graphics(
71 GraphicsCommand::GetFrameBufferInfo,
72 info.as_mut_ptr() as *const _ as u64,
73 )?;
74 }
75
76 unsafe { Ok(info.assume_init()) }
78}
79
80pub fn blit(command: &BlitCommand<'_>) -> Result<(), SyscallError> {
81 if !command.is_buffer_valid() {
82 return Err(SyscallError::InvalidGraphicsBuffer);
83 }
84
85 let converted_command = kernel_user_link::graphics::BlitCommand {
86 memory: command.memory.as_ptr(),
87 src_framebuffer_info: command.src_framebuffer_info,
88 src: command.src,
89 dst: command.dst,
90 size: command.size,
91 };
92
93 unsafe { graphics(GraphicsCommand::Blit, &converted_command as *const _ as u64) }
96}