diff --git a/Cargo.lock b/Cargo.lock index 29af2ad0a1..42bed02ac7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,6 +417,14 @@ dependencies = [ "rand_core", ] +[[package]] +name = "redox-ioctl" +version = "0.1.0" +dependencies = [ + "drm-sys", + "redox_syscall", +] + [[package]] name = "redox-path" version = "0.3.1" @@ -465,7 +473,6 @@ dependencies = [ "chrono", "chrono-tz", "dlmalloc", - "drm-sys", "generic-rt", "libc", "libm", @@ -478,6 +485,7 @@ dependencies = [ "rand", "rand_jitter", "rand_xorshift", + "redox-ioctl", "redox-path", "redox-rt", "redox_event", diff --git a/Cargo.toml b/Cargo.toml index 29550d0ddf..c5191f508e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,13 +62,13 @@ features = ["c_api"] sc = "0.2.7" [target.'cfg(target_os = "redox")'.dependencies] -drm-sys = "0.8.0" redox_syscall = "0.5.13" redox-rt = { path = "redox-rt" } redox-path = "0.3" redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git", default-features = false, features = [ "redox_syscall", ] } +redox-ioctl = { path = "redox-ioctl" } [features] default = ["check_against_libc_crate"] diff --git a/redox-ioctl/Cargo.toml b/redox-ioctl/Cargo.toml new file mode 100644 index 0000000000..1096248d3a --- /dev/null +++ b/redox-ioctl/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "redox-ioctl" +authors = ["bjorn3 "] +version = "0.1.0" +edition = "2024" +license = "MIT" +description = "Ioctl definitions and (de)serialization for Redox" + +[dependencies] +drm-sys = "0.8.0" +redox_syscall = "0.5.8" + +[features] diff --git a/redox-ioctl/src/drm.rs b/redox-ioctl/src/drm.rs new file mode 100644 index 0000000000..edab1d5424 --- /dev/null +++ b/redox-ioctl/src/drm.rs @@ -0,0 +1,172 @@ +use alloc::vec::Vec; +use core::{ + cmp, + ffi::{c_char, c_int}, + iter, mem, slice, +}; + +pub use drm_sys::{ + __kernel_size_t, drm_get_cap, drm_mode_card_res, drm_mode_crtc, drm_mode_fb_cmd, + drm_mode_fb_cmd2, drm_mode_get_connector, drm_mode_get_encoder, drm_mode_get_plane, + drm_mode_get_plane_res, drm_mode_modeinfo, drm_mode_obj_get_properties, drm_set_client_cap, + drm_version, +}; + +pub const VERSION: u64 = 0; +define_ioctl_data! { + struct drm_version, DrmVersion { + version_major: c_int, + version_minor: c_int, + version_patchlevel: c_int, + name_len: __kernel_size_t, + name: *mut c_char [array], + date_len: __kernel_size_t, + date: *mut c_char [array], + desc_len: __kernel_size_t, + desc: *mut c_char [array], + } +} + +pub const GET_CAP: u64 = 0x0C; +pub use drm_sys::DRM_CAP_DUMB_BUFFER; +define_ioctl_data! { + struct drm_get_cap, DrmGetCap { + capability: u64, + value: u64, + } +} + +pub const SET_CLIENT_CAP: u64 = 0x0D; +pub use drm_sys::DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT; +define_ioctl_data! { + struct drm_set_client_cap, DrmSetClientCap { + capability: u64, + value: u64, + } +} + +pub const MODE_CARD_RES: u64 = 0xA0; +define_ioctl_data! { + struct drm_mode_card_res, DrmModeCardRes { + fb_id_ptr: u64 [array], + crtc_id_ptr: u64 [array], + connector_id_ptr: u64 [array], + encoder_id_ptr: u64 [array], + count_fbs: u32, + count_crtcs: u32, + count_connectors: u32, + count_encoders: u32, + min_width: u32, + max_width: u32, + min_height: u32, + max_height: u32, + } +} + +pub const MODE_GET_CRTC: u64 = 0xA1; +define_ioctl_data! { + struct drm_mode_crtc, DrmModeCrtc { + set_connectors_ptr: u64, + count_connectors: u32, + crtc_id: u32, + fb_id: u32, + x: u32, + y: u32, + gamma_size: u32, + mode_valid: u32, + mode: drm_mode_modeinfo, + } +} + +pub const MODE_GET_ENCODER: u64 = 0xA6; +define_ioctl_data! { + struct drm_mode_get_encoder, DrmModeGetEncoder { + encoder_id: u32, + encoder_type: u32, + crtc_id: u32, + possible_crtcs: u32, + possible_clones: u32, + } +} + +pub const MODE_GET_CONNECTOR: u64 = 0xA7; +define_ioctl_data! { + struct drm_mode_get_connector, DrmModeGetConnector { + encoders_ptr: u64 [array], + modes_ptr: u64 [array], + props_ptr: u64 [array], + prop_values_ptr: u64 [array], + count_modes: u32, + count_props: u32, + count_encoders: u32, + encoder_id: u32, + connector_id: u32, + connector_type: u32, + connector_type_id: u32, + connection: u32, + mm_width: u32, + mm_height: u32, + subpixel: u32, + pad: u32, + } +} + +pub const MODE_GET_FB: u64 = 0xAD; +define_ioctl_data! { + struct drm_mode_fb_cmd, DrmModeFbCmd { + fb_id: u32, + width: u32, + height: u32, + pitch: u32, + bpp: u32, + depth: u32, + handle: u32, + } +} + +pub const MODE_GET_PLANE_RES: u64 = 0xB5; +define_ioctl_data! { + struct drm_mode_get_plane_res, DrmModeGetPlaneRes { + plane_id_ptr: u64 [array], + count_planes: u32, + } +} + +pub const MODE_GET_PLANE: u64 = 0xB6; +define_ioctl_data! { + struct drm_mode_get_plane, DrmModeGetPlane { + plane_id: u32, + crtc_id: u32, + fb_id: u32, + possible_crtcs: u32, + gamma_size: u32, + count_format_types: u32, + format_type_ptr: u64 [array], + } +} + +pub const MODE_OBJ_GET_PROPERTIES: u64 = 0xB9; +define_ioctl_data! { + struct drm_mode_obj_get_properties, DrmModeObjGetProperties { + props_ptr: u64 [array], + prop_values_ptr: u64 [array], + count_props: u32, + obj_id: u32, + obj_type: u32, + } +} + +pub const MODE_GET_FB2: u64 = 0xCE; +define_ioctl_data! { + struct drm_mode_fb_cmd2, DrmModeFbCmd2 { + fb_id: u32, + width: u32, + height: u32, + pixel_format: u32, + flags: u32, + handles: [u32; 4], + pitches: [u32; 4], + offsets: [u32; 4], + modifier: [u64; 4], + } +} diff --git a/redox-ioctl/src/ioctl_data.rs b/redox-ioctl/src/ioctl_data.rs new file mode 100644 index 0000000000..f9673f6d7d --- /dev/null +++ b/redox-ioctl/src/ioctl_data.rs @@ -0,0 +1,169 @@ +use alloc::vec::Vec; + +pub trait IoctlData { + unsafe fn write(&self) -> Vec; + unsafe fn read_from(&mut self, buf: &[u8]); +} + +macro_rules! define_ioctl_data { + (struct $ioctl_ty:ident, $mem_ty:ident { + $($rest:tt)* + }) => { + define_ioctl_data!( + struct $ioctl_ty, $mem_ty { $($rest)* } => (), (), () + ); + }; + (struct $ioctl_ty:ident, $mem_ty:ident { + $field:ident: $ty:ty, + $($rest:tt)* + } => + ($($ioctl_fields:tt)*), + ($($counted_fields:tt)*), + ($($noncounted_fields:tt)*) + ) => { + define_ioctl_data!( + struct $ioctl_ty, $mem_ty { $($rest)* } => + ($($ioctl_fields)* $field: $ty,), + ($($counted_fields)*), + ($($noncounted_fields)* $field: $ty,) + ); + }; + (struct $ioctl_ty:ident, $mem_ty:ident { + $field:ident: $ty:ty [array<$el:ty, $counted_by:ident>], + $($rest:tt)* + } => + ($($ioctl_fields:tt)*), + ($($counted_fields:tt)*), + ($($noncounted_fields:tt)*) + ) => { + define_ioctl_data!( + struct $ioctl_ty, $mem_ty { $($rest)* } => + ($($ioctl_fields)* $field: $ty,), + ($($counted_fields)* $field: $ty [array<$el, $counted_by>],), + ($($noncounted_fields)*) + ); + }; + (struct $ioctl_ty:ident, $mem_ty:ident {} => + ($($ioctl_field:ident: $ioctl_field_ty:ty,)*), + ($($counted_field:ident: $counted_ty:ty [array<$el:ty, $counted_by:ident>],)*), + ($($noncounted_field:ident: $noncounted_ty:ty,)*) + ) => { + // FIXME check ioctl_ty doesn't have padding + const _: $ioctl_ty = $ioctl_ty { + $($ioctl_field: unsafe { mem::zeroed::<$ioctl_field_ty>() },)* + }; + + #[repr(C)] + pub struct ${concat(__, $mem_ty, Noncounted)} { + $($noncounted_field: $noncounted_ty,)* + } + + pub struct $mem_ty<'a> { + noncounted_fields: &'a mut ${concat(__, $mem_ty, Noncounted)}, + $($counted_field: &'a mut [$el],)* + } + + impl $crate::ioctl_data::IoctlData for $ioctl_ty { + unsafe fn write(&self) -> Vec { + let noncounted_fields = ${concat(__, $mem_ty, Noncounted)} { + $($noncounted_field: self.$noncounted_field,)* + }; + // FIXME use Vec::with_capacity + let mut data = Vec::::new(); + data.extend_from_slice(&unsafe { + mem::transmute::< + ${concat(__, $mem_ty, Noncounted)}, + [u8; size_of::<${concat(__, $mem_ty, Noncounted)}>()], + >(noncounted_fields) + }); + $( + let size = self.$counted_by as usize * size_of::<$el>(); + if self.$counted_field as usize != 0 { + let $counted_field = unsafe { + slice::from_raw_parts(self.$counted_field as *const u8, size) + }; + data.extend_from_slice(&$counted_field); + } else { + data.extend(iter::repeat(0u8).take(size)); + }; + + )* + data + } + + unsafe fn read_from(&mut self, mut buf: &[u8]) { + // FIXME be robust against malicious scheme implementations by returning an error + // when the buf is the wrong size + let noncounted_fields = buf.split_off(..size_of::<${concat(__, $mem_ty, Noncounted)}>()).unwrap(); + + $( + let size = self.$counted_by as usize * size_of::<$el>(); + let $counted_field = buf.split_off(..size).unwrap(); + if self.$counted_field as usize != 0 { + unsafe { + slice::from_raw_parts_mut(self.$counted_field as *mut u8, size).copy_from_slice($counted_field); + } + } + )* + + assert!(buf.is_empty()); + + let noncounted_fields = unsafe { &*(noncounted_fields as *const _ as *const ${concat(__, $mem_ty, Noncounted)}) }; + $(self.$noncounted_field = noncounted_fields.$noncounted_field;)* + } + } + + impl<'a> $mem_ty<'a> { + pub fn with( + mut buf: &'a mut [u8], + f: impl FnOnce($mem_ty<'a>) -> syscall::Result, + ) -> syscall::Result { + let noncounted_fields = buf.split_off_mut(..size_of::<${concat(__, $mem_ty, Noncounted)}>()) + .ok_or(syscall::Error::new(syscall::EINVAL))?; + let noncounted_fields = unsafe { &mut *(noncounted_fields as *mut _ as *mut ${concat(__, $mem_ty, Noncounted)}) }; + + $( + let $counted_field = buf.split_off_mut(..noncounted_fields.$counted_by as usize * size_of::<$el>()) + .ok_or(syscall::Error::new(syscall::EINVAL))?; + let $counted_field = unsafe { + slice::from_raw_parts_mut($counted_field as *mut _ as *mut $el, noncounted_fields.$counted_by as usize) + }; + )* + + if !buf.is_empty() { + return Err(syscall::Error::new(syscall::EINVAL)); + } + + + + Ok( f($mem_ty { + noncounted_fields, + $($counted_field,)* + })?) + } + + $( + pub fn $noncounted_field(&self) -> $noncounted_ty { + self.noncounted_fields.$noncounted_field + } + + /// Should not be called for fields used as array length + pub fn ${concat(set_, $noncounted_field)}(&mut self, data: $noncounted_ty) { + self.noncounted_fields.$noncounted_field = data; + } + )* + + $( + pub fn $counted_field(&self) -> &[$el] { + self.$counted_field + } + + pub fn ${concat(set_, $counted_field)}(&mut self, data: &[$el]) { + let copied_count = cmp::min(data.len(), self.$counted_field.len()); + self.$counted_field[..copied_count].copy_from_slice(&data[..copied_count]); + self.noncounted_fields.$counted_by = data.len() as _; + } + )* + } + }; +} diff --git a/redox-ioctl/src/lib.rs b/redox-ioctl/src/lib.rs new file mode 100644 index 0000000000..2405f5eeb2 --- /dev/null +++ b/redox-ioctl/src/lib.rs @@ -0,0 +1,10 @@ +#![feature(macro_metavar_expr_concat)] +#![no_std] + +extern crate alloc; + +#[macro_use] +mod ioctl_data; +pub use ioctl_data::IoctlData; + +pub mod drm; diff --git a/src/header/sys_ioctl/redox/drm.rs b/src/header/sys_ioctl/redox/drm.rs index 01b0d5afbf..a0692bdd95 100644 --- a/src/header/sys_ioctl/redox/drm.rs +++ b/src/header/sys_ioctl/redox/drm.rs @@ -1,10 +1,6 @@ -use alloc::vec::Vec; -use core::{mem, slice}; -use drm_sys::{ - drm_get_cap, drm_mode_card_res, drm_mode_crtc, drm_mode_fb_cmd, drm_mode_fb_cmd2, - drm_mode_get_connector, drm_mode_get_encoder, drm_mode_get_plane, drm_mode_get_plane_res, - drm_mode_obj_get_properties, drm_set_client_cap, drm_version, -}; +use core::slice; + +use redox_ioctl::{IoctlData, drm::*}; use crate::{ error::{Errno, Result}, @@ -12,7 +8,7 @@ use crate::{ platform::types::*, }; -use super::{IoctlBuffer, graphics_ipc as ipc, graphics_ipc::IoctlData}; +use super::IoctlBuffer; const DRM_FORMAT_ARGB8888: u32 = 0x34325241; // 'AR24' fourcc code, for ARGB8888 @@ -61,7 +57,7 @@ impl Dev { } unsafe fn call(&self, payload: &mut T, func: u64) -> syscall::Result { - let bytes = slice::from_raw_parts_mut(payload as *mut T as *mut u8, mem::size_of::()); + let bytes = slice::from_raw_parts_mut(payload as *mut T as *mut u8, size_of::()); redox_rt::sys::sys_call( self.fd as usize, bytes, @@ -70,7 +66,7 @@ impl Dev { ) } - unsafe fn read_write_ioctl( + unsafe fn read_write_ioctl( &self, mut buf: IoctlBuffer, func: u64, @@ -88,11 +84,7 @@ impl Dev { Ok(res as c_int) } - unsafe fn write_ioctl( - &self, - mut buf: IoctlBuffer, - func: u64, - ) -> Result { + unsafe fn write_ioctl(&self, mut buf: IoctlBuffer, func: u64) -> Result { let mut data = buf.read::()?; let mut wire = data.write(); let res = redox_rt::sys::sys_call( @@ -103,45 +95,23 @@ impl Dev { )?; Ok(res as c_int) } - - fn display_count(&self) -> Result { - let mut cmd = ipc::DisplayCount { count: 0 }; - unsafe { - self.call(&mut cmd, ipc::DISPLAY_COUNT)?; - } - Ok(cmd.count) - } - - fn display_size(&self, display_id: usize) -> Result<(u32, u32)> { - let mut cmd = ipc::DisplaySize { - display_id, - width: 0, - height: 0, - }; - unsafe { - self.call(&mut cmd, ipc::DISPLAY_SIZE)?; - } - Ok((cmd.width, cmd.height)) - } } pub(super) unsafe fn ioctl(fd: c_int, func: u8, buf: IoctlBuffer) -> Result { let dev = Dev::new(fd)?; match func { - 0x00 => dev.read_write_ioctl::(buf, ipc::VERSION), - 0x0C => dev.read_write_ioctl::(buf, ipc::GET_CAP), - 0x0D => dev.write_ioctl::(buf, ipc::SET_CLIENT_CAP), - 0xA0 => dev.read_write_ioctl::(buf, ipc::MODE_CARD_RES), - 0xA1 => dev.read_write_ioctl::(buf, ipc::MODE_GET_CRTC), - 0xA6 => dev.read_write_ioctl::(buf, ipc::MODE_GET_ENCODER), - 0xA7 => dev.read_write_ioctl::(buf, ipc::MODE_GET_CONNECTOR), - 0xAD => dev.read_write_ioctl::(buf, ipc::MODE_GET_FB), - 0xB5 => dev.read_write_ioctl::(buf, ipc::MODE_GET_PLANE_RES), - 0xB6 => dev.read_write_ioctl::(buf, ipc::MODE_GET_PLANE), - 0xB9 => { - dev.read_write_ioctl::(buf, ipc::MODE_OBJ_GET_PROPERTIES) - } - 0xCE => dev.read_write_ioctl::(buf, ipc::MODE_GET_FB2), + 0x00 => dev.read_write_ioctl::(buf, VERSION), + 0x0C => dev.read_write_ioctl::(buf, GET_CAP), + 0x0D => dev.write_ioctl::(buf, SET_CLIENT_CAP), + 0xA0 => dev.read_write_ioctl::(buf, MODE_CARD_RES), + 0xA1 => dev.read_write_ioctl::(buf, MODE_GET_CRTC), + 0xA6 => dev.read_write_ioctl::(buf, MODE_GET_ENCODER), + 0xA7 => dev.read_write_ioctl::(buf, MODE_GET_CONNECTOR), + 0xAD => dev.read_write_ioctl::(buf, MODE_GET_FB), + 0xB5 => dev.read_write_ioctl::(buf, MODE_GET_PLANE_RES), + 0xB6 => dev.read_write_ioctl::(buf, MODE_GET_PLANE), + 0xB9 => dev.read_write_ioctl::(buf, MODE_OBJ_GET_PROPERTIES), + 0xCE => dev.read_write_ioctl::(buf, MODE_GET_FB2), _ => { eprintln!("unimplemented DRM ioctl({}, 0x{:02x}, {:?})", fd, func, buf); Err(Errno(EINVAL)) diff --git a/src/header/sys_ioctl/redox/graphics_ipc.rs b/src/header/sys_ioctl/redox/graphics_ipc.rs deleted file mode 100644 index 86938a053d..0000000000 --- a/src/header/sys_ioctl/redox/graphics_ipc.rs +++ /dev/null @@ -1,392 +0,0 @@ -// Adapted from graphics-ipc v2 ipc module, cannot use as it needs libstd -#[derive(Debug, Copy, Clone)] -#[repr(C, packed)] -pub struct Damage { - pub x: u32, - pub y: u32, - pub width: u32, - pub height: u32, -} - -use alloc::vec::Vec; -use core::{ - cmp, - ffi::{c_char, c_int}, - iter, mem, slice, -}; - -pub trait IoctlData { - unsafe fn write(&self) -> Vec; - unsafe fn read_from(&mut self, buf: &[u8]); -} - -macro_rules! define_ioctl_data { - (struct $ioctl_ty:ident, $mem_ty:ident { - $($rest:tt)* - }) => { - define_ioctl_data!( - struct $ioctl_ty, $mem_ty { $($rest)* } => (), (), () - ); - }; - (struct $ioctl_ty:ident, $mem_ty:ident { - $field:ident: $ty:ty, - $($rest:tt)* - } => - ($($ioctl_fields:tt)*), - ($($counted_fields:tt)*), - ($($noncounted_fields:tt)*) - ) => { - define_ioctl_data!( - struct $ioctl_ty, $mem_ty { $($rest)* } => - ($($ioctl_fields)* $field: $ty,), - ($($counted_fields)*), - ($($noncounted_fields)* $field: $ty,) - ); - }; - (struct $ioctl_ty:ident, $mem_ty:ident { - $field:ident: $ty:ty [array<$el:ty, $counted_by:ident>], - $($rest:tt)* - } => - ($($ioctl_fields:tt)*), - ($($counted_fields:tt)*), - ($($noncounted_fields:tt)*) - ) => { - define_ioctl_data!( - struct $ioctl_ty, $mem_ty { $($rest)* } => - ($($ioctl_fields)* $field: $ty,), - ($($counted_fields)* $field: $ty [array<$el, $counted_by>],), - ($($noncounted_fields)*) - ); - }; - (struct $ioctl_ty:ident, $mem_ty:ident {} => - ($($ioctl_field:ident: $ioctl_field_ty:ty,)*), - ($($counted_field:ident: $counted_ty:ty [array<$el:ty, $counted_by:ident>],)*), - ($($noncounted_field:ident: $noncounted_ty:ty,)*) - ) => { - pub use drm_sys::$ioctl_ty; - - // FIXME check ioctl_ty doesn't have padding - const _: $ioctl_ty = $ioctl_ty { - $($ioctl_field: unsafe { mem::zeroed::<$ioctl_field_ty>() },)* - }; - - #[repr(C)] - pub struct ${concat(__, $mem_ty, Noncounted)} { - $($noncounted_field: $noncounted_ty,)* - } - - pub struct $mem_ty<'a> { - noncounted_fields: &'a mut ${concat(__, $mem_ty, Noncounted)}, - $($counted_field: &'a mut [$el],)* - } - - impl IoctlData for $ioctl_ty { - unsafe fn write(&self) -> Vec { - let noncounted_fields = ${concat(__, $mem_ty, Noncounted)} { - $($noncounted_field: self.$noncounted_field,)* - }; - // FIXME use Vec::with_capacity - let mut data = Vec::::new(); - data.extend_from_slice(&unsafe { - mem::transmute::< - ${concat(__, $mem_ty, Noncounted)}, - [u8; size_of::<${concat(__, $mem_ty, Noncounted)}>()], - >(noncounted_fields) - }); - $( - let size = self.$counted_by as usize * size_of::<$el>(); - if self.$counted_field as usize != 0 { - let $counted_field = unsafe { - slice::from_raw_parts(self.$counted_field as *const u8, size) - }; - data.extend_from_slice(&$counted_field); - } else { - data.extend(iter::repeat(0u8).take(size)); - }; - - )* - data - } - - unsafe fn read_from(&mut self, mut buf: &[u8]) { - // FIXME be robust against malicious scheme implementations by returning an error - // when the buf is the wrong size - let noncounted_fields = buf.split_off(..size_of::<${concat(__, $mem_ty, Noncounted)}>()).unwrap(); - - $( - let size = self.$counted_by as usize * size_of::<$el>(); - let $counted_field = buf.split_off(..size).unwrap(); - if self.$counted_field as usize != 0 { - unsafe { - slice::from_raw_parts_mut(self.$counted_field as *mut u8, size).copy_from_slice($counted_field); - } - } - )* - - assert!(buf.is_empty()); - - let noncounted_fields = unsafe { &*(noncounted_fields as *const _ as *const ${concat(__, $mem_ty, Noncounted)}) }; - $(self.$noncounted_field = noncounted_fields.$noncounted_field;)* - } - } - - impl<'a> $mem_ty<'a> { - pub fn with( - mut buf: &'a mut [u8], - f: impl FnOnce($mem_ty<'a>) -> syscall::Result, - ) -> syscall::Result { - let noncounted_fields = buf.split_off_mut(..size_of::<${concat(__, $mem_ty, Noncounted)}>()) - .ok_or(syscall::Error::new(syscall::EINVAL))?; - let noncounted_fields = unsafe { &mut *(noncounted_fields as *mut _ as *mut ${concat(__, $mem_ty, Noncounted)}) }; - - $( - let $counted_field = buf.split_off_mut(..noncounted_fields.$counted_by as usize * size_of::<$el>()) - .ok_or(syscall::Error::new(syscall::EINVAL))?; - let $counted_field = unsafe { - slice::from_raw_parts_mut($counted_field as *mut _ as *mut $el, noncounted_fields.$counted_by as usize) - }; - )* - - if !buf.is_empty() { - return Err(syscall::Error::new(syscall::EINVAL)); - } - - - - Ok( f($mem_ty { - noncounted_fields, - $($counted_field,)* - })?) - } - - $( - pub fn $noncounted_field(&self) -> $noncounted_ty { - self.noncounted_fields.$noncounted_field - } - - /// Should not be called for fields used as array length - pub fn ${concat(set_, $noncounted_field)}(&mut self, data: $noncounted_ty) { - self.noncounted_fields.$noncounted_field = data; - } - )* - - $( - pub fn $counted_field(&self) -> &[$el] { - self.$counted_field - } - - pub fn ${concat(set_, $counted_field)}(&mut self, data: &[$el]) { - let copied_count = cmp::min(data.len(), self.$counted_field.len()); - self.$counted_field[..copied_count].copy_from_slice(&data[..copied_count]); - self.noncounted_fields.$counted_by = data.len() as _; - } - )* - } - }; - } - -pub const VERSION: u64 = 0; -define_ioctl_data! { - struct drm_version, DrmVersion { - version_major: c_int, - version_minor: c_int, - version_patchlevel: c_int, - name_len: drm_sys::__kernel_size_t, - name: *mut c_char [array], - date_len: drm_sys::__kernel_size_t, - date: *mut c_char [array], - desc_len: drm_sys::__kernel_size_t, - desc: *mut c_char [array], - } -} - -pub const GET_CAP: u64 = 0x0C; -pub use drm_sys::DRM_CAP_DUMB_BUFFER; -define_ioctl_data! { - struct drm_get_cap, DrmGetCap { - capability: u64, - value: u64, - } -} - -pub const SET_CLIENT_CAP: u64 = 0x0D; -pub use drm_sys::DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT; -define_ioctl_data! { - struct drm_set_client_cap, DrmSetClientCap { - capability: u64, - value: u64, - } -} - -pub const MODE_CARD_RES: u64 = 0xA0; -define_ioctl_data! { - struct drm_mode_card_res, DrmModeCardRes { - fb_id_ptr: u64 [array], - crtc_id_ptr: u64 [array], - connector_id_ptr: u64 [array], - encoder_id_ptr: u64 [array], - count_fbs: u32, - count_crtcs: u32, - count_connectors: u32, - count_encoders: u32, - min_width: u32, - max_width: u32, - min_height: u32, - max_height: u32, - } -} - -pub const MODE_GET_CRTC: u64 = 0xA1; -define_ioctl_data! { - struct drm_mode_crtc, DrmModeCrtc { - set_connectors_ptr: u64, - count_connectors: u32, - crtc_id: u32, - fb_id: u32, - x: u32, - y: u32, - gamma_size: u32, - mode_valid: u32, - mode: drm_sys::drm_mode_modeinfo, - } -} - -pub const MODE_GET_ENCODER: u64 = 0xA6; -define_ioctl_data! { - struct drm_mode_get_encoder, DrmModeGetEncoder { - encoder_id: u32, - encoder_type: u32, - crtc_id: u32, - possible_crtcs: u32, - possible_clones: u32, - } -} - -pub const MODE_GET_CONNECTOR: u64 = 0xA7; -define_ioctl_data! { - struct drm_mode_get_connector, DrmModeGetConnector { - encoders_ptr: u64 [array], - modes_ptr: u64 [array], - props_ptr: u64 [array], - prop_values_ptr: u64 [array], - count_modes: u32, - count_props: u32, - count_encoders: u32, - encoder_id: u32, - connector_id: u32, - connector_type: u32, - connector_type_id: u32, - connection: u32, - mm_width: u32, - mm_height: u32, - subpixel: u32, - pad: u32, - } -} - -pub const MODE_GET_FB: u64 = 0xAD; -define_ioctl_data! { - struct drm_mode_fb_cmd, DrmModeFbCmd { - fb_id: u32, - width: u32, - height: u32, - pitch: u32, - bpp: u32, - depth: u32, - handle: u32, - } -} - -pub const MODE_GET_PLANE_RES: u64 = 0xB5; -define_ioctl_data! { - struct drm_mode_get_plane_res, DrmModeGetPlaneRes { - plane_id_ptr: u64 [array], - count_planes: u32, - } -} - -pub const MODE_GET_PLANE: u64 = 0xB6; -define_ioctl_data! { - struct drm_mode_get_plane, DrmModeGetPlane { - plane_id: u32, - crtc_id: u32, - fb_id: u32, - possible_crtcs: u32, - gamma_size: u32, - count_format_types: u32, - format_type_ptr: u64 [array], - } -} - -pub const MODE_OBJ_GET_PROPERTIES: u64 = 0xB9; -define_ioctl_data! { - struct drm_mode_obj_get_properties, DrmModeObjGetProperties { - props_ptr: u64 [array], - prop_values_ptr: u64 [array], - count_props: u32, - obj_id: u32, - obj_type: u32, - } -} - -pub const MODE_GET_FB2: u64 = 0xCE; -define_ioctl_data! { - struct drm_mode_fb_cmd2, DrmModeFbCmd2 { - fb_id: u32, - width: u32, - height: u32, - pixel_format: u32, - flags: u32, - handles: [u32; 4], - pitches: [u32; 4], - offsets: [u32; 4], - modifier: [u64; 4], - } -} - -// FIXME replace these with proper drm interfaces -pub const DISPLAY_COUNT: u64 = 1; -#[repr(C, packed)] -pub struct DisplayCount { - pub count: usize, -} - -pub const DISPLAY_SIZE: u64 = 2; -#[repr(C, packed)] -pub struct DisplaySize { - pub display_id: usize, - - pub width: u32, - pub height: u32, -} - -pub const CREATE_DUMB_FRAMEBUFFER: u64 = 3; -#[repr(C, packed)] -pub struct CreateDumbFramebuffer { - pub width: u32, - pub height: u32, - - pub fb_id: usize, -} - -pub const DUMB_FRAMEBUFFER_MAP_OFFSET: u64 = 4; -#[repr(C, packed)] -pub struct DumbFramebufferMapOffset { - pub fb_id: usize, - - pub offset: usize, -} - -pub const DESTROY_DUMB_FRAMEBUFFER: u64 = 5; -#[repr(C, packed)] -pub struct DestroyDumbFramebuffer { - pub fb_id: usize, -} - -pub const UPDATE_PLANE: u64 = 6; -#[repr(C, packed)] -pub struct UpdatePlane { - pub display_id: usize, - pub fb_id: usize, - pub damage: Damage, -} diff --git a/src/header/sys_ioctl/redox/mod.rs b/src/header/sys_ioctl/redox/mod.rs index 2914769366..c859e6193c 100644 --- a/src/header/sys_ioctl/redox/mod.rs +++ b/src/header/sys_ioctl/redox/mod.rs @@ -14,7 +14,6 @@ use crate::{ use super::winsize; mod drm; -mod graphics_ipc; pub const TCGETS: c_ulong = 0x5401; pub const TCSETS: c_ulong = 0x5402; diff --git a/src/lib.rs b/src/lib.rs index e74975e661..3ea46c6a6b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,6 @@ #![feature(c_variadic)] #![feature(core_intrinsics)] #![feature(macro_derive)] -#![feature(macro_metavar_expr_concat)] #![feature(maybe_uninit_slice)] #![feature(lang_items)] #![feature(linkage)]