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

📄 fbcon.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));    p->cursor_x = conp->vc_x;    p->cursor_y = y;    switch (mode) {        case CM_ERASE:            cursor_drawn = 0;            break;        case CM_MOVE:        case CM_DRAW:            if (cursor_drawn)	        p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));            vbl_cursor_cnt = CURSOR_DRAW_DELAY;            cursor_on = 1;            break;        }}static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp){    struct display *p;    if (!cursor_on)	return;    if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {	p = &fb_display[fg_console];	if (p->dispsw->revc)		p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));	cursor_drawn ^= 1;	vbl_cursor_cnt = cursor_blink_rate;    }}static int scrollback_phys_max = 0;static int scrollback_max = 0;static int scrollback_current = 0;static __inline__ void ywrap_up(int unit, struct vc_data *conp,				struct display *p, int count){    p->yscroll += count;    if (p->yscroll >= p->vrows)	/* Deal with wrap */	p->yscroll -= p->vrows;    p->var.xoffset = 0;    p->var.yoffset = p->yscroll*fontheight(p);    p->var.vmode |= FB_VMODE_YWRAP;    p->fb_info->updatevar(unit, p->fb_info);    scrollback_max += count;    if (scrollback_max > scrollback_phys_max)	scrollback_max = scrollback_phys_max;    scrollback_current = 0;}static __inline__ void ywrap_down(int unit, struct vc_data *conp,				  struct display *p, int count){    p->yscroll -= count;    if (p->yscroll < 0)		/* Deal with wrap */	p->yscroll += p->vrows;    p->var.xoffset = 0;    p->var.yoffset = p->yscroll*fontheight(p);    p->var.vmode |= FB_VMODE_YWRAP;    p->fb_info->updatevar(unit, p->fb_info);    scrollback_max -= count;    if (scrollback_max < 0)	scrollback_max = 0;    scrollback_current = 0;}static __inline__ void ypan_up(int unit, struct vc_data *conp,			       struct display *p, int count){    p->yscroll += count;    if (p->yscroll > p->vrows-conp->vc_rows) {	p->dispsw->bmove(p, p->vrows-conp->vc_rows, 0, 0, 0,			 conp->vc_rows, conp->vc_cols);	p->yscroll -= p->vrows-conp->vc_rows;    }    p->var.xoffset = 0;    p->var.yoffset = p->yscroll*fontheight(p);    p->var.vmode &= ~FB_VMODE_YWRAP;    p->fb_info->updatevar(unit, p->fb_info);    if (p->dispsw->clear_margins)	p->dispsw->clear_margins(conp, p, 1);    scrollback_max += count;    if (scrollback_max > scrollback_phys_max)	scrollback_max = scrollback_phys_max;    scrollback_current = 0;}static __inline__ void ypan_down(int unit, struct vc_data *conp,				 struct display *p, int count){    p->yscroll -= count;    if (p->yscroll < 0) {	p->dispsw->bmove(p, 0, 0, p->vrows-conp->vc_rows, 0,			 conp->vc_rows, conp->vc_cols);	p->yscroll += p->vrows-conp->vc_rows;    }    p->var.xoffset = 0;    p->var.yoffset = p->yscroll*fontheight(p);    p->var.vmode &= ~FB_VMODE_YWRAP;    p->fb_info->updatevar(unit, p->fb_info);    if (p->dispsw->clear_margins)	p->dispsw->clear_margins(conp, p, 1);    scrollback_max -= count;    if (scrollback_max < 0)	scrollback_max = 0;    scrollback_current = 0;}static void fbcon_redraw_softback(struct vc_data *conp, struct display *p, long delta){    unsigned short *d, *s;    unsigned long n;    int line = 0;    int count = conp->vc_rows;        d = (u16 *)softback_curr;    if (d == (u16 *)softback_in)	d = (u16 *)conp->vc_origin;    n = softback_curr + delta * conp->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) / conp->vc_size_row;		n = softback_top;	    }        } else if (softback_curr >= softback_top && n < softback_top) {	    softback_lines -= (softback_top - n) / conp->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 *)conp->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) {		    p->dispsw->putcs(conp, p, start, s - start,				     real_y(p, line), x);		    x += s - start;		    start = s;		}	    }	    if (c == scr_readw(d)) {	    	if (s > start) {	    	    p->dispsw->putcs(conp, p, start, s - start,				     real_y(p, line), x);		    x += s - start + 1;		    start = s + 1;	    	} else {	    	    x++;	    	    start++;	    	}	    }	    s++;	    d++;	} while (s < le);	if (s > start)	    p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);	line++;	if (d == (u16 *)softback_end)	    d = (u16 *)softback_buf;	if (d == (u16 *)softback_in)	    d = (u16 *)conp->vc_origin;	if (s == (u16 *)softback_end)	    s = (u16 *)softback_buf;	if (s == (u16 *)softback_in)	    s = (u16 *)conp->vc_origin;    }}static void fbcon_redraw(struct vc_data *conp, struct display *p, 			 int line, int count, int offset){    unsigned short *d = (unsigned short *)	(conp->vc_origin + conp->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) {		    p->dispsw->putcs(conp, p, start, s - start,				     real_y(p, line), x);		    x += s - start;		    start = s;		}	    }	    if (c == scr_readw(d)) {	    	if (s > start) {	    	    p->dispsw->putcs(conp, p, start, s - start,				     real_y(p, 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)	    p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);	console_conditional_schedule();	if (offset > 0)		line++;	else {		line--;		/* NOTE: We subtract two lines from these pointers */		s -= conp->vc_size_row;		d -= conp->vc_size_row;	}    }}/** *	fbcon_redraw_clear - clear area of the screen *	@conp: stucture pointing to current active virtual console *	@p: display structure *	@sy: starting Y coordinate *	@sx: starting X coordinate *	@height: height of area to clear *	@width: width of area to clear * *	Clears a specified area of the screen.  All dimensions are in *	pixels. * */void fbcon_redraw_clear(struct vc_data *conp, struct display *p, int sy, int sx,		     int height, int width){    int x, y;    for (y=0; y<height; y++)	for (x=0; x<width; x++)	    fbcon_putc(conp, ' ', sy+y, sx+x);}/** *	fbcon_redraw_bmove - copy area of screen to another area *	@p: display structure *	@sy: origin Y coordinate *	@sx: origin X coordinate *	@dy: destination Y coordinate *	@dx: destination X coordinate *	@h: height of area to copy *	@w: width of area to copy * *	Copies an area of the screen to another area of the same screen. *	All dimensions are in pixels. * *	Note that this function cannot be used together with ypan or *	ywrap. * */void fbcon_redraw_bmove(struct display *p, int sy, int sx, int dy, int dx, int h, int w){    if (sy != dy)    	panic("fbcon_redraw_bmove width sy != dy");    /* h will be always 1, but it does not matter if we are more generic */    while (h-- > 0) {	struct vc_data *conp = p->conp;	unsigned short *d = (unsigned short *)		(conp->vc_origin + conp->vc_size_row * dy + dx * 2);	unsigned short *s = d + (dx - sx);	unsigned short *start = d;	unsigned short *ls = d;	unsigned short *le = d + w;	unsigned short c;	int x = dx;	unsigned short attr = 1;	do {	    c = scr_readw(d);	    if (attr != (c & 0xff00)) {		attr = c & 0xff00;		if (d > start) {		    p->dispsw->putcs(conp, p, start, d - start, dy, x);		    x += d - start;		    start = d;		}	    }	    if (s >= ls && s < le && c == scr_readw(s)) {		if (d > start) {		    p->dispsw->putcs(conp, p, start, d - start, dy, x);		    x += d - start + 1;		    start = d + 1;		} else {		    x++;		    start++;		}	    }	    s++;	    d++;	} while (d < le);	if (d > start)	    p->dispsw->putcs(conp, p, start, d - start, dy, x);	sy++;	dy++;    }}static inline void fbcon_softback_note(struct vc_data *conp, int t, int count){    unsigned short *p;    if (conp->vc_num != fg_console)	return;    p = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);    while (count) {    	scr_memcpyw((u16 *)softback_in, p, conp->vc_size_row);    	count--;    	p = advance_row(p, 1);    	softback_in += conp->vc_size_row;    	if (softback_in == softback_end)    	    softback_in = softback_buf;    	if (softback_in == softback_top) {    	    softback_top += conp->vc_size_row;    	    if (softback_top == softback_end)    	    	softback_top = softback_buf;    	}    }    softback_curr = softback_in;}static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,			int count){    int unit = conp->vc_num;    struct display *p = &fb_display[unit];    int scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);    if (!p->can_soft_blank && console_blanked)	return 0;    if (!count || vt_cons[unit]->vc_mode != KD_TEXT)	return 0;    fbcon_cursor(conp, 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 > conp->vc_rows)	/* Maximum realistic size */		count = conp->vc_rows;	    if (softback_top)	        fbcon_softback_note(conp, t, count);	    if (logo_shown >= 0) goto redraw_up;	    switch (p->scrollmode & __SCROLL_YMASK) {	    case __SCROLL_YMOVE:		p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,				 conp->vc_cols);		p->dispsw->clear(conp, p, b-count, 0, count,				 conp->vc_cols);		break;	    case __SCROLL_YWRAP:		if (b-t-count > 3*conp->vc_rows>>2) {		    if (t > 0)			fbcon_bmove(conp, 0, 0, count, 0, t,				    conp->vc_cols);			ywrap_up(unit, conp, p, count);		    if (conp->vc_rows-b > 0)			fbcon_bmove(conp, b-count, 0, b, 0,				    conp->vc_rows-b, conp->vc_cols);		} else if (p->scrollmode & __SCROLL_YPANREDRAW)		    goto redraw_up;		else		    fbcon_bmove(conp, t+count, 0, t, 0, b-t-count,				conp->vc_cols);		fbcon_clear(conp, b-count, 0, count, conp->vc_cols);		break;	    case __SCROLL_YPAN:		if (( p->yscroll + count <= 2 * (p->vrows - conp->vc_rows)) &&		    (( !scroll_partial && (b-t == conp->vc_rows)) ||		     ( scroll_partial  && (b-t-count > 3*conp->vc_rows>>2)))) {		    if (t > 0)			fbcon_bmove(conp, 0, 0, count, 0, t,				    conp->vc_cols);		    ypan_up(unit, conp, p, count);		    if (conp->vc_rows-b > 0)			fbcon_bmove(conp, b-count, 0, b, 0,				    conp->vc_rows-b, conp->vc_cols);		} else if (p->scrollmode & __SCROLL_YPANREDRAW)		    goto redraw_up;		else		    fbcon_bmove(conp, t+count, 0, t, 0, b-t-count,				conp->vc_cols);		fbcon_clear(conp, b-count, 0, count, conp->vc_cols);		break;	    case __SCROLL_YREDRAW:	    redraw_up:		fbcon_redraw(conp, p, t, b-t-count, count*conp->vc_cols);		p->dispsw->clear(conp, p, real_y(p, b-count), 0,				 count, conp->vc_cols);		scr_memsetw((unsigned short *)(conp->vc_origin + 		    	    conp->vc_size_row * (b-count)), 		    	    conp->vc_video_erase_char,		    	    conp->vc_size_row * count);		return 1;	    }	    break;	case SM_DOWN:	    if (count > conp->vc_rows)	/* Maximum realistic size */		count = conp->vc_rows;	    switch (p->scrollmode & __SCROLL_YMASK) {	    case __SCROLL_YMOVE:		p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,

⌨️ 快捷键说明

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