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