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

📄 fbcon.c

📁 Linux程序设计权威指南代码.包含所有章节代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if (p == (u16 *)softback_end)	    p = (u16 *)softback_buf;	if (p == (u16 *)softback_in)	    p = (u16 *)conp->vc_origin;    }}static int fbcon_scrolldelta(struct vc_data *conp, int lines){    int unit, offset, limit, scrollback_old;    struct display *p;        unit = fg_console;    p = &fb_display[unit];    if (softback_top) {    	if (conp->vc_num != unit)    	    return 0;    	if (vt_cons[unit]->vc_mode != KD_TEXT || !lines)    	    return 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;    		if (logo_shown == unit) {    		    unsigned long p, q;    		    int i;    		        		    p = softback_in;    		    q = conp->vc_origin + logo_lines * conp->vc_size_row;    		    for (i = 0; i < logo_lines; i++) {    		    	if (p == softback_top) break;    		    	if (p == softback_buf) p = softback_end;    		    	p -= conp->vc_size_row;    		    	q -= conp->vc_size_row;    		    	scr_memcpyw((u16 *)q, (u16 *)p, conp->vc_size_row);    		    }    		    softback_in = p;    		    update_region(unit, conp->vc_origin, logo_lines * conp->vc_cols);    		}		logo_shown = -1;	}    	fbcon_cursor(conp, CM_ERASE|CM_SOFTBACK);    	fbcon_redraw_softback(conp, p, lines);    	fbcon_cursor(conp, CM_DRAW|CM_SOFTBACK);    	return 0;    }    if (!scrollback_phys_max)	return -ENOSYS;    scrollback_old = scrollback_current;    scrollback_current -= lines;    if (scrollback_current < 0)	scrollback_current = 0;    else if (scrollback_current > scrollback_max)	scrollback_current = scrollback_max;    if (scrollback_current == scrollback_old)	return 0;    if (!p->can_soft_blank &&	(console_blanked || vt_cons[unit]->vc_mode != KD_TEXT || !lines))	return 0;    fbcon_cursor(conp, CM_ERASE);    offset = p->yscroll-scrollback_current;    limit = p->vrows;    switch (p->scrollmode && __SCROLL_YMASK) {	case __SCROLL_YWRAP:	    p->var.vmode |= FB_VMODE_YWRAP;	    break;	case __SCROLL_YPAN:	    limit -= conp->vc_rows;	    p->var.vmode &= ~FB_VMODE_YWRAP;	    break;    }    if (offset < 0)	offset += limit;    else if (offset >= limit)	offset -= limit;    p->var.xoffset = 0;    p->var.yoffset = offset*fontheight(p);    p->fb_info->updatevar(unit, p->fb_info);    if (!scrollback_current)	fbcon_cursor(conp, CM_DRAW);    return 0;}static int fbcon_set_origin(struct vc_data *conp){    if (softback_lines && !console_blanked)        fbcon_scrolldelta(conp, softback_lines);    return 0;}static inline unsigned safe_shift(unsigned d,int n){    return n<0 ? d>>-n : d<<n;}__initfunc(static int fbcon_show_logo( void )){    struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */    int depth = p->var.bits_per_pixel;    int line = p->next_line;    unsigned char *fb = p->screen_base;    unsigned char *logo;    unsigned char *dst, *src;    int i, j, n, x1, y1, x;    int logo_depth, done = 0;    /*hacked by zerow_jp*/    int logo_w,logo_h,logo_line;    /* Return if the frame buffer is not mapped */    if (!fb)	return 0;	    /*hacked by zerow_jp*/    logo_w = LOGO_W;    logo_h = LOGO_H;    logo_line = LOGO_LINE;    /* Set colors if visual is PSEUDOCOLOR and we have enough colors, or for     * DIRECTCOLOR */    if ((p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 4) ||	p->visual == FB_VISUAL_DIRECTCOLOR) {	int is_truecolor = (p->visual == FB_VISUAL_DIRECTCOLOR);	int use_256 = (!is_truecolor && depth >= 8) ||		      (is_truecolor && depth >= 24);	int first_col = use_256 ? 32 : depth > 4 ? 16 : 0;	int num_cols = use_256 ? LINUX_LOGO_COLORS : 16;	unsigned char *red, *green, *blue;	if (use_256) {	    red   = linux_logo_red;	    green = linux_logo_green;	    blue  = linux_logo_blue;	}	else {	    red   = linux_logo16_red;	    green = linux_logo16_green;	    blue  = linux_logo16_blue;	}	for( i = 0; i < num_cols; i += n ) {	    n = num_cols - i;	    if (n > 16)		/* palette_cmap provides space for only 16 colors at once */		n = 16;	    palette_cmap.start = first_col + i;	    palette_cmap.len   = n;	    for( j = 0; j < n; ++j ) {		palette_cmap.red[j]   = (red[i+j] << 8) | red[i+j];		palette_cmap.green[j] = (green[i+j] << 8) | green[i+j];		palette_cmap.blue[j]  = (blue[i+j] << 8) | blue[i+j];	    }	    p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,					   p->fb_info);	}    }	    if (depth >= 8) {	logo = linux_logo;	logo_depth = 8;	/*hacked by zerow_jp*/#ifdef CONFIG_MY_LOGO	logo_w = MY_LOGO_W;	logo_h = MY_LOGO_H;	logo_line = MY_LOGO_LINE;#endif    }    else if (depth >= 4) {	logo = linux_logo16;	logo_depth = 4;    }    else {	logo = linux_logo_bw;	logo_depth = 1;    }        if (p->fb_info->fbops->fb_rasterimg)    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);#ifdef CONFIG_MINI_LOGO    if (depth >= 8){    /* paint mini_logo on linux_logo.*/	 for (i = 0; i < smp_num_cpus + 1 ; i++){	      unsigned char pix;	      x = MINI_LOGO_X + i * MINI_LOGO_ADD;	      if( x < 0 || x + MINI_LOGO_W > MY_LOGO_W) break ;	      dst = &linux_logo[MINI_LOGO_Y * logo_w + x];	      for(y1 = 0; y1 < MINI_LOGO_H; y1 ++)		   for(x1 = 0; x1 < MINI_LOGO_W; x1 ++){			pix = mini_logo[y1 * MINI_LOGO_W + x1];			if(mini_logo[0] != pix) dst[y1 * logo_w + x1] = pix;		   }	 }    }#endif    for (x = 0; x < smp_num_cpus * (logo_w + 8) &&    	 x < p->var.xres - (logo_w + 8); x += (logo_w + 8)) {    	 #if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \    defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)        if (p->visual == FB_VISUAL_DIRECTCOLOR) {	    unsigned int val;		/* max. depth 32! */	    int bdepth;	    int redshift, greenshift, blueshift;			    /* Bug: Doesn't obey msb_right ... (who needs that?) */	    redshift   = p->var.red.offset;	    greenshift = p->var.green.offset;	    blueshift  = p->var.blue.offset;	    if (depth >= 24 && (depth % 8) == 0) {		/* have at least 8 bits per color */		src = logo;		bdepth = depth/8;		for( y1 = 0; y1 < logo_h; y1++ ) {		    dst = fb + y1*line + x*bdepth;		    for( x1 = 0; x1 < logo_w; x1++, src++ ) {			val = (*src << redshift) |			      (*src << greenshift) |			      (*src << blueshift);			if (bdepth == 4 && !((long)dst & 3)) {			    /* Some cards require 32bit access */			    *(u32 *)dst = val;			    dst += 4;			} else {#ifdef __LITTLE_ENDIAN			    for( i = 0; i < bdepth; ++i )#else			    for( i = bdepth-1; i >= 0; --i )#endif			        *dst++ = val >> (i*8);			}		    }		}	    }	    else if (depth >= 15 && depth <= 23) {	        /* have 5..7 bits per color, using 16 color image */		unsigned int pix;		src = linux_logo16;		bdepth = (depth+7)/8;		/*hacked by zerow_jp*/		logo_w = LOGO_W;		logo_h = LOGO_H;		logo_line = LOGO_LINE;		for( y1 = 0; y1 < logo_h; y1++ ) {		    dst = fb + y1*line + x*bdepth;		    for( x1 = 0; x1 < logo_w/2; x1++, src++ ) {			pix = (*src >> 4) | 0x10; /* upper nibble */			val = (pix << redshift) |			      (pix << greenshift) |			      (pix << blueshift);#ifdef __LITTLE_ENDIAN			for( i = 0; i < bdepth; ++i )#else			for( i = bdepth-1; i >= 0; --i )#endif			    *dst++ = val >> (i*8);			pix = (*src & 0x0f) | 0x10; /* lower nibble */			val = (pix << redshift) |			      (pix << greenshift) |			      (pix << blueshift);#ifdef __LITTLE_ENDIAN			for( i = 0; i < bdepth; ++i )#else			for( i = bdepth-1; i >= 0; --i )#endif			    *dst++ = val >> (i*8);		    }		}	    }	    done = 1;        }#endif#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \    defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)	if ((depth % 8 == 0) && (p->visual == FB_VISUAL_TRUECOLOR)) {	    /* Modes without color mapping, needs special data transformation... */	    unsigned int val;		/* max. depth 32! */	    int bdepth = depth/8;	    unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };	    unsigned char redmask, greenmask, bluemask;	    int redshift, greenshift, blueshift;			    /* Bug: Doesn't obey msb_right ... (who needs that?) */	    redmask   = mask[p->var.red.length   < 8 ? p->var.red.length   : 8];	    greenmask = mask[p->var.green.length < 8 ? p->var.green.length : 8];	    bluemask  = mask[p->var.blue.length  < 8 ? p->var.blue.length  : 8];	    redshift   = p->var.red.offset   - (8-p->var.red.length);	    greenshift = p->var.green.offset - (8-p->var.green.length);	    blueshift  = p->var.blue.offset  - (8-p->var.blue.length);	    src = logo;	    for( y1 = 0; y1 < logo_h; y1++ ) {		dst = fb + y1*line + x*bdepth;		for( x1 = 0; x1 < logo_w; x1++, src++ ) {		    val = safe_shift((linux_logo_red[*src-32]   & redmask), redshift) |		          safe_shift((linux_logo_green[*src-32] & greenmask), greenshift) |		          safe_shift((linux_logo_blue[*src-32]  & bluemask), blueshift);		    if (bdepth == 4 && !((long)dst & 3)) {			/* Some cards require 32bit access */			*(u32 *)dst = val;			dst += 4;		    } else {#ifdef __LITTLE_ENDIAN			for( i = 0; i < bdepth; ++i )#else			for( i = bdepth-1; i >= 0; --i )#endif			    *dst++ = val >> (i*8);		    }		}	    }	    done = 1;	}#endif#if defined(CONFIG_FBCON_CFB4)	if (depth == 4 && p->type == FB_TYPE_PACKED_PIXELS) {		src = logo;		for( y1 = 0; y1 < logo_h; y1++) {			dst = fb + y1*line + x/2;			for( x1 = 0; x1 < logo_w/2; x1++) {				u8 q = *src++;				q = (q << 4) | (q >> 4);				*dst++ = q;			}		}		done = 1;	}#endif#if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FB_SBUS)	if (depth == 8 && p->type == FB_TYPE_PACKED_PIXELS) {	    /* depth 8 or more, packed, with color registers */			    src = logo;	    for( y1 = 0; y1 < logo_h; y1++ ) {		dst = fb + y1*line + x;		for( x1 = 0; x1 < logo_w; x1++ )		    *dst++ = *src++;	    }	    done = 1;	}#endif#if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_ILBM) || \    defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \    defined(CONFIG_FBCON_IPLAN2P8)	if (depth >= 2 && (p->type == FB_TYPE_PLANES ||			   p->type == FB_TYPE_INTERLEAVED_PLANES)) {	    /* planes (normal or interleaved), with color registers */	    int bit;	    unsigned char val, mask;	    int plane = p->next_plane;#if defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \    defined(CONFIG_FBCON_IPLAN2P8)	    int line_length = p->line_length;	    /* for support of Atari interleaved planes */#define MAP_X(x)	(line_length ? (x) : ((x) & ~1)*depth + ((x) & 1))#else#define MAP_X(x)	(x)#endif	    /* extract a bit from the source image */#define	BIT(p,pix,bit)	(p[pix*logo_depth/8] & \			 (1 << ((8-((pix*logo_depth)&7)-logo_depth) + bit)))			    src = logo;	    for( y1 = 0; y1 < logo_h; y1++ ) {		for( x1 = 0; x1 < logo_line; x1++, src += logo_depth ) {		    dst = fb + y1*line + MAP_X(x/8+x1);		    for( bit = 0; bit < logo_depth; bit++ ) {			val = 0;			for( mask = 0x80, i = 0; i < 8; mask >>= 1, i++ ) {			    if (BIT( src, i, bit ))				val |= mask;			}			*dst = val;			dst += plane;		    }		}	    }		    /* fill remaining planes	     * special case for logo_depth == 4: we used color registers 16..31,	     * so fill plane 4 with 1 bits instead of 0 */	    if (depth > logo_depth) {		for( y1 = 0; y1 < logo_h; y1++ ) {		    for( x1 = 0; x1 < logo_line; x1++ ) {			dst = fb + y1*line + MAP_X(x/8+x1) + logo_depth*plane;			for( i = logo_depth; i < depth; i++, dst += plane )			    *dst = (i == logo_depth && logo_depth == 4)				   ? 0xff : 0x00;		    }		}	    }	    done = 1;	    break;	}#endif#if defined(CONFIG_FBCON_MFB) || defined(CONFIG_FBCON_AFB) || \    defined(CONFIG_FBCON_ILBM)	if (depth == 1 && (p->type == FB_TYPE_PACKED_PIXELS ||			   p->type == FB_TYPE_PLANES ||			   p->type == FB_TYPE_INTERLEAVED_PLANES)) {	    /* monochrome */	    unsigned char inverse = p->inverse || p->visual == FB_VISUAL_MONO01		? 0x00 : 0xff;	    /* can't use simply memcpy because need to apply inverse */	    for( y1 = 0; y1 < logo_h; y1++ ) {		src = logo + y1*logo_line;		dst = fb + y1*line + x/8;		for( x1 = 0; x1 < logo_line; ++x1 )		    *dst++ = *src++ ^ inverse;	    }	    done = 1;	}#endif#if defined(CONFIG_FBCON_VGA_PLANES)	if (depth == 4 && p->type == FB_TYPE_VGA_PLANES) {		outb_p(1,0x3ce); outb_p(0xf,0x3cf);		outb_p(3,0x3ce); outb_p(0,0x3cf);		outb_p(5,0x3ce); outb_p(0,0x3cf);		src = logo;		for (y1 = 0; y1 < logo_h; y1++) {			for (x1 = 0; x1 < logo_w / 2; x1++) {				dst = fb + y1*line + x1/4 + x/8;				outb_p(0,0x3ce);				outb_p(*src >> 4,0x3cf);				outb_p(8,0x3ce);				outb_p(1 << (7 - x1 % 4 * 2),0x3cf);				*(volatile char *) dst |= 1;				outb_p(0,0x3ce);				outb_p(*src & 0xf,0x3cf);				outb_p(8,0x3ce);				outb_p(1 << (7 - (1 + x1 % 4 * 2)),0x3cf);				*(volatile char *) dst |= 1;				src++;			}		}		done = 1;	}#endif			    }        if (p->fb_info->fbops->fb_rasterimg)    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);    /* Modes not yet supported: packed pixels with depth != 8 (does such a     * thing exist in reality?) */    return done ? (logo_h + fontheight(p) - 1) / fontheight(p) : 0 ;}/* *  The console `switch' structure for the frame buffer based consol

⌨️ 快捷键说明

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