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