1*52da9a59SGnoCiYeH use alloc::{sync::Arc, vec::Vec}; 2*52da9a59SGnoCiYeH use system_error::SystemError; 3*52da9a59SGnoCiYeH 4*52da9a59SGnoCiYeH use crate::{ 5*52da9a59SGnoCiYeH driver::{ 6*52da9a59SGnoCiYeH tty::{ 7*52da9a59SGnoCiYeH console::ConsoleSwitch, 8*52da9a59SGnoCiYeH virtual_terminal::{ 9*52da9a59SGnoCiYeH virtual_console::{CursorOperation, ScrollDir, VcCursor, VirtualConsoleData}, 10*52da9a59SGnoCiYeH Color, 11*52da9a59SGnoCiYeH }, 12*52da9a59SGnoCiYeH }, 13*52da9a59SGnoCiYeH video::fbdev::base::{ 14*52da9a59SGnoCiYeH CopyAreaData, FbCursor, FbCursorSetMode, FbImage, FbVisual, FillRectData, FillRectROP, 15*52da9a59SGnoCiYeH FrameBuffer, ScrollMode, FRAME_BUFFER_SET, 16*52da9a59SGnoCiYeH }, 17*52da9a59SGnoCiYeH }, 18*52da9a59SGnoCiYeH libs::{ 19*52da9a59SGnoCiYeH font::FontDesc, 20*52da9a59SGnoCiYeH spinlock::{SpinLock, SpinLockGuard}, 21*52da9a59SGnoCiYeH }, 22*52da9a59SGnoCiYeH }; 23*52da9a59SGnoCiYeH 24*52da9a59SGnoCiYeH use super::{FbConAttr, FrameBufferConsole, FrameBufferConsoleData}; 25*52da9a59SGnoCiYeH 26*52da9a59SGnoCiYeH #[derive(Debug)] 27*52da9a59SGnoCiYeH pub struct BlittingFbConsole { 28*52da9a59SGnoCiYeH fb: SpinLock<Option<Arc<dyn FrameBuffer>>>, 29*52da9a59SGnoCiYeH fbcon_data: SpinLock<FrameBufferConsoleData>, 30*52da9a59SGnoCiYeH } 31*52da9a59SGnoCiYeH 32*52da9a59SGnoCiYeH unsafe impl Send for BlittingFbConsole {} 33*52da9a59SGnoCiYeH unsafe impl Sync for BlittingFbConsole {} 34*52da9a59SGnoCiYeH 35*52da9a59SGnoCiYeH impl BlittingFbConsole { 36*52da9a59SGnoCiYeH pub fn new() -> Result<Self, SystemError> { 37*52da9a59SGnoCiYeH Ok(Self { 38*52da9a59SGnoCiYeH fb: SpinLock::new(None), 39*52da9a59SGnoCiYeH fbcon_data: SpinLock::new(FrameBufferConsoleData::default()), 40*52da9a59SGnoCiYeH }) 41*52da9a59SGnoCiYeH } 42*52da9a59SGnoCiYeH 43*52da9a59SGnoCiYeH pub fn fb(&self) -> Arc<dyn FrameBuffer> { 44*52da9a59SGnoCiYeH self.fb.lock().clone().unwrap() 45*52da9a59SGnoCiYeH } 46*52da9a59SGnoCiYeH 47*52da9a59SGnoCiYeH pub fn get_color(&self, vc_data: &VirtualConsoleData, c: u16, is_fg: bool) -> u32 { 48*52da9a59SGnoCiYeH let fb_info = self.fb(); 49*52da9a59SGnoCiYeH let mut color = 0; 50*52da9a59SGnoCiYeH 51*52da9a59SGnoCiYeH let depth = fb_info.color_depth(); 52*52da9a59SGnoCiYeH 53*52da9a59SGnoCiYeH if depth != 1 { 54*52da9a59SGnoCiYeH if is_fg { 55*52da9a59SGnoCiYeH let fg_shift = if vc_data.hi_font_mask != 0 { 9 } else { 8 }; 56*52da9a59SGnoCiYeH color = (c as u32 >> fg_shift) & 0x0f 57*52da9a59SGnoCiYeH } else { 58*52da9a59SGnoCiYeH let bg_shift = if vc_data.hi_font_mask != 0 { 13 } else { 12 }; 59*52da9a59SGnoCiYeH color = (c as u32 >> bg_shift) & 0x0f 60*52da9a59SGnoCiYeH } 61*52da9a59SGnoCiYeH } 62*52da9a59SGnoCiYeH 63*52da9a59SGnoCiYeH match depth { 64*52da9a59SGnoCiYeH 1 => { 65*52da9a59SGnoCiYeH let col = self.mono_color(); 66*52da9a59SGnoCiYeH let fg; 67*52da9a59SGnoCiYeH let bg; 68*52da9a59SGnoCiYeH if fb_info.current_fb_fix().visual != FbVisual::Mono01 { 69*52da9a59SGnoCiYeH fg = col; 70*52da9a59SGnoCiYeH bg = 0; 71*52da9a59SGnoCiYeH } else { 72*52da9a59SGnoCiYeH fg = 0; 73*52da9a59SGnoCiYeH bg = col; 74*52da9a59SGnoCiYeH } 75*52da9a59SGnoCiYeH color = if is_fg { fg } else { bg }; 76*52da9a59SGnoCiYeH } 77*52da9a59SGnoCiYeH 2 => { 78*52da9a59SGnoCiYeH /* 79*52da9a59SGnoCiYeH 颜色深度为2,即16色, 80*52da9a59SGnoCiYeH 将16色的颜色值映射到4色的灰度, 81*52da9a59SGnoCiYeH 其中颜色0映射为黑色,颜色1到6映射为白色, 82*52da9a59SGnoCiYeH 颜色7到8映射为灰色,其他颜色映射为强烈的白色。 83*52da9a59SGnoCiYeH */ 84*52da9a59SGnoCiYeH if color >= 1 && color <= 6 { 85*52da9a59SGnoCiYeH // 白色 86*52da9a59SGnoCiYeH color = 2; 87*52da9a59SGnoCiYeH } else if color >= 7 && color <= 8 { 88*52da9a59SGnoCiYeH // 灰色 89*52da9a59SGnoCiYeH color = 1; 90*52da9a59SGnoCiYeH } else { 91*52da9a59SGnoCiYeH // 强白 92*52da9a59SGnoCiYeH color = 3; 93*52da9a59SGnoCiYeH } 94*52da9a59SGnoCiYeH } 95*52da9a59SGnoCiYeH 3 => { 96*52da9a59SGnoCiYeH /* 97*52da9a59SGnoCiYeH 颜色深度为3,即256色,仅保留颜色的低3位,即颜色 0 到 7 98*52da9a59SGnoCiYeH */ 99*52da9a59SGnoCiYeH color &= 7; 100*52da9a59SGnoCiYeH } 101*52da9a59SGnoCiYeH _ => {} 102*52da9a59SGnoCiYeH } 103*52da9a59SGnoCiYeH color 104*52da9a59SGnoCiYeH } 105*52da9a59SGnoCiYeH 106*52da9a59SGnoCiYeH /// ## 计算单色调的函数 107*52da9a59SGnoCiYeH pub fn mono_color(&self) -> u32 { 108*52da9a59SGnoCiYeH let fb_info = self.fb(); 109*52da9a59SGnoCiYeH let mut max_len = fb_info 110*52da9a59SGnoCiYeH .current_fb_var() 111*52da9a59SGnoCiYeH .green 112*52da9a59SGnoCiYeH .length 113*52da9a59SGnoCiYeH .max(fb_info.current_fb_var().red.length); 114*52da9a59SGnoCiYeH 115*52da9a59SGnoCiYeH max_len = max_len.max(fb_info.current_fb_var().blue.length); 116*52da9a59SGnoCiYeH 117*52da9a59SGnoCiYeH return (!(0xfff << max_len)) & 0xff; 118*52da9a59SGnoCiYeH } 119*52da9a59SGnoCiYeH 120*52da9a59SGnoCiYeH pub fn bit_put_string( 121*52da9a59SGnoCiYeH &self, 122*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 123*52da9a59SGnoCiYeH buf: &[u16], 124*52da9a59SGnoCiYeH attr: FbConAttr, 125*52da9a59SGnoCiYeH cnt: u32, 126*52da9a59SGnoCiYeH cellsize: u32, 127*52da9a59SGnoCiYeH image: &mut FbImage, 128*52da9a59SGnoCiYeH ) { 129*52da9a59SGnoCiYeH let charmask = if vc_data.hi_font_mask != 0 { 130*52da9a59SGnoCiYeH 0x1ff 131*52da9a59SGnoCiYeH } else { 132*52da9a59SGnoCiYeH 0xff 133*52da9a59SGnoCiYeH }; 134*52da9a59SGnoCiYeH 135*52da9a59SGnoCiYeH let mut offset; 136*52da9a59SGnoCiYeH let image_line_byte = image.width as usize / 8; 137*52da9a59SGnoCiYeH 138*52da9a59SGnoCiYeH let byte_width = vc_data.font.width as usize / 8; 139*52da9a59SGnoCiYeH let font_height = vc_data.font.height as usize; 140*52da9a59SGnoCiYeH // let mut char_offset = 0; 141*52da9a59SGnoCiYeH for char_offset in 0..cnt as usize { 142*52da9a59SGnoCiYeH // 在字符表中的index 143*52da9a59SGnoCiYeH let ch = buf[char_offset] & charmask; 144*52da9a59SGnoCiYeH // 计算出在font表中的偏移量 145*52da9a59SGnoCiYeH let font_offset = ch as usize * cellsize as usize; 146*52da9a59SGnoCiYeH let font_offset_end = font_offset + cellsize as usize; 147*52da9a59SGnoCiYeH // 设置image的data 148*52da9a59SGnoCiYeH 149*52da9a59SGnoCiYeH let src = &vc_data.font.data[font_offset..font_offset_end]; 150*52da9a59SGnoCiYeH let mut dst = Vec::new(); 151*52da9a59SGnoCiYeH dst.resize(src.len(), 0); 152*52da9a59SGnoCiYeH dst.copy_from_slice(src); 153*52da9a59SGnoCiYeH 154*52da9a59SGnoCiYeH if !attr.is_empty() { 155*52da9a59SGnoCiYeH attr.update_attr(&mut dst, src, vc_data) 156*52da9a59SGnoCiYeH } 157*52da9a59SGnoCiYeH 158*52da9a59SGnoCiYeH offset = char_offset * byte_width; 159*52da9a59SGnoCiYeH let mut dst_offset = 0; 160*52da9a59SGnoCiYeH for _ in 0..font_height { 161*52da9a59SGnoCiYeH let dst_offset_next = dst_offset + byte_width; 162*52da9a59SGnoCiYeH image.data[offset..offset + byte_width] 163*52da9a59SGnoCiYeH .copy_from_slice(&dst[dst_offset..dst_offset_next]); 164*52da9a59SGnoCiYeH 165*52da9a59SGnoCiYeH offset += image_line_byte; 166*52da9a59SGnoCiYeH dst_offset = dst_offset_next; 167*52da9a59SGnoCiYeH } 168*52da9a59SGnoCiYeH } 169*52da9a59SGnoCiYeH 170*52da9a59SGnoCiYeH self.fb().fb_image_blit(image); 171*52da9a59SGnoCiYeH } 172*52da9a59SGnoCiYeH } 173*52da9a59SGnoCiYeH 174*52da9a59SGnoCiYeH impl ConsoleSwitch for BlittingFbConsole { 175*52da9a59SGnoCiYeH fn con_init( 176*52da9a59SGnoCiYeH &self, 177*52da9a59SGnoCiYeH vc_data: &mut VirtualConsoleData, 178*52da9a59SGnoCiYeH init: bool, 179*52da9a59SGnoCiYeH ) -> Result<(), system_error::SystemError> { 180*52da9a59SGnoCiYeH let fb_set_guard = FRAME_BUFFER_SET.read(); 181*52da9a59SGnoCiYeH let fb = fb_set_guard.get(vc_data.index); 182*52da9a59SGnoCiYeH if fb.is_none() { 183*52da9a59SGnoCiYeH return Err(SystemError::EINVAL); 184*52da9a59SGnoCiYeH } 185*52da9a59SGnoCiYeH let fb = fb.unwrap(); 186*52da9a59SGnoCiYeH if fb.is_none() { 187*52da9a59SGnoCiYeH panic!( 188*52da9a59SGnoCiYeH "The Framebuffer with FbID {} has not been initialized yet.", 189*52da9a59SGnoCiYeH vc_data.index 190*52da9a59SGnoCiYeH ) 191*52da9a59SGnoCiYeH } 192*52da9a59SGnoCiYeH 193*52da9a59SGnoCiYeH let fb = fb.as_ref().unwrap().clone(); 194*52da9a59SGnoCiYeH 195*52da9a59SGnoCiYeH if init { 196*52da9a59SGnoCiYeH // 初始化字体 197*52da9a59SGnoCiYeH let var = fb.current_fb_var(); 198*52da9a59SGnoCiYeH let font = FontDesc::get_default_font(var.xres, var.yres, 0, 0); 199*52da9a59SGnoCiYeH vc_data.font.data = font.data.to_vec(); 200*52da9a59SGnoCiYeH vc_data.font.width = font.width; 201*52da9a59SGnoCiYeH vc_data.font.height = font.height; 202*52da9a59SGnoCiYeH vc_data.font.count = font.char_count; 203*52da9a59SGnoCiYeH } else { 204*52da9a59SGnoCiYeH kwarn!("The frontend Framebuffer is not implemented"); 205*52da9a59SGnoCiYeH } 206*52da9a59SGnoCiYeH 207*52da9a59SGnoCiYeH vc_data.color_mode = fb.color_depth() != 1; 208*52da9a59SGnoCiYeH vc_data.complement_mask = if vc_data.color_mode { 0x7700 } else { 0x0800 }; 209*52da9a59SGnoCiYeH 210*52da9a59SGnoCiYeH if vc_data.font.count == 256 { 211*52da9a59SGnoCiYeH // ascii 212*52da9a59SGnoCiYeH vc_data.hi_font_mask = 0; 213*52da9a59SGnoCiYeH } else { 214*52da9a59SGnoCiYeH vc_data.hi_font_mask = 0x100; 215*52da9a59SGnoCiYeH if vc_data.color_mode { 216*52da9a59SGnoCiYeH vc_data.complement_mask <<= 1; 217*52da9a59SGnoCiYeH } 218*52da9a59SGnoCiYeH } 219*52da9a59SGnoCiYeH 220*52da9a59SGnoCiYeH // TODO: 考虑rotate 221*52da9a59SGnoCiYeH if init { 222*52da9a59SGnoCiYeH vc_data.cols = (fb.current_fb_var().xres / vc_data.font.width) as usize; 223*52da9a59SGnoCiYeH vc_data.rows = (fb.current_fb_var().yres / vc_data.font.height) as usize; 224*52da9a59SGnoCiYeH 225*52da9a59SGnoCiYeH vc_data.pos = vc_data.state.x + vc_data.state.y * vc_data.cols; 226*52da9a59SGnoCiYeH 227*52da9a59SGnoCiYeH let new_size = vc_data.cols * vc_data.rows; 228*52da9a59SGnoCiYeH vc_data.screen_buf.resize(new_size, 0); 229*52da9a59SGnoCiYeH } else { 230*52da9a59SGnoCiYeH unimplemented!("Resize is not supported at the moment!"); 231*52da9a59SGnoCiYeH } 232*52da9a59SGnoCiYeH 233*52da9a59SGnoCiYeH // 初始化fb 234*52da9a59SGnoCiYeH *self.fb.lock() = Some(fb); 235*52da9a59SGnoCiYeH 236*52da9a59SGnoCiYeH Ok(()) 237*52da9a59SGnoCiYeH } 238*52da9a59SGnoCiYeH 239*52da9a59SGnoCiYeH fn con_deinit(&self) -> Result<(), system_error::SystemError> { 240*52da9a59SGnoCiYeH todo!() 241*52da9a59SGnoCiYeH } 242*52da9a59SGnoCiYeH 243*52da9a59SGnoCiYeH fn con_clear( 244*52da9a59SGnoCiYeH &self, 245*52da9a59SGnoCiYeH vc_data: &mut VirtualConsoleData, 246*52da9a59SGnoCiYeH sy: usize, 247*52da9a59SGnoCiYeH sx: usize, 248*52da9a59SGnoCiYeH height: usize, 249*52da9a59SGnoCiYeH width: usize, 250*52da9a59SGnoCiYeH ) -> Result<(), system_error::SystemError> { 251*52da9a59SGnoCiYeH let fb_data = self.fbcon_data(); 252*52da9a59SGnoCiYeH 253*52da9a59SGnoCiYeH if height == 0 || width == 0 { 254*52da9a59SGnoCiYeH return Ok(()); 255*52da9a59SGnoCiYeH } 256*52da9a59SGnoCiYeH 257*52da9a59SGnoCiYeH let y_break = (fb_data.display.virt_rows - fb_data.display.yscroll) as usize; 258*52da9a59SGnoCiYeH if sy < y_break && sy + height - 1 >= y_break { 259*52da9a59SGnoCiYeH // 分两次clear 260*52da9a59SGnoCiYeH let b = y_break - sy; 261*52da9a59SGnoCiYeH let _ = self.clear( 262*52da9a59SGnoCiYeH &vc_data, 263*52da9a59SGnoCiYeH fb_data.display.real_y(sy as u32), 264*52da9a59SGnoCiYeH sx as u32, 265*52da9a59SGnoCiYeH b as u32, 266*52da9a59SGnoCiYeH width as u32, 267*52da9a59SGnoCiYeH ); 268*52da9a59SGnoCiYeH let _ = self.clear( 269*52da9a59SGnoCiYeH &vc_data, 270*52da9a59SGnoCiYeH fb_data.display.real_y((sy + b) as u32), 271*52da9a59SGnoCiYeH sx as u32, 272*52da9a59SGnoCiYeH (height - b) as u32, 273*52da9a59SGnoCiYeH width as u32, 274*52da9a59SGnoCiYeH ); 275*52da9a59SGnoCiYeH } else { 276*52da9a59SGnoCiYeH let _ = self.clear( 277*52da9a59SGnoCiYeH &vc_data, 278*52da9a59SGnoCiYeH fb_data.display.real_y(sy as u32), 279*52da9a59SGnoCiYeH sx as u32, 280*52da9a59SGnoCiYeH height as u32, 281*52da9a59SGnoCiYeH width as u32, 282*52da9a59SGnoCiYeH ); 283*52da9a59SGnoCiYeH } 284*52da9a59SGnoCiYeH 285*52da9a59SGnoCiYeH Ok(()) 286*52da9a59SGnoCiYeH } 287*52da9a59SGnoCiYeH 288*52da9a59SGnoCiYeH fn con_putc( 289*52da9a59SGnoCiYeH &self, 290*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 291*52da9a59SGnoCiYeH ch: u16, 292*52da9a59SGnoCiYeH xpos: u32, 293*52da9a59SGnoCiYeH ypos: u32, 294*52da9a59SGnoCiYeH ) -> Result<(), system_error::SystemError> { 295*52da9a59SGnoCiYeH self.con_putcs(vc_data, &[ch], 1, ypos, xpos) 296*52da9a59SGnoCiYeH } 297*52da9a59SGnoCiYeH 298*52da9a59SGnoCiYeH fn con_putcs( 299*52da9a59SGnoCiYeH &self, 300*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 301*52da9a59SGnoCiYeH buf: &[u16], 302*52da9a59SGnoCiYeH count: usize, 303*52da9a59SGnoCiYeH ypos: u32, 304*52da9a59SGnoCiYeH xpos: u32, 305*52da9a59SGnoCiYeH ) -> Result<(), SystemError> { 306*52da9a59SGnoCiYeH if count == 0 { 307*52da9a59SGnoCiYeH return Ok(()); 308*52da9a59SGnoCiYeH } 309*52da9a59SGnoCiYeH let fbcon_data = self.fbcon_data(); 310*52da9a59SGnoCiYeH let c = buf[0]; 311*52da9a59SGnoCiYeH self.put_string( 312*52da9a59SGnoCiYeH vc_data, 313*52da9a59SGnoCiYeH buf, 314*52da9a59SGnoCiYeH count as u32, 315*52da9a59SGnoCiYeH fbcon_data.display.real_y(ypos), 316*52da9a59SGnoCiYeH xpos, 317*52da9a59SGnoCiYeH self.get_color(vc_data, c, true), 318*52da9a59SGnoCiYeH self.get_color(vc_data, c, false), 319*52da9a59SGnoCiYeH ) 320*52da9a59SGnoCiYeH } 321*52da9a59SGnoCiYeH 322*52da9a59SGnoCiYeH fn con_getxy( 323*52da9a59SGnoCiYeH &self, 324*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 325*52da9a59SGnoCiYeH pos: usize, 326*52da9a59SGnoCiYeH ) -> Result<(usize, usize, usize), SystemError> { 327*52da9a59SGnoCiYeH if pos < vc_data.screen_buf.len() { 328*52da9a59SGnoCiYeH let x = pos % vc_data.cols; 329*52da9a59SGnoCiYeH let y = pos / vc_data.cols; 330*52da9a59SGnoCiYeH let mut next_line_start = pos + (vc_data.cols - x); 331*52da9a59SGnoCiYeH if next_line_start >= vc_data.screen_buf.len() { 332*52da9a59SGnoCiYeH next_line_start = 0 333*52da9a59SGnoCiYeH } 334*52da9a59SGnoCiYeH return Ok((next_line_start, x, y)); 335*52da9a59SGnoCiYeH } else { 336*52da9a59SGnoCiYeH return Ok((0, 0, 0)); 337*52da9a59SGnoCiYeH } 338*52da9a59SGnoCiYeH } 339*52da9a59SGnoCiYeH 340*52da9a59SGnoCiYeH fn con_cursor( 341*52da9a59SGnoCiYeH &self, 342*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 343*52da9a59SGnoCiYeH op: crate::driver::tty::virtual_terminal::virtual_console::CursorOperation, 344*52da9a59SGnoCiYeH ) { 345*52da9a59SGnoCiYeH let mut fbcon_data = self.fbcon_data(); 346*52da9a59SGnoCiYeH 347*52da9a59SGnoCiYeH let c = vc_data.screen_buf[vc_data.pos]; 348*52da9a59SGnoCiYeH 349*52da9a59SGnoCiYeH if vc_data.cursor_type.contains(VcCursor::CUR_SW) { 350*52da9a59SGnoCiYeH // 取消硬光标Timer,但是现在没有硬光标,先写在这 351*52da9a59SGnoCiYeH } else { 352*52da9a59SGnoCiYeH // 添加硬光标Timer 353*52da9a59SGnoCiYeH } 354*52da9a59SGnoCiYeH 355*52da9a59SGnoCiYeH fbcon_data.cursor_flash = op != CursorOperation::Erase; 356*52da9a59SGnoCiYeH 357*52da9a59SGnoCiYeH drop(fbcon_data); 358*52da9a59SGnoCiYeH 359*52da9a59SGnoCiYeH self.cursor( 360*52da9a59SGnoCiYeH vc_data, 361*52da9a59SGnoCiYeH op, 362*52da9a59SGnoCiYeH self.get_color(vc_data, c, true), 363*52da9a59SGnoCiYeH self.get_color(vc_data, c, false), 364*52da9a59SGnoCiYeH ); 365*52da9a59SGnoCiYeH } 366*52da9a59SGnoCiYeH 367*52da9a59SGnoCiYeH fn con_set_palette( 368*52da9a59SGnoCiYeH &self, 369*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 370*52da9a59SGnoCiYeH color_table: &[u8], 371*52da9a59SGnoCiYeH ) -> Result<(), SystemError> { 372*52da9a59SGnoCiYeH let fb_info = self.fb(); 373*52da9a59SGnoCiYeH let depth = fb_info.color_depth(); 374*52da9a59SGnoCiYeH let mut palette = Vec::new(); 375*52da9a59SGnoCiYeH palette.resize(16, Color::default()); 376*52da9a59SGnoCiYeH if depth > 3 { 377*52da9a59SGnoCiYeH let vc_palette = &vc_data.palette; 378*52da9a59SGnoCiYeH for i in 0..16 { 379*52da9a59SGnoCiYeH let idx = color_table[i]; 380*52da9a59SGnoCiYeH let col = palette.get_mut(idx as usize).unwrap(); 381*52da9a59SGnoCiYeH col.red = (vc_palette[i].red << 8) | vc_palette[i].red; 382*52da9a59SGnoCiYeH col.green = (vc_palette[i].green << 8) | vc_palette[i].green; 383*52da9a59SGnoCiYeH col.blue = (vc_palette[i].blue << 8) | vc_palette[i].blue; 384*52da9a59SGnoCiYeH } 385*52da9a59SGnoCiYeH } else { 386*52da9a59SGnoCiYeH todo!() 387*52da9a59SGnoCiYeH } 388*52da9a59SGnoCiYeH 389*52da9a59SGnoCiYeH self.fb().set_color_map(palette)?; 390*52da9a59SGnoCiYeH 391*52da9a59SGnoCiYeH Ok(()) 392*52da9a59SGnoCiYeH } 393*52da9a59SGnoCiYeH 394*52da9a59SGnoCiYeH fn con_scroll( 395*52da9a59SGnoCiYeH &self, 396*52da9a59SGnoCiYeH vc_data: &mut VirtualConsoleData, 397*52da9a59SGnoCiYeH top: usize, 398*52da9a59SGnoCiYeH bottom: usize, 399*52da9a59SGnoCiYeH dir: crate::driver::tty::virtual_terminal::virtual_console::ScrollDir, 400*52da9a59SGnoCiYeH mut count: usize, 401*52da9a59SGnoCiYeH ) -> bool { 402*52da9a59SGnoCiYeH self.con_cursor(vc_data, CursorOperation::Erase); 403*52da9a59SGnoCiYeH 404*52da9a59SGnoCiYeH let fbcon_data = self.fbcon_data(); 405*52da9a59SGnoCiYeH let scroll_mode = fbcon_data.display.scroll_mode; 406*52da9a59SGnoCiYeH 407*52da9a59SGnoCiYeH drop(fbcon_data); 408*52da9a59SGnoCiYeH 409*52da9a59SGnoCiYeH match dir { 410*52da9a59SGnoCiYeH ScrollDir::Up => { 411*52da9a59SGnoCiYeH if count > vc_data.rows { 412*52da9a59SGnoCiYeH count = vc_data.rows; 413*52da9a59SGnoCiYeH } 414*52da9a59SGnoCiYeH 415*52da9a59SGnoCiYeH match scroll_mode { 416*52da9a59SGnoCiYeH ScrollMode::Move => { 417*52da9a59SGnoCiYeH let start = top * vc_data.cols; 418*52da9a59SGnoCiYeH let end = bottom * vc_data.cols; 419*52da9a59SGnoCiYeH vc_data.screen_buf[start..end].rotate_left(count * vc_data.cols); 420*52da9a59SGnoCiYeH 421*52da9a59SGnoCiYeH let _ = self.bmove( 422*52da9a59SGnoCiYeH vc_data, 423*52da9a59SGnoCiYeH top as i32, 424*52da9a59SGnoCiYeH 0, 425*52da9a59SGnoCiYeH top as i32 - count as i32, 426*52da9a59SGnoCiYeH 0, 427*52da9a59SGnoCiYeH (bottom - top) as u32, 428*52da9a59SGnoCiYeH vc_data.cols as u32, 429*52da9a59SGnoCiYeH ); 430*52da9a59SGnoCiYeH 431*52da9a59SGnoCiYeH let _ = self.con_clear(vc_data, bottom - count, 0, count, vc_data.cols); 432*52da9a59SGnoCiYeH 433*52da9a59SGnoCiYeH let offset = vc_data.cols * (bottom - count); 434*52da9a59SGnoCiYeH for i in 435*52da9a59SGnoCiYeH vc_data.screen_buf[offset..(offset + (vc_data.cols * count))].iter_mut() 436*52da9a59SGnoCiYeH { 437*52da9a59SGnoCiYeH *i = vc_data.erase_char; 438*52da9a59SGnoCiYeH } 439*52da9a59SGnoCiYeH 440*52da9a59SGnoCiYeH return true; 441*52da9a59SGnoCiYeH } 442*52da9a59SGnoCiYeH ScrollMode::PanMove => todo!(), 443*52da9a59SGnoCiYeH ScrollMode::WrapMove => todo!(), 444*52da9a59SGnoCiYeH ScrollMode::Redraw => { 445*52da9a59SGnoCiYeH let start = top * vc_data.cols; 446*52da9a59SGnoCiYeH let end = bottom * vc_data.cols; 447*52da9a59SGnoCiYeH vc_data.screen_buf[start..end].rotate_left(count * vc_data.cols); 448*52da9a59SGnoCiYeH 449*52da9a59SGnoCiYeH let data = &vc_data.screen_buf[start..(bottom - count) * vc_data.cols]; 450*52da9a59SGnoCiYeH 451*52da9a59SGnoCiYeH for line in top..(bottom - count) { 452*52da9a59SGnoCiYeH let mut start = line * vc_data.cols; 453*52da9a59SGnoCiYeH let end = start + vc_data.cols; 454*52da9a59SGnoCiYeH let mut offset = start; 455*52da9a59SGnoCiYeH let mut attr = 1; 456*52da9a59SGnoCiYeH let mut x = 0; 457*52da9a59SGnoCiYeH while offset < end { 458*52da9a59SGnoCiYeH let c = data[offset]; 459*52da9a59SGnoCiYeH 460*52da9a59SGnoCiYeH if attr != c & 0xff00 { 461*52da9a59SGnoCiYeH // 属性变化,输出完上一个的并且更新属性 462*52da9a59SGnoCiYeH attr = c & 0xff00; 463*52da9a59SGnoCiYeH 464*52da9a59SGnoCiYeH let count = offset - start; 465*52da9a59SGnoCiYeH let _ = self.con_putcs( 466*52da9a59SGnoCiYeH vc_data, 467*52da9a59SGnoCiYeH &data[start..offset], 468*52da9a59SGnoCiYeH count, 469*52da9a59SGnoCiYeH line as u32, 470*52da9a59SGnoCiYeH x, 471*52da9a59SGnoCiYeH ); 472*52da9a59SGnoCiYeH start = offset; 473*52da9a59SGnoCiYeH x += count as u32; 474*52da9a59SGnoCiYeH } 475*52da9a59SGnoCiYeH 476*52da9a59SGnoCiYeH offset += 1; 477*52da9a59SGnoCiYeH } 478*52da9a59SGnoCiYeH let _ = self.con_putcs( 479*52da9a59SGnoCiYeH vc_data, 480*52da9a59SGnoCiYeH &data[start..offset], 481*52da9a59SGnoCiYeH offset - start, 482*52da9a59SGnoCiYeH line as u32, 483*52da9a59SGnoCiYeH x, 484*52da9a59SGnoCiYeH ); 485*52da9a59SGnoCiYeH } 486*52da9a59SGnoCiYeH 487*52da9a59SGnoCiYeH let _ = self.con_clear(vc_data, bottom - count, 0, count, vc_data.cols); 488*52da9a59SGnoCiYeH 489*52da9a59SGnoCiYeH let offset = vc_data.cols * (bottom - count); 490*52da9a59SGnoCiYeH for i in 491*52da9a59SGnoCiYeH vc_data.screen_buf[offset..(offset + (vc_data.cols * count))].iter_mut() 492*52da9a59SGnoCiYeH { 493*52da9a59SGnoCiYeH *i = vc_data.erase_char; 494*52da9a59SGnoCiYeH } 495*52da9a59SGnoCiYeH 496*52da9a59SGnoCiYeH return true; 497*52da9a59SGnoCiYeH } 498*52da9a59SGnoCiYeH ScrollMode::PanRedraw => todo!(), 499*52da9a59SGnoCiYeH } 500*52da9a59SGnoCiYeH } 501*52da9a59SGnoCiYeH ScrollDir::Down => { 502*52da9a59SGnoCiYeH if count > vc_data.rows { 503*52da9a59SGnoCiYeH count = vc_data.rows; 504*52da9a59SGnoCiYeH } 505*52da9a59SGnoCiYeH 506*52da9a59SGnoCiYeH match scroll_mode { 507*52da9a59SGnoCiYeH ScrollMode::Move => todo!(), 508*52da9a59SGnoCiYeH ScrollMode::PanMove => todo!(), 509*52da9a59SGnoCiYeH ScrollMode::WrapMove => todo!(), 510*52da9a59SGnoCiYeH ScrollMode::Redraw => { 511*52da9a59SGnoCiYeH // self.scroll_redraw( 512*52da9a59SGnoCiYeH // vc_data, 513*52da9a59SGnoCiYeH // bottom - 1, 514*52da9a59SGnoCiYeH // bottom - top - count, 515*52da9a59SGnoCiYeH // count * vc_data.cols, 516*52da9a59SGnoCiYeH // false, 517*52da9a59SGnoCiYeH // ); 518*52da9a59SGnoCiYeH 519*52da9a59SGnoCiYeH let _ = self.con_clear(vc_data, top, 0, count, vc_data.cols); 520*52da9a59SGnoCiYeH 521*52da9a59SGnoCiYeH let offset = vc_data.cols * top; 522*52da9a59SGnoCiYeH for i in 523*52da9a59SGnoCiYeH vc_data.screen_buf[offset..(offset + (vc_data.cols * count))].iter_mut() 524*52da9a59SGnoCiYeH { 525*52da9a59SGnoCiYeH *i = vc_data.erase_char; 526*52da9a59SGnoCiYeH } 527*52da9a59SGnoCiYeH 528*52da9a59SGnoCiYeH return true; 529*52da9a59SGnoCiYeH } 530*52da9a59SGnoCiYeH ScrollMode::PanRedraw => todo!(), 531*52da9a59SGnoCiYeH } 532*52da9a59SGnoCiYeH } 533*52da9a59SGnoCiYeH } 534*52da9a59SGnoCiYeH } 535*52da9a59SGnoCiYeH } 536*52da9a59SGnoCiYeH 537*52da9a59SGnoCiYeH impl FrameBufferConsole for BlittingFbConsole { 538*52da9a59SGnoCiYeH fn bmove( 539*52da9a59SGnoCiYeH &self, 540*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 541*52da9a59SGnoCiYeH sy: i32, 542*52da9a59SGnoCiYeH sx: i32, 543*52da9a59SGnoCiYeH dy: i32, 544*52da9a59SGnoCiYeH dx: i32, 545*52da9a59SGnoCiYeH height: u32, 546*52da9a59SGnoCiYeH width: u32, 547*52da9a59SGnoCiYeH ) -> Result<(), SystemError> { 548*52da9a59SGnoCiYeH let area = CopyAreaData::new( 549*52da9a59SGnoCiYeH dx * vc_data.font.width as i32, 550*52da9a59SGnoCiYeH dy * vc_data.font.height as i32, 551*52da9a59SGnoCiYeH width * vc_data.font.width, 552*52da9a59SGnoCiYeH height * vc_data.font.height, 553*52da9a59SGnoCiYeH sx * vc_data.font.width as i32, 554*52da9a59SGnoCiYeH sy * vc_data.font.height as i32, 555*52da9a59SGnoCiYeH ); 556*52da9a59SGnoCiYeH 557*52da9a59SGnoCiYeH self.fb().fb_copyarea(area) 558*52da9a59SGnoCiYeH } 559*52da9a59SGnoCiYeH 560*52da9a59SGnoCiYeH fn clear( 561*52da9a59SGnoCiYeH &self, 562*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 563*52da9a59SGnoCiYeH sy: u32, 564*52da9a59SGnoCiYeH sx: u32, 565*52da9a59SGnoCiYeH height: u32, 566*52da9a59SGnoCiYeH width: u32, 567*52da9a59SGnoCiYeH ) -> Result<(), SystemError> { 568*52da9a59SGnoCiYeH let region = FillRectData::new( 569*52da9a59SGnoCiYeH sx * vc_data.font.width, 570*52da9a59SGnoCiYeH sy * vc_data.font.height, 571*52da9a59SGnoCiYeH width * vc_data.font.width, 572*52da9a59SGnoCiYeH height * vc_data.font.height, 573*52da9a59SGnoCiYeH self.get_color(vc_data, vc_data.erase_char, false), 574*52da9a59SGnoCiYeH FillRectROP::Copy, 575*52da9a59SGnoCiYeH ); 576*52da9a59SGnoCiYeH 577*52da9a59SGnoCiYeH self.fb().fb_fillrect(region)?; 578*52da9a59SGnoCiYeH 579*52da9a59SGnoCiYeH Ok(()) 580*52da9a59SGnoCiYeH } 581*52da9a59SGnoCiYeH 582*52da9a59SGnoCiYeH fn put_string( 583*52da9a59SGnoCiYeH &self, 584*52da9a59SGnoCiYeH vc_data: &VirtualConsoleData, 585*52da9a59SGnoCiYeH data: &[u16], 586*52da9a59SGnoCiYeH mut count: u32, 587*52da9a59SGnoCiYeH y: u32, 588*52da9a59SGnoCiYeH x: u32, 589*52da9a59SGnoCiYeH fg: u32, 590*52da9a59SGnoCiYeH bg: u32, 591*52da9a59SGnoCiYeH ) -> Result<(), SystemError> { 592*52da9a59SGnoCiYeH // 向上取整 593*52da9a59SGnoCiYeH let width = (vc_data.font.width + 7) / 8; 594*52da9a59SGnoCiYeH let cellsize = width * vc_data.font.height; 595*52da9a59SGnoCiYeH let fb_info = self.fb(); 596*52da9a59SGnoCiYeH // 一次能输出的最大字数,避免帧缓冲区溢出 597*52da9a59SGnoCiYeH let max_cnt = (fb_info.current_fb_var().xres * fb_info.current_fb_var().yres) / cellsize; 598*52da9a59SGnoCiYeH let attr = FbConAttr::get_attr(data[0], fb_info.color_depth()); 599*52da9a59SGnoCiYeH 600*52da9a59SGnoCiYeH let mut image = FbImage { 601*52da9a59SGnoCiYeH x: x * vc_data.font.width, 602*52da9a59SGnoCiYeH y: y * vc_data.font.height, 603*52da9a59SGnoCiYeH width: 0, 604*52da9a59SGnoCiYeH height: vc_data.font.height, 605*52da9a59SGnoCiYeH fg, 606*52da9a59SGnoCiYeH bg, 607*52da9a59SGnoCiYeH depth: 1, 608*52da9a59SGnoCiYeH data: Default::default(), 609*52da9a59SGnoCiYeH }; 610*52da9a59SGnoCiYeH 611*52da9a59SGnoCiYeH image.data.resize(cellsize as usize * count as usize, 0); 612*52da9a59SGnoCiYeH 613*52da9a59SGnoCiYeH while count > 0 { 614*52da9a59SGnoCiYeH let cnt = count.min(max_cnt); 615*52da9a59SGnoCiYeH 616*52da9a59SGnoCiYeH image.width = vc_data.font.width * cnt; 617*52da9a59SGnoCiYeH 618*52da9a59SGnoCiYeH self.bit_put_string(vc_data, data, attr, cnt, cellsize, &mut image); 619*52da9a59SGnoCiYeH 620*52da9a59SGnoCiYeH image.x += cnt * vc_data.font.width; 621*52da9a59SGnoCiYeH count -= cnt; 622*52da9a59SGnoCiYeH } 623*52da9a59SGnoCiYeH 624*52da9a59SGnoCiYeH Ok(()) 625*52da9a59SGnoCiYeH } 626*52da9a59SGnoCiYeH 627*52da9a59SGnoCiYeH fn fbcon_data(&self) -> SpinLockGuard<super::FrameBufferConsoleData> { 628*52da9a59SGnoCiYeH self.fbcon_data.lock() 629*52da9a59SGnoCiYeH } 630*52da9a59SGnoCiYeH 631*52da9a59SGnoCiYeH fn cursor(&self, vc_data: &VirtualConsoleData, op: CursorOperation, fg: u32, bg: u32) { 632*52da9a59SGnoCiYeH let mut fbcon_data = self.fbcon_data(); 633*52da9a59SGnoCiYeH let fb_info = self.fb(); 634*52da9a59SGnoCiYeH let mut cursor = FbCursor::default(); 635*52da9a59SGnoCiYeH let charmask = if vc_data.hi_font_mask != 0 { 636*52da9a59SGnoCiYeH 0x1ff 637*52da9a59SGnoCiYeH } else { 638*52da9a59SGnoCiYeH 0xff 639*52da9a59SGnoCiYeH }; 640*52da9a59SGnoCiYeH 641*52da9a59SGnoCiYeH // 向上取整 642*52da9a59SGnoCiYeH let w = (vc_data.font.width + 7) / 8; 643*52da9a59SGnoCiYeH let y = fbcon_data.display.real_y(vc_data.state.y as u32); 644*52da9a59SGnoCiYeH 645*52da9a59SGnoCiYeH let c = vc_data.screen_buf[vc_data.pos]; 646*52da9a59SGnoCiYeH let attr = FbConAttr::get_attr(c, fb_info.color_depth()); 647*52da9a59SGnoCiYeH let char_offset = (c as usize & charmask) * ((w * vc_data.font.height) as usize); 648*52da9a59SGnoCiYeH 649*52da9a59SGnoCiYeH if fbcon_data.cursor_state.image.data != &vc_data.font.data[char_offset..] 650*52da9a59SGnoCiYeH || fbcon_data.cursor_reset 651*52da9a59SGnoCiYeH { 652*52da9a59SGnoCiYeH fbcon_data.cursor_state.image.data = vc_data.font.data[char_offset..].to_vec(); 653*52da9a59SGnoCiYeH cursor.set_mode.insert(FbCursorSetMode::FB_CUR_SETIMAGE); 654*52da9a59SGnoCiYeH } 655*52da9a59SGnoCiYeH 656*52da9a59SGnoCiYeH if !attr.is_empty() { 657*52da9a59SGnoCiYeH fbcon_data 658*52da9a59SGnoCiYeH .cursor_data 659*52da9a59SGnoCiYeH .resize(w as usize * vc_data.font.height as usize, 0); 660*52da9a59SGnoCiYeH 661*52da9a59SGnoCiYeH attr.update_attr( 662*52da9a59SGnoCiYeH &mut fbcon_data.cursor_data, 663*52da9a59SGnoCiYeH &vc_data.font.data[char_offset..], 664*52da9a59SGnoCiYeH vc_data, 665*52da9a59SGnoCiYeH ); 666*52da9a59SGnoCiYeH } 667*52da9a59SGnoCiYeH 668*52da9a59SGnoCiYeH if fbcon_data.cursor_state.image.fg != fg 669*52da9a59SGnoCiYeH || fbcon_data.cursor_state.image.bg != bg 670*52da9a59SGnoCiYeH || fbcon_data.cursor_reset 671*52da9a59SGnoCiYeH { 672*52da9a59SGnoCiYeH fbcon_data.cursor_state.image.fg = fg; 673*52da9a59SGnoCiYeH fbcon_data.cursor_state.image.bg = bg; 674*52da9a59SGnoCiYeH cursor.set_mode.insert(FbCursorSetMode::FB_CUR_SETCMAP); 675*52da9a59SGnoCiYeH } 676*52da9a59SGnoCiYeH 677*52da9a59SGnoCiYeH if fbcon_data.cursor_state.image.x != (vc_data.font.width * vc_data.state.x as u32) 678*52da9a59SGnoCiYeH || fbcon_data.cursor_state.image.y != (vc_data.font.height * y) 679*52da9a59SGnoCiYeH || fbcon_data.cursor_reset 680*52da9a59SGnoCiYeH { 681*52da9a59SGnoCiYeH fbcon_data.cursor_state.image.x = vc_data.font.width * vc_data.state.x as u32; 682*52da9a59SGnoCiYeH fbcon_data.cursor_state.image.y = vc_data.font.height * y; 683*52da9a59SGnoCiYeH cursor.set_mode.insert(FbCursorSetMode::FB_CUR_SETPOS); 684*52da9a59SGnoCiYeH } 685*52da9a59SGnoCiYeH 686*52da9a59SGnoCiYeH if fbcon_data.cursor_state.image.height != vc_data.font.height 687*52da9a59SGnoCiYeH || fbcon_data.cursor_state.image.width != vc_data.font.width 688*52da9a59SGnoCiYeH || fbcon_data.cursor_reset 689*52da9a59SGnoCiYeH { 690*52da9a59SGnoCiYeH fbcon_data.cursor_state.image.height = vc_data.font.height; 691*52da9a59SGnoCiYeH fbcon_data.cursor_state.image.width = vc_data.font.width; 692*52da9a59SGnoCiYeH cursor.set_mode.insert(FbCursorSetMode::FB_CUR_SETSIZE); 693*52da9a59SGnoCiYeH } 694*52da9a59SGnoCiYeH 695*52da9a59SGnoCiYeH if fbcon_data.cursor_state.hot_x > 0 696*52da9a59SGnoCiYeH || fbcon_data.cursor_state.hot_y > 0 697*52da9a59SGnoCiYeH || fbcon_data.cursor_reset 698*52da9a59SGnoCiYeH { 699*52da9a59SGnoCiYeH fbcon_data.cursor_state.hot_x = 0; 700*52da9a59SGnoCiYeH cursor.hot_y = 0; 701*52da9a59SGnoCiYeH cursor.set_mode.insert(FbCursorSetMode::FB_CUR_SETHOT); 702*52da9a59SGnoCiYeH } 703*52da9a59SGnoCiYeH 704*52da9a59SGnoCiYeH if cursor.set_mode.contains(FbCursorSetMode::FB_CUR_SETSIZE) 705*52da9a59SGnoCiYeH || vc_data.cursor_type != fbcon_data.display.cursor_shape 706*52da9a59SGnoCiYeH || fbcon_data.cursor_state.mask.is_empty() 707*52da9a59SGnoCiYeH || fbcon_data.cursor_reset 708*52da9a59SGnoCiYeH { 709*52da9a59SGnoCiYeH fbcon_data.display.cursor_shape = vc_data.cursor_type; 710*52da9a59SGnoCiYeH cursor.set_mode.insert(FbCursorSetMode::FB_CUR_SETSHAPE); 711*52da9a59SGnoCiYeH 712*52da9a59SGnoCiYeH let cur_height; 713*52da9a59SGnoCiYeH match fbcon_data.display.cursor_shape.cursor_size() { 714*52da9a59SGnoCiYeH VcCursor::CUR_NONE => { 715*52da9a59SGnoCiYeH cur_height = 0; 716*52da9a59SGnoCiYeH } 717*52da9a59SGnoCiYeH VcCursor::CUR_UNDERLINE => { 718*52da9a59SGnoCiYeH if vc_data.font.height < 10 { 719*52da9a59SGnoCiYeH cur_height = 1; 720*52da9a59SGnoCiYeH } else { 721*52da9a59SGnoCiYeH cur_height = 2; 722*52da9a59SGnoCiYeH } 723*52da9a59SGnoCiYeH } 724*52da9a59SGnoCiYeH VcCursor::CUR_LOWER_THIRD => { 725*52da9a59SGnoCiYeH cur_height = vc_data.font.height / 3; 726*52da9a59SGnoCiYeH } 727*52da9a59SGnoCiYeH VcCursor::CUR_LOWER_HALF => { 728*52da9a59SGnoCiYeH cur_height = vc_data.font.height >> 1; 729*52da9a59SGnoCiYeH } 730*52da9a59SGnoCiYeH VcCursor::CUR_TWO_THIRDS => { 731*52da9a59SGnoCiYeH cur_height = (vc_data.font.height << 1) / 3; 732*52da9a59SGnoCiYeH } 733*52da9a59SGnoCiYeH _ => { 734*52da9a59SGnoCiYeH cur_height = vc_data.font.height; 735*52da9a59SGnoCiYeH } 736*52da9a59SGnoCiYeH } 737*52da9a59SGnoCiYeH 738*52da9a59SGnoCiYeH // 表示空白部分 739*52da9a59SGnoCiYeH let mut size = (vc_data.font.height - cur_height) * w; 740*52da9a59SGnoCiYeH while size > 0 { 741*52da9a59SGnoCiYeH size -= 1; 742*52da9a59SGnoCiYeH fbcon_data.cursor_state.mask.push(0x00); 743*52da9a59SGnoCiYeH } 744*52da9a59SGnoCiYeH size = cur_height * w; 745*52da9a59SGnoCiYeH // 表示光标显示部分 746*52da9a59SGnoCiYeH while size > 0 { 747*52da9a59SGnoCiYeH size -= 1; 748*52da9a59SGnoCiYeH fbcon_data.cursor_state.mask.push(0xff); 749*52da9a59SGnoCiYeH } 750*52da9a59SGnoCiYeH } 751*52da9a59SGnoCiYeH 752*52da9a59SGnoCiYeH match op { 753*52da9a59SGnoCiYeH CursorOperation::Erase => { 754*52da9a59SGnoCiYeH fbcon_data.cursor_state.enable = false; 755*52da9a59SGnoCiYeH } 756*52da9a59SGnoCiYeH _ => { 757*52da9a59SGnoCiYeH fbcon_data.cursor_state.enable = !vc_data.cursor_type.contains(VcCursor::CUR_SW); 758*52da9a59SGnoCiYeH } 759*52da9a59SGnoCiYeH } 760*52da9a59SGnoCiYeH 761*52da9a59SGnoCiYeH if !attr.is_empty() { 762*52da9a59SGnoCiYeH cursor.image.data = fbcon_data.cursor_data.clone(); 763*52da9a59SGnoCiYeH } else { 764*52da9a59SGnoCiYeH cursor.image.data = vc_data.font.data 765*52da9a59SGnoCiYeH [char_offset..char_offset + (w as usize * vc_data.font.height as usize)] 766*52da9a59SGnoCiYeH .to_vec(); 767*52da9a59SGnoCiYeH } 768*52da9a59SGnoCiYeH cursor.image.fg = fbcon_data.cursor_state.image.fg; 769*52da9a59SGnoCiYeH cursor.image.bg = fbcon_data.cursor_state.image.bg; 770*52da9a59SGnoCiYeH cursor.image.x = fbcon_data.cursor_state.image.x; 771*52da9a59SGnoCiYeH cursor.image.y = fbcon_data.cursor_state.image.y; 772*52da9a59SGnoCiYeH cursor.image.height = fbcon_data.cursor_state.image.height; 773*52da9a59SGnoCiYeH cursor.image.width = fbcon_data.cursor_state.image.width; 774*52da9a59SGnoCiYeH cursor.hot_x = fbcon_data.cursor_state.hot_x; 775*52da9a59SGnoCiYeH cursor.hot_y = fbcon_data.cursor_state.hot_y; 776*52da9a59SGnoCiYeH cursor.mask = fbcon_data.cursor_state.mask.clone(); 777*52da9a59SGnoCiYeH cursor.enable = fbcon_data.cursor_state.enable; 778*52da9a59SGnoCiYeH cursor.image.depth = 1; 779*52da9a59SGnoCiYeH cursor.rop = true; 780*52da9a59SGnoCiYeH 781*52da9a59SGnoCiYeH if fb_info.fb_cursor(&cursor).is_err() { 782*52da9a59SGnoCiYeH let _ = fb_info.soft_cursor(cursor); 783*52da9a59SGnoCiYeH } 784*52da9a59SGnoCiYeH 785*52da9a59SGnoCiYeH fbcon_data.cursor_reset = false; 786*52da9a59SGnoCiYeH } 787*52da9a59SGnoCiYeH } 788