San Mehat | a430b2b | 2014-09-23 08:30:51 -0700 | [diff] [blame] | 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 | |