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

📄 fbcon.c

📁 Linux程序设计权威指南代码.包含所有章节代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		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))) {#ifdef 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;#if defined(CONFIG_MY_LOGO) && (MY_LOGO_H > LOGO_H)    	logo_lines = (MY_LOGO_H + fontheight(p) - 1) / fontheight(p);#else    	logo_lines = (LOGO_H + fontheight(p) - 1) / fontheight(p);#endif    	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 (*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_to(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_from(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->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;

⌨️ 快捷键说明

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