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

📄 fbcon.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				}			}			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;				}			}			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++;				}			}			scr_writew(c, d);			console_conditional_schedule();			s++;			d++;		} while (s < le);		if (s > start)			fbcon_putcs(vc, start, s - start, line, x);		console_conditional_schedule();		if (offset > 0)			line++;		else {			line--;			/* NOTE: We subtract two lines from these pointers */			s -= vc->vc_size_row;			d -= vc->vc_size_row;		}	}}static inline void fbcon_softback_note(struct vc_data *vc, int t,				       int count){	unsigned short *p;	if (vc->vc_num != fg_console)		return;	p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row);	while (count) {		scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);		count--;		p = advance_row(p, 1);		softback_in += vc->vc_size_row;		if (softback_in == softback_end)			softback_in = softback_buf;		if (softback_in == softback_top) {			softback_top += vc->vc_size_row;			if (softback_top == softback_end)				softback_top = softback_buf;		}	}	softback_curr = softback_in;}static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,			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;	int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;	if (fbcon_is_inactive(vc, info))		return -EINVAL;	fbcon_cursor(vc, CM_ERASE);	/*	 * ++Geert: Only use ywrap/ypan if the console is in text mode	 * ++Andrew: Only use ypan on hardware text mode when scrolling the	 *           whole screen (prevents flicker).	 */	switch (dir) {	case SM_UP:		if (count > vc->vc_rows)	/* Maximum realistic size */			count = vc->vc_rows;		if (softback_top)			fbcon_softback_note(vc, t, count);		if (logo_shown >= 0)			goto redraw_up;		switch (p->scrollmode) {		case SCROLL_MOVE:			ops->bmove(vc, info, t + count, 0, t, 0,				    b - t - count, vc->vc_cols);			ops->clear(vc, info, b - count, 0, count,				  vc->vc_cols);			break;		case SCROLL_WRAP_MOVE:			if (b - t - count > 3 * vc->vc_rows >> 2) {				if (t > 0)					fbcon_bmove(vc, 0, 0, count, 0, t,						    vc->vc_cols);				ywrap_up(vc, count);				if (vc->vc_rows - b > 0)					fbcon_bmove(vc, b - count, 0, b, 0,						    vc->vc_rows - b,						    vc->vc_cols);			} else if (info->flags & FBINFO_READS_FAST)				fbcon_bmove(vc, t + count, 0, t, 0,					    b - t - count, vc->vc_cols);			else				goto redraw_up;			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);			break;		case SCROLL_PAN_REDRAW:			if ((p->yscroll + count <=			     2 * (p->vrows - vc->vc_rows))			    && ((!scroll_partial && (b - t == vc->vc_rows))				|| (scroll_partial				    && (b - t - count >					3 * vc->vc_rows >> 2)))) {				if (t > 0)					fbcon_redraw_move(vc, p, 0, t, count);				ypan_up_redraw(vc, t, count);				if (vc->vc_rows - b > 0)					fbcon_redraw_move(vc, p, b,							  vc->vc_rows - b, b);			} else				fbcon_redraw_move(vc, p, t + count, b - t - count, t);			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);			break;		case SCROLL_PAN_MOVE:			if ((p->yscroll + count <=			     2 * (p->vrows - vc->vc_rows))			    && ((!scroll_partial && (b - t == vc->vc_rows))				|| (scroll_partial				    && (b - t - count >					3 * vc->vc_rows >> 2)))) {				if (t > 0)					fbcon_bmove(vc, 0, 0, count, 0, t,						    vc->vc_cols);				ypan_up(vc, count);				if (vc->vc_rows - b > 0)					fbcon_bmove(vc, b - count, 0, b, 0,						    vc->vc_rows - b,						    vc->vc_cols);			} else if (info->flags & FBINFO_READS_FAST)				fbcon_bmove(vc, t + count, 0, t, 0,					    b - t - count, vc->vc_cols);			else				goto redraw_up;			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);			break;		case SCROLL_REDRAW:		      redraw_up:			fbcon_redraw(vc, p, t, b - t - count,				     count * vc->vc_cols);			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);			scr_memsetw((unsigned short *) (vc->vc_origin +							vc->vc_size_row *							(b - count)),				    vc->vc_video_erase_char,				    vc->vc_size_row * count);			return 1;		}		break;	case SM_DOWN:		if (count > vc->vc_rows)	/* Maximum realistic size */			count = vc->vc_rows;		if (logo_shown >= 0)			goto redraw_down;		switch (p->scrollmode) {		case SCROLL_MOVE:			ops->bmove(vc, info, t, 0, t + count, 0,				    b - t - count, vc->vc_cols);			ops->clear(vc, info, t, 0, count, vc->vc_cols);			break;		case SCROLL_WRAP_MOVE:			if (b - t - count > 3 * vc->vc_rows >> 2) {				if (vc->vc_rows - b > 0)					fbcon_bmove(vc, b, 0, b - count, 0,						    vc->vc_rows - b,						    vc->vc_cols);				ywrap_down(vc, count);				if (t > 0)					fbcon_bmove(vc, count, 0, 0, 0, t,						    vc->vc_cols);			} else if (info->flags & FBINFO_READS_FAST)				fbcon_bmove(vc, t, 0, t + count, 0,					    b - t - count, vc->vc_cols);			else				goto redraw_down;			fbcon_clear(vc, t, 0, count, vc->vc_cols);			break;		case SCROLL_PAN_MOVE:			if ((count - p->yscroll <= p->vrows - vc->vc_rows)			    && ((!scroll_partial && (b - t == vc->vc_rows))				|| (scroll_partial				    && (b - t - count >					3 * vc->vc_rows >> 2)))) {				if (vc->vc_rows - b > 0)					fbcon_bmove(vc, b, 0, b - count, 0,						    vc->vc_rows - b,						    vc->vc_cols);				ypan_down(vc, count);				if (t > 0)					fbcon_bmove(vc, count, 0, 0, 0, t,						    vc->vc_cols);			} else if (info->flags & FBINFO_READS_FAST)				fbcon_bmove(vc, t, 0, t + count, 0,					    b - t - count, vc->vc_cols);			else				goto redraw_down;			fbcon_clear(vc, t, 0, count, vc->vc_cols);			break;		case SCROLL_PAN_REDRAW:			if ((count - p->yscroll <= p->vrows - vc->vc_rows)			    && ((!scroll_partial && (b - t == vc->vc_rows))				|| (scroll_partial				    && (b - t - count >					3 * vc->vc_rows >> 2)))) {				if (vc->vc_rows - b > 0)					fbcon_redraw_move(vc, p, b, vc->vc_rows - b,							  b - count);				ypan_down_redraw(vc, t, count);				if (t > 0)					fbcon_redraw_move(vc, p, count, t, 0);			} else				fbcon_redraw_move(vc, p, t, b - t - count, t + count);			fbcon_clear(vc, t, 0, count, vc->vc_cols);			break;		case SCROLL_REDRAW:		      redraw_down:			fbcon_redraw(vc, p, b - 1, b - t - count,				     -count * vc->vc_cols);			fbcon_clear(vc, t, 0, count, vc->vc_cols);			scr_memsetw((unsigned short *) (vc->vc_origin +							vc->vc_size_row *							t),				    vc->vc_video_erase_char,				    vc->vc_size_row * count);			return 1;		}	}	return 0;}static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,			int height, int width){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct display *p = &fb_display[vc->vc_num];		if (fbcon_is_inactive(vc, info))		return;	if (!width || !height)		return;	/*  Split blits that cross physical y_wrap case.	 *  Pathological case involves 4 blits, better to use recursive	 *  code rather than unrolled case	 *	 *  Recursive invocations don't need to erase the cursor over and	 *  over again, so we use fbcon_bmove_rec()	 */	fbcon_bmove_rec(vc, p, sy, sx, dy, dx, height, width,			p->vrows - p->yscroll);}static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, 			    int dy, int dx, int height, int width, u_int y_break){	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];	struct fbcon_ops *ops = info->fbcon_par;	u_int b;	if (sy < y_break && sy + height > y_break) {		b = y_break - sy;		if (dy < sy) {	/* Avoid trashing self */			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,					y_break);			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,					height - b, width, y_break);		} else {			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,					height - b, width, y_break);			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,					y_break);		}		return;	}	if (dy < y_break && dy + height > y_break) {		b = y_break - dy;		if (dy < sy) {	/* Avoid trashing self */			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,					y_break);			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,					height - b, width, y_break);		} else {			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,					height - b, width, y_break);			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,					y_break);		}		return;	}	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,		   height, width);}static __inline__ void updatescrollmode(struct display *p,					struct fb_info *info,					struct vc_data *vc){	struct fbcon_ops *ops = info->fbcon_par;	int fh = vc->vc_font.height;	int cap = info->flags;	u16 t = 0;	int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,				  info->fix.xpanstep);	int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);	int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);	int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,				   info->var.xres_virtual);	int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&		divides(ypan, vc->vc_font.height) && vyres > yres;	int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&		divides(ywrap, vc->vc_font.height) &&		divides(vc->vc_font.height, vyres) &&		divides(vc->vc_font.height, yres);	int reading_fast = cap & FBINFO_READS_FAST;	int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&		!(cap & FBINFO_HWACCEL_DISABLED);	int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&		!(cap & FBINFO_HWACCEL_DISABLED);	p->vrows = vyres/fh;	if (yres > (fh * (vc->vc_rows + 1)))		p->vrows -= (yres - (fh * vc->vc_rows)) / fh;	if ((yres % fh) && (vyres % fh < yres % fh))		p->vrows--;	if (good_wrap || good_pan) {		if (reading_fast || fast_copyarea)			p->scrollmode = good_wrap ?				SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;		else			p->scrollmode = good_wrap ? SCROLL_REDRAW :				SCROLL_PAN_REDRAW;	} else {		if (reading_fast || (fast_copyarea && !fast_imageblit))			p->scrollmode = SCROLL_MOVE;		else			p->scrollmode = SCROLL_REDRAW;	}}static int fbcon_resize(struct vc_data *vc, unsigned int width, 			unsigned int height){	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];	struct fb_var_screeninfo var = info->var;	int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;	virt_w = FBCON_SWAP(ops->rotate, width, height);	virt_h = FBCON_SWAP(ops->rotate, height, width);	virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,				 vc->vc_font.height);	virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,				 vc->vc_font.width);	var.xres = virt_w * virt_fw;	var.yres = virt_h * virt_fh;	x_diff = info->var.xres - var.xres;	y_diff = info->var.yres - var.yres;	if (x_diff < 0 || x_diff > virt_fw ||	    y_diff < 0 || y_diff > virt_fh) {		const struct fb_videomode *mode;		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);		mode = fb_find_best_mode(&var, &info->modelist);		if (mode == NULL)			return -EINVAL;		display_to_var(&var, p);		fb_videomode_to_var(&var, mode);		if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)			return -EINVAL;		DPRINTK("resize now %ix%i\n", var.xres, var.yres);		if (CON_IS_VISIBLE(vc)) {			var.activate = FB_ACTIVATE_NOW |				FB_ACTIVATE_FORCE;			fb_set_var(info, &var);		}		var_to_display(p, &info->var, info);		ops->var = info->var;	}	updatescrollmode(p, info, vc);	return 0;}static int fbcon_switch(struct vc_data *vc){	struct fb_info *info, *old_info = NULL;	struct fbcon_ops *ops;	struct display *p = &fb_display[vc->vc_num];	struct fb_var_screeninfo var;	int i, prev_console, charcnt = 256;	info = registered_fb[con2fb_map[vc->vc_num]];	ops = info->fbcon_par;	if (softback_top) {		if (softback_lines)			fbcon_set_origin(vc);		softback_top = softback_curr = softback_in = softback_buf;		softback_lines = 0;		fbcon_update_softback(vc);	}	if (logo_shown >= 0) {		struct vc_data *conp2 = vc_cons[logo_shown].d;		if (conp2->vc_top == logo_lines		    && conp2->vc_bottom == conp2->vc_rows)			conp2->vc_top = 0;		logo_shown = FBCON_LOGO_CANSHOW;	}	prev_console = ops->currcon;	if (prev_console != -1)		old_info = registered_fb[con2fb_map[prev_console]];	/*	 * FIXME: If we have multiple fbdev's loaded, we need to	 * update all info->currcon.  Perhaps, we can place this	 * in a centralized structure, but this might break some	 * drivers.	 *	 * info->currcon = vc->vc_num;	 */	for (i = 0; i < FB_MAX; i++) {		if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {			struct fbcon_ops *o = registered_fb[i]->fbcon_par;			o->currcon = vc->vc_num;		}	}	memset(&var, 0, sizeof(struct fb_var_screeninfo));	display_to_var(&var, p);	var.activate = FB_ACTIVATE_NOW;	/*	 * make sure we don't unnecessarily trip the memcmp()	 * in fb_set_var()	 */	info->var.activate = var.activate;	var.yoffset = info->var.yoffset;	var.xoffset = info->var.xoffset;	var.vmode = info->var.vmode;

⌨️ 快捷键说明

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