1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/* A simple example of an RFB client */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <rfb/rfbclient.h>
static void PrintRect(rfbClient* client, int x, int y, int w, int h) {
rfbClientLog("Received an update for %d,%d,%d,%d.\n",x,y,w,h);
}
static void SaveFramebufferAsPPM(rfbClient* client, int x, int y, int w, int h) {
static time_t t=0,t1;
FILE* f;
int i,j;
rfbPixelFormat* pf=&client->format;
int bpp=pf->bitsPerPixel/8;
int row_stride=client->width*bpp;
/* save one picture only if the last is older than 2 seconds */
t1=time(NULL);
if(t1-t>2)
t=t1;
else
return;
/* assert bpp=4 */
if(bpp!=4 && bpp!=2) {
rfbClientLog("bpp = %d (!=4)\n",bpp);
return;
}
f=fopen("framebuffer.ppm","wb");
if(!f) {
rfbClientErr("Could not open framebuffer.ppm\n");
return;
}
fprintf(f,"P6\n# %s\n%d %d\n255\n",client->desktopName,client->width,client->height);
for(j=0;j<client->height*row_stride;j+=row_stride)
for(i=0;i<client->width*bpp;i+=bpp) {
const char* p=client->frameBuffer+j+i;
unsigned int v;
if(bpp==4)
v=*(unsigned int*)p;
else if(bpp==2)
v=*(unsigned short*)p;
else
v=*(unsigned char*)p;
fputc((v>>pf->redShift)*256/(pf->redMax+1),f);
fputc((v>>pf->greenShift)*256/(pf->greenMax+1),f);
fputc((v>>pf->blueShift)*256/(pf->blueMax+1),f);
}
fclose(f);
}
int
main(int argc, char **argv)
{
rfbClient* client = rfbGetClient(8,3,4);
time_t t=time(NULL);
if(argc>1 && !strcmp("-print",argv[1])) {
client->GotFrameBufferUpdate = PrintRect;
argv[1]=argv[0]; argv++; argc--;
} else
client->GotFrameBufferUpdate = SaveFramebufferAsPPM;
/* The -listen option is used to make us a daemon process which listens for
incoming connections from servers, rather than actively connecting to a
given server. The -tunnel and -via options are useful to create
connections tunneled via SSH port forwarding. We must test for the
-listen option before invoking any Xt functions - this is because we use
forking, and Xt doesn't seem to cope with forking very well. For -listen
option, when a successful incoming connection has been accepted,
listenForIncomingConnections() returns, setting the listenSpecified
flag. */
if (!rfbInitClient(client,&argc,argv))
return 1;
/* TODO: better wait for update completion */
while (time(NULL)-t<5) {
static int i=0;
fprintf(stderr,"\r%d",i++);
if(WaitForMessage(client,50)<0)
break;
if(!HandleRFBServerMessage(client))
break;
}
rfbClientCleanup(client);
return 0;
}
|