기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.
안드로이드용 VNC Server를 컴파일해서 각종 안드로이드 기반 폰에 동작을 시켜보고 있습니다.
그런데 대부분의 폰에서는 정상 동작을 하는데 유독 드로이드 폰에서만 동작을 하지 않네요.
소스를 분석하면서 디버깅을 해보니
/dev/graphics/fb0 가 정상적으로 open되고 mmap도 제대로 되었으나 값이 0 (zero)만 출력됩니다.
다른 폰은 정상적인 값이 출력이 되구요.
VNC server를 root 권한으로 실행하였고 /dev/graphics/fb0의 permission도 777로 설정해 보았으나
raw data가 출력되지 않았습니다.
도대체 원인이 무엇인지 모르겠습니다.
코드는 다음과 같습니다.
fb0를 open해서 얻어온 fb_var_screeninfo 값은 정상적으로 출력됩니다.
단지 raw data만 읽어지지 않을 뿐....ㅠㅠ
static int fbfd = -1;
static unsigned short int *fbmmap = MAP_FAILED;
static void init_fb(void)
{
size_t pixels;
size_t bytespp;
if ((fbfd = open(FB_DEVICE, O_RDONLY)) == -1)
{
printf("cannot open fb device %sn", FB_DEVICE);
exit(EXIT_FAILURE);
}
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &scrinfo) != 0)
{
printf("ioctl errorn");
exit(EXIT_FAILURE);
}
pixels = scrinfo.xres * scrinfo.yres;
bytespp = scrinfo.bits_per_pixel / 8;
fprintf(stderr, "xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%dn",
(int)scrinfo.xres, (int)scrinfo.yres,
(int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual,
(int)scrinfo.xoffset, (int)scrinfo.yoffset,
(int)scrinfo.bits_per_pixel);
fbmmap = mmap(NULL, pixels * bytespp, PROT_READ, MAP_SHARED, fbfd, 0);
if (fbmmap == MAP_FAILED)
{
printf("mmap failedn");
exit(EXIT_FAILURE);
}
}
static void update_screen(void)
{
unsigned int *f, *c, *r;
int x, y;
varblock.min_i = varblock.min_j = 9999;
varblock.max_i = varblock.max_j = -1;
f = (unsigned int *)fbmmap; /* -> framebuffer */ <== 프린트해보면 값이 항상 0으로 출력됩니다. (ㅠㅠ)
c = (unsigned int *)fbbuf; /* -> compare framebuffer */
r = (unsigned int *)vncbuf; /* -> remote framebuffer */
for (y = 0; y < scrinfo.yres; y++)
{
/* Compare every 2 pixels at a time, assuming that changes are likely
* in pairs. */sp
for (x = 0; x < scrinfo.xres; x += 2)
{
unsigned int pixel = *f;
if (pixel != *c)
{
*c = pixel;
/* XXX: Undo the checkered pattern to test the efficiency
* gain using hextile encoding. */
if (pixel == 0x18e320e4 || pixel == 0x20e418e3)
pixel = 0x18e318e3;
*r = PIXEL_FB_TO_RFB(pixel,
varblock.r_offset, varblock.g_offset, varblock.b_offset);
if (x < varblock.min_i)
varblock.min_i = x;
else
{
if (x > varblock.max_i)
varblock.max_i = x;
if (y > varblock.max_j)
varblock.max_j = y;
else if (y < varblock.min_j)
varblock.min_j = y;
}
}
f++, c++;
r++;
}
}
if (varblock.min_i < 9999)
{
if (varblock.max_i < 0)
varblock.max_i = varblock.min_i;
if (varblock.max_j < 0)
varblock.max_j = varblock.min_j;
fprintf(stderr, "Dirty page: %dx%d+%d+%d...n",
(varblock.max_i+2) - varblock.min_i, (varblock.max_j+1) - varblock.min_j,
varblock.min_i, varblock.min_j);
rfbMarkRectAsModified(vncscr, varblock.min_i, varblock.min_j,
varblock.max_i + 2, varblock.max_j + 1);
rfbProcessEvents(vncscr, 10000);
}
}