/* fbtool — fb0 helper: pan | blank <0|4> | copy | status. * Used to seed the double-buffer bug condition and clean up /dev/fb0. * ioctls: GETV 0x4600, GETFIX 0x4602, PAN 0x4606, BLANK 0x4611. */ #include #include #include #include #include #include #include #include #include #define GETV 0x4600 #define GETFIX 0x4602 #define PAN 0x4606 #define BLANK 0x4611 static int set_blank(int fd, int bl) { errno = 0; int r = ioctl(fd, BLANK, bl); printf("blank(%d) r=%d errno=%d\n", bl, r, errno); return r; } static int set_pan(int fd, int yoff) { unsigned char v[160]; memset(v,0,sizeof v); if (ioctl(fd, GETV, v) < 0) { perror("getvar"); return -1; } *(uint32_t*)(v+16)=0; *(uint32_t*)(v+20)=(uint32_t)yoff; errno = 0; int r = ioctl(fd, PAN, v); unsigned char w[160]; memset(w,0,sizeof w); ioctl(fd, GETV, w); printf("pan(%u) r=%d errno=%d yoffset now=%u\n", yoff, r, errno, *(uint32_t*)(w+20)); return r; } static int do_copy(int fd) { unsigned char v[160]; memset(v,0,sizeof v); if (ioctl(fd, GETV, v) < 0) { perror("getvar"); return -1; } uint32_t yres=*(uint32_t*)(v+4), yv=*(uint32_t*)(v+12), bpp=*(uint32_t*)(v+24); unsigned char f[68]; memset(f,0,sizeof f); if (ioctl(fd, GETFIX, f) < 0) { perror("getfix"); return -1; } uint32_t line = *(uint32_t*)(f+44); if (!line) line = yres*(bpp/8); if (yv < yres) { printf("not double-buffered\n"); return -1; } size_t frame = (size_t)line * yres; unsigned char *p = mmap(NULL, frame*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { perror("mmap"); return -1; } memcpy(p+frame, p, frame); munmap(p, frame*2); printf("copy buffer0 -> buffer1 (%zu bytes)\n", frame); return 0; } int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr,"usage: fbtool {blank 0|4} | {pan N} | {copy}\n"); return 2; } int fd = open("/dev/fb0", O_RDWR); if (fd < 0) { perror("open"); return 1; } int r = 0; if (!strcmp(argv[1],"blank") && argc>2) r = set_blank(fd, atoi(argv[2])); else if (!strcmp(argv[1],"pan") && argc>2) r = set_pan(fd, atoi(argv[2])); else if (!strcmp(argv[1],"copy")) r = do_copy(fd); else fprintf(stderr,"unknown cmd\n"), r=2; close(fd); return r<0?1:0; }