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

📄 fbcon.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		 * Probe for VBL: set temp. handler ...		 */		irqres = request_irq(IRQ_MAC_VBL, fb_vbl_detect, 0,				     "framebuffer vbl", info);		vbl_detected = 0;		/*		 * ... and spin for 20 ms ...		 */		while (!vbl_detected && ++ct < 1000)			udelay(20);		if (ct == 1000)			printk			    ("fbcon_startup: No VBL detected, using timer based cursor.\n");		free_irq(IRQ_MAC_VBL, fb_vbl_detect);		if (vbl_detected) {			/*			 * interrupt based cursor ok			 */			cursor_blink_rate = MAC_CURSOR_BLINK_RATE;			irqres =			    request_irq(IRQ_MAC_VBL, fb_vbl_handler, 0,					"framebuffer vbl", info);		} else {			/*			 * VBL not detected: fall through, use timer based cursor			 */			irqres = 1;		}	}#endif				/* CONFIG_MAC */	fbcon_add_cursor_timer(info);	return display_desc;}static void fbcon_init(struct vc_data *vc, int init){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct fbcon_ops *ops;	struct vc_data **default_mode = vc->vc_display_fg;	struct vc_data *svc = *default_mode;	struct display *t, *p = &fb_display[vc->vc_num];	int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;	int cap;	if (info_idx == -1 || info == NULL)	    return;	cap = info->flags;	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||	    (info->fix.type == FB_TYPE_TEXT))		logo = 0;	if (var_to_display(p, &info->var, info))		return;	/* If we are not the first console on this	   fb, copy the font from that console */	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);	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 = rotate;	set_blitting_type(vc, info, NULL);	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)) {		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, p)) {		ops->rotate = FB_ROTATE_UR;		set_blitting_type(vc, info, p);	}}static void fbcon_deinit(struct vc_data *vc){	struct display *p = &fb_display[vc->vc_num];	if (info_idx != -1)	    return;	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 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; 	int c = scr_readw((u16 *) vc->vc_pos);	if (fbcon_is_inactive(vc, info))		return;	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, p, 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;/* * If no vc is existent yet, just set struct display */static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,			      int unit){	struct display *p = &fb_display[unit];	struct display *t = &fb_display[fg_console];	if (var_to_display(p, 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 fb_var_screeninfo *var,			   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;	struct fbcon_ops *ops = info->fbcon_par;	int rows, cols, charcnt = 256;	if (var_to_display(p, var, info))		return;	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];	int redraw = 0;	p->yscroll += count;	if (p->yscroll > p->vrows - vc->vc_rows) {		p->yscroll -= p->vrows - vc->vc_rows;		redraw = 1;	}	if (redraw)		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];	int redraw = 0;	p->yscroll -= count;	if (p->yscroll < 0) {		p->yscroll += p->vrows - vc->vc_rows;		redraw = 1;	}	if (redraw)		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;

⌨️ 快捷键说明

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