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

📄 fbcon.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }#endif /* CONFIG_MAC */#if defined(__arm__) && defined(IRQ_VSYNCPULSE)    cursor_blink_rate = ARM_CURSOR_BLINK_RATE;    irqres = request_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler, SA_SHIRQ,			 "console/cursor", fbcon_vbl_handler);#endif    if (irqres) {	use_timer_cursor = 1;	cursor_blink_rate = DEFAULT_CURSOR_BLINK_RATE;	cursor_timer.expires = jiffies+HZ/50;	add_timer(&cursor_timer);    }#ifdef CONFIG_PM    pm_fbcon = pm_register(PM_SYS_DEV, PM_SYS_VGA, pm_fbcon_request);#endif    return display_desc;}static void fbcon_init(struct vc_data *conp, int init){    int unit = conp->vc_num;    struct fb_info *info;    /* on which frame buffer will we open this console? */    info = registered_fb[(int)con2fb_map[unit]];    info->changevar = &fbcon_changevar;    fb_display[unit] = *(info->disp);	/* copy from default */    DPRINTK("mode:   %s\n",info->modename);    DPRINTK("visual: %d\n",fb_display[unit].visual);    DPRINTK("res:    %dx%d-%d\n",fb_display[unit].var.xres,	                     fb_display[unit].var.yres,	                     fb_display[unit].var.bits_per_pixel);    fb_display[unit].conp = conp;    fb_display[unit].fb_info = info;    /* clear out the cmap so we don't have dangling pointers */    fb_display[unit].cmap.len = 0;    fb_display[unit].cmap.red = 0;    fb_display[unit].cmap.green = 0;    fb_display[unit].cmap.blue = 0;    fb_display[unit].cmap.transp = 0;    fbcon_setup(unit, init, !init);    /* Must be done after fbcon_setup to prevent excess updates */    conp->vc_display_fg = &info->display_fg;    if (!info->display_fg)        info->display_fg = conp;}static void fbcon_deinit(struct vc_data *conp){    int unit = conp->vc_num;    struct display *p = &fb_display[unit];    fbcon_free_font(p);    p->dispsw = &fbcon_dummy;    p->conp = 0;}static int fbcon_changevar(int con){    if (fb_display[con].conp)	    fbcon_setup(con, 0, 0);    return 0;}static __inline__ void updatescrollmode(struct display *p){    int m;    if (p->scrollmode & __SCROLL_YFIXED)    	return;    if (divides(p->ywrapstep, fontheight(p)) &&	divides(fontheight(p), p->var.yres_virtual))	m = __SCROLL_YWRAP;    else if (divides(p->ypanstep, fontheight(p)) &&	     p->var.yres_virtual >= p->var.yres+fontheight(p))	m = __SCROLL_YPAN;    else if (p->scrollmode & __SCROLL_YNOMOVE)    	m = __SCROLL_YREDRAW;    else	m = __SCROLL_YMOVE;    p->scrollmode = (p->scrollmode & ~__SCROLL_YMASK) | m;}static void fbcon_font_widths(struct display *p){    int i;        p->_fontwidthlog = 0;    for (i = 2; i <= 6; i++)    	if (fontwidth(p) == (1 << i))	    p->_fontwidthlog = i;    p->_fontheightlog = 0;    for (i = 2; i <= 6; i++)    	if (fontheight(p) == (1 << i))	    p->_fontheightlog = i;}#define fontwidthvalid(p,w) ((p)->dispsw->fontwidthmask & FONTWIDTH(w))static void fbcon_setup(int con, int init, int logo){    struct display *p = &fb_display[con];    struct vc_data *conp = p->conp;    int nr_rows, nr_cols;    int old_rows, old_cols;    unsigned short *save = NULL, *r, *q;    int i, charcnt = 256;    struct fbcon_font_desc *font;        if (con != fg_console || (p->fb_info->flags & FBINFO_FLAG_MODULE) ||        p->type == FB_TYPE_TEXT)    	logo = 0;    p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */    if (con == fg_console && p->type != FB_TYPE_TEXT) {   	if (fbcon_softback_size) {	    if (!softback_buf) {		softback_buf = (unsigned long)kmalloc(fbcon_softback_size, GFP_KERNEL);		if (!softback_buf) {    	            fbcon_softback_size = 0;    	            softback_top = 0;    		}    	    }	} else {	    if (softback_buf) {		kfree((void *)softback_buf);		softback_buf = 0;		softback_top = 0;	    }	}	if (softback_buf)	    softback_in = softback_top = softback_curr = softback_buf;	softback_lines = 0;    }        for (i = 0; i < MAX_NR_CONSOLES; i++)    	if (i != con && fb_display[i].fb_info == p->fb_info &&    	    fb_display[i].conp && fb_display[i].fontdata)    		break;    fbcon_free_font(p);        if (i < MAX_NR_CONSOLES) {    	struct display *q = &fb_display[i];        if (fontwidthvalid(p,fontwidth(q))) {            /* If we are not the first console on this               fb, copy the font from that console */	    p->_fontwidth = q->_fontwidth;	    p->_fontheight = q->_fontheight;    	    p->_fontwidthlog = q->_fontwidthlog;    	    p->_fontheightlog = q->_fontheightlog;    	    p->fontdata = q->fontdata;    	    p->userfont = q->userfont;     	    if (p->userfont) {    		REFCOUNT(p->fontdata)++;    		charcnt = FNTCHARCNT(p->fontdata);    	    }    	    con_copy_unimap(con, i);    	}    }    if (!p->fontdata) {        if (!p->fb_info->fontname[0] ||	    !(font = fbcon_find_font(p->fb_info->fontname)))	        font = fbcon_get_default_font(p->var.xres, p->var.yres);        p->_fontwidth = font->width;        p->_fontheight = font->height;        p->fontdata = font->data;        fbcon_font_widths(p);    }        if (!fontwidthvalid(p,fontwidth(p))) {#if defined(CONFIG_FBCON_MAC) && defined(CONFIG_MAC)	if (MACH_IS_MAC)	    /* ++Geert: hack to make 6x11 fonts work on mac */	    p->dispsw = &fbcon_mac;	else#endif	{	    /* ++Geert: changed from panic() to `correct and continue' */	    printk(KERN_ERR "fbcon_setup: No support for fontwidth %d\n", fontwidth(p));	    p->dispsw = &fbcon_dummy;	}    }    if (p->dispsw->set_font)    	p->dispsw->set_font(p, fontwidth(p), fontheight(p));    updatescrollmode(p);        old_cols = conp->vc_cols;    old_rows = conp->vc_rows;        nr_cols = p->var.xres/fontwidth(p);    nr_rows = p->var.yres/fontheight(p);        if (logo) {    	/* Need to make room for the logo */	int cnt;	int step;        	logo_lines = (LOGO_H + fontheight(p) - 1) / fontheight(p);    	q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);    	step = logo_lines * old_cols;    	for (r = q - logo_lines * old_cols; r < q; r++)    	    if (scr_readw(r) != conp->vc_video_erase_char)    	    	break;	if (r != q && nr_rows >= old_rows + logo_lines) {    	    save = kmalloc(logo_lines * nr_cols * 2, GFP_KERNEL);    	    if (save) {    	        int i = old_cols < nr_cols ? old_cols : nr_cols;    	    	scr_memsetw(save, conp->vc_video_erase_char, logo_lines * nr_cols * 2);    	    	r = q - step;    	    	for (cnt = 0; cnt < logo_lines; cnt++, r += i)    	    		scr_memcpyw(save + cnt * nr_cols, r, 2 * i);    	    	r = q;    	    }    	}    	if (r == q) {    	    /* We can scroll screen down */	    r = q - step - old_cols;    	    for (cnt = old_rows - logo_lines; cnt > 0; cnt--) {    	    	scr_memcpyw(r + step, r, conp->vc_size_row);    	    	r -= old_cols;    	    }    	    if (!save) {	    	conp->vc_y += logo_lines;    		conp->vc_pos += logo_lines * conp->vc_size_row;    	    }    	}    	scr_memsetw((unsigned short *)conp->vc_origin,		    conp->vc_video_erase_char, 		    conp->vc_size_row * logo_lines);    }        /*     *  ++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) {	conp->vc_cols = nr_cols;	conp->vc_rows = nr_rows;    }    p->vrows = p->var.yres_virtual/fontheight(p);    if ((p->var.yres % fontheight(p)) &&	(p->var.yres_virtual % fontheight(p) < p->var.yres % fontheight(p)))	p->vrows--;    conp->vc_can_do_color = p->var.bits_per_pixel != 1;    conp->vc_complement_mask = conp->vc_can_do_color ? 0x7700 : 0x0800;    if (charcnt == 256) {    	conp->vc_hi_font_mask = 0;    	p->fgshift = 8;    	p->bgshift = 12;    	p->charmask = 0xff;    } else {    	conp->vc_hi_font_mask = 0x100;    	if (conp->vc_can_do_color)	    conp->vc_complement_mask <<= 1;    	p->fgshift = 9;    	p->bgshift = 13;    	p->charmask = 0x1ff;    }    if (p->dispsw == &fbcon_dummy)	printk(KERN_WARNING "fbcon_setup: type %d (aux %d, depth %d) not "	       "supported\n", p->type, p->type_aux, p->var.bits_per_pixel);    p->dispsw->setup(p);    p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;    p->bgcol = 0;    if (!init) {	if (conp->vc_cols != nr_cols || conp->vc_rows != nr_rows)	    vc_resize_con(nr_rows, nr_cols, con);	else if (CON_IS_VISIBLE(conp) &&		 vt_cons[conp->vc_num]->vc_mode == KD_TEXT) {	    if (p->dispsw->clear_margins)		p->dispsw->clear_margins(conp, p, 0);	    update_screen(con);	}	if (save) {    	    q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);	    scr_memcpyw(q, save, logo_lines * nr_cols * 2);	    conp->vc_y += logo_lines;    	    conp->vc_pos += logo_lines * conp->vc_size_row;    	    kfree(save);	}    }	    if (logo) {	logo_shown = -2;    	conp->vc_top = logo_lines;    }        if (con == fg_console && 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;    	}    }}/* ====================================================================== *//*  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() * *  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()	    -- (fontwidth != 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 __inline__ int real_y(struct display *p, int ypos){    int rows = p->vrows;    ypos += p->yscroll;    return ypos < rows ? ypos : ypos-rows;}static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,			int width){    int unit = conp->vc_num;    struct display *p = &fb_display[unit];    u_int y_break;    int redraw_cursor = 0;    if (!p->can_soft_blank && console_blanked)	return;    if (!height || !width)	return;    if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&	(sx <= p->cursor_x) && (p->cursor_x < sx+width)) {	cursor_undrawn();	redraw_cursor = 1;    }    /* 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;	p->dispsw->clear(conp, p, real_y(p, sy), sx, b, width);	p->dispsw->clear(conp, p, real_y(p, sy+b), sx, height-b, width);    } else	p->dispsw->clear(conp, p, real_y(p, sy), sx, height, width);    if (redraw_cursor)	vbl_cursor_cnt = CURSOR_DRAW_DELAY;}static void fbcon_putc(struct vc_data *conp, int c, int ypos, int xpos){    int unit = conp->vc_num;    struct display *p = &fb_display[unit];    int redraw_cursor = 0;    if (!p->can_soft_blank && console_blanked)	    return;	        if (vt_cons[unit]->vc_mode != KD_TEXT)    	    return;    if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {	    cursor_undrawn();	    redraw_cursor = 1;    }    p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos);    if (redraw_cursor)	    vbl_cursor_cnt = CURSOR_DRAW_DELAY;}static void fbcon_putcs(struct vc_data *conp, const unsigned short *s, int count,		       int ypos, int xpos){    int unit = conp->vc_num;    struct display *p = &fb_display[unit];    int redraw_cursor = 0;    if (!p->can_soft_blank && console_blanked)	    return;    if (vt_cons[unit]->vc_mode != KD_TEXT)    	    return;    if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&	(p->cursor_x < (xpos + count))) {	    cursor_undrawn();	    redraw_cursor = 1;    }    p->dispsw->putcs(conp, p, s, count, real_y(p, ypos), xpos);    if (redraw_cursor)	    vbl_cursor_cnt = CURSOR_DRAW_DELAY;}static void fbcon_cursor(struct vc_data *conp, int mode){    int unit = conp->vc_num;    struct display *p = &fb_display[unit];    int y = conp->vc_y;        if (mode & CM_SOFTBACK) {    	mode &= ~CM_SOFTBACK;    	if (softback_lines) {    	    if (y + softback_lines >= conp->vc_rows)    		mode = CM_ERASE;    	    else    	        y += softback_lines;    	}    } else if (softback_lines)        fbcon_set_origin(conp);    /* do we have a hardware cursor ? */    if (p->dispsw->cursor) {	p->cursor_x = conp->vc_x;	p->cursor_y = y;	p->dispsw->cursor(p, mode, p->cursor_x, real_y(p, p->cursor_y));	return;    }    /* Avoid flickering if there's no real change. */    if (p->cursor_x == conp->vc_x && p->cursor_y == y &&	(mode == CM_ERASE) == !cursor_on)	return;    cursor_on = 0;    if (cursor_drawn && p->cursor_x < conp->vc_cols &&	p->cursor_y < conp->vc_rows)

⌨️ 快捷键说明

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