vga16fb.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,441 行 · 第 1/3 页

C
1,441
字号
			case ROP_COPY:				setmode(0);				setop(0);				setsr(0xf);				setcolor(rect->color);				selectmask();				setmask(0xff);				while (height--) {					for (x = 0; x < width; x++) {						writeb(0, dst);						dst++;					}					dst += line_ofs;				}				break;			case ROP_XOR:				setmode(0);				setop(0x18);				setsr(0xf);				setcolor(0xf);				selectmask();				setmask(0xff);				while (height--) {					for (x = 0; x < width; x++) {						rmw(dst);						dst++;					}					dst += line_ofs;				}				break;			}		} else 			vga_8planes_fillrect(info, rect);		break;	case FB_TYPE_PACKED_PIXELS:	default:		cfb_fillrect(info, rect);		break;	}}void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea *area){        char oldindex = getindex();        char oldmode = setmode(0x41);        char oldop = setop(0);        char oldsr = setsr(0xf);        int height, line_ofs, x;	u32 sx, dx, width;	char *dest, *src;        height = area->height;        sx = area->sx / 4;        dx = area->dx / 4;        width = area->width / 4;        if (area->dy < area->sy || (area->dy == area->sy && dx < sx)) {                line_ofs = info->fix.line_length - width;                dest = info->screen_base + dx + area->dy * info->fix.line_length;                src = info->screen_base + sx + area->sy * info->fix.line_length;                while (height--) {                        for (x = 0; x < width; x++) {                                readb(src);                                writeb(0, dest);                                src++;                                dest++;                        }                        src += line_ofs;                        dest += line_ofs;                }        } else {                line_ofs = info->fix.line_length - width;                dest = info->screen_base + dx + width +			(area->dy + height - 1) * info->fix.line_length;                src = info->screen_base + sx + width +			(area->sy + height - 1) * info->fix.line_length;                while (height--) {                        for (x = 0; x < width; x++) {                                --src;                                --dest;                                readb(src);                                writeb(0, dest);                        }                        src -= line_ofs;                        dest -= line_ofs;                }        }        setsr(oldsr);        setop(oldop);        setmode(oldmode);        setindex(oldindex);}void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *area){	u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy; 	int x, x2, y2, old_dx, old_dy, vxres, vyres;	int height, width, line_ofs;	char *dst = NULL, *src = NULL;	vxres = info->var.xres_virtual;	vyres = info->var.yres_virtual;	if (area->dx > vxres || area->sx > vxres || area->dy > vyres ||	    area->sy > vyres)		return;	/* clip the destination */	old_dx = area->dx;	old_dy = area->dy;	/*	 * We could use hardware clipping but on many cards you get around	 * hardware clipping by writing to framebuffer directly.	 */	x2 = area->dx + area->width;	y2 = area->dy + area->height;	dx = area->dx > 0 ? area->dx : 0;	dy = area->dy > 0 ? area->dy : 0;	x2 = x2 < vxres ? x2 : vxres;	y2 = y2 < vyres ? y2 : vyres;	width = x2 - dx;	height = y2 - dy;	/* update sx1,sy1 */	sx += (dx - old_dx);	sy += (dy - old_dy);	/* the source must be completely inside the virtual screen */	if (sx < 0 || sy < 0 || (sx + width) > vxres || (sy + height) > vyres)		return;	switch (info->fix.type) {	case FB_TYPE_VGA_PLANES:		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {			width = width/8;			height = height;			line_ofs = info->fix.line_length - width;			setmode(1);			setop(0);			setsr(0xf);			if (dy < sy || (dy == sy && dx < sx)) {				dst = info->screen_base + (dx/8) + dy * info->fix.line_length;				src = info->screen_base + (sx/8) + sy * info->fix.line_length;				while (height--) {					for (x = 0; x < width; x++) {						readb(src);						writeb(0, dst);						dst++;						src++;					}					src += line_ofs;					dst += line_ofs;				}			} else {				dst = info->screen_base + (dx/8) + width + 					(dy + height - 1) * info->fix.line_length;				src = info->screen_base + (sx/8) + width + 					(sy + height  - 1) * info->fix.line_length;				while (height--) {					for (x = 0; x < width; x++) {						dst--;						src--;						readb(src);						writeb(0, dst);					}					src -= line_ofs;					dst -= line_ofs;				}			}		} else 			vga_8planes_copyarea(info, area);		break;	case FB_TYPE_PACKED_PIXELS:	default:		cfb_copyarea(info, area);		break;	}}#ifdef __LITTLE_ENDIANstatic unsigned int transl_l[] ={0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};static unsigned int transl_h[] ={0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00, 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};#else#ifdef __BIG_ENDIANstatic unsigned int transl_h[] ={0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};static unsigned int transl_l[] ={0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00, 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};#else#error "Only __BIG_ENDIAN and __LITTLE_ENDIAN are supported in vga-planes"#endif#endifvoid vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image){        char oldindex = getindex();        char oldmode = setmode(0x40);        char oldop = setop(0);        char oldsr = setsr(0);        char oldmask = selectmask();        const char *cdat = image->data;	u32 dx = image->dx;        char *where;        int y;        dx /= 4;        where = info->screen_base + dx + image->dy * info->fix.line_length;        setmask(0xff);        writeb(image->bg_color, where);        readb(where);        selectmask();        setmask(image->fg_color ^ image->bg_color);        setmode(0x42);        setop(0x18);        for (y = 0; y < image->height; y++, where += info->fix.line_length)                writew(transl_h[cdat[y]&0xF] | transl_l[cdat[y] >> 4], where);        setmask(oldmask);        setsr(oldsr);        setop(oldop);        setmode(oldmode);        setindex(oldindex);}void vga_imageblit_expand(struct fb_info *info, const struct fb_image *image){	char *where = info->screen_base + (image->dx/8) + 		image->dy * info->fix.line_length;	struct vga16fb_par *par = (struct vga16fb_par *) info->par;	char *cdat = (char *) image->data, *dst;	int x, y;	switch (info->fix.type) {	case FB_TYPE_VGA_PLANES:		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {			if (par->isVGA) {				setmode(2);				setop(0);				setsr(0xf);				setcolor(image->fg_color);				selectmask();								setmask(0xff);				writeb(image->bg_color, where);				rmb();				readb(where); /* fill latches */				setmode(3);				wmb();				for (y = 0; y < image->height; y++) {					dst = where;					for (x = image->width/8; x--;) 						writeb(*cdat++, dst++);					where += info->fix.line_length;				}				wmb();			} else {				setmode(0);				setop(0);				setsr(0xf);				setcolor(image->bg_color);				selectmask();								setmask(0xff);				for (y = 0; y < image->height; y++) {					dst = where;					for (x=image->width/8; x--;){						rmw(dst);						setcolor(image->fg_color);						selectmask();						if (*cdat) {							setmask(*cdat++);							rmw(dst++);						}					}					where += info->fix.line_length;				}			}		} else 			vga_8planes_imageblit(info, image);		break;	case FB_TYPE_PACKED_PIXELS:	default:		cfb_imageblit(info, image);		break;	}}void vga_imageblit_color(struct fb_info *info, const struct fb_image *image) {	/*	 * Draw logo 	 */	struct vga16fb_par *par = (struct vga16fb_par *) info->par;	char *where = info->screen_base + image->dy * info->fix.line_length + 		image->dx/8;	const char *cdat = image->data, *dst;	int x, y;	switch (info->fix.type) {	case FB_TYPE_VGA_PLANES:		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4 &&		    par->isVGA) {			setsr(0xf);			setop(0);			setmode(0);						for (y = 0; y < image->height; y++) {				for (x = 0; x < image->width; x++) {					dst = where + x/8;					setcolor(*cdat);					selectmask();					setmask(1 << (7 - (x % 8)));					fb_readb(dst);					fb_writeb(0, dst);					cdat++;				}				where += info->fix.line_length;			}		}		break;	case FB_TYPE_PACKED_PIXELS:		cfb_imageblit(info, image);		break;	default:		break;	}}				void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image){	if (image->depth == 1)		vga_imageblit_expand(info, image);	else if (image->depth <= info->var.bits_per_pixel)		vga_imageblit_color(info, image);}static struct fb_ops vga16fb_ops = {	.owner		= THIS_MODULE,	.fb_open        = vga16fb_open,	.fb_release     = vga16fb_release,	.fb_check_var	= vga16fb_check_var,	.fb_set_par	= vga16fb_set_par,	.fb_setcolreg 	= vga16fb_setcolreg,	.fb_pan_display = vga16fb_pan_display,	.fb_blank 	= vga16fb_blank,	.fb_fillrect	= vga16fb_fillrect,	.fb_copyarea	= vga16fb_copyarea,	.fb_imageblit	= vga16fb_imageblit,	.fb_cursor      = soft_cursor,};int vga16fb_setup(char *options){	char *this_opt;		if (!options || !*options)		return 0;		while ((this_opt = strsep(&options, ",")) != NULL) {		if (!*this_opt) continue;	}	return 0;}int __init vga16fb_init(void){	int i;	int ret;#ifndef MODULE	char *option = NULL;	if (fb_get_options("vga16fb", &option))		return -ENODEV;	vga16fb_setup(option);#endif	printk(KERN_DEBUG "vga16fb: initializing\n");	/* XXX share VGA_FB_PHYS and I/O region with vgacon and others */	vga16fb.screen_base = (void *)VGA_MAP_MEM(VGA_FB_PHYS);	if (!vga16fb.screen_base) {		printk(KERN_ERR "vga16fb: unable to map device\n");		ret = -ENOMEM;		goto err_ioremap;	}	printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);	vga16_par.isVGA = ORIG_VIDEO_ISVGA;	vga16_par.palette_blanked = 0;	vga16_par.vesa_blanked = 0;	i = vga16_par.isVGA? 6 : 2;		vga16fb_defined.red.length   = i;	vga16fb_defined.green.length = i;	vga16fb_defined.blue.length  = i;		/* name should not depend on EGA/VGA */	vga16fb.fbops = &vga16fb_ops;	vga16fb.var = vga16fb_defined;	vga16fb.fix = vga16fb_fix;	vga16fb.par = &vga16_par;	vga16fb.flags = FBINFO_FLAG_DEFAULT |		FBINFO_HWACCEL_YPAN;	i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;	ret = fb_alloc_cmap(&vga16fb.cmap, i, 0);	if (ret) {		printk(KERN_ERR "vga16fb: unable to allocate colormap\n");		ret = -ENOMEM;		goto err_alloc_cmap;	}	if (vga16fb_check_var(&vga16fb.var, &vga16fb)) {		printk(KERN_ERR "vga16fb: unable to validate variable\n");		ret = -EINVAL;		goto err_check_var;	}	vga16fb_update_fix(&vga16fb);	if (register_framebuffer(&vga16fb) < 0) {		printk(KERN_ERR "vga16fb: unable to register framebuffer\n");		ret = -EINVAL;		goto err_check_var;	}	printk(KERN_INFO "fb%d: %s frame buffer device\n",	       vga16fb.node, vga16fb.fix.id);	return 0; err_check_var:	fb_dealloc_cmap(&vga16fb.cmap); err_alloc_cmap:	iounmap(vga16fb.screen_base); err_ioremap:	return ret;}static void __exit vga16fb_exit(void){    unregister_framebuffer(&vga16fb);    iounmap(vga16fb.screen_base);    fb_dealloc_cmap(&vga16fb.cmap);    /* XXX unshare VGA regions */}#ifdef MODULEMODULE_LICENSE("GPL");#endifmodule_init(vga16fb_init);module_exit(vga16fb_exit);/* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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