linux_fbcon.c
来自「mini gui 1.6.8 lib and source」· C语言 代码 · 共 785 行 · 第 1/2 页
C
785 行
src_bits = this->hidden->fb; src_bits += src_update.top * this->hidden->pitch + src_update.left; dst_line = fbcon_info.fb + src_update.top * fbcon_info.pitch; for (y = 0; y < height; y++) { fbcon_info.put_one_line (src_bits, dst_line, src_update.left, width); src_bits += this->hidden->pitch; dst_line += fbcon_info.pitch; }}#endif /* !_COOR_TRANS */static int a_getinfo (struct lcd_info* lcd_info){#ifdef _COOR_TRANS lcd_info->width = fbcon_info.yres; lcd_info->height = fbcon_info.xres; lcd_info->fb = NULL; fbcon_info.a_line = malloc (fbcon_info.xres * fbcon_info.bpp); if (fbcon_info.a_line == NULL) return 1;# if _ROT_DIR_CW == 1 __mg_shadow_lcd_ops.refresh = a_refresh_cw;# else __mg_shadow_lcd_ops.refresh = a_refresh_ccw;# endif#else /* _COOR_TRANS */ lcd_info->width = fbcon_info.xres; lcd_info->height = fbcon_info.yres; if (fbcon_info.depth >= 8) { lcd_info->fb = fbcon_info.fb; lcd_info->rlen = fbcon_info.pitch; } else lcd_info->fb = NULL; __mg_shadow_lcd_ops.refresh = a_refresh_normal;#endif /* !_COOR_TRANS */ lcd_info->bpp = fbcon_info.depth; switch (fbcon_info.depth) { case 1: fbcon_info.put_one_line = put_one_line_1bpp; break; case 2: fbcon_info.put_one_line = put_one_line_2bpp; break; case 4: fbcon_info.put_one_line = put_one_line_4bpp; break; default: fbcon_info.put_one_line = put_one_line_8bpp; break; } lcd_info->type = 0; return 0;}/* original hw palette */static unsigned short saved_red[16];static unsigned short saved_green[16];static unsigned short saved_blue[16];/* get framebuffer palette */static void ioctl_getpalette (int start, int len, unsigned short *red, unsigned short *green, unsigned short *blue){ struct fb_cmap cmap; if (fbcon_info.pixel_format != PF_PALETTE) return; cmap.start = start; cmap.len = len; cmap.red = red; cmap.green = green; cmap.blue = blue; cmap.transp = NULL; ioctl (fbcon_info.fd_fb, FBIOGETCMAP, &cmap);}/* set framebuffer palette */static void ioctl_setpalette (int start, int len, unsigned short *red, unsigned short *green, unsigned short *blue){ struct fb_cmap cmap; if (fbcon_info.pixel_format != PF_PALETTE) return; cmap.start = start; cmap.len = len; cmap.red = red; cmap.green = green; cmap.blue = blue; cmap.transp = NULL; ioctl (fbcon_info.fd_fb, FBIOPUTCMAP, &cmap);}static int a_setclut_1bpp (int first, int ncolors, GAL_Color *colors){ int i, entry = first; int set = 0; unsigned short r, g, b; for (i = 0; i < ncolors; i++) { if (entry == 0 || entry == 255) { set++; r = colors[i].r << 8; g = colors[i].g << 8; b = colors[i].b << 8; ioctl_setpalette (entry/255, 1, &r, &g, &b); } entry ++; } return set;}static int a_setclut_2bpp (int first, int ncolors, GAL_Color *colors){ int i, entry = first; int set = 0; unsigned short r, g, b; for (i = 0; i < ncolors; i++) { if (entry == 0 || (entry + 1) % 64 == 0) { set++; r = colors[i].r << 8; g = colors[i].g << 8; b = colors[i].b << 8; ioctl_setpalette (entry/64, 1, &r, &g, &b); } entry ++; } return set;}static int a_setclut_4bpp (int first, int ncolors, GAL_Color *colors){ int i, entry = first; int set = 0; unsigned short r, g, b; for (i = 0; i < ncolors; i++) { if (entry == 0 || ((entry + 1) % 16 == 0)) { set++; r = colors[i].r << 8; g = colors[i].g << 8; b = colors[i].b << 8; ioctl_setpalette (entry/16, 1, &r, &g, &b); } entry ++; } return set;}static int a_setclut_8bpp (int first, int ncolors, GAL_Color *colors){ int i, entry = first; int set = 0; unsigned short r, g, b; for (i = 0; i < ncolors; i++) { if (entry < 256) { r = colors[i].r << 8; g = colors[i].g << 8; b = colors[i].b << 8; ioctl_setpalette (entry, 1, &r, &g, &b); set++; entry++; } } return set;}static int a_init (void){ char *env; int err_value = 0; struct fb_fix_screeninfo fb_fix; struct fb_var_screeninfo fb_var; /* locate and open framebuffer, get info*/ err_value++; if (!(env = getenv ("FRAMEBUFFER"))) env = "/dev/fb0"; fbcon_info.fd_fb = open (env, O_RDWR); if (fbcon_info.fd_fb < 0) { goto fail; } err_value++; if (ioctl (fbcon_info.fd_fb, FBIOGET_FSCREENINFO, &fb_fix) == -1 || ioctl (fbcon_info.fd_fb, FBIOGET_VSCREENINFO, &fb_var) == -1) { goto fail; } /* setup screen device from framebuffer info*/ fbcon_info.type = fb_fix.type; fbcon_info.xres = fb_var.xres; fbcon_info.yres = fb_var.yres; /* set planes from fb type*/ if (fbcon_info.type == FB_TYPE_VGA_PLANES) fbcon_info.planes = 4; else if (fbcon_info.type == FB_TYPE_PACKED_PIXELS) fbcon_info.planes = 1; else fbcon_info.planes = 0; fbcon_info.depth = fb_var.bits_per_pixel; /* set pitch to byte length, possibly converted later*/ fbcon_info.pitch = fb_fix.line_length; if (fb_var.red.msb_right) fbcon_info.pixel_endiness = PE_MSBRIGHT; else fbcon_info.pixel_endiness = PE_MSBLEFT; /* set pixel format*/ if (fb_fix.visual == FB_VISUAL_TRUECOLOR || fb_fix.visual == FB_VISUAL_DIRECTCOLOR) { fbcon_info.pixel_format = PF_DIRECT; } else fbcon_info.pixel_format = PF_PALETTE; /* select the setclut operation based on bpp */ switch (fbcon_info.depth) { case 1: __mg_shadow_lcd_ops.setclut = a_setclut_1bpp; break; case 2: __mg_shadow_lcd_ops.setclut = a_setclut_2bpp; break; case 4: __mg_shadow_lcd_ops.setclut = a_setclut_4bpp; break; case 8: __mg_shadow_lcd_ops.setclut = a_setclut_8bpp; break; }#ifdef _HAVE_TEXT_MODE { /* open tty, enter graphics mode*/ char* tty_dev; if (geteuid() == 0) tty_dev = "/dev/tty0"; else /* not a super user, so try to open the control terminal */ tty_dev = "/dev/tty"; err_value++; fbcon_info.fd_tty = open (tty_dev, O_RDWR); if (fbcon_info.fd_tty < 0) { goto fail; } err_value++; if (ioctl (fbcon_info.fd_tty, KDSETMODE, KD_GRAPHICS) == -1) { goto fail; } }#endif /* mmap framebuffer into this address space*/ fbcon_info.fb_size = fbcon_info.pitch * fbcon_info.yres; fbcon_info.fb_size = (fbcon_info.fb_size + getpagesize () - 1) / getpagesize () * getpagesize (); fbcon_info.fb = #ifdef _FXRM9200_IAL /* workaround for Fuxu RM9200 */ mmap (NULL, fbcon_info.fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fbcon_info.fd_fb, 0);#elif defined (__uClinux__) mmap (NULL, fbcon_info.fb_size, PROT_READ | PROT_WRITE, 0, fbcon_info.fd_fb, 0);#else mmap (NULL, fbcon_info.fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fbcon_info.fd_fb, 0);#endif err_value++; if (fbcon_info.fb == NULL || fbcon_info.fb == (unsigned char *)-1) { goto fail; } switch (fbcon_info.depth) { case 32: fbcon_info.bpp = 4; break; case 24: fbcon_info.bpp = 3; break; case 16: fbcon_info.bpp = 2; break; case 15: fbcon_info.bpp = 2; break; default: fbcon_info.bpp = 1; break; } /* save original palette*/ ioctl_getpalette (0, 16, saved_red, saved_green, saved_blue); return 0; /* success*/fail:#ifdef _HAVE_TEXT_MODE /* enter text mode */ if (fbcon_info.fd_tty >= 0) { ioctl (fbcon_info.fd_tty, KDSETMODE, KD_TEXT); close (fbcon_info.fd_tty); fbcon_info.fd_tty = -1; }#endif if (fbcon_info.fd_fb >= 0) { close (fbcon_info.fd_fb); fbcon_info.fd_fb = -1; } return err_value;}static int a_release (void){ /* reset hw palette */ ioctl_setpalette (0, 16, saved_red, saved_green, saved_blue); /* unmap framebuffer */ munmap (fbcon_info.fb, fbcon_info.fb_size); #ifdef _HAVE_TEXT_MODE /* enter text mode */ if (fbcon_info.fd_tty >= 0) { ioctl (fbcon_info.fd_tty, KDSETMODE, KD_TEXT); close (fbcon_info.fd_tty); fbcon_info.fd_tty = -1; }#endif /* close framebuffer */ if (fbcon_info.fd_fb >= 0) { close (fbcon_info.fd_fb); fbcon_info.fd_fb = -1; } if (fbcon_info.a_line) { free (fbcon_info.a_line); fbcon_info.a_line = NULL; } return 0;}static void a_sleep (void){ /* 20ms */ usleep (20000);}struct shadow_lcd_ops __mg_shadow_lcd_ops = { a_init, a_getinfo, a_release, NULL, a_sleep, NULL};#endif /* __LINUX__ && __TARGET_FBCON__ */#endif /* _NEWGAL_ENGINE_SHADOW */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?