1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __STRICT_ANSI__
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define _BSD_SOURCE
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <time.h>
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdarg.h>
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfb.h>
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfbclient.h>
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef LIBVNCSERVER_HAVE_LIBPTHREAD
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#error This test need pthread support (otherwise the client blocks the client)
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define ALL_AT_ONCE
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*#define VERY_VERBOSE*/
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic MUTEX(frameBufferMutex);
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehattypedef struct { int id; char* str; } encoding_t;
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic encoding_t testEncodings[]={
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        { rfbEncodingRaw, "raw" },
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingRRE, "rre" },
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingCoRRE, "corre" },
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingHextile, "hextile" },
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingUltra, "ultra" },
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingZlib, "zlib" },
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingZlibHex, "zlibhex" },
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingZRLE, "zrle" },
29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingZYWRLE, "zywrle" },
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ rfbEncodingTight, "tight" },
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{ 0, NULL }
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define NUMBER_OF_ENCODINGS_TO_TEST (sizeof(testEncodings)/sizeof(encoding_t)-1)
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*#define NUMBER_OF_ENCODINGS_TO_TEST 1*/
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* Here come the variables/functions to handle the test output */
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic const int width=400,height=300;
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned int statistics[2][NUMBER_OF_ENCODINGS_TO_TEST];
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned int totalFailed,totalCount;
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned int countGotUpdate;
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic MUTEX(statisticsMutex);
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void initStatistics(void) {
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	memset(statistics[0],0,sizeof(int)*NUMBER_OF_ENCODINGS_TO_TEST);
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	memset(statistics[1],0,sizeof(int)*NUMBER_OF_ENCODINGS_TO_TEST);
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	totalFailed=totalCount=0;
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	INIT_MUTEX(statisticsMutex);
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void updateStatistics(int encodingIndex,rfbBool failed) {
57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	LOCK(statisticsMutex);
58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(failed) {
59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		statistics[1][encodingIndex]++;
60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		totalFailed++;
61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	statistics[0][encodingIndex]++;
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	totalCount++;
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	countGotUpdate++;
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	UNLOCK(statisticsMutex);
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* Here begin the functions for the client. They will be called in a
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * pthread. */
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* maxDelta=0 means they are expected to match exactly;
72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * maxDelta>0 means that the average difference must be lower than maxDelta */
73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool doFramebuffersMatch(rfbScreenInfo* server,rfbClient* client,
74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int maxDelta)
75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int i,j,k;
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned int total=0,diff=0;
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(server->width!=client->width || server->height!=client->height)
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return FALSE;
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	LOCK(frameBufferMutex);
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* TODO: write unit test for colour transformation, use here, too */
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for(i=0;i<server->width;i++)
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		for(j=0;j<server->height;j++)
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			for(k=0;k<3/*server->serverFormat.bitsPerPixel/8*/;k++) {
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				unsigned char s=server->frameBuffer[k+i*4+j*server->paddedWidthInBytes];
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				unsigned char cl=client->frameBuffer[k+i*4+j*client->width*4];
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if(maxDelta==0 && s!=cl) {
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					UNLOCK(frameBufferMutex);
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					return FALSE;
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else {
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					total++;
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					diff+=(s>cl?s-cl:cl-s);
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	UNLOCK(frameBufferMutex);
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(maxDelta>0 && diff/total>=maxDelta)
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return FALSE;
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return TRUE;
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool resize(rfbClient* cl) {
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(cl->frameBuffer)
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(cl->frameBuffer);
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cl->frameBuffer=malloc(cl->width*cl->height*cl->format.bitsPerPixel/8);
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(!cl->frameBuffer)
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return FALSE;
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	SendFramebufferUpdateRequest(cl,0,0,cl->width,cl->height,FALSE);
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return TRUE;
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehattypedef struct clientData {
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int encodingIndex;
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbScreenInfo* server;
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char* display;
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} clientData;
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void update(rfbClient* client,int x,int y,int w,int h) {
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef VERY_VERBOSE
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static const char* progress="|/-\\";
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static int counter=0;
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(++counter>sizeof(progress)) counter=0;
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fprintf(stderr,"%c\r",progress[counter]);
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	clientData* cd=(clientData*)client->clientData;
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientLog("Got update (encoding=%s): (%d,%d)-(%d,%d)\n",
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			testEncodings[cd->encodingIndex].str,
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			x,y,x+w,y+h);
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void update_finished(rfbClient* client) {
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	clientData* cd=(clientData*)client->clientData;
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        int maxDelta=0;
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(testEncodings[cd->encodingIndex].id==rfbEncodingZYWRLE)
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		maxDelta=5;
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(testEncodings[cd->encodingIndex].id==rfbEncodingTight)
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		maxDelta=5;
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	updateStatistics(cd->encodingIndex,
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			!doFramebuffersMatch(cd->server,client,maxDelta));
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void* clientLoop(void* data) {
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClient* client=(rfbClient*)data;
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	clientData* cd=(clientData*)client->clientData;
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->appData.encodingsString=strdup(testEncodings[cd->encodingIndex].str);
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->appData.qualityLevel = 7; /* ZYWRLE fails the test with standard settings */
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	sleep(1);
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientLog("Starting client (encoding %s, display %s)\n",
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			testEncodings[cd->encodingIndex].str,
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			cd->display);
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(!rfbInitClient(client,NULL,NULL)) {
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbClientErr("Had problems starting client (encoding %s)\n",
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				testEncodings[cd->encodingIndex].str);
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		updateStatistics(cd->encodingIndex,TRUE);
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return NULL;
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while(1) {
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(WaitForMessage(client,50)>=0)
170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if(!HandleRFBServerMessage(client))
171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(((clientData*)client->clientData)->display);
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(client->clientData);
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(client->frameBuffer)
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(client->frameBuffer);
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientCleanup(client);
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return NULL;
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic pthread_t all_threads[NUMBER_OF_ENCODINGS_TO_TEST];
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int thread_counter;
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void startClient(int encodingIndex,rfbScreenInfo* server) {
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClient* client=rfbGetClient(8,3,4);
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	clientData* cd;
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->clientData=malloc(sizeof(clientData));
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->MallocFrameBuffer=resize;
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->GotFrameBufferUpdate=update;
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->FinishedFrameBufferUpdate=update_finished;
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cd=(clientData*)client->clientData;
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cd->encodingIndex=encodingIndex;
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cd->server=server;
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cd->display=(char*)malloc(6);
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	sprintf(cd->display,":%d",server->port-5900);
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	pthread_create(&all_threads[thread_counter++],NULL,clientLoop,(void*)client);
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* Here begin the server functions */
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void idle(rfbScreenInfo* server)
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int c;
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbBool goForward;
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	LOCK(statisticsMutex);
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef ALL_AT_ONCE
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	goForward=(countGotUpdate==NUMBER_OF_ENCODINGS_TO_TEST);
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	goForward=(countGotUpdate==1);
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	UNLOCK(statisticsMutex);
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(!goForward)
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  return;
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	countGotUpdate=0;
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	LOCK(frameBufferMutex);
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int i,j;
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int x1=(rand()%(server->width-1)),x2=(rand()%(server->width-1)),
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		y1=(rand()%(server->height-1)),y2=(rand()%(server->height-1));
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(x1>x2) { i=x1; x1=x2; x2=i; }
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(y1>y2) { i=y1; y1=y2; y2=i; }
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		x2++; y2++;
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		for(c=0;c<3;c++) {
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			for(i=x1;i<x2;i++)
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				for(j=y1;j<y2;j++)
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					server->frameBuffer[i*4+c+j*server->paddedWidthInBytes]=255*(i-x1+j-y1)/(x2-x1+y2-y1);
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbMarkRectAsModified(server,x1,y1,x2,y2);
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef VERY_VERBOSE
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("Sent update (%d,%d)-(%d,%d)\n",x1,y1,x2,y2);
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	UNLOCK(frameBufferMutex);
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* log function (to show what messages are from the client) */
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbTestLog(const char *format, ...)
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	va_list args;
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char buf[256];
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	time_t log_clock;
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(!rfbEnableClientLogging)
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	va_start(args, format);
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	time(&log_clock);
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	strftime(buf, 255, "%d/%m/%Y %X (client) ", localtime(&log_clock));
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fprintf(stderr,buf);
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vfprintf(stderr, format, args);
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fflush(stderr);
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	va_end(args);
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* the main function */
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint main(int argc,char** argv)
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int i,j;
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	time_t t;
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbScreenInfoPtr server;
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientLog=rfbTestLog;
276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientErr=rfbTestLog;
277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Initialize server */
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	server=rfbGetScreen(&argc,argv,width,height,8,3,4);
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if(!server)
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          return 0;
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	server->frameBuffer=malloc(400*300*4);
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	server->cursor=NULL;
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for(j=0;j<400*300*4;j++)
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		server->frameBuffer[j]=j;
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbInitServer(server);
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbProcessEvents(server,0);
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	initStatistics();
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef ALL_AT_ONCE
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for(i=0;i<NUMBER_OF_ENCODINGS_TO_TEST;i++) {
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Initialize clients */
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for(i=0;i<NUMBER_OF_ENCODINGS_TO_TEST;i++)
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		startClient(i,server);
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	t=time(NULL);
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* test 20 seconds */
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while(time(NULL)-t<20) {
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		idle(server);
305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbProcessEvents(server,1);
307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("%d failed, %d received\n",totalFailed,totalCount);
309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef ALL_AT_ONCE
310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbClientPtr cl;
312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbClientIteratorPtr iter=rfbGetClientIterator(server);
313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while((cl=rfbClientIteratorNext(iter)))
314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbCloseClient(cl);
315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbReleaseClientIterator(iter);
316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* shut down server, disconnecting all clients */
321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbShutdownServer(server, TRUE);
322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for(i=0;i<thread_counter;i++)
324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		pthread_join(all_threads[i], NULL);
325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(server->frameBuffer);
327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbScreenCleanup(server);
328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("Statistics:\n");
330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for(i=0;i<NUMBER_OF_ENCODINGS_TO_TEST;i++)
331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("%s encoding: %d failed, %d received\n",
332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				testEncodings[i].str,statistics[1][i],statistics[0][i]);
333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(totalFailed)
334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 1;
335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return(0);
336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
339