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

📄 fbcon.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (var_to_display(p, &info->var, info))		return;	if (!info->fbcon_par)		con2fb_acquire_newinfo(vc, info, vc->vc_num, -1);	/* If we are not the first console on this	   fb, copy the font from that console */	t = &fb_display[fg_console];	if (!p->fontdata) {		if (t->fontdata) {			struct vc_data *fvc = vc_cons[fg_console].d;			vc->vc_font.data = (void *)(p->fontdata =						    fvc->vc_font.data);			vc->vc_font.width = fvc->vc_font.width;			vc->vc_font.height = fvc->vc_font.height;			p->userfont = t->userfont;			if (p->userfont)				REFCOUNT(p->fontdata)++;		} else {			const struct font_desc *font = NULL;			if (!fontname[0] || !(font = find_font(fontname)))				font = get_default_font(info->var.xres,							info->var.yres,							info->pixmap.blit_x,							info->pixmap.blit_y);			vc->vc_font.width = font->width;			vc->vc_font.height = font->height;			vc->vc_font.data = (void *)(p->fontdata = font->data);			vc->vc_font.charcount = 256; /* FIXME  Need to							support more fonts */		}	}	if (p->userfont)		charcnt = FNTCHARCNT(p->fontdata);	vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=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(svc);	if (!*vc->vc_uni_pagedir_loc)		con_copy_unimap(vc, svc);	ops = info->fbcon_par;	p->con_rotate = initial_rotation;	set_blitting_type(vc, info);	cols = vc->vc_cols;	rows = vc->vc_rows;	new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);	new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);	new_cols /= vc->vc_font.width;	new_rows /= vc->vc_font.height;	vc_resize(vc, new_cols, new_rows);	/*	 * We must always set the mode. The mode of the previous console	 * driver could be in the same resolution but we are using different	 * hardware so we have to initialize the hardware.	 *	 * We need to do it in fbcon_init() to prevent screen corruption.	 */	if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) {		if (info->fbops->fb_set_par &&		    !(ops->flags & FBCON_FLAGS_INIT))			info->fbops->fb_set_par(info);		ops->flags |= FBCON_FLAGS_INIT;	}	ops->graphics = 0;	if ((cap & FBINFO_HWACCEL_COPYAREA) &&	    !(cap & FBINFO_HWACCEL_DISABLED))		p->scrollmode = SCROLL_MOVE;	else /* default to something safe */		p->scrollmode = SCROLL_REDRAW;	/*	 *  ++guenther: console.c:vc_allocate() relies on initializing	 *  vc_{cols,rows}, but we must not set those if we are only	 *  resizing the console.	 */	if (!init) {		vc->vc_cols = new_cols;		vc->vc_rows = new_rows;	}	if (logo)		fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);	if (vc == svc && softback_buf)		fbcon_update_softback(vc);	if (ops->rotate_font && ops->rotate_font(info, vc)) {		ops->rotate = FB_ROTATE_UR;		set_blitting_type(vc, info);	}	ops->p = &fb_display[fg_console];}static void fbcon_free_font(struct display *p){	if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))		kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));	p->fontdata = NULL;	p->userfont = 0;}static void fbcon_deinit(struct vc_data *vc){	struct display *p = &fb_display[vc->vc_num];	struct fb_info *info;	struct fbcon_ops *ops;	int idx;	fbcon_free_font(p);	idx = con2fb_map[vc->vc_num];	if (idx == -1)		goto finished;	info = registered_fb[idx];	if (!info)		goto finished;	ops = info->fbcon_par;	if (!ops)		goto finished;	if (CON_IS_VISIBLE(vc))		fbcon_del_cursor_timer(info);	ops->flags &= ~FBCON_FLAGS_INIT;finished:	if (!con_is_bound(&fb_con))		fbcon_exit();	return;}/* ====================================================================== *//*  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 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;	if (sy < vc->vc_top && vc->vc_top == logo_lines)		vc->vc_top = 0;	/* 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;	int y; 	int c = scr_readw((u16 *) vc->vc_pos);	if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)		return;	if (vc->vc_cursor_type & 0x10)		fbcon_del_cursor_timer(info);	else		fbcon_add_cursor_timer(info);	ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;	if (mode & CM_SOFTBACK) {		mode &= ~CM_SOFTBACK;		y = softback_lines;	} else {		if (softback_lines)			fbcon_set_origin(vc);		y = 0;	}	ops->cursor(vc, info, mode, y, 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;static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,			   int unit){	struct display *p, *t;	struct vc_data **default_mode, *vc;	struct vc_data *svc;	struct fbcon_ops *ops = info->fbcon_par;	int rows, cols, charcnt = 256;	p = &fb_display[unit];	if (var_to_display(p, var, info))		return;	vc = vc_cons[unit].d;	if (!vc)		return;	default_mode = vc->vc_display_fg;	svc = *default_mode;	t = &fb_display[svc->vc_num];	if (!vc->vc_font.data) {		vc->vc_font.data = (void *)(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);	var->activate = FB_ACTIVATE_NOW;	info->var.activate = var->activate;	var->yoffset = info->var.yoffset;	var->xoffset = info->var.xoffset;	fb_set_var(info, var);	ops->var = info->var;	vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=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(svc);	if (!*vc->vc_uni_pagedir_loc)		con_copy_unimap(vc, svc);	cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);	cols /= vc->vc_font.width;	rows /= vc->vc_font.height;	vc_resize(vc, cols, rows);	if (CON_IS_VISIBLE(vc)) {		update_screen(vc);		if (softback_buf)			fbcon_update_softback(vc);	}}static __inline__ void ywrap_up(struct vc_data *vc, int count){	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];		p->yscroll += count;	if (p->yscroll >= p->vrows)	/* Deal with wrap */		p->yscroll -= p->vrows;	ops->var.xoffset = 0;	ops->var.yoffset = p->yscroll * vc->vc_font.height;	ops->var.vmode |= FB_VMODE_YWRAP;	ops->update_start(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 fbcon_ops *ops = info->fbcon_par;	struct display *p = &fb_display[vc->vc_num];		p->yscroll -= count;	if (p->yscroll < 0)	/* Deal with wrap */		p->yscroll += p->vrows;	ops->var.xoffset = 0;	ops->var.yoffset = p->yscroll * vc->vc_font.height;	ops->var.vmode |= FB_VMODE_YWRAP;	ops->update_start(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;	}	ops->var.xoffset = 0;	ops->var.yoffset = p->yscroll * vc->vc_font.height;	ops->var.vmode &= ~FB_VMODE_YWRAP;	ops->update_start(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 fbcon_ops *ops = info->fbcon_par;	struct display *p = &fb_display[vc->vc_num];	p->yscroll += count;	if (p->yscroll > p->vrows - vc->vc_rows) {		p->yscroll -= p->vrows - vc->vc_rows;		fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);	}	ops->var.xoffset = 0;	ops->var.yoffset = p->yscroll * vc->vc_font.height;	ops->var.vmode &= ~FB_VMODE_YWRAP;	ops->update_start(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;	}	ops->var.xoffset = 0;	ops->var.yoffset = p->yscroll * vc->vc_font.height;	ops->var.vmode &= ~FB_VMODE_YWRAP;	ops->update_start(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 fbcon_ops *ops = info->fbcon_par;	struct display *p = &fb_display[vc->vc_num];	p->yscroll -= count;	if (p->yscroll < 0) {		p->yscroll += p->vrows - vc->vc_rows;		fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);	}	ops->var.xoffset = 0;	ops->var.yoffset = p->yscroll * vc->vc_font.height;	ops->var.vmode &= ~FB_VMODE_YWRAP;	ops->update_start(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) {

⌨️ 快捷键说明

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