Blame examples/android/jni/fbvncserver.c

Packit Service b05338
/*
Packit Service b05338
 * $Id$
Packit Service b05338
 *
Packit Service b05338
 * This program is free software; you can redistribute it and/or modify it
Packit Service b05338
 * under the terms of the GNU General Public License as published by the
Packit Service b05338
 * Free Software Foundation; either version 2, or (at your option) any
Packit Service b05338
 * later version.
Packit Service b05338
 *
Packit Service b05338
 * This program is distributed in the hope that it will be useful, but
Packit Service b05338
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service b05338
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service b05338
 * General Public License for more details.
Packit Service b05338
 *
Packit Service b05338
 * This project is an adaptation of the original fbvncserver for the iPAQ
Packit Service b05338
 * and Zaurus.
Packit Service b05338
 */
Packit Service b05338
Packit Service b05338
#include <stdio.h>
Packit Service b05338
#include <stdlib.h>
Packit Service b05338
#include <string.h>
Packit Service b05338
Packit Service b05338
#include <unistd.h>
Packit Service b05338
#include <sys/mman.h>
Packit Service b05338
#include <sys/ioctl.h>
Packit Service b05338
Packit Service b05338
#include <sys/stat.h>
Packit Service b05338
#include <sys/sysmacros.h>             /* For makedev() */
Packit Service b05338
Packit Service b05338
#include <fcntl.h>
Packit Service b05338
#include <linux/fb.h>
Packit Service b05338
#include <linux/input.h>
Packit Service b05338
Packit Service b05338
#include <assert.h>
Packit Service b05338
#include <errno.h>
Packit Service b05338
Packit Service b05338
/* libvncserver */
Packit Service b05338
#include "rfb/rfb.h"
Packit Service b05338
#include "rfb/keysym.h"
Packit Service b05338
Packit Service b05338
/*****************************************************************************/
Packit Service b05338
Packit Service b05338
/* Android does not use /dev/fb0. */
Packit Service b05338
#define FB_DEVICE "/dev/graphics/fb0"
Packit Service b05338
static char KBD_DEVICE[256] = "/dev/input/event3";
Packit Service b05338
static char TOUCH_DEVICE[256] = "/dev/input/event1";
Packit Service b05338
static struct fb_var_screeninfo scrinfo;
Packit Service b05338
static int fbfd = -1;
Packit Service b05338
static int kbdfd = -1;
Packit Service b05338
static int touchfd = -1;
Packit Service b05338
static unsigned short int *fbmmap = MAP_FAILED;
Packit Service b05338
static unsigned short int *vncbuf;
Packit Service b05338
static unsigned short int *fbbuf;
Packit Service b05338
Packit Service b05338
/* Android already has 5900 bound natively. */
Packit Service b05338
#define VNC_PORT 5901
Packit Service b05338
static rfbScreenInfoPtr vncscr;
Packit Service b05338
Packit Service b05338
static int xmin, xmax;
Packit Service b05338
static int ymin, ymax;
Packit Service b05338
Packit Service b05338
/* No idea, just copied from fbvncserver as part of the frame differerencing
Packit Service b05338
 * algorithm.  I will probably be later rewriting all of this. */
Packit Service b05338
static struct varblock_t
Packit Service b05338
{
Packit Service b05338
	int min_i;
Packit Service b05338
	int min_j;
Packit Service b05338
	int max_i;
Packit Service b05338
	int max_j;
Packit Service b05338
	int r_offset;
Packit Service b05338
	int g_offset;
Packit Service b05338
	int b_offset;
Packit Service b05338
	int rfb_xres;
Packit Service b05338
	int rfb_maxy;
Packit Service b05338
} varblock;
Packit Service b05338
Packit Service b05338
/*****************************************************************************/
Packit Service b05338
Packit Service b05338
static void keyevent(rfbBool down, rfbKeySym key, rfbClientPtr cl);
Packit Service b05338
static void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl);
Packit Service b05338
Packit Service b05338
/*****************************************************************************/
Packit Service b05338
Packit Service b05338
static void init_fb(void)
Packit Service b05338
{
Packit Service b05338
	size_t pixels;
Packit Service b05338
	size_t bytespp;
Packit Service b05338
Packit Service b05338
	if ((fbfd = open(FB_DEVICE, O_RDONLY)) == -1)
Packit Service b05338
	{
Packit Service b05338
		printf("cannot open fb device %s\n", FB_DEVICE);
Packit Service b05338
		exit(EXIT_FAILURE);
Packit Service b05338
	}
Packit Service b05338
Packit Service b05338
	if (ioctl(fbfd, FBIOGET_VSCREENINFO, &scrinfo) != 0)
Packit Service b05338
	{
Packit Service b05338
		printf("ioctl error\n");
Packit Service b05338
		exit(EXIT_FAILURE);
Packit Service b05338
	}
Packit Service b05338
Packit Service b05338
	pixels = scrinfo.xres * scrinfo.yres;
Packit Service b05338
	bytespp = scrinfo.bits_per_pixel / 8;
Packit Service b05338
Packit Service b05338
	fprintf(stderr, "xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n", 
Packit Service b05338
	  (int)scrinfo.xres, (int)scrinfo.yres,
Packit Service b05338
	  (int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual,
Packit Service b05338
	  (int)scrinfo.xoffset, (int)scrinfo.yoffset,
Packit Service b05338
	  (int)scrinfo.bits_per_pixel);
Packit Service b05338
Packit Service b05338
	fbmmap = mmap(NULL, pixels * bytespp, PROT_READ, MAP_SHARED, fbfd, 0);
Packit Service b05338
Packit Service b05338
	if (fbmmap == MAP_FAILED)
Packit Service b05338
	{
Packit Service b05338
		printf("mmap failed\n");
Packit Service b05338
		exit(EXIT_FAILURE);
Packit Service b05338
	}
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
static void cleanup_fb(void)
Packit Service b05338
{
Packit Service b05338
	if(fbfd != -1)
Packit Service b05338
	{
Packit Service b05338
		close(fbfd);
Packit Service b05338
	}
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
static void init_kbd()
Packit Service b05338
{
Packit Service b05338
	if((kbdfd = open(KBD_DEVICE, O_RDWR)) == -1)
Packit Service b05338
	{
Packit Service b05338
		printf("cannot open kbd device %s\n", KBD_DEVICE);
Packit Service b05338
		exit(EXIT_FAILURE);
Packit Service b05338
	}
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
static void cleanup_kbd()
Packit Service b05338
{
Packit Service b05338
	if(kbdfd != -1)
Packit Service b05338
	{
Packit Service b05338
		close(kbdfd);
Packit Service b05338
	}
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
static void init_touch()
Packit Service b05338
{
Packit Service b05338
    struct input_absinfo info;
Packit Service b05338
        if((touchfd = open(TOUCH_DEVICE, O_RDWR)) == -1)
Packit Service b05338
        {
Packit Service b05338
                printf("cannot open touch device %s\n", TOUCH_DEVICE);
Packit Service b05338
                exit(EXIT_FAILURE);
Packit Service b05338
        }
Packit Service b05338
    // Get the Range of X and Y
Packit Service b05338
    if(ioctl(touchfd, EVIOCGABS(ABS_X), &info)) {
Packit Service b05338
        printf("cannot get ABS_X info, %s\n", strerror(errno));
Packit Service b05338
        exit(EXIT_FAILURE);
Packit Service b05338
    }
Packit Service b05338
    xmin = info.minimum;
Packit Service b05338
    xmax = info.maximum;
Packit Service b05338
    if(ioctl(touchfd, EVIOCGABS(ABS_Y), &info)) {
Packit Service b05338
        printf("cannot get ABS_Y, %s\n", strerror(errno));
Packit Service b05338
        exit(EXIT_FAILURE);
Packit Service b05338
    }
Packit Service b05338
    ymin = info.minimum;
Packit Service b05338
    ymax = info.maximum;
Packit Service b05338
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
static void cleanup_touch()
Packit Service b05338
{
Packit Service b05338
	if(touchfd != -1)
Packit Service b05338
	{
Packit Service b05338
		close(touchfd);
Packit Service b05338
	}
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
/*****************************************************************************/
Packit Service b05338
Packit Service b05338
static void init_fb_server(int argc, char **argv)
Packit Service b05338
{
Packit Service b05338
	printf("Initializing server...\n");
Packit Service b05338
Packit Service b05338
	/* Allocate the VNC server buffer to be managed (not manipulated) by 
Packit Service b05338
	 * libvncserver. */
Packit Service b05338
	vncbuf = calloc(scrinfo.xres * scrinfo.yres, scrinfo.bits_per_pixel / 8);
Packit Service b05338
	assert(vncbuf != NULL);
Packit Service b05338
Packit Service b05338
	/* Allocate the comparison buffer for detecting drawing updates from frame
Packit Service b05338
	 * to frame. */
Packit Service b05338
	fbbuf = calloc(scrinfo.xres * scrinfo.yres, scrinfo.bits_per_pixel / 8);
Packit Service b05338
	assert(fbbuf != NULL);
Packit Service b05338
Packit Service b05338
	/* TODO: This assumes scrinfo.bits_per_pixel is 16. */
Packit Service b05338
	vncscr = rfbGetScreen(&argc, argv, scrinfo.xres, scrinfo.yres, 5, 2, (scrinfo.bits_per_pixel / 8));
Packit Service b05338
	assert(vncscr != NULL);
Packit Service b05338
Packit Service b05338
	vncscr->desktopName = "Android";
Packit Service b05338
	vncscr->frameBuffer = (char *)vncbuf;
Packit Service b05338
	vncscr->alwaysShared = TRUE;
Packit Service b05338
	vncscr->httpDir = NULL;
Packit Service b05338
	vncscr->port = VNC_PORT;
Packit Service b05338
Packit Service b05338
	vncscr->kbdAddEvent = keyevent;
Packit Service b05338
	vncscr->ptrAddEvent = ptrevent;
Packit Service b05338
Packit Service b05338
	rfbInitServer(vncscr);
Packit Service b05338
Packit Service b05338
	/* Mark as dirty since we haven't sent any updates at all yet. */
Packit Service b05338
	rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.xres, scrinfo.yres);
Packit Service b05338
Packit Service b05338
	/* No idea. */
Packit Service b05338
	varblock.r_offset = scrinfo.red.offset + scrinfo.red.length - 5;
Packit Service b05338
	varblock.g_offset = scrinfo.green.offset + scrinfo.green.length - 5;
Packit Service b05338
	varblock.b_offset = scrinfo.blue.offset + scrinfo.blue.length - 5;
Packit Service b05338
	varblock.rfb_xres = scrinfo.yres;
Packit Service b05338
	varblock.rfb_maxy = scrinfo.xres - 1;
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
/*****************************************************************************/
Packit Service b05338
void injectKeyEvent(uint16_t code, uint16_t value)
Packit Service b05338
{
Packit Service b05338
    struct input_event ev;
Packit Service b05338
    memset(&ev, 0, sizeof(ev));
Packit Service b05338
    gettimeofday(&ev.time,0);
Packit Service b05338
    ev.type = EV_KEY;
Packit Service b05338
    ev.code = code;
Packit Service b05338
    ev.value = value;
Packit Service b05338
    if(write(kbdfd, &ev, sizeof(ev)) < 0)
Packit Service b05338
    {
Packit Service b05338
        printf("write event failed, %s\n", strerror(errno));
Packit Service b05338
    }
Packit Service b05338
Packit Service b05338
    printf("injectKey (%d, %d)\n", code , value);    
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
static int keysym2scancode(rfbBool down, rfbKeySym key, rfbClientPtr cl)
Packit Service b05338
{
Packit Service b05338
    int scancode = 0;
Packit Service b05338
Packit Service b05338
    int code = (int)key;
Packit Service b05338
    if (code>='0' && code<='9') {
Packit Service b05338
        scancode = (code & 0xF) - 1;
Packit Service b05338
        if (scancode<0) scancode += 10;
Packit Service b05338
        scancode += KEY_1;
Packit Service b05338
    } else if (code>=0xFF50 && code<=0xFF58) {
Packit Service b05338
        static const uint16_t map[] =
Packit Service b05338
             {  KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN,
Packit Service b05338
                KEY_SOFT1, KEY_SOFT2, KEY_END, 0 };
Packit Service b05338
        scancode = map[code & 0xF];
Packit Service b05338
    } else if (code>=0xFFE1 && code<=0xFFEE) {
Packit Service b05338
        static const uint16_t map[] =
Packit Service b05338
             {  KEY_LEFTSHIFT, KEY_LEFTSHIFT,
Packit Service b05338
                KEY_COMPOSE, KEY_COMPOSE,
Packit Service b05338
                KEY_LEFTSHIFT, KEY_LEFTSHIFT,
Packit Service b05338
                0,0,
Packit Service b05338
                KEY_LEFTALT, KEY_RIGHTALT,
Packit Service b05338
                0, 0, 0, 0 };
Packit Service b05338
        scancode = map[code & 0xF];
Packit Service b05338
    } else if ((code>='A' && code<='Z') || (code>='a' && code<='z')) {
Packit Service b05338
        static const uint16_t map[] = {
Packit Service b05338
                KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
Packit Service b05338
                KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
Packit Service b05338
                KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
Packit Service b05338
                KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
Packit Service b05338
                KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z };
Packit Service b05338
        scancode = map[(code & 0x5F) - 'A'];
Packit Service b05338
    } else {
Packit Service b05338
        switch (code) {
Packit Service b05338
            case 0x0003:    scancode = KEY_CENTER;      break;
Packit Service b05338
            case 0x0020:    scancode = KEY_SPACE;       break;
Packit Service b05338
            case 0x0023:    scancode = KEY_SHARP;       break;
Packit Service b05338
            case 0x0033:    scancode = KEY_SHARP;       break;
Packit Service b05338
            case 0x002C:    scancode = KEY_COMMA;       break;
Packit Service b05338
            case 0x003C:    scancode = KEY_COMMA;       break;
Packit Service b05338
            case 0x002E:    scancode = KEY_DOT;         break;
Packit Service b05338
            case 0x003E:    scancode = KEY_DOT;         break;
Packit Service b05338
            case 0x002F:    scancode = KEY_SLASH;       break;
Packit Service b05338
            case 0x003F:    scancode = KEY_SLASH;       break;
Packit Service b05338
            case 0x0032:    scancode = KEY_EMAIL;       break;
Packit Service b05338
            case 0x0040:    scancode = KEY_EMAIL;       break;
Packit Service b05338
            case 0xFF08:    scancode = KEY_BACKSPACE;   break;
Packit Service b05338
            case 0xFF1B:    scancode = KEY_BACK;        break;
Packit Service b05338
            case 0xFF09:    scancode = KEY_TAB;         break;
Packit Service b05338
            case 0xFF0D:    scancode = KEY_ENTER;       break;
Packit Service b05338
            case 0x002A:    scancode = KEY_STAR;        break;
Packit Service b05338
            case 0xFFBE:    scancode = KEY_F1;        break; // F1
Packit Service b05338
            case 0xFFBF:    scancode = KEY_F2;         break; // F2
Packit Service b05338
            case 0xFFC0:    scancode = KEY_F3;        break; // F3
Packit Service b05338
            case 0xFFC5:    scancode = KEY_F4;       break; // F8
Packit Service b05338
            case 0xFFC8:    rfbShutdownServer(cl->screen,TRUE);       break; // F11            
Packit Service b05338
        }
Packit Service b05338
    }
Packit Service b05338
Packit Service b05338
    return scancode;
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
static void keyevent(rfbBool down, rfbKeySym key, rfbClientPtr cl)
Packit Service b05338
{
Packit Service b05338
	int scancode;
Packit Service b05338
Packit Service b05338
	printf("Got keysym: %04x (down=%d)\n", (unsigned int)key, (int)down);
Packit Service b05338
Packit Service b05338
	if ((scancode = keysym2scancode(down, key, cl)))
Packit Service b05338
	{
Packit Service b05338
		injectKeyEvent(scancode, down);
Packit Service b05338
	}
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
void injectTouchEvent(int down, int x, int y)
Packit Service b05338
{
Packit Service b05338
    struct input_event ev;
Packit Service b05338
    
Packit Service b05338
    // Calculate the final x and y
Packit Service b05338
    /* Fake touch screen always reports zero */
Packit Service b05338
    if (xmin != 0 && xmax != 0 && ymin != 0 && ymax != 0)
Packit Service b05338
    {
Packit Service b05338
        x = xmin + (x * (xmax - xmin)) / (scrinfo.xres);
Packit Service b05338
        y = ymin + (y * (ymax - ymin)) / (scrinfo.yres);
Packit Service b05338
    }
Packit Service b05338
    
Packit Service b05338
    memset(&ev, 0, sizeof(ev));
Packit Service b05338
Packit Service b05338
    // Then send a BTN_TOUCH
Packit Service b05338
    gettimeofday(&ev.time,0);
Packit Service b05338
    ev.type = EV_KEY;
Packit Service b05338
    ev.code = BTN_TOUCH;
Packit Service b05338
    ev.value = down;
Packit Service b05338
    if(write(touchfd, &ev, sizeof(ev)) < 0)
Packit Service b05338
    {
Packit Service b05338
        printf("write event failed, %s\n", strerror(errno));
Packit Service b05338
    }
Packit Service b05338
Packit Service b05338
    // Then send the X
Packit Service b05338
    gettimeofday(&ev.time,0);
Packit Service b05338
    ev.type = EV_ABS;
Packit Service b05338
    ev.code = ABS_X;
Packit Service b05338
    ev.value = x;
Packit Service b05338
    if(write(touchfd, &ev, sizeof(ev)) < 0)
Packit Service b05338
    {
Packit Service b05338
        printf("write event failed, %s\n", strerror(errno));
Packit Service b05338
    }
Packit Service b05338
Packit Service b05338
    // Then send the Y
Packit Service b05338
    gettimeofday(&ev.time,0);
Packit Service b05338
    ev.type = EV_ABS;
Packit Service b05338
    ev.code = ABS_Y;
Packit Service b05338
    ev.value = y;
Packit Service b05338
    if(write(touchfd, &ev, sizeof(ev)) < 0)
Packit Service b05338
    {
Packit Service b05338
        printf("write event failed, %s\n", strerror(errno));
Packit Service b05338
    }
Packit Service b05338
Packit Service b05338
    // Finally send the SYN
Packit Service b05338
    gettimeofday(&ev.time,0);
Packit Service b05338
    ev.type = EV_SYN;
Packit Service b05338
    ev.code = 0;
Packit Service b05338
    ev.value = 0;
Packit Service b05338
    if(write(touchfd, &ev, sizeof(ev)) < 0)
Packit Service b05338
    {
Packit Service b05338
        printf("write event failed, %s\n", strerror(errno));
Packit Service b05338
    }
Packit Service b05338
Packit Service b05338
    printf("injectTouchEvent (x=%d, y=%d, down=%d)\n", x , y, down);    
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
static void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl)
Packit Service b05338
{
Packit Service b05338
	/* Indicates either pointer movement or a pointer button press or release. The pointer is
Packit Service b05338
now at (x-position, y-position), and the current state of buttons 1 to 8 are represented
Packit Service b05338
by bits 0 to 7 of button-mask respectively, 0 meaning up, 1 meaning down (pressed).
Packit Service b05338
On a conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and right
Packit Service b05338
buttons on the mouse. On a wheel mouse, each step of the wheel upwards is represented
Packit Service b05338
by a press and release of button 4, and each step downwards is represented by
Packit Service b05338
a press and release of button 5. 
Packit Service b05338
  From: http://www.vislab.usyd.edu.au/blogs/index.php/2009/05/22/an-headerless-indexed-protocol-for-input-1?blog=61 */
Packit Service b05338
	
Packit Service b05338
	//printf("Got ptrevent: %04x (x=%d, y=%d)\n", buttonMask, x, y);
Packit Service b05338
	if(buttonMask & 1) {
Packit Service b05338
		// Simulate left mouse event as touch event
Packit Service b05338
		injectTouchEvent(1, x, y);
Packit Service b05338
		injectTouchEvent(0, x, y);
Packit Service b05338
	} 
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
#define PIXEL_FB_TO_RFB(p,r,g,b) ((p>>r)&0x1f001f)|(((p>>g)&0x1f001f)<<5)|(((p>>b)&0x1f001f)<<10)
Packit Service b05338
Packit Service b05338
static void update_screen(void)
Packit Service b05338
{
Packit Service b05338
	unsigned int *f, *c, *r;
Packit Service b05338
	int x, y;
Packit Service b05338
Packit Service b05338
	varblock.min_i = varblock.min_j = 9999;
Packit Service b05338
	varblock.max_i = varblock.max_j = -1;
Packit Service b05338
Packit Service b05338
	f = (unsigned int *)fbmmap;        /* -> framebuffer         */
Packit Service b05338
	c = (unsigned int *)fbbuf;         /* -> compare framebuffer */
Packit Service b05338
	r = (unsigned int *)vncbuf;        /* -> remote framebuffer  */
Packit Service b05338
Packit Service b05338
	for (y = 0; y < scrinfo.yres; y++)
Packit Service b05338
	{
Packit Service b05338
		/* Compare every 2 pixels at a time, assuming that changes are likely
Packit Service b05338
		 * in pairs. */
Packit Service b05338
		for (x = 0; x < scrinfo.xres; x += 2)
Packit Service b05338
		{
Packit Service b05338
			unsigned int pixel = *f;
Packit Service b05338
Packit Service b05338
			if (pixel != *c)
Packit Service b05338
			{
Packit Service b05338
				*c = pixel;
Packit Service b05338
Packit Service b05338
				/* XXX: Undo the checkered pattern to test the efficiency
Packit Service b05338
				 * gain using hextile encoding. */
Packit Service b05338
				if (pixel == 0x18e320e4 || pixel == 0x20e418e3)
Packit Service b05338
					pixel = 0x18e318e3;
Packit Service b05338
Packit Service b05338
				*r = PIXEL_FB_TO_RFB(pixel,
Packit Service b05338
				  varblock.r_offset, varblock.g_offset, varblock.b_offset);
Packit Service b05338
Packit Service b05338
				if (x < varblock.min_i)
Packit Service b05338
					varblock.min_i = x;
Packit Service b05338
				else
Packit Service b05338
				{
Packit Service b05338
					if (x > varblock.max_i)
Packit Service b05338
						varblock.max_i = x;
Packit Service b05338
Packit Service b05338
					if (y > varblock.max_j)
Packit Service b05338
						varblock.max_j = y;
Packit Service b05338
					else if (y < varblock.min_j)
Packit Service b05338
						varblock.min_j = y;
Packit Service b05338
				}
Packit Service b05338
			}
Packit Service b05338
Packit Service b05338
			f++, c++;
Packit Service b05338
			r++;
Packit Service b05338
		}
Packit Service b05338
	}
Packit Service b05338
Packit Service b05338
	if (varblock.min_i < 9999)
Packit Service b05338
	{
Packit Service b05338
		if (varblock.max_i < 0)
Packit Service b05338
			varblock.max_i = varblock.min_i;
Packit Service b05338
Packit Service b05338
		if (varblock.max_j < 0)
Packit Service b05338
			varblock.max_j = varblock.min_j;
Packit Service b05338
Packit Service b05338
		fprintf(stderr, "Dirty page: %dx%d+%d+%d...\n",
Packit Service b05338
		  (varblock.max_i+2) - varblock.min_i, (varblock.max_j+1) - varblock.min_j,
Packit Service b05338
		  varblock.min_i, varblock.min_j);
Packit Service b05338
Packit Service b05338
		rfbMarkRectAsModified(vncscr, varblock.min_i, varblock.min_j,
Packit Service b05338
		  varblock.max_i + 2, varblock.max_j + 1);
Packit Service b05338
Packit Service b05338
		rfbProcessEvents(vncscr, 10000);
Packit Service b05338
	}
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
/*****************************************************************************/
Packit Service b05338
Packit Service b05338
void print_usage(char **argv)
Packit Service b05338
{
Packit Service b05338
	printf("%s [-k device] [-t device] [-h]\n"
Packit Service b05338
		"-k device: keyboard device node, default is /dev/input/event3\n"
Packit Service b05338
		"-t device: touch device node, default is /dev/input/event1\n"
Packit Service b05338
		"-h : print this help\n");
Packit Service b05338
}
Packit Service b05338
Packit Service b05338
int main(int argc, char **argv)
Packit Service b05338
{
Packit Service b05338
	if(argc > 1)
Packit Service b05338
	{
Packit Service b05338
		int i=1;
Packit Service b05338
		while(i < argc)
Packit Service b05338
		{
Packit Service b05338
			if(*argv[i] == '-')
Packit Service b05338
			{
Packit Service b05338
				switch(*(argv[i] + 1))
Packit Service b05338
				{
Packit Service b05338
					case 'h':
Packit Service b05338
						print_usage(argv);
Packit Service b05338
						exit(0);
Packit Service b05338
						break;
Packit Service b05338
					case 'k':
Packit Service b05338
						i++;
Packit Service b05338
						strcpy(KBD_DEVICE, argv[i]);
Packit Service b05338
						break;
Packit Service b05338
					case 't':
Packit Service b05338
						i++;
Packit Service b05338
						strcpy(TOUCH_DEVICE, argv[i]);
Packit Service b05338
						break;
Packit Service b05338
				}
Packit Service b05338
			}
Packit Service b05338
			i++;
Packit Service b05338
		}
Packit Service b05338
	}
Packit Service b05338
Packit Service b05338
	printf("Initializing framebuffer device " FB_DEVICE "...\n");
Packit Service b05338
	init_fb();
Packit Service b05338
	printf("Initializing keyboard device %s ...\n", KBD_DEVICE);
Packit Service b05338
	init_kbd();
Packit Service b05338
	printf("Initializing touch device %s ...\n", TOUCH_DEVICE);
Packit Service b05338
	init_touch();
Packit Service b05338
Packit Service b05338
	printf("Initializing VNC server:\n");
Packit Service b05338
	printf("	width:  %d\n", (int)scrinfo.xres);
Packit Service b05338
	printf("	height: %d\n", (int)scrinfo.yres);
Packit Service b05338
	printf("	bpp:    %d\n", (int)scrinfo.bits_per_pixel);
Packit Service b05338
	printf("	port:   %d\n", (int)VNC_PORT);
Packit Service b05338
	init_fb_server(argc, argv);
Packit Service b05338
Packit Service b05338
	/* Implement our own event loop to detect changes in the framebuffer. */
Packit Service b05338
	while (1)
Packit Service b05338
	{
Packit Service b05338
		while (vncscr->clientHead == NULL)
Packit Service b05338
			rfbProcessEvents(vncscr, 100000);
Packit Service b05338
Packit Service b05338
		rfbProcessEvents(vncscr, 100000);
Packit Service b05338
		update_screen();
Packit Service b05338
	}
Packit Service b05338
Packit Service b05338
	printf("Cleaning up...\n");
Packit Service b05338
	cleanup_fb();
Packit Service b05338
	cleanup_kdb();
Packit Service b05338
	cleanup_touch();
Packit Service b05338
}