/* fbcopy — copy buffer0 -> buffer1 within /dev/fb0 (mmap both, memcpy). * Reproduces the player's "screen-off frame lives in buffer1" state so the * launcher's bug condition (yoffset=1 at menu open) can be tested without * pressing power (which would also pause the player). */ #include #include #include #include #include #include #include #include #define GETV 0x4600 int main(void) { int fd = open("/dev/fb0", O_RDWR); if (fd < 0) { perror("open"); return 1; } 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); uint32_t yv = *(uint32_t*)(v+12); uint32_t bpp = *(uint32_t*)(v+24); if (yv <= yres) { printf("not double-buffered (yv=%u yres=%u)\n", yv, yres); return 2; } /* line_length via fix info */ unsigned char f[68]; memset(f,0,sizeof f); if (ioctl(fd, 0x4602, f) < 0) { perror("getfix"); return 1; } uint32_t line = *(uint32_t*)(f+44); if (!line) line = yres * (bpp/8); 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); /* buffer1 <- buffer0 */ printf("copied %zu bytes buffer0 -> buffer1 (line=%u yres=%u frame=%zu)\n", frame, line, yres, frame); munmap(p, frame*2); close(fd); return 0; }