Home | History | Annotate | Download | only in examples
      1 /**
      2 * @example pnmshow.c
      3 */
      4 #include <stdio.h>
      5 #include <rfb/rfb.h>
      6 #include <rfb/keysym.h>
      7 
      8 #ifndef HAVE_HANDLEKEY
      9 static void HandleKey(rfbBool down,rfbKeySym key,rfbClientPtr cl)
     10 {
     11   if(down && (key==XK_Escape || key=='q' || key=='Q'))
     12     rfbCloseClient(cl);
     13 }
     14 #endif
     15 
     16 int main(int argc,char** argv)
     17 {
     18   FILE* in=stdin;
     19   int i,j,k,l,width,height,paddedWidth;
     20   char buffer[1024];
     21   rfbScreenInfoPtr rfbScreen;
     22   enum { BW, GRAY, TRUECOLOUR } picType=TRUECOLOUR;
     23   int bytesPerPixel,bitsPerPixelInFile;
     24 
     25   if(argc>1) {
     26     in=fopen(argv[1],"rb");
     27     if(!in) {
     28       printf("Couldn't find file %s.\n",argv[1]);
     29       exit(1);
     30     }
     31   }
     32 
     33   fgets(buffer,1024,in);
     34   if(!strncmp(buffer,"P6",2)) {
     35 	  picType=TRUECOLOUR;
     36 	  bytesPerPixel=4; bitsPerPixelInFile=3*8;
     37   } else if(!strncmp(buffer,"P5",2)) {
     38 	  picType=GRAY;
     39 	  bytesPerPixel=1; bitsPerPixelInFile=1*8;
     40   } else if(!strncmp(buffer,"P4",2)) {
     41 	  picType=BW;
     42 	  bytesPerPixel=1; bitsPerPixelInFile=1;
     43   } else {
     44     printf("Not a ppm.\n");
     45     exit(2);
     46   }
     47 
     48   /* skip comments */
     49   do {
     50     fgets(buffer,1024,in);
     51   } while(buffer[0]=='#');
     52 
     53   /* get width & height */
     54   sscanf(buffer,"%d %d",&width,&height);
     55   rfbLog("Got width %d and height %d.\n",width,height);
     56   if(picType!=BW)
     57 	fgets(buffer,1024,in);
     58   else
     59 	  width=1+((width-1)|7);
     60 
     61   /* vncviewers have problems with widths which are no multiple of 4. */
     62   paddedWidth = width;
     63   if(width&3)
     64     paddedWidth+=4-(width&3);
     65 
     66   /* initialize data for vnc server */
     67   rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,(bitsPerPixelInFile+7)/8,bytesPerPixel);
     68   if(!rfbScreen)
     69     return 0;
     70   if(argc>1)
     71     rfbScreen->desktopName = argv[1];
     72   else
     73     rfbScreen->desktopName = "Picture";
     74   rfbScreen->alwaysShared = TRUE;
     75   rfbScreen->kbdAddEvent = HandleKey;
     76 
     77   /* enable http */
     78   rfbScreen->httpDir = "../webclients";
     79 
     80   /* allocate picture and read it */
     81   rfbScreen->frameBuffer = (char*)malloc(paddedWidth*bytesPerPixel*height);
     82   fread(rfbScreen->frameBuffer,width*bitsPerPixelInFile/8,height,in);
     83   fclose(in);
     84 
     85   if(picType!=TRUECOLOUR) {
     86 	  rfbScreen->serverFormat.trueColour=FALSE;
     87 	  rfbScreen->colourMap.count=256;
     88 	  rfbScreen->colourMap.is16=FALSE;
     89 	  rfbScreen->colourMap.data.bytes=malloc(256*3);
     90 	  for(i=0;i<256;i++)
     91 		  memset(rfbScreen->colourMap.data.bytes+3*i,i,3);
     92   }
     93 
     94   switch(picType) {
     95 	case TRUECOLOUR:
     96 		  /* correct the format to 4 bytes instead of 3 (and pad to paddedWidth) */
     97 		  for(j=height-1;j>=0;j--) {
     98 		    for(i=width-1;i>=0;i--)
     99 		      for(k=2;k>=0;k--)
    100 			rfbScreen->frameBuffer[(j*paddedWidth+i)*4+k]=
    101 			  rfbScreen->frameBuffer[(j*width+i)*3+k];
    102 		    for(i=width*4;i<paddedWidth*4;i++)
    103 		      rfbScreen->frameBuffer[j*paddedWidth*4+i]=0;
    104 		  }
    105 		  break;
    106 	case GRAY:
    107 		  break;
    108 	case BW:
    109 		  /* correct the format from 1 bit to 8 bits */
    110 		  for(j=height-1;j>=0;j--)
    111 			  for(i=width-1;i>=0;i-=8) {
    112 				  l=(unsigned char)rfbScreen->frameBuffer[(j*width+i)/8];
    113 				  for(k=7;k>=0;k--)
    114 					  rfbScreen->frameBuffer[j*paddedWidth+i+7-k]=(l&(1<<k))?0:255;
    115 			  }
    116 		  break;
    117   }
    118 
    119   /* initialize server */
    120   rfbInitServer(rfbScreen);
    121 
    122   /* run event loop */
    123   rfbRunEventLoop(rfbScreen,40000,FALSE);
    124 
    125   return(0);
    126 }
    127