| /** |
| * @example pnmshow.c |
| */ |
| #include <stdio.h> |
| #include <rfb/rfb.h> |
| #include <rfb/keysym.h> |
| |
| #ifndef HAVE_HANDLEKEY |
| static void HandleKey(rfbBool down,rfbKeySym key,rfbClientPtr cl) |
| { |
| if(down && (key==XK_Escape || key=='q' || key=='Q')) |
| rfbCloseClient(cl); |
| } |
| #endif |
| |
| int main(int argc,char** argv) |
| { |
| FILE* in=stdin; |
| int i,j,k,l,width,height,paddedWidth; |
| char buffer[1024]; |
| rfbScreenInfoPtr rfbScreen; |
| enum { BW, GRAY, TRUECOLOUR } picType=TRUECOLOUR; |
| int bytesPerPixel,bitsPerPixelInFile; |
| |
| if(argc>1) { |
| in=fopen(argv[1],"rb"); |
| if(!in) { |
| printf("Couldn't find file %s.\n",argv[1]); |
| exit(1); |
| } |
| } |
| |
| fgets(buffer,1024,in); |
| if(!strncmp(buffer,"P6",2)) { |
| picType=TRUECOLOUR; |
| bytesPerPixel=4; bitsPerPixelInFile=3*8; |
| } else if(!strncmp(buffer,"P5",2)) { |
| picType=GRAY; |
| bytesPerPixel=1; bitsPerPixelInFile=1*8; |
| } else if(!strncmp(buffer,"P4",2)) { |
| picType=BW; |
| bytesPerPixel=1; bitsPerPixelInFile=1; |
| } else { |
| printf("Not a ppm.\n"); |
| exit(2); |
| } |
| |
| /* skip comments */ |
| do { |
| fgets(buffer,1024,in); |
| } while(buffer[0]=='#'); |
| |
| /* get width & height */ |
| sscanf(buffer,"%d %d",&width,&height); |
| rfbLog("Got width %d and height %d.\n",width,height); |
| if(picType!=BW) |
| fgets(buffer,1024,in); |
| else |
| width=1+((width-1)|7); |
| |
| /* vncviewers have problems with widths which are no multiple of 4. */ |
| paddedWidth = width; |
| if(width&3) |
| paddedWidth+=4-(width&3); |
| |
| /* initialize data for vnc server */ |
| rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,(bitsPerPixelInFile+7)/8,bytesPerPixel); |
| if(!rfbScreen) |
| return 0; |
| if(argc>1) |
| rfbScreen->desktopName = argv[1]; |
| else |
| rfbScreen->desktopName = "Picture"; |
| rfbScreen->alwaysShared = TRUE; |
| rfbScreen->kbdAddEvent = HandleKey; |
| |
| /* enable http */ |
| rfbScreen->httpDir = "../webclients"; |
| |
| /* allocate picture and read it */ |
| rfbScreen->frameBuffer = (char*)malloc(paddedWidth*bytesPerPixel*height); |
| fread(rfbScreen->frameBuffer,width*bitsPerPixelInFile/8,height,in); |
| fclose(in); |
| |
| if(picType!=TRUECOLOUR) { |
| rfbScreen->serverFormat.trueColour=FALSE; |
| rfbScreen->colourMap.count=256; |
| rfbScreen->colourMap.is16=FALSE; |
| rfbScreen->colourMap.data.bytes=malloc(256*3); |
| for(i=0;i<256;i++) |
| memset(rfbScreen->colourMap.data.bytes+3*i,i,3); |
| } |
| |
| switch(picType) { |
| case TRUECOLOUR: |
| /* correct the format to 4 bytes instead of 3 (and pad to paddedWidth) */ |
| for(j=height-1;j>=0;j--) { |
| for(i=width-1;i>=0;i--) |
| for(k=2;k>=0;k--) |
| rfbScreen->frameBuffer[(j*paddedWidth+i)*4+k]= |
| rfbScreen->frameBuffer[(j*width+i)*3+k]; |
| for(i=width*4;i<paddedWidth*4;i++) |
| rfbScreen->frameBuffer[j*paddedWidth*4+i]=0; |
| } |
| break; |
| case GRAY: |
| break; |
| case BW: |
| /* correct the format from 1 bit to 8 bits */ |
| for(j=height-1;j>=0;j--) |
| for(i=width-1;i>=0;i-=8) { |
| l=(unsigned char)rfbScreen->frameBuffer[(j*width+i)/8]; |
| for(k=7;k>=0;k--) |
| rfbScreen->frameBuffer[j*paddedWidth+i+7-k]=(l&(1<<k))?0:255; |
| } |
| break; |
| } |
| |
| /* initialize server */ |
| rfbInitServer(rfbScreen); |
| |
| /* run event loop */ |
| rfbRunEventLoop(rfbScreen,40000,FALSE); |
| |
| return(0); |
| } |