1*52da9a59SGnoCiYeH use alloc::{ 2*52da9a59SGnoCiYeH string::{String, ToString}, 3*52da9a59SGnoCiYeH sync::{Arc, Weak}, 4*52da9a59SGnoCiYeH vec::Vec, 5*52da9a59SGnoCiYeH }; 6*52da9a59SGnoCiYeH use system_error::SystemError; 7*52da9a59SGnoCiYeH 8*52da9a59SGnoCiYeH use crate::{ 9*52da9a59SGnoCiYeH driver::{ 10*52da9a59SGnoCiYeH base::{ 11*52da9a59SGnoCiYeH class::Class, 12*52da9a59SGnoCiYeH device::{bus::Bus, device_manager, driver::Driver, Device, DeviceType, IdTable}, 13*52da9a59SGnoCiYeH kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, 14*52da9a59SGnoCiYeH kset::KSet, 15*52da9a59SGnoCiYeH }, 16*52da9a59SGnoCiYeH tty::virtual_terminal::virtual_console::{CursorOperation, VcCursor, VirtualConsoleData}, 17*52da9a59SGnoCiYeH }, 18*52da9a59SGnoCiYeH filesystem::{ 19*52da9a59SGnoCiYeH kernfs::KernFSInode, 20*52da9a59SGnoCiYeH sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport}, 21*52da9a59SGnoCiYeH vfs::syscall::ModeType, 22*52da9a59SGnoCiYeH }, 23*52da9a59SGnoCiYeH libs::{ 24*52da9a59SGnoCiYeH rwlock::{RwLockReadGuard, RwLockWriteGuard}, 25*52da9a59SGnoCiYeH spinlock::{SpinLock, SpinLockGuard}, 26*52da9a59SGnoCiYeH }, 27*52da9a59SGnoCiYeH }; 28*52da9a59SGnoCiYeH 29*52da9a59SGnoCiYeH use super::{fbmem::sys_class_graphics_instance, FbCursor, ScrollMode}; 30*52da9a59SGnoCiYeH 31*52da9a59SGnoCiYeH pub mod framebuffer_console; 32*52da9a59SGnoCiYeH 33*52da9a59SGnoCiYeH /// framebuffer console设备管理器实例 34*52da9a59SGnoCiYeH static mut FB_CONSOLE_MANAGER: Option<FbConsoleManager> = None; 35*52da9a59SGnoCiYeH 36*52da9a59SGnoCiYeH pub fn fb_console_manager() -> &'static FbConsoleManager { 37*52da9a59SGnoCiYeH unsafe { FB_CONSOLE_MANAGER.as_ref().unwrap() } 38*52da9a59SGnoCiYeH } 39*52da9a59SGnoCiYeH 40*52da9a59SGnoCiYeH /// 初始化framebuffer console 41*52da9a59SGnoCiYeH pub(super) fn fb_console_init() -> Result<(), SystemError> { 42*52da9a59SGnoCiYeH // todo: 对全局的console信号量加锁(linux中是console_lock) 43*52da9a59SGnoCiYeH 44*52da9a59SGnoCiYeH let fbcon_device: Arc<FbConsoleDevice> = FbConsoleDevice::new(); 45*52da9a59SGnoCiYeH 46*52da9a59SGnoCiYeH { 47*52da9a59SGnoCiYeH let fbcon_manager = FbConsoleManager::new(fbcon_device.clone()); 48*52da9a59SGnoCiYeH unsafe { FB_CONSOLE_MANAGER = Some(fbcon_manager) }; 49*52da9a59SGnoCiYeH } 50*52da9a59SGnoCiYeH 51*52da9a59SGnoCiYeH device_manager().register(fbcon_device.clone() as Arc<dyn Device>)?; 52*52da9a59SGnoCiYeH fb_console_manager().init_device()?; 53*52da9a59SGnoCiYeH 54*52da9a59SGnoCiYeH return Ok(()); 55*52da9a59SGnoCiYeH } 56*52da9a59SGnoCiYeH 57*52da9a59SGnoCiYeH /// framebuffer console设备管理器 58*52da9a59SGnoCiYeH #[derive(Debug)] 59*52da9a59SGnoCiYeH pub struct FbConsoleManager { 60*52da9a59SGnoCiYeH _inner: SpinLock<InnerFbConsoleManager>, 61*52da9a59SGnoCiYeH /// framebuffer console设备实例 62*52da9a59SGnoCiYeH /// (对应`/sys/class/graphics/fbcon`) 63*52da9a59SGnoCiYeH device: Arc<FbConsoleDevice>, 64*52da9a59SGnoCiYeH } 65*52da9a59SGnoCiYeH 66*52da9a59SGnoCiYeH impl FbConsoleManager { 67*52da9a59SGnoCiYeH pub fn new(device: Arc<FbConsoleDevice>) -> Self { 68*52da9a59SGnoCiYeH return Self { 69*52da9a59SGnoCiYeH _inner: SpinLock::new(InnerFbConsoleManager {}), 70*52da9a59SGnoCiYeH device, 71*52da9a59SGnoCiYeH }; 72*52da9a59SGnoCiYeH } 73*52da9a59SGnoCiYeH 74*52da9a59SGnoCiYeH #[allow(dead_code)] 75*52da9a59SGnoCiYeH #[inline(always)] 76*52da9a59SGnoCiYeH pub fn device(&self) -> &Arc<FbConsoleDevice> { 77*52da9a59SGnoCiYeH &self.device 78*52da9a59SGnoCiYeH } 79*52da9a59SGnoCiYeH 80*52da9a59SGnoCiYeH /// 初始化设备 81*52da9a59SGnoCiYeH fn init_device(&self) -> Result<(), SystemError> { 82*52da9a59SGnoCiYeH return Ok(()); // todo 83*52da9a59SGnoCiYeH } 84*52da9a59SGnoCiYeH } 85*52da9a59SGnoCiYeH 86*52da9a59SGnoCiYeH #[derive(Debug)] 87*52da9a59SGnoCiYeH struct InnerFbConsoleManager {} 88*52da9a59SGnoCiYeH 89*52da9a59SGnoCiYeH #[derive(Debug)] 90*52da9a59SGnoCiYeH struct InnerFbConsoleDevice { 91*52da9a59SGnoCiYeH kernfs_inode: Option<Arc<KernFSInode>>, 92*52da9a59SGnoCiYeH parent: Option<Weak<dyn KObject>>, 93*52da9a59SGnoCiYeH kset: Option<Arc<KSet>>, 94*52da9a59SGnoCiYeH bus: Option<Weak<dyn Bus>>, 95*52da9a59SGnoCiYeH driver: Option<Weak<dyn Driver>>, 96*52da9a59SGnoCiYeH ktype: Option<&'static dyn KObjType>, 97*52da9a59SGnoCiYeH } 98*52da9a59SGnoCiYeH 99*52da9a59SGnoCiYeH /// `/sys/class/graphics/fbcon`代表的 framebuffer console 设备 100*52da9a59SGnoCiYeH #[derive(Debug)] 101*52da9a59SGnoCiYeH #[cast_to([sync] Device)] 102*52da9a59SGnoCiYeH pub struct FbConsoleDevice { 103*52da9a59SGnoCiYeH inner: SpinLock<InnerFbConsoleDevice>, 104*52da9a59SGnoCiYeH kobj_state: LockedKObjectState, 105*52da9a59SGnoCiYeH } 106*52da9a59SGnoCiYeH 107*52da9a59SGnoCiYeH impl FbConsoleDevice { 108*52da9a59SGnoCiYeH const NAME: &'static str = "fbcon"; 109*52da9a59SGnoCiYeH 110*52da9a59SGnoCiYeH pub fn new() -> Arc<Self> { 111*52da9a59SGnoCiYeH return Arc::new(Self { 112*52da9a59SGnoCiYeH inner: SpinLock::new(InnerFbConsoleDevice { 113*52da9a59SGnoCiYeH kernfs_inode: None, 114*52da9a59SGnoCiYeH parent: None, 115*52da9a59SGnoCiYeH kset: None, 116*52da9a59SGnoCiYeH bus: None, 117*52da9a59SGnoCiYeH ktype: None, 118*52da9a59SGnoCiYeH driver: None, 119*52da9a59SGnoCiYeH }), 120*52da9a59SGnoCiYeH kobj_state: LockedKObjectState::new(None), 121*52da9a59SGnoCiYeH }); 122*52da9a59SGnoCiYeH } 123*52da9a59SGnoCiYeH } 124*52da9a59SGnoCiYeH 125*52da9a59SGnoCiYeH impl KObject for FbConsoleDevice { 126*52da9a59SGnoCiYeH fn as_any_ref(&self) -> &dyn core::any::Any { 127*52da9a59SGnoCiYeH self 128*52da9a59SGnoCiYeH } 129*52da9a59SGnoCiYeH 130*52da9a59SGnoCiYeH fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 131*52da9a59SGnoCiYeH self.inner.lock().kernfs_inode = inode; 132*52da9a59SGnoCiYeH } 133*52da9a59SGnoCiYeH 134*52da9a59SGnoCiYeH fn inode(&self) -> Option<Arc<KernFSInode>> { 135*52da9a59SGnoCiYeH self.inner.lock().kernfs_inode.clone() 136*52da9a59SGnoCiYeH } 137*52da9a59SGnoCiYeH 138*52da9a59SGnoCiYeH fn parent(&self) -> Option<Weak<dyn KObject>> { 139*52da9a59SGnoCiYeH self.inner.lock().parent.clone() 140*52da9a59SGnoCiYeH } 141*52da9a59SGnoCiYeH 142*52da9a59SGnoCiYeH fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 143*52da9a59SGnoCiYeH self.inner.lock().parent = parent; 144*52da9a59SGnoCiYeH } 145*52da9a59SGnoCiYeH 146*52da9a59SGnoCiYeH fn kset(&self) -> Option<Arc<KSet>> { 147*52da9a59SGnoCiYeH self.inner.lock().kset.clone() 148*52da9a59SGnoCiYeH } 149*52da9a59SGnoCiYeH 150*52da9a59SGnoCiYeH fn set_kset(&self, kset: Option<Arc<KSet>>) { 151*52da9a59SGnoCiYeH self.inner.lock().kset = kset; 152*52da9a59SGnoCiYeH } 153*52da9a59SGnoCiYeH 154*52da9a59SGnoCiYeH fn kobj_type(&self) -> Option<&'static dyn KObjType> { 155*52da9a59SGnoCiYeH self.inner.lock().ktype 156*52da9a59SGnoCiYeH } 157*52da9a59SGnoCiYeH 158*52da9a59SGnoCiYeH fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 159*52da9a59SGnoCiYeH self.inner.lock().ktype = ktype; 160*52da9a59SGnoCiYeH } 161*52da9a59SGnoCiYeH 162*52da9a59SGnoCiYeH fn name(&self) -> String { 163*52da9a59SGnoCiYeH Self::NAME.to_string() 164*52da9a59SGnoCiYeH } 165*52da9a59SGnoCiYeH 166*52da9a59SGnoCiYeH fn set_name(&self, _name: String) { 167*52da9a59SGnoCiYeH // 不允许修改 168*52da9a59SGnoCiYeH kwarn!("fbcon name can not be changed"); 169*52da9a59SGnoCiYeH } 170*52da9a59SGnoCiYeH 171*52da9a59SGnoCiYeH fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 172*52da9a59SGnoCiYeH self.kobj_state.read() 173*52da9a59SGnoCiYeH } 174*52da9a59SGnoCiYeH 175*52da9a59SGnoCiYeH fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 176*52da9a59SGnoCiYeH self.kobj_state.write() 177*52da9a59SGnoCiYeH } 178*52da9a59SGnoCiYeH 179*52da9a59SGnoCiYeH fn set_kobj_state(&self, state: KObjectState) { 180*52da9a59SGnoCiYeH *self.kobj_state.write() = state; 181*52da9a59SGnoCiYeH } 182*52da9a59SGnoCiYeH } 183*52da9a59SGnoCiYeH impl Device for FbConsoleDevice { 184*52da9a59SGnoCiYeH fn dev_type(&self) -> DeviceType { 185*52da9a59SGnoCiYeH DeviceType::Char 186*52da9a59SGnoCiYeH } 187*52da9a59SGnoCiYeH 188*52da9a59SGnoCiYeH fn id_table(&self) -> IdTable { 189*52da9a59SGnoCiYeH IdTable::new(Self::NAME.to_string(), None) 190*52da9a59SGnoCiYeH } 191*52da9a59SGnoCiYeH 192*52da9a59SGnoCiYeH fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 193*52da9a59SGnoCiYeH self.inner.lock().bus = bus; 194*52da9a59SGnoCiYeH } 195*52da9a59SGnoCiYeH 196*52da9a59SGnoCiYeH fn bus(&self) -> Option<Weak<dyn Bus>> { 197*52da9a59SGnoCiYeH self.inner.lock().bus.clone() 198*52da9a59SGnoCiYeH } 199*52da9a59SGnoCiYeH 200*52da9a59SGnoCiYeH fn set_class(&self, _class: Option<Arc<dyn Class>>) { 201*52da9a59SGnoCiYeH // 不允许修改 202*52da9a59SGnoCiYeH kwarn!("fbcon's class can not be changed"); 203*52da9a59SGnoCiYeH } 204*52da9a59SGnoCiYeH 205*52da9a59SGnoCiYeH fn class(&self) -> Option<Arc<dyn Class>> { 206*52da9a59SGnoCiYeH sys_class_graphics_instance().map(|ins| ins.clone() as Arc<dyn Class>) 207*52da9a59SGnoCiYeH } 208*52da9a59SGnoCiYeH 209*52da9a59SGnoCiYeH fn driver(&self) -> Option<Arc<dyn Driver>> { 210*52da9a59SGnoCiYeH self.inner 211*52da9a59SGnoCiYeH .lock() 212*52da9a59SGnoCiYeH .driver 213*52da9a59SGnoCiYeH .clone() 214*52da9a59SGnoCiYeH .and_then(|driver| driver.upgrade()) 215*52da9a59SGnoCiYeH } 216*52da9a59SGnoCiYeH 217*52da9a59SGnoCiYeH fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 218*52da9a59SGnoCiYeH self.inner.lock().driver = driver; 219*52da9a59SGnoCiYeH } 220*52da9a59SGnoCiYeH 221*52da9a59SGnoCiYeH fn is_dead(&self) -> bool { 222*52da9a59SGnoCiYeH todo!() 223*52da9a59SGnoCiYeH } 224*52da9a59SGnoCiYeH 225*52da9a59SGnoCiYeH fn can_match(&self) -> bool { 226*52da9a59SGnoCiYeH todo!() 227*52da9a59SGnoCiYeH } 228*52da9a59SGnoCiYeH 229*52da9a59SGnoCiYeH fn set_can_match(&self, _can_match: bool) { 230*52da9a59SGnoCiYeH todo!() 231*52da9a59SGnoCiYeH } 232*52da9a59SGnoCiYeH 233*52da9a59SGnoCiYeH fn state_synced(&self) -> bool { 234*52da9a59SGnoCiYeH todo!() 235*52da9a59SGnoCiYeH } 236*52da9a59SGnoCiYeH 237*52da9a59SGnoCiYeH fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 238*52da9a59SGnoCiYeH return Some(&[&AnonymousAttributeGroup]); 239*52da9a59SGnoCiYeH } 240*52da9a59SGnoCiYeH } 241*52da9a59SGnoCiYeH 242*52da9a59SGnoCiYeH /// framebuffer console设备的匿名属性组 243*52da9a59SGnoCiYeH #[derive(Debug)] 244*52da9a59SGnoCiYeH struct AnonymousAttributeGroup; 245*52da9a59SGnoCiYeH 246*52da9a59SGnoCiYeH impl AttributeGroup for AnonymousAttributeGroup { 247*52da9a59SGnoCiYeH fn name(&self) -> Option<&str> { 248*52da9a59SGnoCiYeH None 249*52da9a59SGnoCiYeH } 250*52da9a59SGnoCiYeH 251*52da9a59SGnoCiYeH fn attrs(&self) -> &[&'static dyn Attribute] { 252*52da9a59SGnoCiYeH return &[&AttrRotate, &AttrRotateAll, &AttrCursorBlink]; 253*52da9a59SGnoCiYeH } 254*52da9a59SGnoCiYeH 255*52da9a59SGnoCiYeH fn is_visible( 256*52da9a59SGnoCiYeH &self, 257*52da9a59SGnoCiYeH _kobj: Arc<dyn KObject>, 258*52da9a59SGnoCiYeH attr: &'static dyn Attribute, 259*52da9a59SGnoCiYeH ) -> Option<ModeType> { 260*52da9a59SGnoCiYeH return Some(attr.mode()); 261*52da9a59SGnoCiYeH } 262*52da9a59SGnoCiYeH } 263*52da9a59SGnoCiYeH 264*52da9a59SGnoCiYeH #[derive(Debug)] 265*52da9a59SGnoCiYeH struct AttrRotate; 266*52da9a59SGnoCiYeH 267*52da9a59SGnoCiYeH impl Attribute for AttrRotate { 268*52da9a59SGnoCiYeH fn name(&self) -> &str { 269*52da9a59SGnoCiYeH "rotate" 270*52da9a59SGnoCiYeH } 271*52da9a59SGnoCiYeH 272*52da9a59SGnoCiYeH fn mode(&self) -> ModeType { 273*52da9a59SGnoCiYeH ModeType::S_IRUGO | ModeType::S_IWUSR 274*52da9a59SGnoCiYeH } 275*52da9a59SGnoCiYeH 276*52da9a59SGnoCiYeH fn support(&self) -> SysFSOpsSupport { 277*52da9a59SGnoCiYeH SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE 278*52da9a59SGnoCiYeH } 279*52da9a59SGnoCiYeH 280*52da9a59SGnoCiYeH /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3226 281*52da9a59SGnoCiYeH fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 282*52da9a59SGnoCiYeH kwarn!("fbcon rotate show not implemented"); 283*52da9a59SGnoCiYeH return sysfs_emit_str(buf, "0\n"); 284*52da9a59SGnoCiYeH } 285*52da9a59SGnoCiYeH 286*52da9a59SGnoCiYeH /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3182 287*52da9a59SGnoCiYeH fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> { 288*52da9a59SGnoCiYeH kwarn!("fbcon rotate store not implemented"); 289*52da9a59SGnoCiYeH return Err(SystemError::ENOSYS); 290*52da9a59SGnoCiYeH } 291*52da9a59SGnoCiYeH } 292*52da9a59SGnoCiYeH 293*52da9a59SGnoCiYeH #[derive(Debug)] 294*52da9a59SGnoCiYeH struct AttrRotateAll; 295*52da9a59SGnoCiYeH 296*52da9a59SGnoCiYeH impl Attribute for AttrRotateAll { 297*52da9a59SGnoCiYeH fn name(&self) -> &str { 298*52da9a59SGnoCiYeH "rotate_all" 299*52da9a59SGnoCiYeH } 300*52da9a59SGnoCiYeH 301*52da9a59SGnoCiYeH fn mode(&self) -> ModeType { 302*52da9a59SGnoCiYeH ModeType::S_IWUSR 303*52da9a59SGnoCiYeH } 304*52da9a59SGnoCiYeH 305*52da9a59SGnoCiYeH fn support(&self) -> SysFSOpsSupport { 306*52da9a59SGnoCiYeH SysFSOpsSupport::ATTR_STORE 307*52da9a59SGnoCiYeH } 308*52da9a59SGnoCiYeH 309*52da9a59SGnoCiYeH /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3204 310*52da9a59SGnoCiYeH fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> { 311*52da9a59SGnoCiYeH kwarn!("fbcon rotate_all store not implemented"); 312*52da9a59SGnoCiYeH return Err(SystemError::ENOSYS); 313*52da9a59SGnoCiYeH } 314*52da9a59SGnoCiYeH } 315*52da9a59SGnoCiYeH 316*52da9a59SGnoCiYeH #[derive(Debug)] 317*52da9a59SGnoCiYeH struct AttrCursorBlink; 318*52da9a59SGnoCiYeH 319*52da9a59SGnoCiYeH impl Attribute for AttrCursorBlink { 320*52da9a59SGnoCiYeH fn name(&self) -> &str { 321*52da9a59SGnoCiYeH "cursor_blink" 322*52da9a59SGnoCiYeH } 323*52da9a59SGnoCiYeH 324*52da9a59SGnoCiYeH fn mode(&self) -> ModeType { 325*52da9a59SGnoCiYeH ModeType::S_IRUGO | ModeType::S_IWUSR 326*52da9a59SGnoCiYeH } 327*52da9a59SGnoCiYeH 328*52da9a59SGnoCiYeH fn support(&self) -> SysFSOpsSupport { 329*52da9a59SGnoCiYeH SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE 330*52da9a59SGnoCiYeH } 331*52da9a59SGnoCiYeH 332*52da9a59SGnoCiYeH /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3245 333*52da9a59SGnoCiYeH fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> { 334*52da9a59SGnoCiYeH todo!() 335*52da9a59SGnoCiYeH } 336*52da9a59SGnoCiYeH 337*52da9a59SGnoCiYeH fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> { 338*52da9a59SGnoCiYeH todo!() 339*52da9a59SGnoCiYeH } 340*52da9a59SGnoCiYeH } 341*52da9a59SGnoCiYeH 342*52da9a59SGnoCiYeH #[derive(Debug, Default)] 343*52da9a59SGnoCiYeH pub struct FrameBufferConsoleData { 344*52da9a59SGnoCiYeH /// 光标闪烁间隔 345*52da9a59SGnoCiYeH pub cursor_blink_jiffies: i64, 346*52da9a59SGnoCiYeH /// 是否刷新光标 347*52da9a59SGnoCiYeH pub cursor_flash: bool, 348*52da9a59SGnoCiYeH /// 349*52da9a59SGnoCiYeH pub display: FbConsoleDisplay, 350*52da9a59SGnoCiYeH /// 光标状态 351*52da9a59SGnoCiYeH pub cursor_state: FbCursor, 352*52da9a59SGnoCiYeH /// 重设光标? 353*52da9a59SGnoCiYeH pub cursor_reset: bool, 354*52da9a59SGnoCiYeH /// cursor 位图数据 355*52da9a59SGnoCiYeH pub cursor_data: Vec<u8>, 356*52da9a59SGnoCiYeH } 357*52da9a59SGnoCiYeH 358*52da9a59SGnoCiYeH pub trait FrameBufferConsole { 359*52da9a59SGnoCiYeH fn fbcon_data(&self) -> SpinLockGuard<FrameBufferConsoleData>; 360*52da9a59SGnoCiYeH 361*52da9a59SGnoCiYeH /// ## 将位块移动到目标位置 362*52da9a59SGnoCiYeH /// 坐标均以字体为单位而不是pixel 363*52da9a59SGnoCiYeH /// ### 参数 364*52da9a59SGnoCiYeH /// ### sy: 起始位置的y坐标 365*52da9a59SGnoCiYeH /// ### sx: 起始位置的x坐标、 366*52da9a59SGnoCiYeH /// ### dy: 目标位置的y坐标 367*52da9a59SGnoCiYeH /// ### dx: 目标位置的x坐标 368*52da9a59SGnoCiYeH /// ### height: 位图高度 369*52da9a59SGnoCiYeH /// ### width: 位图宽度 370*52da9a59SGnoCiYeH fn bmove( 371*52da9a59SGnoCiYeH &self, 372*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 373*52da9a59SGnoCiYeH sy: i32, 374*52da9a59SGnoCiYeH sx: i32, 375*52da9a59SGnoCiYeH dy: i32, 376*52da9a59SGnoCiYeH dx: i32, 377*52da9a59SGnoCiYeH height: u32, 378*52da9a59SGnoCiYeH width: u32, 379*52da9a59SGnoCiYeH ) -> Result<(), SystemError>; 380*52da9a59SGnoCiYeH 381*52da9a59SGnoCiYeH /// ## 清除位图 382*52da9a59SGnoCiYeH /// 383*52da9a59SGnoCiYeH /// ### 参数 384*52da9a59SGnoCiYeH /// ### sy: 原位置的y坐标 385*52da9a59SGnoCiYeH /// ### sx: 原位置的x坐标、 386*52da9a59SGnoCiYeH /// ### height: 位图高度 387*52da9a59SGnoCiYeH /// ### width: 位图宽度 388*52da9a59SGnoCiYeH fn clear( 389*52da9a59SGnoCiYeH &self, 390*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 391*52da9a59SGnoCiYeH sy: u32, 392*52da9a59SGnoCiYeH sx: u32, 393*52da9a59SGnoCiYeH height: u32, 394*52da9a59SGnoCiYeH width: u32, 395*52da9a59SGnoCiYeH ) -> Result<(), SystemError>; 396*52da9a59SGnoCiYeH 397*52da9a59SGnoCiYeH /// ## 显示字符串 398*52da9a59SGnoCiYeH /// 399*52da9a59SGnoCiYeH /// ### 参数 400*52da9a59SGnoCiYeH /// ### y: 起始位置y坐标 401*52da9a59SGnoCiYeH /// ### x: 起始位置的x坐标、 402*52da9a59SGnoCiYeH /// ### fg: 前景色 403*52da9a59SGnoCiYeH /// ### bg: 背景色 404*52da9a59SGnoCiYeH fn put_string( 405*52da9a59SGnoCiYeH &self, 406*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 407*52da9a59SGnoCiYeH data: &[u16], 408*52da9a59SGnoCiYeH count: u32, 409*52da9a59SGnoCiYeH y: u32, 410*52da9a59SGnoCiYeH x: u32, 411*52da9a59SGnoCiYeH fg: u32, 412*52da9a59SGnoCiYeH bg: u32, 413*52da9a59SGnoCiYeH ) -> Result<(), SystemError>; 414*52da9a59SGnoCiYeH 415*52da9a59SGnoCiYeH fn cursor(&self, vc_data: &VirtualConsoleData, op: CursorOperation, fg: u32, bg: u32); 416*52da9a59SGnoCiYeH } 417*52da9a59SGnoCiYeH 418*52da9a59SGnoCiYeH /// 表示 framebuffer 控制台与低级帧缓冲设备之间接口的数据结构 419*52da9a59SGnoCiYeH #[derive(Debug, Default)] 420*52da9a59SGnoCiYeH pub struct FbConsoleDisplay { 421*52da9a59SGnoCiYeH /// 硬件滚动的行数 422*52da9a59SGnoCiYeH pub yscroll: u32, 423*52da9a59SGnoCiYeH /// 光标 424*52da9a59SGnoCiYeH pub cursor_shape: VcCursor, 425*52da9a59SGnoCiYeH /// 滚动模式 426*52da9a59SGnoCiYeH pub scroll_mode: ScrollMode, 427*52da9a59SGnoCiYeH virt_rows: u32, 428*52da9a59SGnoCiYeH } 429*52da9a59SGnoCiYeH 430*52da9a59SGnoCiYeH impl FbConsoleDisplay { 431*52da9a59SGnoCiYeH pub fn real_y(&self, mut ypos: u32) -> u32 { 432*52da9a59SGnoCiYeH let rows = self.virt_rows; 433*52da9a59SGnoCiYeH ypos += self.yscroll; 434*52da9a59SGnoCiYeH if ypos < rows { 435*52da9a59SGnoCiYeH return ypos; 436*52da9a59SGnoCiYeH } else { 437*52da9a59SGnoCiYeH return ypos - rows; 438*52da9a59SGnoCiYeH } 439*52da9a59SGnoCiYeH } 440*52da9a59SGnoCiYeH } 441*52da9a59SGnoCiYeH 442*52da9a59SGnoCiYeH bitflags! { 443*52da9a59SGnoCiYeH pub struct FbConAttr:u8 { 444*52da9a59SGnoCiYeH const UNDERLINE = 1; 445*52da9a59SGnoCiYeH const REVERSE = 2; 446*52da9a59SGnoCiYeH const BOLD = 4; 447*52da9a59SGnoCiYeH } 448*52da9a59SGnoCiYeH } 449*52da9a59SGnoCiYeH 450*52da9a59SGnoCiYeH impl FbConAttr { 451*52da9a59SGnoCiYeH pub fn get_attr(c: u16, color_depth: u32) -> Self { 452*52da9a59SGnoCiYeH let mut attr = Self::empty(); 453*52da9a59SGnoCiYeH if color_depth == 1 { 454*52da9a59SGnoCiYeH if Self::underline(c) { 455*52da9a59SGnoCiYeH attr.insert(Self::UNDERLINE); 456*52da9a59SGnoCiYeH } 457*52da9a59SGnoCiYeH if Self::reverse(c) { 458*52da9a59SGnoCiYeH attr.intersects(Self::REVERSE); 459*52da9a59SGnoCiYeH } 460*52da9a59SGnoCiYeH if Self::blod(c) { 461*52da9a59SGnoCiYeH attr.insert(Self::BOLD); 462*52da9a59SGnoCiYeH } 463*52da9a59SGnoCiYeH } 464*52da9a59SGnoCiYeH attr 465*52da9a59SGnoCiYeH } 466*52da9a59SGnoCiYeH 467*52da9a59SGnoCiYeH pub fn update_attr(&self, dst: &mut [u8], src: &[u8], vc_data: &VirtualConsoleData) { 468*52da9a59SGnoCiYeH let mut offset = if vc_data.font.height < 10 { 1 } else { 2 } as usize; 469*52da9a59SGnoCiYeH 470*52da9a59SGnoCiYeH let width = (vc_data.font.width + 7) / 8; 471*52da9a59SGnoCiYeH let cellsize = (vc_data.font.height * width) as usize; 472*52da9a59SGnoCiYeH 473*52da9a59SGnoCiYeH // 大于offset的部分就是下划线 474*52da9a59SGnoCiYeH offset = cellsize - (offset * width as usize); 475*52da9a59SGnoCiYeH for i in 0..cellsize { 476*52da9a59SGnoCiYeH let mut c = src[i]; 477*52da9a59SGnoCiYeH if self.contains(Self::UNDERLINE) && i >= offset { 478*52da9a59SGnoCiYeH // 下划线 479*52da9a59SGnoCiYeH c = 0xff; 480*52da9a59SGnoCiYeH } 481*52da9a59SGnoCiYeH if self.contains(Self::BOLD) { 482*52da9a59SGnoCiYeH c |= c >> 1; 483*52da9a59SGnoCiYeH } 484*52da9a59SGnoCiYeH if self.contains(Self::REVERSE) { 485*52da9a59SGnoCiYeH c = !c; 486*52da9a59SGnoCiYeH } 487*52da9a59SGnoCiYeH 488*52da9a59SGnoCiYeH dst[i] = c; 489*52da9a59SGnoCiYeH } 490*52da9a59SGnoCiYeH } 491*52da9a59SGnoCiYeH 492*52da9a59SGnoCiYeH pub fn underline(c: u16) -> bool { 493*52da9a59SGnoCiYeH c & 0x400 != 0 494*52da9a59SGnoCiYeH } 495*52da9a59SGnoCiYeH 496*52da9a59SGnoCiYeH pub fn blod(c: u16) -> bool { 497*52da9a59SGnoCiYeH c & 0x200 != 0 498*52da9a59SGnoCiYeH } 499*52da9a59SGnoCiYeH 500*52da9a59SGnoCiYeH pub fn reverse(c: u16) -> bool { 501*52da9a59SGnoCiYeH c & 0x800 != 0 502*52da9a59SGnoCiYeH } 503*52da9a59SGnoCiYeH } 504