drivers/graphics: Introduce UPDATE_CURSOR ioctl
Orbital needs this as we don't implement cursor planes yet.
This commit is contained in:
@@ -349,6 +349,67 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn handle_cursor_update(
|
||||
&mut self,
|
||||
vt: usize,
|
||||
cursor_damage: &graphics_ipc::v2::ipc::UpdateCursor,
|
||||
) -> Result<()> {
|
||||
let vt_state = self.vts.get_mut(&vt).unwrap();
|
||||
|
||||
let Some(cursor_plane) = &mut vt_state.cursor_plane else {
|
||||
// Hardware cursor not supported
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
|
||||
cursor_plane.x = cursor_damage.x;
|
||||
cursor_plane.y = cursor_damage.y;
|
||||
|
||||
if cursor_damage.header == 0 {
|
||||
if vt != self.active_vt {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.adapter.handle_cursor(cursor_plane, false);
|
||||
} else {
|
||||
cursor_plane.hot_x = cursor_damage.hot_x;
|
||||
cursor_plane.hot_y = cursor_damage.hot_y;
|
||||
|
||||
let w: i32 = cursor_damage.width;
|
||||
let h: i32 = cursor_damage.height;
|
||||
let cursor_image = cursor_damage.cursor_img_bytes;
|
||||
let cursor_ptr = self
|
||||
.adapter
|
||||
.map_cursor_framebuffer(&cursor_plane.framebuffer);
|
||||
|
||||
//Clear previous image from backing storage
|
||||
unsafe {
|
||||
core::ptr::write_bytes(cursor_ptr as *mut u8, 0, 64 * 64 * 4);
|
||||
}
|
||||
|
||||
//Write image to backing storage
|
||||
for row in 0..h {
|
||||
let start: usize = (w * row) as usize;
|
||||
let end: usize = (w * row + w) as usize;
|
||||
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
cursor_image[start..end].as_ptr(),
|
||||
cursor_ptr.cast::<u32>().offset(64 * row as isize),
|
||||
w as usize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if vt != self.active_vt {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.adapter.handle_cursor(cursor_plane, true);
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
const MAP_FAKE_OFFSET_MULTIPLIER: usize = 0x10_000_000;
|
||||
@@ -495,6 +556,14 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
) -> Result<usize> {
|
||||
match self.handles.get(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::V1Screen { vt, screen } => {
|
||||
if size_of_val(buf) == std::mem::size_of::<CursorDamage>() {
|
||||
let cursor_damage = unsafe { &*buf.as_ptr().cast::<CursorDamage>() };
|
||||
|
||||
self.handle_cursor_update(*vt, cursor_damage)?;
|
||||
|
||||
return Ok(buf.len());
|
||||
}
|
||||
|
||||
if *vt != self.active_vt {
|
||||
// This is a protection against background VT's spamming us with flush requests. We will
|
||||
// flush the framebuffer on the next VT switch anyway
|
||||
@@ -503,55 +572,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
let vt_state = self.vts.get_mut(vt).unwrap();
|
||||
|
||||
if size_of_val(buf) == std::mem::size_of::<CursorDamage>() {
|
||||
let Some(cursor_plane) = &mut vt_state.cursor_plane else {
|
||||
// Hardware cursor not supported
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
|
||||
let cursor_damage = unsafe { *buf.as_ptr().cast::<CursorDamage>() };
|
||||
|
||||
cursor_plane.x = cursor_damage.x;
|
||||
cursor_plane.y = cursor_damage.y;
|
||||
|
||||
if cursor_damage.header == 0 {
|
||||
self.adapter.handle_cursor(cursor_plane, false);
|
||||
} else {
|
||||
cursor_plane.hot_x = cursor_damage.hot_x;
|
||||
cursor_plane.hot_y = cursor_damage.hot_y;
|
||||
|
||||
let w: i32 = cursor_damage.width;
|
||||
let h: i32 = cursor_damage.height;
|
||||
let cursor_image = cursor_damage.cursor_img_bytes;
|
||||
let cursor_ptr = self
|
||||
.adapter
|
||||
.map_cursor_framebuffer(&cursor_plane.framebuffer);
|
||||
|
||||
//Clear previous image from backing storage
|
||||
unsafe {
|
||||
core::ptr::write_bytes(cursor_ptr as *mut u8, 0, 64 * 64 * 4);
|
||||
}
|
||||
|
||||
//Write image to backing storage
|
||||
for row in 0..h {
|
||||
let start: usize = (w * row) as usize;
|
||||
let end: usize = (w * row + w) as usize;
|
||||
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
cursor_image[start..end].as_ptr(),
|
||||
cursor_ptr.cast::<u32>().offset(64 * row as isize),
|
||||
w as usize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.adapter.handle_cursor(cursor_plane, true);
|
||||
}
|
||||
|
||||
return Ok(buf.len());
|
||||
}
|
||||
|
||||
assert_eq!(buf.len(), std::mem::size_of::<Damage>());
|
||||
let damage = unsafe { *buf.as_ptr().cast::<Damage>() };
|
||||
|
||||
@@ -935,6 +955,20 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
Ok(size_of::<ipc::UpdatePlane>())
|
||||
}
|
||||
ipc::UPDATE_CURSOR => {
|
||||
if payload.len() < size_of::<ipc::UpdateCursor>() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let payload = unsafe {
|
||||
transmute::<&mut [u8; size_of::<ipc::UpdateCursor>()], &mut ipc::UpdateCursor>(
|
||||
payload.as_mut_array().unwrap(),
|
||||
)
|
||||
};
|
||||
let vt = *vt;
|
||||
self.handle_cursor_update(vt, payload)?;
|
||||
|
||||
Ok(size_of::<ipc::UpdateCursor>())
|
||||
}
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,14 +1,2 @@
|
||||
pub use crate::common::Damage;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C, packed)]
|
||||
pub struct CursorDamage {
|
||||
pub header: u32,
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub hot_x: i32,
|
||||
pub hot_y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
pub cursor_img_bytes: [u32; 4096],
|
||||
}
|
||||
pub use crate::v2::ipc::UpdateCursor as CursorDamage;
|
||||
|
||||
@@ -69,11 +69,25 @@ pub mod ipc {
|
||||
pub use redox_ioctl::drm::*;
|
||||
|
||||
// FIXME replace these with proper drm interfaces
|
||||
pub const UPDATE_PLANE: u64 = 6;
|
||||
pub const UPDATE_PLANE: u64 = 0x12345670;
|
||||
#[repr(C, packed)]
|
||||
pub struct UpdatePlane {
|
||||
pub display_id: usize,
|
||||
pub fb_id: u32,
|
||||
pub damage: Damage,
|
||||
}
|
||||
|
||||
pub const UPDATE_CURSOR: u64 = 0x12345671;
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C, packed)]
|
||||
pub struct UpdateCursor {
|
||||
pub header: u32,
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub hot_x: i32,
|
||||
pub hot_y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
pub cursor_img_bytes: [u32; 4096],
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user