1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * $Id$
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This program is free software; you can redistribute it and/or modify it
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * under the terms of the GNU General Public License as published by the
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Free Software Foundation; either version 2, or (at your option) any
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * later version.
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This program is distributed in the hope that it will be useful, but
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * WITHOUT ANY WARRANTY; without even the implied warranty of
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * General Public License for more details.
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This project is an adaptation of the original fbvncserver for the iPAQ
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and Zaurus.
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdio.h>
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdlib.h>
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <string.h>
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <unistd.h>
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/mman.h>
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/ioctl.h>
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/stat.h>
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/sysmacros.h>             /* For makedev() */
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <fcntl.h>
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <linux/fb.h>
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <linux/input.h>
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <assert.h>
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <errno.h>
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* libvncserver */
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "rfb/rfb.h"
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "rfb/keysym.h"
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*****************************************************************************/
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* Android does not use /dev/fb0. */
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define FB_DEVICE "/dev/graphics/fb0"
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char KBD_DEVICE[256] = "/dev/input/event3";
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char TOUCH_DEVICE[256] = "/dev/input/event1";
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic struct fb_var_screeninfo scrinfo;
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int fbfd = -1;
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int kbdfd = -1;
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int touchfd = -1;
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned short int *fbmmap = MAP_FAILED;
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned short int *vncbuf;
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned short int *fbbuf;
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* Android already has 5900 bound natively. */
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define VNC_PORT 5901
56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbScreenInfoPtr vncscr;
57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int xmin, xmax;
59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int ymin, ymax;
60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* No idea, just copied from fbvncserver as part of the frame differerencing
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * algorithm.  I will probably be later rewriting all of this. */
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic struct varblock_t
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int min_i;
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int min_j;
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int max_i;
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int max_j;
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int r_offset;
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int g_offset;
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int b_offset;
72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int rfb_xres;
73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int rfb_maxy;
74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} varblock;
75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*****************************************************************************/
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void keyevent(rfbBool down, rfbKeySym key, rfbClientPtr cl);
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl);
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*****************************************************************************/
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void init_fb(void)
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	size_t pixels;
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	size_t bytespp;
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if ((fbfd = open(FB_DEVICE, O_RDONLY)) == -1)
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		printf("cannot open fb device %s\n", FB_DEVICE);
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		exit(EXIT_FAILURE);
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (ioctl(fbfd, FBIOGET_VSCREENINFO, &scrinfo) != 0)
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		printf("ioctl error\n");
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		exit(EXIT_FAILURE);
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	pixels = scrinfo.xres * scrinfo.yres;
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	bytespp = scrinfo.bits_per_pixel / 8;
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fprintf(stderr, "xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n",
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  (int)scrinfo.xres, (int)scrinfo.yres,
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  (int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual,
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  (int)scrinfo.xoffset, (int)scrinfo.yoffset,
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  (int)scrinfo.bits_per_pixel);
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fbmmap = mmap(NULL, pixels * bytespp, PROT_READ, MAP_SHARED, fbfd, 0);
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fbmmap == MAP_FAILED)
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		printf("mmap failed\n");
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		exit(EXIT_FAILURE);
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void cleanup_fb(void)
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(fbfd != -1)
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		close(fbfd);
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void init_kbd()
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if((kbdfd = open(KBD_DEVICE, O_RDWR)) == -1)
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		printf("cannot open kbd device %s\n", KBD_DEVICE);
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		exit(EXIT_FAILURE);
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void cleanup_kbd()
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(kbdfd != -1)
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		close(kbdfd);
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void init_touch()
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    struct input_absinfo info;
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if((touchfd = open(TOUCH_DEVICE, O_RDWR)) == -1)
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        {
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                printf("cannot open touch device %s\n", TOUCH_DEVICE);
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                exit(EXIT_FAILURE);
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Get the Range of X and Y
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(ioctl(touchfd, EVIOCGABS(ABS_X), &info)) {
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        printf("cannot get ABS_X info, %s\n", strerror(errno));
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        exit(EXIT_FAILURE);
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    xmin = info.minimum;
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    xmax = info.maximum;
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(ioctl(touchfd, EVIOCGABS(ABS_Y), &info)) {
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        printf("cannot get ABS_Y, %s\n", strerror(errno));
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        exit(EXIT_FAILURE);
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ymin = info.minimum;
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ymax = info.maximum;
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void cleanup_touch()
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(touchfd != -1)
170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		close(touchfd);
172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*****************************************************************************/
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void init_fb_server(int argc, char **argv)
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("Initializing server...\n");
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Allocate the VNC server buffer to be managed (not manipulated) by
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * libvncserver. */
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncbuf = calloc(scrinfo.xres * scrinfo.yres, scrinfo.bits_per_pixel / 8);
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	assert(vncbuf != NULL);
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Allocate the comparison buffer for detecting drawing updates from frame
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * to frame. */
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fbbuf = calloc(scrinfo.xres * scrinfo.yres, scrinfo.bits_per_pixel / 8);
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	assert(fbbuf != NULL);
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* TODO: This assumes scrinfo.bits_per_pixel is 16. */
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncscr = rfbGetScreen(&argc, argv, scrinfo.xres, scrinfo.yres, 5, 2, (scrinfo.bits_per_pixel / 8));
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	assert(vncscr != NULL);
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncscr->desktopName = "Android";
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncscr->frameBuffer = (char *)vncbuf;
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncscr->alwaysShared = TRUE;
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncscr->httpDir = NULL;
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncscr->port = VNC_PORT;
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncscr->kbdAddEvent = keyevent;
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vncscr->ptrAddEvent = ptrevent;
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbInitServer(vncscr);
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Mark as dirty since we haven't sent any updates at all yet. */
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.xres, scrinfo.yres);
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* No idea. */
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	varblock.r_offset = scrinfo.red.offset + scrinfo.red.length - 5;
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	varblock.g_offset = scrinfo.green.offset + scrinfo.green.length - 5;
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	varblock.b_offset = scrinfo.blue.offset + scrinfo.blue.length - 5;
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	varblock.rfb_xres = scrinfo.yres;
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	varblock.rfb_maxy = scrinfo.xres - 1;
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*****************************************************************************/
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid injectKeyEvent(uint16_t code, uint16_t value)
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    struct input_event ev;
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    memset(&ev, 0, sizeof(ev));
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gettimeofday(&ev.time,0);
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.type = EV_KEY;
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.code = code;
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.value = value;
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(write(kbdfd, &ev, sizeof(ev)) < 0)
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        printf("write event failed, %s\n", strerror(errno));
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    printf("injectKey (%d, %d)\n", code , value);
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int keysym2scancode(rfbBool down, rfbKeySym key, rfbClientPtr cl)
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int scancode = 0;
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int code = (int)key;
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (code>='0' && code<='9') {
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        scancode = (code & 0xF) - 1;
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (scancode<0) scancode += 10;
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        scancode += KEY_1;
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else if (code>=0xFF50 && code<=0xFF58) {
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        static const uint16_t map[] =
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat             {  KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN,
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_SOFT1, KEY_SOFT2, KEY_END, 0 };
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        scancode = map[code & 0xF];
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else if (code>=0xFFE1 && code<=0xFFEE) {
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        static const uint16_t map[] =
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat             {  KEY_LEFTSHIFT, KEY_LEFTSHIFT,
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_COMPOSE, KEY_COMPOSE,
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_LEFTSHIFT, KEY_LEFTSHIFT,
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                0,0,
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_LEFTALT, KEY_RIGHTALT,
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                0, 0, 0, 0 };
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        scancode = map[code & 0xF];
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else if ((code>='A' && code<='Z') || (code>='a' && code<='z')) {
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        static const uint16_t map[] = {
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z };
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        scancode = map[(code & 0x5F) - 'A'];
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else {
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        switch (code) {
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x0003:    scancode = KEY_CENTER;      break;
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x0020:    scancode = KEY_SPACE;       break;
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x0023:    scancode = KEY_SHARP;       break;
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x0033:    scancode = KEY_SHARP;       break;
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x002C:    scancode = KEY_COMMA;       break;
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x003C:    scancode = KEY_COMMA;       break;
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x002E:    scancode = KEY_DOT;         break;
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x003E:    scancode = KEY_DOT;         break;
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x002F:    scancode = KEY_SLASH;       break;
276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x003F:    scancode = KEY_SLASH;       break;
277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x0032:    scancode = KEY_EMAIL;       break;
278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x0040:    scancode = KEY_EMAIL;       break;
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFF08:    scancode = KEY_BACKSPACE;   break;
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFF1B:    scancode = KEY_BACK;        break;
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFF09:    scancode = KEY_TAB;         break;
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFF0D:    scancode = KEY_ENTER;       break;
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0x002A:    scancode = KEY_STAR;        break;
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFFBE:    scancode = KEY_F1;        break; // F1
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFFBF:    scancode = KEY_F2;         break; // F2
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFFC0:    scancode = KEY_F3;        break; // F3
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFFC5:    scancode = KEY_F4;       break; // F8
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            case 0xFFC8:    rfbShutdownServer(cl->screen,TRUE);       break; // F11
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return scancode;
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void keyevent(rfbBool down, rfbKeySym key, rfbClientPtr cl)
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int scancode;
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("Got keysym: %04x (down=%d)\n", (unsigned int)key, (int)down);
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if ((scancode = keysym2scancode(down, key, cl)))
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		injectKeyEvent(scancode, down);
304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid injectTouchEvent(int down, int x, int y)
308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    struct input_event ev;
310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Calculate the final x and y
312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* Fake touch screen always reports zero */
313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (xmin != 0 && xmax != 0 && ymin != 0 && ymax != 0)
314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        x = xmin + (x * (xmax - xmin)) / (scrinfo.xres);
316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        y = ymin + (y * (ymax - ymin)) / (scrinfo.yres);
317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    memset(&ev, 0, sizeof(ev));
320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Then send a BTN_TOUCH
322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gettimeofday(&ev.time,0);
323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.type = EV_KEY;
324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.code = BTN_TOUCH;
325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.value = down;
326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(write(touchfd, &ev, sizeof(ev)) < 0)
327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        printf("write event failed, %s\n", strerror(errno));
329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Then send the X
332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gettimeofday(&ev.time,0);
333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.type = EV_ABS;
334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.code = ABS_X;
335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.value = x;
336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(write(touchfd, &ev, sizeof(ev)) < 0)
337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        printf("write event failed, %s\n", strerror(errno));
339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Then send the Y
342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gettimeofday(&ev.time,0);
343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.type = EV_ABS;
344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.code = ABS_Y;
345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.value = y;
346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(write(touchfd, &ev, sizeof(ev)) < 0)
347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        printf("write event failed, %s\n", strerror(errno));
349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Finally send the SYN
352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gettimeofday(&ev.time,0);
353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.type = EV_SYN;
354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.code = 0;
355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ev.value = 0;
356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(write(touchfd, &ev, sizeof(ev)) < 0)
357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        printf("write event failed, %s\n", strerror(errno));
359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    printf("injectTouchEvent (x=%d, y=%d, down=%d)\n", x , y, down);
362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl)
365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Indicates either pointer movement or a pointer button press or release. The pointer is
367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatnow at (x-position, y-position), and the current state of buttons 1 to 8 are represented
368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatby bits 0 to 7 of button-mask respectively, 0 meaning up, 1 meaning down (pressed).
369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatOn a conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and right
370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatbuttons on the mouse. On a wheel mouse, each step of the wheel upwards is represented
371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatby a press and release of button 4, and each step downwards is represented by
372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehata press and release of button 5.
373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  From: http://www.vislab.usyd.edu.au/blogs/index.php/2009/05/22/an-headerless-indexed-protocol-for-input-1?blog=61 */
374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	//printf("Got ptrevent: %04x (x=%d, y=%d)\n", buttonMask, x, y);
376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(buttonMask & 1) {
377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		// Simulate left mouse event as touch event
378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		injectTouchEvent(1, x, y);
379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		injectTouchEvent(0, x, y);
380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define PIXEL_FB_TO_RFB(p,r,g,b) ((p>>r)&0x1f001f)|(((p>>g)&0x1f001f)<<5)|(((p>>b)&0x1f001f)<<10)
384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void update_screen(void)
386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned int *f, *c, *r;
388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int x, y;
389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	varblock.min_i = varblock.min_j = 9999;
391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	varblock.max_i = varblock.max_j = -1;
392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	f = (unsigned int *)fbmmap;        /* -> framebuffer         */
394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	c = (unsigned int *)fbbuf;         /* -> compare framebuffer */
395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	r = (unsigned int *)vncbuf;        /* -> remote framebuffer  */
396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (y = 0; y < scrinfo.yres; y++)
398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* Compare every 2 pixels at a time, assuming that changes are likely
400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 * in pairs. */
401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		for (x = 0; x < scrinfo.xres; x += 2)
402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		{
403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			unsigned int pixel = *f;
404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (pixel != *c)
406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			{
407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*c = pixel;
408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/* XXX: Undo the checkered pattern to test the efficiency
410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				 * gain using hextile encoding. */
411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (pixel == 0x18e320e4 || pixel == 0x20e418e3)
412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					pixel = 0x18e318e3;
413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*r = PIXEL_FB_TO_RFB(pixel,
415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				  varblock.r_offset, varblock.g_offset, varblock.b_offset);
416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (x < varblock.min_i)
418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					varblock.min_i = x;
419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				else
420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				{
421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (x > varblock.max_i)
422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						varblock.max_i = x;
423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (y > varblock.max_j)
425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						varblock.max_j = y;
426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					else if (y < varblock.min_j)
427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						varblock.min_j = y;
428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			f++, c++;
432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			r++;
433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (varblock.min_i < 9999)
437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (varblock.max_i < 0)
439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			varblock.max_i = varblock.min_i;
440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (varblock.max_j < 0)
442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			varblock.max_j = varblock.min_j;
443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stderr, "Dirty page: %dx%d+%d+%d...\n",
445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		  (varblock.max_i+2) - varblock.min_i, (varblock.max_j+1) - varblock.min_j,
446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		  varblock.min_i, varblock.min_j);
447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbMarkRectAsModified(vncscr, varblock.min_i, varblock.min_j,
449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		  varblock.max_i + 2, varblock.max_j + 1);
450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbProcessEvents(vncscr, 10000);
452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*****************************************************************************/
456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid print_usage(char **argv)
458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("%s [-k device] [-t device] [-h]\n"
460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"-k device: keyboard device node, default is /dev/input/event3\n"
461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"-t device: touch device node, default is /dev/input/event1\n"
462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"-h : print this help\n");
463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint main(int argc, char **argv)
466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(argc > 1)
468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int i=1;
470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while(i < argc)
471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		{
472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if(*argv[i] == '-')
473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			{
474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				switch(*(argv[i] + 1))
475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				{
476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					case 'h':
477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						print_usage(argv);
478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						exit(0);
479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						break;
480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					case 'k':
481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						i++;
482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						strcpy(KBD_DEVICE, argv[i]);
483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						break;
484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					case 't':
485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						i++;
486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						strcpy(TOUCH_DEVICE, argv[i]);
487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						break;
488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i++;
491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("Initializing framebuffer device " FB_DEVICE "...\n");
495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	init_fb();
496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("Initializing keyboard device %s ...\n", KBD_DEVICE);
497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	init_kbd();
498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("Initializing touch device %s ...\n", TOUCH_DEVICE);
499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	init_touch();
500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("Initializing VNC server:\n");
502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("	width:  %d\n", (int)scrinfo.xres);
503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("	height: %d\n", (int)scrinfo.yres);
504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("	bpp:    %d\n", (int)scrinfo.bits_per_pixel);
505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("	port:   %d\n", (int)VNC_PORT);
506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	init_fb_server(argc, argv);
507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Implement our own event loop to detect changes in the framebuffer. */
509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (1)
510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (vncscr->clientHead == NULL)
512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbProcessEvents(vncscr, 100000);
513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbProcessEvents(vncscr, 100000);
515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		update_screen();
516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	printf("Cleaning up...\n");
519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cleanup_fb();
520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cleanup_kdb();
521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cleanup_touch();
522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
523