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

📄 fbcon.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				 conp->vc_cols);		p->dispsw->clear(conp, p, t, 0,				 count, conp->vc_cols);		break;	    case __SCROLL_YWRAP:		if (b-t-count > 3*conp->vc_rows>>2) {		    if (conp->vc_rows-b > 0)			fbcon_bmove(conp, b, 0, b-count, 0,				    conp->vc_rows-b, conp->vc_cols);		    ywrap_down(unit, conp, p, count);		    if (t > 0)			fbcon_bmove(conp, count, 0, 0, 0, t,				    conp->vc_cols);		} else if (p->scrollmode & __SCROLL_YPANREDRAW)		    goto redraw_down;		else		    fbcon_bmove(conp, t, 0, t+count, 0, b-t-count,				conp->vc_cols);		fbcon_clear(conp, t, 0, count, conp->vc_cols);		break;	    case __SCROLL_YPAN:		if (( count-p->yscroll <= p->vrows-conp->vc_rows) &&		    (( !scroll_partial && (b-t == conp->vc_rows)) ||		     ( scroll_partial  && (b-t-count > 3*conp->vc_rows>>2)))) {		    if (conp->vc_rows-b > 0)			fbcon_bmove(conp, b, 0, b-count, 0,				    conp->vc_rows-b, conp->vc_cols);		    ypan_down(unit, conp, p, count);		    if (t > 0)			fbcon_bmove(conp, count, 0, 0, 0, t,				    conp->vc_cols);		} else if (p->scrollmode & __SCROLL_YPANREDRAW)		    goto redraw_down;		else		    fbcon_bmove(conp, t, 0, t+count, 0, b-t-count,				conp->vc_cols);		fbcon_clear(conp, t, 0, count, conp->vc_cols);		break;	    case __SCROLL_YREDRAW:	    redraw_down:		fbcon_redraw(conp, p, b - 1, b-t-count, -count*conp->vc_cols);		p->dispsw->clear(conp, p, real_y(p, t), 0,				 count, conp->vc_cols);	    	scr_memsetw((unsigned short *)(conp->vc_origin + 	    		    conp->vc_size_row * t), 	    		    conp->vc_video_erase_char,	    		    conp->vc_size_row * count);	    	return 1;	    }    }    return 0;}static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,			int height, int width){    int unit = conp->vc_num;    struct display *p = &fb_display[unit];        if (!p->can_soft_blank && console_blanked)	return;    if (!width || !height)	return;    if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&	  (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||	 ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&	  (dx <= p->cursor_x) && (p->cursor_x < dx+width)))	fbcon_cursor(conp, CM_ERASE|CM_SOFTBACK);    /*  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(p, sy, sx, dy, dx, height, width, p->vrows-p->yscroll);}static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,			    int height, int width, u_int y_break){    u_int b;    if (sy < y_break && sy+height > y_break) {	b = y_break-sy;	if (dy < sy) {	/* Avoid trashing self */	    fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);	} else {	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);	    fbcon_bmove_rec(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(p, sy, sx, dy, dx, b, width, y_break);	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);	} else {	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);	    fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);	}	return;    }    p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);}static int fbcon_switch(struct vc_data *conp){    int unit = conp->vc_num;    struct display *p = &fb_display[unit];    struct fb_info *info = p->fb_info;    if (softback_top) {    	int l = fbcon_softback_size / conp->vc_size_row;	if (softback_lines)	    fbcon_set_origin(conp);        softback_top = softback_curr = softback_in = softback_buf;        softback_lines = 0;	if (l > 5)	    softback_end = softback_buf + l * conp->vc_size_row;	else {	    /* Smaller scrollback makes no sense, and 0 would screw	       the operation totally */	    softback_top = 0;	}    }    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 = -1;    }    p->var.yoffset = p->yscroll = 0;    switch (p->scrollmode & __SCROLL_YMASK) {	case __SCROLL_YWRAP:	    scrollback_phys_max = p->vrows-conp->vc_rows;	    break;	case __SCROLL_YPAN:	    scrollback_phys_max = p->vrows-2*conp->vc_rows;	    if (scrollback_phys_max < 0)		scrollback_phys_max = 0;	    break;	default:	    scrollback_phys_max = 0;	    break;    }    scrollback_max = 0;    scrollback_current = 0;    if (info && info->switch_con)	(*info->switch_con)(unit, info);    if (p->dispsw->clear_margins && vt_cons[unit]->vc_mode == KD_TEXT)	p->dispsw->clear_margins(conp, p, 0);    if (logo_shown == -2) {	logo_shown = fg_console;	fbcon_show_logo(); /* This is protected above by initmem_freed */	update_region(fg_console,		      conp->vc_origin + conp->vc_size_row * conp->vc_top,		      conp->vc_size_row * (conp->vc_bottom - conp->vc_top) / 2);	return 0;    }    return 1;}static int fbcon_blank(struct vc_data *conp, int blank){    struct display *p = &fb_display[conp->vc_num];    struct fb_info *info = p->fb_info;    if (blank < 0)	/* Entering graphics mode */	return 0;    fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);    if (!p->can_soft_blank) {	if (blank) {	    if (p->visual == FB_VISUAL_MONO01) {		if (p->screen_base)		    fb_memset255(p->screen_base,				 p->var.xres_virtual*p->var.yres_virtual*				 p->var.bits_per_pixel>>3);	    } else {	    	unsigned short oldc;	    	u_int height;	    	u_int y_break;	    	oldc = conp->vc_video_erase_char;	    	conp->vc_video_erase_char &= p->charmask;	    	height = conp->vc_rows;		y_break = p->vrows-p->yscroll;		if (height > y_break) {			p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, conp->vc_cols);			p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, conp->vc_cols);		} else			p->dispsw->clear(conp, p, real_y(p, 0), 0, height, conp->vc_cols);		conp->vc_video_erase_char = oldc;	    }	    return 0;	} else {	    /* Tell console.c that it has to restore the screen itself */	    return 1;	}    }    (*info->blank)(blank, info);    return 0;}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 inline int fbcon_get_font(int unit, struct console_font_op *op){    struct display *p = &fb_display[unit];    u8 *data = op->data;    u8 *fontdata = p->fontdata;    int i, j;#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY    if (fontwidth(p) != 8) return -EINVAL;#endif    op->width = fontwidth(p);    op->height = fontheight(p);    op->charcount = (p->charmask == 0x1ff) ? 512 : 256;    if (!op->data) return 0;        if (op->width <= 8) {	j = fontheight(p);    	for (i = 0; i < op->charcount; i++) {	    memcpy(data, fontdata, j);	    memset(data+j, 0, 32-j);	    data += 32;	    fontdata += j;	}    }#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY    else if (op->width <= 16) {	j = fontheight(p) * 2;	for (i = 0; i < op->charcount; i++) {	    memcpy(data, fontdata, j);	    memset(data+j, 0, 64-j);	    data += 64;	    fontdata += j;	}    } else if (op->width <= 24) {	for (i = 0; i < op->charcount; i++) {	    for (j = 0; j < fontheight(p); j++) {		*data++ = fontdata[0];		*data++ = fontdata[1];		*data++ = fontdata[2];		fontdata += sizeof(u32);	    }	    memset(data, 0, 3*(32-j));	    data += 3 * (32 - j);	}    } else {	j = fontheight(p) * 4;	for (i = 0; i < op->charcount; i++) {	    memcpy(data, fontdata, j);	    memset(data+j, 0, 128-j);	    data += 128;	    fontdata += j;	}    }#endif    return 0;}static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int userfont){    struct display *p = &fb_display[unit];    int resize;    int w = op->width;    int h = op->height;    int cnt;    char *old_data = NULL;    if (!fontwidthvalid(p,w)) {        if (userfont && op->op != KD_FONT_OP_COPY)	    kfree(data - FONT_EXTRA_WORDS*sizeof(int));	return -ENXIO;    }    if (CON_IS_VISIBLE(p->conp) && softback_lines)	fbcon_set_origin(p->conp);	    resize = (w != fontwidth(p)) || (h != fontheight(p));    if (p->userfont)        old_data = p->fontdata;    if (userfont)        cnt = FNTCHARCNT(data);    else    	cnt = 256;    p->fontdata = data;    if ((p->userfont = userfont))        REFCOUNT(data)++;    p->_fontwidth = w;    p->_fontheight = h;    if (p->conp->vc_hi_font_mask && cnt == 256) {    	p->conp->vc_hi_font_mask = 0;    	if (p->conp->vc_can_do_color)	    p->conp->vc_complement_mask >>= 1;    	p->fgshift--;    	p->bgshift--;    	p->charmask = 0xff;	/* ++Edmund: reorder the attribute bits */	if (p->conp->vc_can_do_color) {	    struct vc_data *conp = p->conp;	    unsigned short *cp = (unsigned short *) conp->vc_origin;	    int count = conp->vc_screenbuf_size/2;	    unsigned short c;	    for (; count > 0; count--, cp++) {	        c = scr_readw(cp);		scr_writew(((c & 0xfe00) >> 1) | (c & 0xff), cp);	    }	    c = conp->vc_video_erase_char;	    conp->vc_video_erase_char = ((c & 0xfe00) >> 1) | (c & 0xff);	    conp->vc_attr >>= 1;	}    } else if (!p->conp->vc_hi_font_mask && cnt == 512) {    	p->conp->vc_hi_font_mask = 0x100;    	if (p->conp->vc_can_do_color)	    p->conp->vc_complement_mask <<= 1;    	p->fgshift++;    	p->bgshift++;    	p->charmask = 0x1ff;	/* ++Edmund: reorder the attribute bits */	{	    struct vc_data *conp = p->conp;	    unsigned short *cp = (unsigned short *) conp->vc_origin;	    int count = conp->vc_screenbuf_size/2;	    unsigned short c;	    for (; count > 0; count--, cp++) {	        unsigned short newc;	        c = scr_readw(cp);		if (conp->vc_can_do_color)		    newc = ((c & 0xff00) << 1) | (c & 0xff);		else		    newc = c & ~0x100;		scr_writew(newc, cp);	    }	    c = conp->vc_video_erase_char;	    if (conp->vc_can_do_color) {		conp->vc_video_erase_char = ((c & 0xff00) << 1) | (c & 0xff);		conp->vc_attr <<= 1;	    } else	        conp->vc_video_erase_char = c & ~0x100;	}    }    fbcon_font_widths(p);    if (resize) {    	struct vc_data *conp = p->conp;	/* reset wrap/pan */	p->var.xoffset = p->var.yoffset = p->yscroll = 0;	p->vrows = p->var.yres_virtual/h;	if ((p->var.yres % h) && (p->var.yres_virtual % h < p->var.yres % h))	    p->vrows--;	updatescrollmode(p);	vc_resize_con( p->var.yres/h, p->var.xres/w, unit );        if (CON_IS_VISIBLE(conp) && softback_buf) {	    int l = fbcon_softback_size / conp->vc_size_row;	    if (l > 5)		softback_end = softback_buf + l * conp->vc_size_row;	    else {		/* Smaller scrollback makes no sense, and 0 would screw		   the operation totally */		softback_top = 0;    	    }    	}    } else if (CON_IS_VISIBLE(p->conp) && vt_cons[unit]->vc_mode == KD_TEXT) {	if (p->dispsw->clear_margins)	    p->dispsw->clear_margins(p->conp, p, 0);	update_screen(unit);    }    if (old_data && (--REFCOUNT(old_data) == 0))	kfree(old_data - FONT_EXTRA_WORDS*sizeof(int));    return 0;}static inline int fbcon_copy_font(int unit, struct console_font_op *op){    struct display *od, *p = &fb_display[unit];    int h = op->height;    if (h < 0 || !vc_cons_allocated( h ))        return -ENOTTY;    if (h == unit)        return 0; /* nothing to do */    od = &fb_display[h];    if (od->fontdata == p->fontdata)        return 0; /* already the same font... */    op->width = fontwidth(od);    op->height = fontheight(od);    return fbcon_do_set_font(unit, op, od->fontdata, od->userfont);}static inline int fbcon_set_font(int unit, struct console_font_op *op){    int w = op->width;    int h = op->height;    int size = h;    int i, k;    u8 *new_data, *data = op->data, *p;#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY    if (w != 8)    	return -EINVAL;#endif    if ((w <= 0) || (w > 32) || (op->charcount != 256 && op->charcount != 512))        return -EINVAL;        if (w > 8) {     	if (w <= 16)    		size *= 2;    	else    		size *= 4;    }    size *= op->charcount;           if (!(new_data = kmalloc(FONT_EXTRA_WORDS*sizeof(int)+size, GFP_USER)))        return -ENOMEM;    new_data += FONT_EXTRA_WORDS*sizeof(int);    FNTSIZE(new_data) = size;    FNTCHARCNT(new_data) = op->charcount;    REFCOUNT(new_data) = 0; /* usage counter */    p = new_data;    if (w <= 8) {	for (i = 0; i < op->charcount; i++) {	    memcpy(p, data, h);	    data += 32;	    p += h;	}    }#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY    else if (w <= 16) {	h *= 2;	for (i = 0; i < op->charcount; i++) {	    memcpy(p, data, h);	    data += 64;	    p += h;

⌨️ 快捷键说明

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