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 + -
显示快捷键?