📄 framebuffer.c
字号:
} else { border_bottom = border_top; } if (*param) goto bad_p; if (fstat(TTY, &st)) { if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } return stracpy("Cannon stat stdin.\n"); } fb_console = st.st_rdev & 0xff; fb_hide_cursor(); if ((e = fb_switch_init())) { if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return e; } fb_handler=open("/dev/fb0",O_RDWR); if (fb_handler==-1) { fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Cannot open /dev/fb0.\n"); } if ((ioctl (fb_handler, FBIOGET_VSCREENINFO, &vi))==-1) { close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Cannot get FB VSCREENINFO.\n"); } oldmode=vi; if ((ioctl (fb_handler, FBIOGET_FSCREENINFO, &fi))==-1) { close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Cannot get FB FSCREENINFO.\n"); } fb_xsize=vi.xres; fb_ysize=vi.yres; fb_bits_pp=vi.bits_per_pixel; if (fb_bits_pp == 16 && vi.green.length == 5) fb_bits_pp = 15; if (fb_xsize <= border_left + border_right) border_left = border_right = 0; fb_xsize -= border_left + border_right; if (fb_ysize <= border_top + border_bottom) border_top = border_bottom = 0; fb_ysize -= border_top + border_bottom; fb_driver.x=fb_xsize; fb_driver.y=fb_ysize; switch(fb_bits_pp) { case 4: fb_pixelsize=1; fb_palette_colors=16; break; case 8: fb_pixelsize=1; fb_palette_colors=256; break; case 15: case 16: fb_pixelsize=2; fb_palette_colors=64; break; case 24: fb_palette_colors=256; fb_pixelsize=3; break; case 32: fb_palette_colors=256; fb_pixelsize=4; fb_bits_pp=24; break; default: close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Unknown bit depth"); } fb_colors=1<<fb_bits_pp; if (fi.visual==FB_VISUAL_PSEUDOCOLOR && fb_colors <= 0x1000000) /* set palette */ { have_cmap=1; fb_palette_colors=fb_colors; alloc_palette(&old_palette); get_palette(&old_palette); alloc_palette(&global_pal); generate_palette(&global_pal); set_palette(&global_pal); } if (fi.visual==FB_VISUAL_DIRECTCOLOR) /* set pseudo palette */ { have_cmap=2; alloc_palette(&old_palette); get_palette(&old_palette); alloc_palette(&global_pal); generate_palette(&global_pal); set_palette(&global_pal); } fb_linesize=fi.line_length; fb_mem_size=fi.smem_len; vi.xoffset=0; vi.yoffset=0; if ((ioctl(fb_handler, FBIOPAN_DISPLAY, &vi))==-1) { /* mikulas : nechodilo mi to, tak jsem tohle vyhodil a ono to chodi */ /*fb_shutdown_palette(); close(fb_handler); fb_show_cursor(); return stracpy("Cannot pan display.\n"); */ } if (init_virtual_devices(&fb_driver, NUMBER_OF_DEVICES)){ fb_shutdown_palette(); close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Allocation of virtual devices failed.\n"); } fb_kbd = handle_svgalib_keyboard((void (*)(void *, unsigned char *, int))fb_key_in); /* Mikulas: nechodi to na sparcu */ if (fb_mem_size < fb_linesize * fb_ysize) { fb_shutdown_palette(); svgalib_free_trm(fb_kbd); shutdown_virtual_devices(); close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Nonlinear mapping of graphics memory not supported.\n"); } if (vi.nonstd) { fb_shutdown_palette(); svgalib_free_trm(fb_kbd); shutdown_virtual_devices(); close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Non-standard pixel format.\n"); } if ((fb_mem=mmap(0,fb_mem_size,PROT_READ|PROT_WRITE,MAP_SHARED,fb_handler,0))==MAP_FAILED) { fb_shutdown_palette(); svgalib_free_trm(fb_kbd); shutdown_virtual_devices(); close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Cannot mmap graphics memory.\n"); } fb_vmem = fb_mem + border_left * fb_pixelsize + border_top * fb_linesize; fb_driver.depth=fb_pixelsize&7; fb_driver.depth|=(fb_bits_pp&31)<<3; if (htonl(0x12345678) == 0x12345678) { /* Big endian */ if (fb_driver.depth == 130 || fb_driver.depth == 122) fb_driver.depth |= 1 << 8; else if (fb_driver.depth == 196) fb_driver.depth |= 1 << 9; } fb_driver.get_color=get_color_fn(fb_driver.depth); if (!fb_driver.get_color) { fb_shutdown_palette(); svgalib_free_trm(fb_kbd); shutdown_virtual_devices(); close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Unknown bit format.\n"); } /*fb_switch_init();*/ install_signal_handler(SIGINT, (void (*)(void *))fb_ctrl_c, fb_kbd, 0); /* mouse */ mouse_buffer=mem_alloc(fb_pixelsize*arrow_area); background_buffer=mem_alloc(fb_pixelsize*arrow_area); new_background_buffer=mem_alloc(fb_pixelsize*arrow_area); background_x=mouse_x=fb_xsize>>1; background_y=mouse_y=fb_ysize>>1; mouse_black=fb_driver.get_color(0); mouse_white=fb_driver.get_color(0xffffff); mouse_graphics_device=fb_driver.init_device(); virtual_devices[0] = NULL; global_mouse_hidden=1; if (handle_fb_mouse()) { fb_driver.shutdown_device(mouse_graphics_device); mem_free(mouse_buffer); mem_free(background_buffer); mem_free(new_background_buffer); fb_shutdown_palette(); svgalib_free_trm(fb_kbd); shutdown_virtual_devices(); close(fb_handler); fb_switch_shutdown(); if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } fb_show_cursor(); return stracpy("Cannot open GPM mouse.\n"); } /* hide cursor */ if (border_left | border_top | border_right | border_bottom) memset(fb_mem,0,fb_mem_size); show_mouse(); return NULL;}static void fb_shutdown_driver(void){ mem_free(mouse_buffer); mem_free(background_buffer); mem_free(new_background_buffer); fb_driver.shutdown_device(mouse_graphics_device); unhandle_fb_mouse(); in_gr_operation=1; if (fb_active) { memset(fb_mem,0,fb_mem_size); ioctl (fb_handler, FBIOPUT_VSCREENINFO, &oldmode); } END_GR; fb_shutdown_palette(); install_signal_handler(SIGINT, NULL, NULL, 0); close(fb_handler); munmap(fb_mem,fb_mem_size); shutdown_virtual_devices(); fb_switch_shutdown(); svgalib_free_trm(fb_kbd); if(fb_driver_param) mem_free(fb_driver_param); /* show cursor */ fb_show_cursor();}static unsigned char *fb_get_driver_param(void){ return fb_driver_param;}/* Return value: 0 alloced on heap * 1 alloced in vidram * 2 alloced in X server shm */static int fb_get_empty_bitmap(struct bitmap *dest){ if (dest->x && (unsigned)dest->x * (unsigned)dest->y / (unsigned)dest->x != (unsigned)dest->y) overalloc(); if ((unsigned)dest->x * (unsigned)dest->y > (unsigned)MAXINT / fb_pixelsize) overalloc(); dest->data=mem_alloc(dest->x*dest->y*fb_pixelsize); dest->skip=dest->x*fb_pixelsize; dest->flags=0; return 0;}/* Return value: 0 alloced on heap * 1 alloced in vidram * 2 alloced in X server shm *//*static int fb_get_filled_bitmap(struct bitmap *dest, long color){ int n; if (dest->x && (unsigned)dest->x * (unsigned)dest->y / (unsigned)dest->x != (unsigned)dest->y) overalloc(); if ((unsigned)dest->x * (unsigned)dest->y > MAXINT / fb_pixelsize) overalloc(); n=dest->x*dest->y*fb_pixelsize; dest->data=mem_alloc(n); pixel_set(dest->data,n,&color); dest->skip=dest->x*fb_pixelsize; dest->flags=0; return 0;}*/static void fb_register_bitmap(struct bitmap *bmp){}static void fb_unregister_bitmap(struct bitmap *bmp){ mem_free(bmp->data);}static void *fb_prepare_strip(struct bitmap *bmp, int top, int lines){ return ((char *)bmp->data)+bmp->skip*top;}static void fb_commit_strip(struct bitmap *bmp, int top, int lines){ return;}void fb_draw_bitmap(struct graphics_device *dev,struct bitmap* hndl, int x, int y){ unsigned char *scr_start; CLIP_PREFACE scr_start=fb_vmem+y*fb_linesize+x*fb_pixelsize; for(;ys;ys--){ memcpy(scr_start,data,xs*fb_pixelsize); data+=hndl->skip; scr_start+=fb_linesize; } END_MOUSE END_GR}static void fb_draw_bitmaps(struct graphics_device *dev, struct bitmap **hndls, int n, int x, int y){ TEST_INACTIVITY if (x>=fb_xsize||y>fb_ysize) return; while(x+(*hndls)->x<=0&&n){ x+=(*hndls)->x; n--; hndls++; } while(n&&x<=fb_xsize){ fb_draw_bitmap(dev, *hndls, x, y); x+=(*hndls)->x; n--; hndls++; }}static void fb_fill_area(struct graphics_device *dev, int left, int top, int right, int bottom, long color){ unsigned char *dest; int y; FILL_CLIP_PREFACE dest=fb_vmem+top*fb_linesize+left*fb_pixelsize; for (y=bottom-top;y;y--){ pixel_set(dest,(right-left)*fb_pixelsize,&color); dest+=fb_linesize; } END_MOUSE END_GR}static void fb_draw_hline(struct graphics_device *dev, int left, int y, int right, long color){ unsigned char *dest; HLINE_CLIP_PREFACE dest=fb_vmem+y*fb_linesize+left*fb_pixelsize; pixel_set(dest,(right-left)*fb_pixelsize,&color); END_MOUSE END_GR}static void fb_draw_vline(struct graphics_device *dev, int x, int top, int bottom, long color){ unsigned char *dest; int y; VLINE_CLIP_PREFACE dest=fb_vmem+top*fb_linesize+x*fb_pixelsize; for (y=(bottom-top);y;y--){ memcpy(dest,&color,fb_pixelsize); dest+=fb_linesize; } END_MOUSE END_GR}static int fb_hscroll(struct graphics_device *dev, struct rect_set **ignore, int sc){ unsigned char *dest, *src; int y; int len; HSCROLL_CLIP_PREFACE ignore=NULL; if (sc>0){ len=(dev->clip.x2-dev->clip.x1-sc)*fb_pixelsize; src=fb_vmem+fb_linesize*dev->clip.y1+dev->clip.x1*fb_pixelsize; dest=src+sc*fb_pixelsize; for (y=dev->clip.y2-dev->clip.y1;y;y--){ memmove(dest,src,len); dest+=fb_linesize; src+=fb_linesize; } }else{ len=(dev->clip.x2-dev->clip.x1+sc)*fb_pixelsize; dest=fb_vmem+fb_linesize*dev->clip.y1+dev->clip.x1*fb_pixelsize; src=dest-sc*fb_pixelsize; for (y=dev->clip.y2-dev->clip.y1;y;y--){ memmove(dest,src,len); dest+=fb_linesize; src+=fb_linesize; } } END_MOUSE END_GR return 1;}static int fb_vscroll(struct graphics_device *dev, struct rect_set **ignore, int sc){ unsigned char *dest, *src; int y; int len; VSCROLL_CLIP_PREFACE ignore=NULL; len=(dev->clip.x2-dev->clip.x1)*fb_pixelsize; if (sc>0){ /* Down */ dest=fb_vmem+(dev->clip.y2-1)*fb_linesize+dev->clip.x1*fb_pixelsize; src=dest-fb_linesize*sc; for (y=dev->clip.y2-dev->clip.y1-sc;y;y--){ memcpy(dest,src,len); dest-=fb_linesize; src-=fb_linesize; } }else{ /* Up */ dest=fb_vmem+dev->clip.y1*fb_linesize+dev->clip.x1*fb_pixelsize; src=dest-fb_linesize*sc; for (y=dev->clip.y2-dev->clip.y1+sc;y;y--){ memcpy(dest,src,len); dest+=fb_linesize; src+=fb_linesize; } } END_MOUSE END_GR return 1;}static void fb_set_clip_area(struct graphics_device *dev, struct rect *r){ memcpy(&dev->clip, r, sizeof(struct rect)); if (dev->clip.x1>=dev->clip.x2||dev->clip.y2<=dev->clip.y1||dev->clip.y2<=0||dev->clip.x2<=0||dev->clip.x1>=fb_xsize ||dev->clip.y1>=fb_ysize){ /* Empty region */ dev->clip.x1=dev->clip.x2=dev->clip.y1=dev->clip.y2=0; }else{ if (dev->clip.x1<0) dev->clip.x1=0; if (dev->clip.x2>fb_xsize) dev->clip.x2=fb_xsize; if (dev->clip.y1<0) dev->clip.y1=0; if (dev->clip.y2>fb_ysize) dev->clip.y2=fb_ysize; }}static int fb_block(struct graphics_device *dev){ if (fb_old_vd) return 1; fb_block_dev = dev; unhandle_fb_mouse(); fb_old_vd = current_virtual_device; current_virtual_device=NULL; svgalib_block_itrm(fb_kbd); if (have_cmap) set_palette(&old_palette); fb_switch_shutdown(); fb_show_cursor(); printf("\n");fflush(stdout); return 0;}static int fb_unblock(struct graphics_device *dev){#ifdef DEBUG if (current_virtual_device) { /*internal("fb_unblock called without fb_block");*/ return 0; }#endif /* #ifdef DEBUG */ if (dev != fb_block_dev) return -2; if (svgalib_unblock_itrm(fb_kbd)) return -1; fb_switch_init(); fb_hide_cursor(); vi.xoffset=0; vi.yoffset=0; ioctl(fb_handler, FBIOPAN_DISPLAY, &vi); current_virtual_device = fb_old_vd; fb_old_vd = NULL; if (have_cmap) set_palette(&global_pal); handle_fb_mouse(); if (border_left | border_top | border_right | border_bottom) memset(fb_mem,0,fb_mem_size); if (current_virtual_device) current_virtual_device->redraw_handler(current_virtual_device ,¤t_virtual_device->size); return 0;}struct graphics_driver fb_driver={ "fb", fb_init_driver, init_virtual_device, shutdown_virtual_device, fb_shutdown_driver, fb_get_driver_param, fb_get_empty_bitmap, /*fb_get_filled_bitmap,*/ fb_register_bitmap, fb_prepare_strip, fb_commit_strip, fb_unregister_bitmap, fb_draw_bitmap, fb_draw_bitmaps, NULL, /* fb_get_color */ fb_fill_area, fb_draw_hline, fb_draw_vline, fb_hscroll, fb_vscroll, fb_set_clip_area, fb_block, fb_unblock, NULL, /* set_title */ NULL, /* exec */ 0, /* depth (filled in fb_init_driver function) */ 0, 0, /* size (in X is empty) */ GD_DONT_USE_SCROLL|GD_NEED_CODEPAGE, /* flags */ 0, /* codepage */ NULL, /* shell */};#endif /* GRDRV_FB */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -