|
Packit Service |
b05338 |
#ifdef __STRICT_ANSI__
|
|
Packit Service |
b05338 |
#define _BSD_SOURCE
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
#include <time.h>
|
|
Packit Service |
b05338 |
#include <stdarg.h>
|
|
Packit Service |
b05338 |
#include <rfb/rfb.h>
|
|
Packit Service |
b05338 |
#include <rfb/rfbclient.h>
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
#ifndef LIBVNCSERVER_HAVE_LIBPTHREAD
|
|
Packit Service |
b05338 |
#error This test need pthread support (otherwise the client blocks the client)
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
#define ALL_AT_ONCE
|
|
Packit Service |
b05338 |
/*#define VERY_VERBOSE*/
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static MUTEX(frameBufferMutex);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
typedef struct { int id; char* str; } encoding_t;
|
|
Packit Service |
b05338 |
static encoding_t testEncodings[]={
|
|
Packit Service |
b05338 |
{ rfbEncodingRaw, "raw" },
|
|
Packit Service |
b05338 |
{ rfbEncodingRRE, "rre" },
|
|
Packit Service |
b05338 |
{ rfbEncodingCoRRE, "corre" },
|
|
Packit Service |
b05338 |
{ rfbEncodingHextile, "hextile" },
|
|
Packit Service |
b05338 |
{ rfbEncodingUltra, "ultra" },
|
|
Packit Service |
b05338 |
#ifdef LIBVNCSERVER_HAVE_LIBZ
|
|
Packit Service |
b05338 |
{ rfbEncodingZlib, "zlib" },
|
|
Packit Service |
b05338 |
{ rfbEncodingZlibHex, "zlibhex" },
|
|
Packit Service |
b05338 |
{ rfbEncodingZRLE, "zrle" },
|
|
Packit Service |
b05338 |
{ rfbEncodingZYWRLE, "zywrle" },
|
|
Packit Service |
b05338 |
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
|
|
Packit Service |
b05338 |
{ rfbEncodingTight, "tight" },
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
{ 0, NULL }
|
|
Packit Service |
b05338 |
};
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
#define NUMBER_OF_ENCODINGS_TO_TEST (sizeof(testEncodings)/sizeof(encoding_t)-1)
|
|
Packit Service |
b05338 |
/*#define NUMBER_OF_ENCODINGS_TO_TEST 1*/
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
/* Here come the variables/functions to handle the test output */
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static const int width=400,height=300;
|
|
Packit Service |
b05338 |
static unsigned int statistics[2][NUMBER_OF_ENCODINGS_TO_TEST];
|
|
Packit Service |
b05338 |
static unsigned int totalFailed,totalCount;
|
|
Packit Service |
b05338 |
static unsigned int countGotUpdate;
|
|
Packit Service |
b05338 |
static MUTEX(statisticsMutex);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static void initStatistics(void) {
|
|
Packit Service |
b05338 |
memset(statistics[0],0,sizeof(int)*NUMBER_OF_ENCODINGS_TO_TEST);
|
|
Packit Service |
b05338 |
memset(statistics[1],0,sizeof(int)*NUMBER_OF_ENCODINGS_TO_TEST);
|
|
Packit Service |
b05338 |
totalFailed=totalCount=0;
|
|
Packit Service |
b05338 |
INIT_MUTEX(statisticsMutex);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static void updateStatistics(int encodingIndex,rfbBool failed) {
|
|
Packit Service |
b05338 |
LOCK(statisticsMutex);
|
|
Packit Service |
b05338 |
if(failed) {
|
|
Packit Service |
b05338 |
statistics[1][encodingIndex]++;
|
|
Packit Service |
b05338 |
totalFailed++;
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
statistics[0][encodingIndex]++;
|
|
Packit Service |
b05338 |
totalCount++;
|
|
Packit Service |
b05338 |
countGotUpdate++;
|
|
Packit Service |
b05338 |
UNLOCK(statisticsMutex);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
/* Here begin the functions for the client. They will be called in a
|
|
Packit Service |
b05338 |
* pthread. */
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
/* maxDelta=0 means they are expected to match exactly;
|
|
Packit Service |
b05338 |
* maxDelta>0 means that the average difference must be lower than maxDelta */
|
|
Packit Service |
b05338 |
static rfbBool doFramebuffersMatch(rfbScreenInfo* server,rfbClient* client,
|
|
Packit Service |
b05338 |
int maxDelta)
|
|
Packit Service |
b05338 |
{
|
|
Packit Service |
b05338 |
int i,j,k;
|
|
Packit Service |
b05338 |
unsigned int total=0,diff=0;
|
|
Packit Service |
b05338 |
if(server->width!=client->width || server->height!=client->height)
|
|
Packit Service |
b05338 |
return FALSE;
|
|
Packit Service |
b05338 |
LOCK(frameBufferMutex);
|
|
Packit Service |
b05338 |
/* TODO: write unit test for colour transformation, use here, too */
|
|
Packit Service |
b05338 |
for(i=0;i<server->width;i++)
|
|
Packit Service |
b05338 |
for(j=0;j<server->height;j++)
|
|
Packit Service |
b05338 |
for(k=0;k<3/*server->serverFormat.bitsPerPixel/8*/;k++) {
|
|
Packit Service |
b05338 |
unsigned char s=server->frameBuffer[k+i*4+j*server->paddedWidthInBytes];
|
|
Packit Service |
b05338 |
unsigned char cl=client->frameBuffer[k+i*4+j*client->width*4];
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
if(maxDelta==0 && s!=cl) {
|
|
Packit Service |
b05338 |
UNLOCK(frameBufferMutex);
|
|
Packit Service |
b05338 |
return FALSE;
|
|
Packit Service |
b05338 |
} else {
|
|
Packit Service |
b05338 |
total++;
|
|
Packit Service |
b05338 |
diff+=(s>cl?s-cl:cl-s);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
UNLOCK(frameBufferMutex);
|
|
Packit Service |
b05338 |
if(maxDelta>0 && diff/total>=maxDelta)
|
|
Packit Service |
b05338 |
return FALSE;
|
|
Packit Service |
b05338 |
return TRUE;
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static rfbBool resize(rfbClient* cl) {
|
|
Packit Service |
b05338 |
if(cl->frameBuffer)
|
|
Packit Service |
b05338 |
free(cl->frameBuffer);
|
|
Packit Service |
b05338 |
cl->frameBuffer=malloc(cl->width*cl->height*cl->format.bitsPerPixel/8);
|
|
Packit Service |
b05338 |
if(!cl->frameBuffer)
|
|
Packit Service |
b05338 |
return FALSE;
|
|
Packit Service |
b05338 |
SendFramebufferUpdateRequest(cl,0,0,cl->width,cl->height,FALSE);
|
|
Packit Service |
b05338 |
return TRUE;
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
typedef struct clientData {
|
|
Packit Service |
b05338 |
int encodingIndex;
|
|
Packit Service |
b05338 |
rfbScreenInfo* server;
|
|
Packit Service |
b05338 |
char* display;
|
|
Packit Service |
b05338 |
} clientData;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static void update(rfbClient* client,int x,int y,int w,int h) {
|
|
Packit Service |
b05338 |
#ifndef VERY_VERBOSE
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static const char* progress="|/-\\";
|
|
Packit Service |
b05338 |
static int counter=0;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
if(++counter>sizeof(progress)) counter=0;
|
|
Packit Service |
b05338 |
fprintf(stderr,"%c\r",progress[counter]);
|
|
Packit Service |
b05338 |
#else
|
|
Packit Service |
b05338 |
clientData* cd=(clientData*)client->clientData;
|
|
Packit Service |
b05338 |
rfbClientLog("Got update (encoding=%s): (%d,%d)-(%d,%d)\n",
|
|
Packit Service |
b05338 |
testEncodings[cd->encodingIndex].str,
|
|
Packit Service |
b05338 |
x,y,x+w,y+h);
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static void update_finished(rfbClient* client) {
|
|
Packit Service |
b05338 |
clientData* cd=(clientData*)client->clientData;
|
|
Packit Service |
b05338 |
int maxDelta=0;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
#ifdef LIBVNCSERVER_HAVE_LIBZ
|
|
Packit Service |
b05338 |
if(testEncodings[cd->encodingIndex].id==rfbEncodingZYWRLE)
|
|
Packit Service |
b05338 |
maxDelta=5;
|
|
Packit Service |
b05338 |
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
|
|
Packit Service |
b05338 |
if(testEncodings[cd->encodingIndex].id==rfbEncodingTight)
|
|
Packit Service |
b05338 |
maxDelta=5;
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
updateStatistics(cd->encodingIndex,
|
|
Packit Service |
b05338 |
!doFramebuffersMatch(cd->server,client,maxDelta));
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static void* clientLoop(void* data) {
|
|
Packit Service |
b05338 |
rfbClient* client=(rfbClient*)data;
|
|
Packit Service |
b05338 |
clientData* cd=(clientData*)client->clientData;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
client->appData.encodingsString=strdup(testEncodings[cd->encodingIndex].str);
|
|
Packit Service |
b05338 |
client->appData.qualityLevel = 7; /* ZYWRLE fails the test with standard settings */
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
sleep(1);
|
|
Packit Service |
b05338 |
rfbClientLog("Starting client (encoding %s, display %s)\n",
|
|
Packit Service |
b05338 |
testEncodings[cd->encodingIndex].str,
|
|
Packit Service |
b05338 |
cd->display);
|
|
Packit Service |
b05338 |
if(!rfbInitClient(client,NULL,NULL)) {
|
|
Packit Service |
b05338 |
rfbClientErr("Had problems starting client (encoding %s)\n",
|
|
Packit Service |
b05338 |
testEncodings[cd->encodingIndex].str);
|
|
Packit Service |
b05338 |
updateStatistics(cd->encodingIndex,TRUE);
|
|
Packit Service |
b05338 |
return NULL;
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
while(1) {
|
|
Packit Service |
b05338 |
if(WaitForMessage(client,50)>=0)
|
|
Packit Service |
b05338 |
if(!HandleRFBServerMessage(client))
|
|
Packit Service |
b05338 |
break;
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
free(((clientData*)client->clientData)->display);
|
|
Packit Service |
b05338 |
free(client->clientData);
|
|
Packit Service |
b05338 |
client->clientData = NULL;
|
|
Packit Service |
b05338 |
if(client->frameBuffer)
|
|
Packit Service |
b05338 |
free(client->frameBuffer);
|
|
Packit Service |
b05338 |
rfbClientCleanup(client);
|
|
Packit Service |
b05338 |
return NULL;
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static pthread_t all_threads[NUMBER_OF_ENCODINGS_TO_TEST];
|
|
Packit Service |
b05338 |
static int thread_counter;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static void startClient(int encodingIndex,rfbScreenInfo* server) {
|
|
Packit Service |
b05338 |
rfbClient* client=rfbGetClient(8,3,4);
|
|
Packit Service |
b05338 |
clientData* cd;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
client->clientData=malloc(sizeof(clientData));
|
|
Packit Service |
b05338 |
client->MallocFrameBuffer=resize;
|
|
Packit Service |
b05338 |
client->GotFrameBufferUpdate=update;
|
|
Packit Service |
b05338 |
client->FinishedFrameBufferUpdate=update_finished;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
cd=(clientData*)client->clientData;
|
|
Packit Service |
b05338 |
cd->encodingIndex=encodingIndex;
|
|
Packit Service |
b05338 |
cd->server=server;
|
|
Packit Service |
b05338 |
cd->display=(char*)malloc(6);
|
|
Packit Service |
b05338 |
sprintf(cd->display,":%d",server->port-5900);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
pthread_create(&all_threads[thread_counter++],NULL,clientLoop,(void*)client);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
/* Here begin the server functions */
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static void idle(rfbScreenInfo* server)
|
|
Packit Service |
b05338 |
{
|
|
Packit Service |
b05338 |
int c;
|
|
Packit Service |
b05338 |
rfbBool goForward;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
LOCK(statisticsMutex);
|
|
Packit Service |
b05338 |
#ifdef ALL_AT_ONCE
|
|
Packit Service |
b05338 |
goForward=(countGotUpdate==NUMBER_OF_ENCODINGS_TO_TEST);
|
|
Packit Service |
b05338 |
#else
|
|
Packit Service |
b05338 |
goForward=(countGotUpdate==1);
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
UNLOCK(statisticsMutex);
|
|
Packit Service |
b05338 |
if(!goForward)
|
|
Packit Service |
b05338 |
return;
|
|
Packit Service |
b05338 |
countGotUpdate=0;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
LOCK(frameBufferMutex);
|
|
Packit Service |
b05338 |
{
|
|
Packit Service |
b05338 |
int i,j;
|
|
Packit Service |
b05338 |
int x1=(rand()%(server->width-1)),x2=(rand()%(server->width-1)),
|
|
Packit Service |
b05338 |
y1=(rand()%(server->height-1)),y2=(rand()%(server->height-1));
|
|
Packit Service |
b05338 |
if(x1>x2) { i=x1; x1=x2; x2=i; }
|
|
Packit Service |
b05338 |
if(y1>y2) { i=y1; y1=y2; y2=i; }
|
|
Packit Service |
b05338 |
x2++; y2++;
|
|
Packit Service |
b05338 |
for(c=0;c<3;c++) {
|
|
Packit Service |
b05338 |
for(i=x1;i
|
|
Packit Service |
b05338 |
for(j=y1;j
|
|
Packit Service |
b05338 |
server->frameBuffer[i*4+c+j*server->paddedWidthInBytes]=255*(i-x1+j-y1)/(x2-x1+y2-y1);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
rfbMarkRectAsModified(server,x1,y1,x2,y2);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
#ifdef VERY_VERBOSE
|
|
Packit Service |
b05338 |
rfbLog("Sent update (%d,%d)-(%d,%d)\n",x1,y1,x2,y2);
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
UNLOCK(frameBufferMutex);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
/* log function (to show what messages are from the client) */
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
static void
|
|
Packit Service |
b05338 |
rfbTestLog(const char *format, ...)
|
|
Packit Service |
b05338 |
{
|
|
Packit Service |
b05338 |
va_list args;
|
|
Packit Service |
b05338 |
char buf[256];
|
|
Packit Service |
b05338 |
time_t log_clock;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
if(!rfbEnableClientLogging)
|
|
Packit Service |
b05338 |
return;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
va_start(args, format);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
time(&log_clock);
|
|
Packit Service |
b05338 |
strftime(buf, 255, "%d/%m/%Y %X (client) ", localtime(&log_clock));
|
|
Packit Service |
b05338 |
fprintf(stderr,"%s",buf);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
vfprintf(stderr, format, args);
|
|
Packit Service |
b05338 |
fflush(stderr);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
va_end(args);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
/* the main function */
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
int main(int argc,char** argv)
|
|
Packit Service |
b05338 |
{
|
|
Packit Service |
b05338 |
int i,j;
|
|
Packit Service |
b05338 |
time_t t;
|
|
Packit Service |
b05338 |
rfbScreenInfoPtr server;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
rfbClientLog=rfbTestLog;
|
|
Packit Service |
b05338 |
rfbClientErr=rfbTestLog;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
/* Initialize server */
|
|
Packit Service |
b05338 |
server=rfbGetScreen(&argc,argv,width,height,8,3,4);
|
|
Packit Service |
b05338 |
if(!server)
|
|
Packit Service |
b05338 |
return 0;
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
server->frameBuffer=malloc(400*300*4);
|
|
Packit Service |
b05338 |
server->cursor=NULL;
|
|
Packit Service |
b05338 |
for(j=0;j<400*300*4;j++)
|
|
Packit Service |
b05338 |
server->frameBuffer[j]=j;
|
|
Packit Service |
b05338 |
rfbInitServer(server);
|
|
Packit Service |
b05338 |
rfbProcessEvents(server,0);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
initStatistics();
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
#ifndef ALL_AT_ONCE
|
|
Packit Service |
b05338 |
for(i=0;i
|
|
Packit Service |
b05338 |
#else
|
|
Packit Service |
b05338 |
/* Initialize clients */
|
|
Packit Service |
b05338 |
for(i=0;i
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
startClient(i,server);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
t=time(NULL);
|
|
Packit Service |
b05338 |
/* test 20 seconds */
|
|
Packit Service |
b05338 |
while(time(NULL)-t<20) {
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
idle(server);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
rfbProcessEvents(server,1);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
rfbLog("%d failed, %d received\n",totalFailed,totalCount);
|
|
Packit Service |
b05338 |
#ifndef ALL_AT_ONCE
|
|
Packit Service |
b05338 |
{
|
|
Packit Service |
b05338 |
rfbClientPtr cl;
|
|
Packit Service |
b05338 |
rfbClientIteratorPtr iter=rfbGetClientIterator(server);
|
|
Packit Service |
b05338 |
while((cl=rfbClientIteratorNext(iter)))
|
|
Packit Service |
b05338 |
rfbCloseClient(cl);
|
|
Packit Service |
b05338 |
rfbReleaseClientIterator(iter);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
#endif
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
/* shut down server, disconnecting all clients */
|
|
Packit Service |
b05338 |
rfbShutdownServer(server, TRUE);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
for(i=0;i
|
|
Packit Service |
b05338 |
pthread_join(all_threads[i], NULL);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
free(server->frameBuffer);
|
|
Packit Service |
b05338 |
rfbScreenCleanup(server);
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
rfbLog("Statistics:\n");
|
|
Packit Service |
b05338 |
for(i=0;i
|
|
Packit Service |
b05338 |
rfbLog("%s encoding: %d failed, %d received\n",
|
|
Packit Service |
b05338 |
testEncodings[i].str,statistics[1][i],statistics[0][i]);
|
|
Packit Service |
b05338 |
if(totalFailed)
|
|
Packit Service |
b05338 |
return 1;
|
|
Packit Service |
b05338 |
return(0);
|
|
Packit Service |
b05338 |
}
|
|
Packit Service |
b05338 |
|
|
Packit Service |
b05338 |
|