152da9a59SGnoCiYeH use alloc::{ 252da9a59SGnoCiYeH string::{String, ToString}, 352da9a59SGnoCiYeH sync::{Arc, Weak}, 452da9a59SGnoCiYeH vec::Vec, 552da9a59SGnoCiYeH }; 6*2eab6dd7S曾俊 use log::warn; 752da9a59SGnoCiYeH use system_error::SystemError; 852da9a59SGnoCiYeH 952da9a59SGnoCiYeH use crate::{ 1052da9a59SGnoCiYeH driver::{ 1152da9a59SGnoCiYeH base::{ 1252da9a59SGnoCiYeH class::Class, 1352da9a59SGnoCiYeH device::{bus::Bus, device_manager, driver::Driver, Device, DeviceType, IdTable}, 1452da9a59SGnoCiYeH kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, 1552da9a59SGnoCiYeH kset::KSet, 1652da9a59SGnoCiYeH }, 1752da9a59SGnoCiYeH tty::virtual_terminal::virtual_console::{CursorOperation, VcCursor, VirtualConsoleData}, 1852da9a59SGnoCiYeH }, 1952da9a59SGnoCiYeH filesystem::{ 2052da9a59SGnoCiYeH kernfs::KernFSInode, 2152da9a59SGnoCiYeH sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport}, 2252da9a59SGnoCiYeH vfs::syscall::ModeType, 2352da9a59SGnoCiYeH }, 2452da9a59SGnoCiYeH libs::{ 2552da9a59SGnoCiYeH rwlock::{RwLockReadGuard, RwLockWriteGuard}, 2652da9a59SGnoCiYeH spinlock::{SpinLock, SpinLockGuard}, 2752da9a59SGnoCiYeH }, 2852da9a59SGnoCiYeH }; 2952da9a59SGnoCiYeH 3052da9a59SGnoCiYeH use super::{fbmem::sys_class_graphics_instance, FbCursor, ScrollMode}; 3152da9a59SGnoCiYeH 3252da9a59SGnoCiYeH pub mod framebuffer_console; 3352da9a59SGnoCiYeH 3452da9a59SGnoCiYeH /// framebuffer console设备管理器实例 3552da9a59SGnoCiYeH static mut FB_CONSOLE_MANAGER: Option<FbConsoleManager> = None; 3652da9a59SGnoCiYeH 3752da9a59SGnoCiYeH pub fn fb_console_manager() -> &'static FbConsoleManager { 3852da9a59SGnoCiYeH unsafe { FB_CONSOLE_MANAGER.as_ref().unwrap() } 3952da9a59SGnoCiYeH } 4052da9a59SGnoCiYeH 4152da9a59SGnoCiYeH /// 初始化framebuffer console 4252da9a59SGnoCiYeH pub(super) fn fb_console_init() -> Result<(), SystemError> { 4352da9a59SGnoCiYeH // todo: 对全局的console信号量加锁(linux中是console_lock) 4452da9a59SGnoCiYeH 4552da9a59SGnoCiYeH let fbcon_device: Arc<FbConsoleDevice> = FbConsoleDevice::new(); 4652da9a59SGnoCiYeH 4752da9a59SGnoCiYeH { 4852da9a59SGnoCiYeH let fbcon_manager = FbConsoleManager::new(fbcon_device.clone()); 4952da9a59SGnoCiYeH unsafe { FB_CONSOLE_MANAGER = Some(fbcon_manager) }; 5052da9a59SGnoCiYeH } 5152da9a59SGnoCiYeH 5252da9a59SGnoCiYeH device_manager().register(fbcon_device.clone() as Arc<dyn Device>)?; 5352da9a59SGnoCiYeH fb_console_manager().init_device()?; 5452da9a59SGnoCiYeH 5552da9a59SGnoCiYeH return Ok(()); 5652da9a59SGnoCiYeH } 5752da9a59SGnoCiYeH 5852da9a59SGnoCiYeH /// framebuffer console设备管理器 5952da9a59SGnoCiYeH #[derive(Debug)] 6052da9a59SGnoCiYeH pub struct FbConsoleManager { 6152da9a59SGnoCiYeH _inner: SpinLock<InnerFbConsoleManager>, 6252da9a59SGnoCiYeH /// framebuffer console设备实例 6352da9a59SGnoCiYeH /// (对应`/sys/class/graphics/fbcon`) 6452da9a59SGnoCiYeH device: Arc<FbConsoleDevice>, 6552da9a59SGnoCiYeH } 6652da9a59SGnoCiYeH 6752da9a59SGnoCiYeH impl FbConsoleManager { 6852da9a59SGnoCiYeH pub fn new(device: Arc<FbConsoleDevice>) -> Self { 6952da9a59SGnoCiYeH return Self { 7052da9a59SGnoCiYeH _inner: SpinLock::new(InnerFbConsoleManager {}), 7152da9a59SGnoCiYeH device, 7252da9a59SGnoCiYeH }; 7352da9a59SGnoCiYeH } 7452da9a59SGnoCiYeH 7552da9a59SGnoCiYeH #[allow(dead_code)] 7652da9a59SGnoCiYeH #[inline(always)] 7752da9a59SGnoCiYeH pub fn device(&self) -> &Arc<FbConsoleDevice> { 7852da9a59SGnoCiYeH &self.device 7952da9a59SGnoCiYeH } 8052da9a59SGnoCiYeH 8152da9a59SGnoCiYeH /// 初始化设备 8252da9a59SGnoCiYeH fn init_device(&self) -> Result<(), SystemError> { 8352da9a59SGnoCiYeH return Ok(()); // todo 8452da9a59SGnoCiYeH } 8552da9a59SGnoCiYeH } 8652da9a59SGnoCiYeH 8752da9a59SGnoCiYeH #[derive(Debug)] 8852da9a59SGnoCiYeH struct InnerFbConsoleManager {} 8952da9a59SGnoCiYeH 9052da9a59SGnoCiYeH #[derive(Debug)] 9152da9a59SGnoCiYeH struct InnerFbConsoleDevice { 9252da9a59SGnoCiYeH kernfs_inode: Option<Arc<KernFSInode>>, 9352da9a59SGnoCiYeH parent: Option<Weak<dyn KObject>>, 9452da9a59SGnoCiYeH kset: Option<Arc<KSet>>, 9552da9a59SGnoCiYeH bus: Option<Weak<dyn Bus>>, 9652da9a59SGnoCiYeH driver: Option<Weak<dyn Driver>>, 9752da9a59SGnoCiYeH ktype: Option<&'static dyn KObjType>, 9852da9a59SGnoCiYeH } 9952da9a59SGnoCiYeH 10052da9a59SGnoCiYeH /// `/sys/class/graphics/fbcon`代表的 framebuffer console 设备 10152da9a59SGnoCiYeH #[derive(Debug)] 10252da9a59SGnoCiYeH #[cast_to([sync] Device)] 10352da9a59SGnoCiYeH pub struct FbConsoleDevice { 10452da9a59SGnoCiYeH inner: SpinLock<InnerFbConsoleDevice>, 10552da9a59SGnoCiYeH kobj_state: LockedKObjectState, 10652da9a59SGnoCiYeH } 10752da9a59SGnoCiYeH 10852da9a59SGnoCiYeH impl FbConsoleDevice { 10952da9a59SGnoCiYeH const NAME: &'static str = "fbcon"; 11052da9a59SGnoCiYeH 11152da9a59SGnoCiYeH pub fn new() -> Arc<Self> { 11252da9a59SGnoCiYeH return Arc::new(Self { 11352da9a59SGnoCiYeH inner: SpinLock::new(InnerFbConsoleDevice { 11452da9a59SGnoCiYeH kernfs_inode: None, 11552da9a59SGnoCiYeH parent: None, 11652da9a59SGnoCiYeH kset: None, 11752da9a59SGnoCiYeH bus: None, 11852da9a59SGnoCiYeH ktype: None, 11952da9a59SGnoCiYeH driver: None, 12052da9a59SGnoCiYeH }), 12152da9a59SGnoCiYeH kobj_state: LockedKObjectState::new(None), 12252da9a59SGnoCiYeH }); 12352da9a59SGnoCiYeH } 12452da9a59SGnoCiYeH } 12552da9a59SGnoCiYeH 12652da9a59SGnoCiYeH impl KObject for FbConsoleDevice { 12752da9a59SGnoCiYeH fn as_any_ref(&self) -> &dyn core::any::Any { 12852da9a59SGnoCiYeH self 12952da9a59SGnoCiYeH } 13052da9a59SGnoCiYeH 13152da9a59SGnoCiYeH fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 13252da9a59SGnoCiYeH self.inner.lock().kernfs_inode = inode; 13352da9a59SGnoCiYeH } 13452da9a59SGnoCiYeH 13552da9a59SGnoCiYeH fn inode(&self) -> Option<Arc<KernFSInode>> { 13652da9a59SGnoCiYeH self.inner.lock().kernfs_inode.clone() 13752da9a59SGnoCiYeH } 13852da9a59SGnoCiYeH 13952da9a59SGnoCiYeH fn parent(&self) -> Option<Weak<dyn KObject>> { 14052da9a59SGnoCiYeH self.inner.lock().parent.clone() 14152da9a59SGnoCiYeH } 14252da9a59SGnoCiYeH 14352da9a59SGnoCiYeH fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 14452da9a59SGnoCiYeH self.inner.lock().parent = parent; 14552da9a59SGnoCiYeH } 14652da9a59SGnoCiYeH 14752da9a59SGnoCiYeH fn kset(&self) -> Option<Arc<KSet>> { 14852da9a59SGnoCiYeH self.inner.lock().kset.clone() 14952da9a59SGnoCiYeH } 15052da9a59SGnoCiYeH 15152da9a59SGnoCiYeH fn set_kset(&self, kset: Option<Arc<KSet>>) { 15252da9a59SGnoCiYeH self.inner.lock().kset = kset; 15352da9a59SGnoCiYeH } 15452da9a59SGnoCiYeH 15552da9a59SGnoCiYeH fn kobj_type(&self) -> Option<&'static dyn KObjType> { 15652da9a59SGnoCiYeH self.inner.lock().ktype 15752da9a59SGnoCiYeH } 15852da9a59SGnoCiYeH 15952da9a59SGnoCiYeH fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 16052da9a59SGnoCiYeH self.inner.lock().ktype = ktype; 16152da9a59SGnoCiYeH } 16252da9a59SGnoCiYeH 16352da9a59SGnoCiYeH fn name(&self) -> String { 16452da9a59SGnoCiYeH Self::NAME.to_string() 16552da9a59SGnoCiYeH } 16652da9a59SGnoCiYeH 16752da9a59SGnoCiYeH fn set_name(&self, _name: String) { 16852da9a59SGnoCiYeH // 不允许修改 169*2eab6dd7S曾俊 warn!("fbcon name can not be changed"); 17052da9a59SGnoCiYeH } 17152da9a59SGnoCiYeH 17252da9a59SGnoCiYeH fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 17352da9a59SGnoCiYeH self.kobj_state.read() 17452da9a59SGnoCiYeH } 17552da9a59SGnoCiYeH 17652da9a59SGnoCiYeH fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 17752da9a59SGnoCiYeH self.kobj_state.write() 17852da9a59SGnoCiYeH } 17952da9a59SGnoCiYeH 18052da9a59SGnoCiYeH fn set_kobj_state(&self, state: KObjectState) { 18152da9a59SGnoCiYeH *self.kobj_state.write() = state; 18252da9a59SGnoCiYeH } 18352da9a59SGnoCiYeH } 18452da9a59SGnoCiYeH impl Device for FbConsoleDevice { 18552da9a59SGnoCiYeH fn dev_type(&self) -> DeviceType { 18652da9a59SGnoCiYeH DeviceType::Char 18752da9a59SGnoCiYeH } 18852da9a59SGnoCiYeH 18952da9a59SGnoCiYeH fn id_table(&self) -> IdTable { 19052da9a59SGnoCiYeH IdTable::new(Self::NAME.to_string(), None) 19152da9a59SGnoCiYeH } 19252da9a59SGnoCiYeH 19352da9a59SGnoCiYeH fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 19452da9a59SGnoCiYeH self.inner.lock().bus = bus; 19552da9a59SGnoCiYeH } 19652da9a59SGnoCiYeH 19752da9a59SGnoCiYeH fn bus(&self) -> Option<Weak<dyn Bus>> { 19852da9a59SGnoCiYeH self.inner.lock().bus.clone() 19952da9a59SGnoCiYeH } 20052da9a59SGnoCiYeH 2014256da7fSLoGin fn set_class(&self, _class: Option<Weak<dyn Class>>) { 20252da9a59SGnoCiYeH // 不允许修改 203*2eab6dd7S曾俊 warn!("fbcon's class can not be changed"); 20452da9a59SGnoCiYeH } 20552da9a59SGnoCiYeH 20652da9a59SGnoCiYeH fn class(&self) -> Option<Arc<dyn Class>> { 20752da9a59SGnoCiYeH sys_class_graphics_instance().map(|ins| ins.clone() as Arc<dyn Class>) 20852da9a59SGnoCiYeH } 20952da9a59SGnoCiYeH 21052da9a59SGnoCiYeH fn driver(&self) -> Option<Arc<dyn Driver>> { 21152da9a59SGnoCiYeH self.inner 21252da9a59SGnoCiYeH .lock() 21352da9a59SGnoCiYeH .driver 21452da9a59SGnoCiYeH .clone() 21552da9a59SGnoCiYeH .and_then(|driver| driver.upgrade()) 21652da9a59SGnoCiYeH } 21752da9a59SGnoCiYeH 21852da9a59SGnoCiYeH fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 21952da9a59SGnoCiYeH self.inner.lock().driver = driver; 22052da9a59SGnoCiYeH } 22152da9a59SGnoCiYeH 22252da9a59SGnoCiYeH fn is_dead(&self) -> bool { 22352da9a59SGnoCiYeH todo!() 22452da9a59SGnoCiYeH } 22552da9a59SGnoCiYeH 22652da9a59SGnoCiYeH fn can_match(&self) -> bool { 22752da9a59SGnoCiYeH todo!() 22852da9a59SGnoCiYeH } 22952da9a59SGnoCiYeH 23052da9a59SGnoCiYeH fn set_can_match(&self, _can_match: bool) { 23152da9a59SGnoCiYeH todo!() 23252da9a59SGnoCiYeH } 23352da9a59SGnoCiYeH 23452da9a59SGnoCiYeH fn state_synced(&self) -> bool { 23552da9a59SGnoCiYeH todo!() 23652da9a59SGnoCiYeH } 23752da9a59SGnoCiYeH 23852da9a59SGnoCiYeH fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 23952da9a59SGnoCiYeH return Some(&[&AnonymousAttributeGroup]); 24052da9a59SGnoCiYeH } 24152da9a59SGnoCiYeH } 24252da9a59SGnoCiYeH 24352da9a59SGnoCiYeH /// framebuffer console设备的匿名属性组 24452da9a59SGnoCiYeH #[derive(Debug)] 24552da9a59SGnoCiYeH struct AnonymousAttributeGroup; 24652da9a59SGnoCiYeH 24752da9a59SGnoCiYeH impl AttributeGroup for AnonymousAttributeGroup { 24852da9a59SGnoCiYeH fn name(&self) -> Option<&str> { 24952da9a59SGnoCiYeH None 25052da9a59SGnoCiYeH } 25152da9a59SGnoCiYeH 25252da9a59SGnoCiYeH fn attrs(&self) -> &[&'static dyn Attribute] { 25352da9a59SGnoCiYeH return &[&AttrRotate, &AttrRotateAll, &AttrCursorBlink]; 25452da9a59SGnoCiYeH } 25552da9a59SGnoCiYeH 25652da9a59SGnoCiYeH fn is_visible( 25752da9a59SGnoCiYeH &self, 25852da9a59SGnoCiYeH _kobj: Arc<dyn KObject>, 25952da9a59SGnoCiYeH attr: &'static dyn Attribute, 26052da9a59SGnoCiYeH ) -> Option<ModeType> { 26152da9a59SGnoCiYeH return Some(attr.mode()); 26252da9a59SGnoCiYeH } 26352da9a59SGnoCiYeH } 26452da9a59SGnoCiYeH 26552da9a59SGnoCiYeH #[derive(Debug)] 26652da9a59SGnoCiYeH struct AttrRotate; 26752da9a59SGnoCiYeH 26852da9a59SGnoCiYeH impl Attribute for AttrRotate { 26952da9a59SGnoCiYeH fn name(&self) -> &str { 27052da9a59SGnoCiYeH "rotate" 27152da9a59SGnoCiYeH } 27252da9a59SGnoCiYeH 27352da9a59SGnoCiYeH fn mode(&self) -> ModeType { 27452da9a59SGnoCiYeH ModeType::S_IRUGO | ModeType::S_IWUSR 27552da9a59SGnoCiYeH } 27652da9a59SGnoCiYeH 27752da9a59SGnoCiYeH fn support(&self) -> SysFSOpsSupport { 27852da9a59SGnoCiYeH SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE 27952da9a59SGnoCiYeH } 28052da9a59SGnoCiYeH 28152da9a59SGnoCiYeH /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3226 28252da9a59SGnoCiYeH fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 283*2eab6dd7S曾俊 warn!("fbcon rotate show not implemented"); 28452da9a59SGnoCiYeH return sysfs_emit_str(buf, "0\n"); 28552da9a59SGnoCiYeH } 28652da9a59SGnoCiYeH 28752da9a59SGnoCiYeH /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3182 28852da9a59SGnoCiYeH fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> { 289*2eab6dd7S曾俊 warn!("fbcon rotate store not implemented"); 29052da9a59SGnoCiYeH return Err(SystemError::ENOSYS); 29152da9a59SGnoCiYeH } 29252da9a59SGnoCiYeH } 29352da9a59SGnoCiYeH 29452da9a59SGnoCiYeH #[derive(Debug)] 29552da9a59SGnoCiYeH struct AttrRotateAll; 29652da9a59SGnoCiYeH 29752da9a59SGnoCiYeH impl Attribute for AttrRotateAll { 29852da9a59SGnoCiYeH fn name(&self) -> &str { 29952da9a59SGnoCiYeH "rotate_all" 30052da9a59SGnoCiYeH } 30152da9a59SGnoCiYeH 30252da9a59SGnoCiYeH fn mode(&self) -> ModeType { 30352da9a59SGnoCiYeH ModeType::S_IWUSR 30452da9a59SGnoCiYeH } 30552da9a59SGnoCiYeH 30652da9a59SGnoCiYeH fn support(&self) -> SysFSOpsSupport { 30752da9a59SGnoCiYeH SysFSOpsSupport::ATTR_STORE 30852da9a59SGnoCiYeH } 30952da9a59SGnoCiYeH 31052da9a59SGnoCiYeH /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3204 31152da9a59SGnoCiYeH fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> { 312*2eab6dd7S曾俊 warn!("fbcon rotate_all store not implemented"); 31352da9a59SGnoCiYeH return Err(SystemError::ENOSYS); 31452da9a59SGnoCiYeH } 31552da9a59SGnoCiYeH } 31652da9a59SGnoCiYeH 31752da9a59SGnoCiYeH #[derive(Debug)] 31852da9a59SGnoCiYeH struct AttrCursorBlink; 31952da9a59SGnoCiYeH 32052da9a59SGnoCiYeH impl Attribute for AttrCursorBlink { 32152da9a59SGnoCiYeH fn name(&self) -> &str { 32252da9a59SGnoCiYeH "cursor_blink" 32352da9a59SGnoCiYeH } 32452da9a59SGnoCiYeH 32552da9a59SGnoCiYeH fn mode(&self) -> ModeType { 32652da9a59SGnoCiYeH ModeType::S_IRUGO | ModeType::S_IWUSR 32752da9a59SGnoCiYeH } 32852da9a59SGnoCiYeH 32952da9a59SGnoCiYeH fn support(&self) -> SysFSOpsSupport { 33052da9a59SGnoCiYeH SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE 33152da9a59SGnoCiYeH } 33252da9a59SGnoCiYeH 33352da9a59SGnoCiYeH /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3245 33452da9a59SGnoCiYeH fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> { 33552da9a59SGnoCiYeH todo!() 33652da9a59SGnoCiYeH } 33752da9a59SGnoCiYeH 33852da9a59SGnoCiYeH fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> { 33952da9a59SGnoCiYeH todo!() 34052da9a59SGnoCiYeH } 34152da9a59SGnoCiYeH } 34252da9a59SGnoCiYeH 34352da9a59SGnoCiYeH #[derive(Debug, Default)] 34452da9a59SGnoCiYeH pub struct FrameBufferConsoleData { 34552da9a59SGnoCiYeH /// 光标闪烁间隔 34652da9a59SGnoCiYeH pub cursor_blink_jiffies: i64, 34752da9a59SGnoCiYeH /// 是否刷新光标 34852da9a59SGnoCiYeH pub cursor_flash: bool, 34952da9a59SGnoCiYeH /// 35052da9a59SGnoCiYeH pub display: FbConsoleDisplay, 35152da9a59SGnoCiYeH /// 光标状态 35252da9a59SGnoCiYeH pub cursor_state: FbCursor, 35352da9a59SGnoCiYeH /// 重设光标? 35452da9a59SGnoCiYeH pub cursor_reset: bool, 35552da9a59SGnoCiYeH /// cursor 位图数据 35652da9a59SGnoCiYeH pub cursor_data: Vec<u8>, 35752da9a59SGnoCiYeH } 35852da9a59SGnoCiYeH 35952da9a59SGnoCiYeH pub trait FrameBufferConsole { 36052da9a59SGnoCiYeH fn fbcon_data(&self) -> SpinLockGuard<FrameBufferConsoleData>; 36152da9a59SGnoCiYeH 36252da9a59SGnoCiYeH /// ## 将位块移动到目标位置 36352da9a59SGnoCiYeH /// 坐标均以字体为单位而不是pixel 36452da9a59SGnoCiYeH /// ### 参数 36552da9a59SGnoCiYeH /// ### sy: 起始位置的y坐标 36652da9a59SGnoCiYeH /// ### sx: 起始位置的x坐标、 36752da9a59SGnoCiYeH /// ### dy: 目标位置的y坐标 36852da9a59SGnoCiYeH /// ### dx: 目标位置的x坐标 36952da9a59SGnoCiYeH /// ### height: 位图高度 37052da9a59SGnoCiYeH /// ### width: 位图宽度 371b5b571e0SLoGin #[allow(clippy::too_many_arguments)] 37252da9a59SGnoCiYeH fn bmove( 37352da9a59SGnoCiYeH &self, 37452da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 37552da9a59SGnoCiYeH sy: i32, 37652da9a59SGnoCiYeH sx: i32, 37752da9a59SGnoCiYeH dy: i32, 37852da9a59SGnoCiYeH dx: i32, 37952da9a59SGnoCiYeH height: u32, 38052da9a59SGnoCiYeH width: u32, 38152da9a59SGnoCiYeH ) -> Result<(), SystemError>; 38252da9a59SGnoCiYeH 38352da9a59SGnoCiYeH /// ## 清除位图 38452da9a59SGnoCiYeH /// 38552da9a59SGnoCiYeH /// ### 参数 38652da9a59SGnoCiYeH /// ### sy: 原位置的y坐标 38752da9a59SGnoCiYeH /// ### sx: 原位置的x坐标、 38852da9a59SGnoCiYeH /// ### height: 位图高度 38952da9a59SGnoCiYeH /// ### width: 位图宽度 39052da9a59SGnoCiYeH fn clear( 39152da9a59SGnoCiYeH &self, 39252da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 39352da9a59SGnoCiYeH sy: u32, 39452da9a59SGnoCiYeH sx: u32, 39552da9a59SGnoCiYeH height: u32, 39652da9a59SGnoCiYeH width: u32, 39752da9a59SGnoCiYeH ) -> Result<(), SystemError>; 39852da9a59SGnoCiYeH 39952da9a59SGnoCiYeH /// ## 显示字符串 40052da9a59SGnoCiYeH /// 40152da9a59SGnoCiYeH /// ### 参数 40252da9a59SGnoCiYeH /// ### y: 起始位置y坐标 40352da9a59SGnoCiYeH /// ### x: 起始位置的x坐标、 40452da9a59SGnoCiYeH /// ### fg: 前景色 40552da9a59SGnoCiYeH /// ### bg: 背景色 406b5b571e0SLoGin #[allow(clippy::too_many_arguments)] 40752da9a59SGnoCiYeH fn put_string( 40852da9a59SGnoCiYeH &self, 40952da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 41052da9a59SGnoCiYeH data: &[u16], 41152da9a59SGnoCiYeH count: u32, 41252da9a59SGnoCiYeH y: u32, 41352da9a59SGnoCiYeH x: u32, 41452da9a59SGnoCiYeH fg: u32, 41552da9a59SGnoCiYeH bg: u32, 41652da9a59SGnoCiYeH ) -> Result<(), SystemError>; 41752da9a59SGnoCiYeH 41852da9a59SGnoCiYeH fn cursor(&self, vc_data: &VirtualConsoleData, op: CursorOperation, fg: u32, bg: u32); 41952da9a59SGnoCiYeH } 42052da9a59SGnoCiYeH 42152da9a59SGnoCiYeH /// 表示 framebuffer 控制台与低级帧缓冲设备之间接口的数据结构 42252da9a59SGnoCiYeH #[derive(Debug, Default)] 42352da9a59SGnoCiYeH pub struct FbConsoleDisplay { 42452da9a59SGnoCiYeH /// 硬件滚动的行数 42552da9a59SGnoCiYeH pub yscroll: u32, 42652da9a59SGnoCiYeH /// 光标 42752da9a59SGnoCiYeH pub cursor_shape: VcCursor, 42852da9a59SGnoCiYeH /// 滚动模式 42952da9a59SGnoCiYeH pub scroll_mode: ScrollMode, 43052da9a59SGnoCiYeH virt_rows: u32, 43152da9a59SGnoCiYeH } 43252da9a59SGnoCiYeH 43352da9a59SGnoCiYeH impl FbConsoleDisplay { 43452da9a59SGnoCiYeH pub fn real_y(&self, mut ypos: u32) -> u32 { 43552da9a59SGnoCiYeH let rows = self.virt_rows; 43652da9a59SGnoCiYeH ypos += self.yscroll; 43752da9a59SGnoCiYeH if ypos < rows { 43852da9a59SGnoCiYeH return ypos; 43952da9a59SGnoCiYeH } else { 44052da9a59SGnoCiYeH return ypos - rows; 44152da9a59SGnoCiYeH } 44252da9a59SGnoCiYeH } 44352da9a59SGnoCiYeH } 44452da9a59SGnoCiYeH 44552da9a59SGnoCiYeH bitflags! { 44652da9a59SGnoCiYeH pub struct FbConAttr:u8 { 44752da9a59SGnoCiYeH const UNDERLINE = 1; 44852da9a59SGnoCiYeH const REVERSE = 2; 44952da9a59SGnoCiYeH const BOLD = 4; 45052da9a59SGnoCiYeH } 45152da9a59SGnoCiYeH } 45252da9a59SGnoCiYeH 45352da9a59SGnoCiYeH impl FbConAttr { 45452da9a59SGnoCiYeH pub fn get_attr(c: u16, color_depth: u32) -> Self { 45552da9a59SGnoCiYeH let mut attr = Self::empty(); 45652da9a59SGnoCiYeH if color_depth == 1 { 45752da9a59SGnoCiYeH if Self::underline(c) { 45852da9a59SGnoCiYeH attr.insert(Self::UNDERLINE); 45952da9a59SGnoCiYeH } 46052da9a59SGnoCiYeH if Self::reverse(c) { 46152da9a59SGnoCiYeH attr.intersects(Self::REVERSE); 46252da9a59SGnoCiYeH } 46352da9a59SGnoCiYeH if Self::blod(c) { 46452da9a59SGnoCiYeH attr.insert(Self::BOLD); 46552da9a59SGnoCiYeH } 46652da9a59SGnoCiYeH } 46752da9a59SGnoCiYeH attr 46852da9a59SGnoCiYeH } 46952da9a59SGnoCiYeH 47052da9a59SGnoCiYeH pub fn update_attr(&self, dst: &mut [u8], src: &[u8], vc_data: &VirtualConsoleData) { 47152da9a59SGnoCiYeH let mut offset = if vc_data.font.height < 10 { 1 } else { 2 } as usize; 47252da9a59SGnoCiYeH 47352da9a59SGnoCiYeH let width = (vc_data.font.width + 7) / 8; 47452da9a59SGnoCiYeH let cellsize = (vc_data.font.height * width) as usize; 47552da9a59SGnoCiYeH 47652da9a59SGnoCiYeH // 大于offset的部分就是下划线 47752da9a59SGnoCiYeH offset = cellsize - (offset * width as usize); 47852da9a59SGnoCiYeH for i in 0..cellsize { 47952da9a59SGnoCiYeH let mut c = src[i]; 48052da9a59SGnoCiYeH if self.contains(Self::UNDERLINE) && i >= offset { 48152da9a59SGnoCiYeH // 下划线 48252da9a59SGnoCiYeH c = 0xff; 48352da9a59SGnoCiYeH } 48452da9a59SGnoCiYeH if self.contains(Self::BOLD) { 48552da9a59SGnoCiYeH c |= c >> 1; 48652da9a59SGnoCiYeH } 48752da9a59SGnoCiYeH if self.contains(Self::REVERSE) { 48852da9a59SGnoCiYeH c = !c; 48952da9a59SGnoCiYeH } 49052da9a59SGnoCiYeH 49152da9a59SGnoCiYeH dst[i] = c; 49252da9a59SGnoCiYeH } 49352da9a59SGnoCiYeH } 49452da9a59SGnoCiYeH 49552da9a59SGnoCiYeH pub fn underline(c: u16) -> bool { 49652da9a59SGnoCiYeH c & 0x400 != 0 49752da9a59SGnoCiYeH } 49852da9a59SGnoCiYeH 49952da9a59SGnoCiYeH pub fn blod(c: u16) -> bool { 50052da9a59SGnoCiYeH c & 0x200 != 0 50152da9a59SGnoCiYeH } 50252da9a59SGnoCiYeH 50352da9a59SGnoCiYeH pub fn reverse(c: u16) -> bool { 50452da9a59SGnoCiYeH c & 0x800 != 0 50552da9a59SGnoCiYeH } 50652da9a59SGnoCiYeH } 507