19 #define FRAMEBUFFER_SIZE(xsz, ysz, bpp) ((xsz) * (ysz) * (bpp) / CHAR_BIT)
21 static unsigned char *framebuffer;
23 static int rgb_order[3];
36 if(!(gfx = (Graphics*)sh_malloc(sizeof *gfx))) {
42 if((dev_fd = open("/dev/fb0", O_RDWR)) == -1) {
43 fprintf(stderr, "Cannot open /dev/fb0 : %s\n", strerror(errno));
47 fb_var_screeninfo sinfo;
48 if(ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo) == -1) {
51 fprintf(stderr, "Unable to get screen info : %s\n", strerror(errno));
55 printf("width : %d height : %d\n : bpp : %d\n", sinfo.xres, sinfo.yres, sinfo.bits_per_pixel);
56 printf("virtual w: %d virtual h: %d\n", sinfo.xres_virtual, sinfo.yres_virtual);
58 gfx->screen_rect.x = gfx->screen_rect.y = 0;
59 gfx->screen_rect.width = sinfo.xres_virtual;
60 gfx->screen_rect.height = sinfo.yres_virtual;
61 gfx->color_depth = sinfo.bits_per_pixel;
63 rgb_order[0] = sinfo.red.offset / 8;
64 rgb_order[1] = sinfo.green.offset / 8;
65 rgb_order[2] = sinfo.blue.offset / 8;
67 set_clipping_rect(gfx->screen_rect);
69 int sz = FRAMEBUFFER_SIZE(gfx->screen_rect.width, gfx->screen_rect.height, gfx->color_depth);
70 framebuffer = (unsigned char*)mmap(0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
72 if(framebuffer == (void*)-1) {
75 fprintf(stderr, "Cannot map the framebuffer to memory : %s\n", strerror(errno));
79 // TODO: uncomment when I find how to use intelfb instead of i915 GRRRR.-
81 if(ioctl(dev_fd, FBIOGET_VBLANK, &vblank) == -1) {
82 // fprintf(stderr, "FBIOGET_VBLANK error: %s\n", strerror(errno));
86 printf("flags: %x\n", vblank.flags);
87 printf("count: %d\n", vblank.count);
88 printf("beam position: %d, %d\n", vblank.hcount, vblank.vcount);
92 if(!(gfx->pixmap = (Pixmap*)sh_malloc(sizeof(Pixmap)))) {
93 fprintf(stderr, "Failed to allocate pixmap.\n");
97 gfx->pixmap->width = gfx->screen_rect.width;
98 gfx->pixmap->height = gfx->screen_rect.height;
100 int fbsize = gfx->pixmap->width * gfx->pixmap->height * gfx->color_depth / 8;
101 if(!(gfx->pixmap->pixels = (unsigned char*)sh_malloc(fbsize))) {
102 fprintf(stderr, "failed to allocate the pixmap framebuffer.\n");
111 clear_screen(0, 0, 0);
112 gfx_update(gfx->screen_rect);
120 munmap(framebuffer, FRAMEBUFFER_SIZE(gfx->screen_rect.width, gfx->screen_rect.height, gfx->color_depth));
123 sh_free(gfx->pixmap->pixels);
124 gfx->pixmap->pixels = 0;
125 sh_free(gfx->pixmap);
129 unsigned char *get_framebuffer()
131 return gfx->pixmap->pixels;
134 Pixmap *get_framebuffer_pixmap()
139 Rect get_screen_size()
141 return gfx->screen_rect;
144 int get_color_depth()
146 return gfx->color_depth;
149 void set_clipping_rect(const Rect &rect)
151 gfx->clipping_rect = rect_intersection(rect, get_screen_size());
154 const Rect &get_clipping_rect()
156 return gfx->clipping_rect;
159 void set_cursor_visibility(bool visible)
162 curs.enable = visible ? 1 : 0;
164 if(ioctl(dev_fd, FBIO_CURSOR, &curs) == -1) {
165 fprintf(stderr, "Cannot toggle cursor visibility : %s\n", strerror(errno));
169 void gfx_update(const Rect &upd_rect)
171 Rect rect = rect_intersection(upd_rect, gfx->screen_rect);
172 unsigned char *sptr = gfx->pixmap->pixels + (rect.y * gfx->screen_rect.width + rect.x) * 4;
173 unsigned char *dptr = framebuffer + (rect.y * gfx->screen_rect.width + rect.x) * 4;
175 for(int i=0; i<rect.height; i++) {
176 memcpy(dptr, sptr, rect.width * 4);
177 sptr += gfx->screen_rect.width * 4;
178 dptr += gfx->screen_rect.width * 4;
184 unsigned long arg = 0;
185 if(ioctl(dev_fd, FBIO_WAITFORVSYNC, &arg) == -1) {
186 // printf("ioctl error %s\n", strerror(errno));
190 void get_rgb_order(int *r, int *g, int *b)
197 #endif // WINNIE_FBDEV