xref: /DragonOS/kernel/src/driver/video/fbdev/base/fbcon/mod.rs (revision 52da9a59374752b4d01907b052135a0d317781dd)
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