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
HandleKey(rfbBool down,rfbKeySym key,rfbClientPtr cl)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 
main(int argc,char ** argv)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