⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fbcon.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	fbcon_free_font(p);}/* ====================================================================== *//*  fbcon_XXX routines - interface used by the world * *  This system is now divided into two levels because of complications *  caused by hardware scrolling. Top level functions: * *	fbcon_bmove(), fbcon_clear(), fbcon_putc(), fbcon_clear_margins() * *  handles y values in range [0, scr_height-1] that correspond to real *  screen positions. y_wrap shift means that first line of bitmap may be *  anywhere on this display. These functions convert lineoffsets to *  bitmap offsets and deal with the wrap-around case by splitting blits. * *	fbcon_bmove_physical_8()    -- These functions fast implementations *	fbcon_clear_physical_8()    -- of original fbcon_XXX fns. *	fbcon_putc_physical_8()	    -- (font width != 8) may be added later * *  WARNING: * *  At the moment fbcon_putc() cannot blit across vertical wrap boundary *  Implies should only really hardware scroll in rows. Only reason for *  restriction is simplicity & efficiency at the moment. */static __inline__ int real_y(struct display *p, int ypos){	int rows = p->vrows;	ypos += p->yscroll;	return ypos < rows ? ypos : ypos - rows;}static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,			int width){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct fbcon_ops *ops = info->fbcon_par;	struct display *p = &fb_display[vc->vc_num];	u_int y_break;	if (fbcon_is_inactive(vc, info))		return;	if (!height || !width)		return;	/* Split blits that cross physical y_wrap boundary */	y_break = p->vrows - p->yscroll;	if (sy < y_break && sy + height - 1 >= y_break) {		u_int b = y_break - sy;		ops->clear(vc, info, real_y(p, sy), sx, b, width);		ops->clear(vc, info, real_y(p, sy + b), sx, height - b,				 width);	} else		ops->clear(vc, info, real_y(p, sy), sx, height, width);}static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,			int count, int ypos, int xpos){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct display *p = &fb_display[vc->vc_num];	struct fbcon_ops *ops = info->fbcon_par;	if (!fbcon_is_inactive(vc, info))		ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,			   get_color(vc, info, scr_readw(s), 1),			   get_color(vc, info, scr_readw(s), 0));}static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos){	unsigned short chr;	scr_writew(c, &chr);	fbcon_putcs(vc, &chr, 1, ypos, xpos);}static void fbcon_clear_margins(struct vc_data *vc, int bottom_only){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct fbcon_ops *ops = info->fbcon_par;	if (!fbcon_is_inactive(vc, info))		ops->clear_margins(vc, info, bottom_only);}static void fbcon_cursor(struct vc_data *vc, int mode){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct fbcon_ops *ops = info->fbcon_par;	struct display *p = &fb_display[vc->vc_num];	int y = real_y(p, vc->vc_y); 	int c = scr_readw((u16 *) vc->vc_pos);	if (fbcon_is_inactive(vc, info))		return;	ops->cursor_flash = 1;	if (mode & CM_SOFTBACK) {		mode &= ~CM_SOFTBACK;		if (softback_lines) {			if (y + softback_lines >= vc->vc_rows) {				mode = CM_ERASE;				ops->cursor_flash = 0;			}			else				y += softback_lines;		}	} else if (softback_lines)		fbcon_set_origin(vc);	ops->cursor(vc, info, p, mode, get_color(vc, info, c, 1),		    get_color(vc, info, c, 0));	vbl_cursor_cnt = CURSOR_DRAW_DELAY;}static int scrollback_phys_max = 0;static int scrollback_max = 0;static int scrollback_current = 0;int update_var(int con, struct fb_info *info){	if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)		return fb_pan_display(info, &info->var);	return 0;}/* * If no vc is existent yet, just set struct display */static void fbcon_preset_disp(struct fb_info *info, int unit){	struct display *p = &fb_display[unit];	struct display *t = &fb_display[fg_console];	info->var.xoffset = info->var.yoffset = p->yscroll = 0;	if (var_to_display(p, &info->var, info))		return;	p->fontdata = t->fontdata;	p->userfont = t->userfont;	if (p->userfont)		REFCOUNT(p->fontdata)++;}static void fbcon_set_disp(struct fb_info *info, struct vc_data *vc){	struct display *p = &fb_display[vc->vc_num], *t;	struct vc_data **default_mode = vc->vc_display_fg;	struct vc_data *svc = *default_mode;	int display_fg = (*default_mode)->vc_num;	int rows, cols, charcnt = 256;	info->var.xoffset = info->var.yoffset = p->yscroll = 0;	if (var_to_display(p, &info->var, info))		return;	t = &fb_display[display_fg];	if (!vc->vc_font.data) {		vc->vc_font.data = p->fontdata = t->fontdata;		vc->vc_font.width = (*default_mode)->vc_font.width;		vc->vc_font.height = (*default_mode)->vc_font.height;		p->userfont = t->userfont;		if (p->userfont)			REFCOUNT(p->fontdata)++;	}	if (p->userfont)		charcnt = FNTCHARCNT(p->fontdata);	vc->vc_can_do_color = (fb_get_color_depth(info) != 1);	vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;	if (charcnt == 256) {		vc->vc_hi_font_mask = 0;	} else {		vc->vc_hi_font_mask = 0x100;		if (vc->vc_can_do_color)			vc->vc_complement_mask <<= 1;	}	if (!*svc->vc_uni_pagedir_loc)		con_set_default_unimap(display_fg);	if (!*vc->vc_uni_pagedir_loc)		con_copy_unimap(vc->vc_num, display_fg);	cols = info->var.xres / vc->vc_font.width;	rows = info->var.yres / vc->vc_font.height;	vc_resize(vc->vc_num, cols, rows);	if (CON_IS_VISIBLE(vc)) {		update_screen(vc->vc_num);		if (softback_buf) {			int l = fbcon_softback_size / vc->vc_size_row;			if (l > 5)				softback_end = softback_buf + l *					vc->vc_size_row;			else {				/* Smaller scrollback makes no sense, and 0				   would screw the operation totally */				softback_top = 0;			}		}	}}static __inline__ void ywrap_up(struct vc_data *vc, int count){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct display *p = &fb_display[vc->vc_num];		p->yscroll += count;	if (p->yscroll >= p->vrows)	/* Deal with wrap */		p->yscroll -= p->vrows;	info->var.xoffset = 0;	info->var.yoffset = p->yscroll * vc->vc_font.height;	info->var.vmode |= FB_VMODE_YWRAP;	update_var(vc->vc_num, info);	scrollback_max += count;	if (scrollback_max > scrollback_phys_max)		scrollback_max = scrollback_phys_max;	scrollback_current = 0;}static __inline__ void ywrap_down(struct vc_data *vc, int count){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct display *p = &fb_display[vc->vc_num];		p->yscroll -= count;	if (p->yscroll < 0)	/* Deal with wrap */		p->yscroll += p->vrows;	info->var.xoffset = 0;	info->var.yoffset = p->yscroll * vc->vc_font.height;	info->var.vmode |= FB_VMODE_YWRAP;	update_var(vc->vc_num, info);	scrollback_max -= count;	if (scrollback_max < 0)		scrollback_max = 0;	scrollback_current = 0;}static __inline__ void ypan_up(struct vc_data *vc, int count){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct display *p = &fb_display[vc->vc_num];	struct fbcon_ops *ops = info->fbcon_par;	p->yscroll += count;	if (p->yscroll > p->vrows - vc->vc_rows) {		ops->bmove(vc, info, p->vrows - vc->vc_rows,			    0, 0, 0, vc->vc_rows, vc->vc_cols);		p->yscroll -= p->vrows - vc->vc_rows;	}	info->var.xoffset = 0;	info->var.yoffset = p->yscroll * vc->vc_font.height;	info->var.vmode &= ~FB_VMODE_YWRAP;	update_var(vc->vc_num, info);	fbcon_clear_margins(vc, 1);	scrollback_max += count;	if (scrollback_max > scrollback_phys_max)		scrollback_max = scrollback_phys_max;	scrollback_current = 0;}static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct display *p = &fb_display[vc->vc_num];	int redraw = 0;	p->yscroll += count;	if (p->yscroll > p->vrows - vc->vc_rows) {		p->yscroll -= p->vrows - vc->vc_rows;		redraw = 1;	}	info->var.xoffset = 0;	info->var.yoffset = p->yscroll * vc->vc_font.height;	info->var.vmode &= ~FB_VMODE_YWRAP;	if (redraw)		fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);	update_var(vc->vc_num, info);	fbcon_clear_margins(vc, 1);	scrollback_max += count;	if (scrollback_max > scrollback_phys_max)		scrollback_max = scrollback_phys_max;	scrollback_current = 0;}static __inline__ void ypan_down(struct vc_data *vc, int count){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct display *p = &fb_display[vc->vc_num];	struct fbcon_ops *ops = info->fbcon_par;		p->yscroll -= count;	if (p->yscroll < 0) {		ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,			    0, vc->vc_rows, vc->vc_cols);		p->yscroll += p->vrows - vc->vc_rows;	}	info->var.xoffset = 0;	info->var.yoffset = p->yscroll * vc->vc_font.height;	info->var.vmode &= ~FB_VMODE_YWRAP;	update_var(vc->vc_num, info);	fbcon_clear_margins(vc, 1);	scrollback_max -= count;	if (scrollback_max < 0)		scrollback_max = 0;	scrollback_current = 0;}static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct display *p = &fb_display[vc->vc_num];	int redraw = 0;	p->yscroll -= count;	if (p->yscroll < 0) {		p->yscroll += p->vrows - vc->vc_rows;		redraw = 1;	}	info->var.xoffset = 0;	info->var.yoffset = p->yscroll * vc->vc_font.height;	info->var.vmode &= ~FB_VMODE_YWRAP;	if (redraw)		fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);	update_var(vc->vc_num, info);	fbcon_clear_margins(vc, 1);	scrollback_max -= count;	if (scrollback_max < 0)		scrollback_max = 0;	scrollback_current = 0;}static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,				  long delta){	int count = vc->vc_rows;	unsigned short *d, *s;	unsigned long n;	int line = 0;	d = (u16 *) softback_curr;	if (d == (u16 *) softback_in)		d = (u16 *) vc->vc_origin;	n = softback_curr + delta * vc->vc_size_row;	softback_lines -= delta;	if (delta < 0) {		if (softback_curr < softback_top && n < softback_buf) {			n += softback_end - softback_buf;			if (n < softback_top) {				softback_lines -=				    (softback_top - n) / vc->vc_size_row;				n = softback_top;			}		} else if (softback_curr >= softback_top			   && n < softback_top) {			softback_lines -=			    (softback_top - n) / vc->vc_size_row;			n = softback_top;		}	} else {		if (softback_curr > softback_in && n >= softback_end) {			n += softback_buf - softback_end;			if (n > softback_in) {				n = softback_in;				softback_lines = 0;			}		} else if (softback_curr <= softback_in && n > softback_in) {			n = softback_in;			softback_lines = 0;		}	}	if (n == softback_curr)		return;	softback_curr = n;	s = (u16 *) softback_curr;	if (s == (u16 *) softback_in)		s = (u16 *) vc->vc_origin;	while (count--) {		unsigned short *start;		unsigned short *le;		unsigned short c;		int x = 0;		unsigned short attr = 1;		start = s;		le = advance_row(s, 1);		do {			c = scr_readw(s);			if (attr != (c & 0xff00)) {				attr = c & 0xff00;				if (s > start) {					fbcon_putcs(vc, start, s - start,						    line, x);					x += s - start;					start = s;				}			}			if (c == scr_readw(d)) {				if (s > start) {					fbcon_putcs(vc, start, s - start,						    line, x);					x += s - start + 1;					start = s + 1;				} else {					x++;					start++;				}			}			s++;			d++;		} while (s < le);		if (s > start)			fbcon_putcs(vc, start, s - start, line, x);		line++;		if (d == (u16 *) softback_end)			d = (u16 *) softback_buf;		if (d == (u16 *) softback_in)			d = (u16 *) vc->vc_origin;		if (s == (u16 *) softback_end)			s = (u16 *) softback_buf;		if (s == (u16 *) softback_in)			s = (u16 *) vc->vc_origin;	}}static void fbcon_redraw_move(struct vc_data *vc, struct display *p,			      int line, int count, int dy){	unsigned short *s = (unsigned short *)		(vc->vc_origin + vc->vc_size_row * line);	while (count--) {		unsigned short *start = s;		unsigned short *le = advance_row(s, 1);		unsigned short c;		int x = 0;		unsigned short attr = 1;		do {			c = scr_readw(s);			if (attr != (c & 0xff00)) {				attr = c & 0xff00;				if (s > start) {					fbcon_putcs(vc, start, s - start,						    dy, x);					x += s - start;					start = s;				}			}			console_conditional_schedule();			s++;		} while (s < le);		if (s > start)			fbcon_putcs(vc, start, s - start, dy, x);		console_conditional_schedule();		dy++;	}}static void fbcon_redraw(struct vc_data *vc, struct display *p,			 int line, int count, int offset){	unsigned short *d = (unsigned short *)	    (vc->vc_origin + vc->vc_size_row * line);	unsigned short *s = d + offset;	while (count--) {		unsigned short *start = s;		unsigned short *le = advance_row(s, 1);		unsigned short c;		int x = 0;		unsigned short attr = 1;		do {			c = scr_readw(s);			if (attr != (c & 0xff00)) {				attr = c & 0xff00;				if (s > start) {					fbcon_putcs(vc, start, s - start,						    line, x);					x += s - start;					start = s;				}			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -