Example #1
0
static int handleHextile(tSDL_vnc *vnc) {
    DBMESSAGE("Hextile encoding.\n");
    //
    if (!(vnc->tilebuffer)) {
        // Create new tilebuffer
        vnc->tilebuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,16,16,32,vnc->rmask,vnc->gmask,vnc->bmask,0);
        if (vnc->tilebuffer) {
            SDL_SetAlpha(vnc->tilebuffer,0,0);
            DBMESSAGE("Created new tilebuffer.\n");
        } else {
            DBERROR("Error creating tilebuffer.\n");
            return 0;
        }
    }
    return 1;
}
Example #2
0
static int read_security_type(tSDL_vnc *vnc) {
    if (vnc->versionMinor < 7) {
        // Read security type (simple)
        CHECKED_READ(vnc, vnc->buffer, 4, "security type");
        vnc->security_type=vnc->buffer[3];
        DBMESSAGE("Security type (read): %i\n", vnc->security_type);
        return 1;
    }

    // Addition for RFB 003 008

    CHECKED_READ(vnc, vnc->buffer, 1, "security type");

    // Security Type List! Receive number of supported Security Types
    int nSecTypes = vnc->buffer[0];
    if (nSecTypes == 0) {
        DBERROR("Server offered an empty list of security types.\n");
        return 0;
    }
        
    // Receive Security Type List (Buffer overflow possible!)
    int result = Recv(vnc->socket,vnc->buffer,nSecTypes,0);
        
    // Find supported one...
    vnc->security_type = 0;
    int i;
    for (i = 0; i < result; i++) {
        vnc->security_type = vnc->buffer[i];
        // Break if supported type (currently 1 or 2) found
        if ((vnc->security_type == 1) || (vnc->security_type == 2)) break;
    }
    
    // Select it
    DBMESSAGE("Security type (select): %i\n", vnc->security_type);
    vnc->buffer[0] = vnc->security_type;
        
    result = send(vnc->socket,vnc->buffer,1,0);
    if (result != 1) {
        DBERROR("Write error on security type selection.\n");
        return 0;
    }

    return 1;
}
Example #3
0
/* FIXME: Is this valid when we never request a non-truecolor display? */
static int HandleServerMessage_colormap(tSDL_vnc * vnc)
{
	tSDL_vnc_serverColormap serverColormap;
    DBMESSAGE("Message: colormap\n");
    // Read data, but ignore it
    CHECKED_READ(vnc, &serverColormap, 5, "server colormap");

    serverColormap.first=swap_16(serverColormap.first);
    serverColormap.number=swap_16(serverColormap.number);

    DBMESSAGE("Server colormap first color: %u\n",serverColormap.first);
    DBMESSAGE("Server colormap number: %u\n",serverColormap.number);

    while (serverColormap.number>0) {
        CHECKED_READ(vnc, &vnc->buffer, 6, "server colormap color");
        DBMESSAGE("Got color %u.\n",serverColormap.first);
        serverColormap.first++;
        serverColormap.number--;
    }
    return 1;
}
Example #4
0
int read_raw(tSDL_vnc * vnc, tSDL_vnc_rect rect) {
    SDL_Rect trec;
    vnc_to_sdl_rect(&rect, &trec);
    SDL_LockMutex(vnc->mutex);
    SDL_LockSurface(vnc->framebuffer);
    
    uint32_t pitch = vnc->framebuffer->pitch/4;
    uint32_t * dest = (uint32_t *)vnc->framebuffer->pixels + (rect.y * pitch) + rect.x;
    uint32_t len = rect.width * rect.height * 4;

    DBMESSAGE("Reading %ld bytes straight into buffer", len);
    CHECKED_READ(vnc, dest, len, "framebuffer");

    GrowUpdateRegion(vnc,&trec);
    SDL_UnlockSurface(vnc->framebuffer);
    SDL_UnlockMutex(vnc->mutex);
    return 1;
}
Example #5
0
static int WaitForMessage(tSDL_vnc *vnc, unsigned int usecs)
{
	fd_set fds;
	struct timeval timeout;
	int result;
	
	timeout.tv_sec=0;
	timeout.tv_usec=usecs;
	FD_ZERO(&fds);
	FD_SET(vnc->socket,&fds);
	result=select(vnc->socket+1, &fds, NULL, NULL, &timeout);
#ifdef DEBUG
	if (result<0) {
		DBMESSAGE("Waiting for message failed: %d (%s)\n",errno,strerror(errno));
	}
#endif
	
	return result;
}
Example #6
0
int HandleServerMessage(tSDL_vnc *vnc)
{
 int i, num_pixels, num_rectangles, num_subrectangles, hx, hy, bx, by, cx, cy, rowindex, bitindex, byteindex;
 int result, bytes_to_read, bytes_read;
 tSDL_vnc_serverMessage serverMessage;
 tSDL_vnc_serverUpdate serverUpdate;
 tSDL_vnc_serverRectangle serverRectangle;
 tSDL_vnc_serverColormap serverColormap;
 tSDL_vnc_serverText serverText;
 tSDL_vnc_serverCopyrect serverCopyrect;
 tSDL_vnc_serverRRE serverRRE;
 tSDL_vnc_serverRREdata serverRREdata;
 tSDL_vnc_serverCoRRE serverCoRRE;
 tSDL_vnc_serverCoRREdata serverCoRREdata;
 tSDL_vnc_serverHextile serverHextile;
 tSDL_vnc_serverHextileBg serverHextileBg;
 tSDL_vnc_serverHextileFg serverHextileFg;
 tSDL_vnc_serverHextileSubrects serverHextileSubrects;
 tSDL_vnc_serverHextileColored serverHextileColored;
 tSDL_vnc_serverHextileRect serverHextileRect;
 unsigned char *target;
 unsigned int *uitarget;
 unsigned char *cursormask;
 SDL_Rect trec, srec;

 DBMESSAGE ("HandleServerMessage\n");
 /* Read message type */
 result = Recv(vnc->socket,&serverMessage,1,0);
 if (result==1) {
  switch (serverMessage.messagetype) {

   case 0:
    DBMESSAGE ("Message: update\n");
    result = Recv(vnc->socket,&serverUpdate,3,0);
    if (result==3) {

     /* ??? Protocol sais U16, TightVNC server sends U8 */
     serverUpdate.rectangles=serverUpdate.rectangles & 0x00ff;
     DBMESSAGE ("Number of rectangles: %u (%04x)\n",serverUpdate.rectangles,serverUpdate.rectangles);

     num_rectangles=0;
     while (num_rectangles<serverUpdate.rectangles) {
      num_rectangles++;
      result = Recv(vnc->socket,&serverRectangle,12,0);
      if (result==12) {
       serverRectangle.x=swap_16(serverRectangle.x);
       serverRectangle.y=swap_16(serverRectangle.y);
       serverRectangle.width=swap_16(serverRectangle.width);
       serverRectangle.height=swap_16(serverRectangle.height);
       serverRectangle.encoding=swap_32(serverRectangle.encoding);
       //
       DBMESSAGE ("Rectangle %i of %i: @ %u,%u size %u,%u encoding %u\n",num_rectangles,serverUpdate.rectangles,serverRectangle.x,serverRectangle.y,serverRectangle.width,serverRectangle.height,serverRectangle.encoding);
       
       /* Sanity check values */
       if (serverRectangle.x>vnc->serverFormat.width) {
        DBMESSAGE("Bad rectangle: x=%u setting to 0\n",serverRectangle.x);
        serverRectangle.x=0;
       }
       if (serverRectangle.y>vnc->serverFormat.height) {
        DBMESSAGE("Bad rectangle: y=%u setting to 0\n",serverRectangle.y);
        serverRectangle.y=0;
       }
       if ((serverRectangle.width<=0) || (serverRectangle.width>vnc->serverFormat.width)) {
        DBMESSAGE("Bad rectangle: width=%u setting to 1\n",serverRectangle.width);
        serverRectangle.width=1;
       }
       if ((serverRectangle.height<=0) || (serverRectangle.height>vnc->serverFormat.height)) {
        DBMESSAGE("Bad rectangle: height=%u setting to 1\n",serverRectangle.height);
        serverRectangle.height=1;
       }
       
       /* Do we have a scratchbuffer */
       if (vnc->scratchbuffer) {
        /* Check size */
        if ( (!(vnc->scratchbuffer->w == serverRectangle.width)) || (!(vnc->scratchbuffer->h == serverRectangle.height)) ) {
         /* Clean out existing scratchbuffer */
         SDL_FreeSurface(vnc->scratchbuffer);
         vnc->scratchbuffer=NULL;
         DBMESSAGE ("Deleted existing scratchbuffer.\n");
        }
       }
       if (!(vnc->scratchbuffer)) {
        /* Create new scratchbuffer */
        vnc->scratchbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,serverRectangle.width,serverRectangle.height,32,
                                         vnc->rmask,vnc->gmask,vnc->bmask,0);
        if (vnc->scratchbuffer) {                                  
         SDL_SetAlpha(vnc->scratchbuffer,0,0);
         DBMESSAGE ("Created new scratchbuffer.\n");
        } else {
         DBERROR ("Error creating scratchbuffer.\n");
         return 0;
        }
       }
       
       /* Rectangle Data */
       switch (serverRectangle.encoding) {

        case 0:
          DBMESSAGE ("RAW encoding.\n");
          bytes_to_read = serverRectangle.width*serverRectangle.height*4;
          result = Recv(vnc->socket,(unsigned char *)vnc->scratchbuffer->pixels,bytes_to_read,0);
          if (result==bytes_to_read) {
           DBMESSAGE ("Blitting %i bytes of raw pixel data.\n",bytes_to_read);
           trec.x=serverRectangle.x;
           trec.y=serverRectangle.y;
           trec.w=serverRectangle.width;
           trec.h=serverRectangle.height;
  	   SDL_LockMutex(vnc->mutex);
           SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec);
           GrowUpdateRegion(vnc,&trec);
  	   SDL_UnlockMutex(vnc->mutex);
           DBMESSAGE ("Blitted raw pixel data.\n");
          } else {
           DBERROR ("Error on pixel data. Got %i of %i bytes.\n",result,bytes_to_read);
           return 0;
          }
         break;

        case 1:
          DBMESSAGE ("CopyRect encoding.\n");
          result = Recv(vnc->socket,&serverCopyrect,4,0);
          if (result==4) {    
           serverCopyrect.x=swap_16(serverCopyrect.x);
           serverCopyrect.y=swap_16(serverCopyrect.y);
           //
           DBMESSAGE ("Copyrect from %u,%u\n",serverCopyrect.x,serverCopyrect.y);
           //
           srec.x=serverCopyrect.x;
           srec.y=serverCopyrect.y;
           srec.w=serverRectangle.width;
           srec.h=serverRectangle.height;
           trec.x=serverRectangle.x;
           trec.y=serverRectangle.y;
           trec.w=serverRectangle.width;
           trec.h=serverRectangle.height;
    	   SDL_LockMutex(vnc->mutex);
           SDL_BlitSurface(vnc->framebuffer, &srec, vnc->scratchbuffer, NULL);
           SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec);
           GrowUpdateRegion(vnc,&trec);
  	   SDL_UnlockMutex(vnc->mutex);
           DBMESSAGE ("Blitted copyrect pixels.\n");
          } else {
           DBERROR ("Error on copyrect data. Got %i of %i bytes.\n",result,4);
           return 0;
          }
         break;

        case 2:         
          DBMESSAGE ("RRE encoding.\n");
          result = Recv(vnc->socket,&serverRRE,8,0);
          if (result==8) {    
           serverRRE.number=swap_32(serverRRE.number);
           //
           DBMESSAGE ("RRE of %u rectangles. Background color 0x%06x\n",serverRRE.number,serverRRE.background);
           SDL_FillRect(vnc->scratchbuffer, NULL, serverRRE.background);
           /* Draw subrectangles */
           num_subrectangles=0;
           while (num_subrectangles<serverRRE.number) {
            num_subrectangles++;
            result = Recv(vnc->socket,&serverRREdata,12,0);
            if (result==12) {
             serverRREdata.x=swap_16(serverRREdata.x);
             serverRREdata.y=swap_16(serverRREdata.y);
             serverRREdata.width=swap_16(serverRREdata.width);
             serverRREdata.height=swap_16(serverRREdata.height);
             srec.x=serverRREdata.x;
             srec.y=serverRREdata.y;
             srec.w=serverRREdata.width;
             srec.h=serverRREdata.height;
	     SDL_FillRect(vnc->scratchbuffer,&srec,serverRREdata.color);
            } else {
             DBERROR ("Error on RRE data. Got %i of %i bytes.\n",result,12);
             return 0;
            } 
           }
           DBMESSAGE ("Drawn %i subrectangles.\n", num_subrectangles);
           trec.x=serverRectangle.x;
           trec.y=serverRectangle.y;
           trec.w=serverRectangle.width;
           trec.h=serverRectangle.height;
    	   SDL_LockMutex(vnc->mutex);
           SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec);
           GrowUpdateRegion(vnc,&trec);
           SDL_UnlockMutex(vnc->mutex);
           DBMESSAGE ("Blitted RRE pixels.\n");
          } else {
           DBERROR ("Error on RRE header. Got %i of %i bytes.\n",result,8);
           return 0;
          }          
         break;

        case 4:         
          DBMESSAGE ("CoRRE encoding.\n");
          result = Recv(vnc->socket,&serverCoRRE,8,0);
          if (result==8) {    
           serverCoRRE.number=swap_32(serverCoRRE.number);
           //
           DBMESSAGE ("CoRRE of %u rectangles. Background color 0x%06x\n",serverCoRRE.number,serverCoRRE.background);
           SDL_FillRect(vnc->scratchbuffer, NULL, serverCoRRE.background);
           /* Draw subrectangles */
           num_subrectangles=0;
           while (num_subrectangles<serverCoRRE.number) {
            num_subrectangles++;
            result = Recv(vnc->socket,&serverCoRREdata,8,0);
            if (result==8) {
             srec.x=serverCoRREdata.x;
             srec.y=serverCoRREdata.y;
             srec.w=serverCoRREdata.width;
             srec.h=serverCoRREdata.height;
	     SDL_FillRect(vnc->scratchbuffer,&srec,serverCoRREdata.color);
            } else {
             DBERROR ("Error on CoRRE data. Got %i of %i bytes.\n",result,8);
             return 0;
            } 
           }
           DBMESSAGE ("Drawn %i subrectangles.\n", num_subrectangles);
           trec.x=serverRectangle.x;
           trec.y=serverRectangle.y;
           trec.w=serverRectangle.width;
           trec.h=serverRectangle.height;
    	   SDL_LockMutex(vnc->mutex);
           SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec);
           GrowUpdateRegion(vnc,&trec);
           SDL_UnlockMutex(vnc->mutex);
           DBMESSAGE ("Blitted CoRRE pixels.\n");
          } else {
           DBERROR ("Error on CoRRE header. Got %i of %i bytes.\n",result,8);
           return 0;
          }          
         break;

        case 5:
          DBMESSAGE ("Hextile encoding.\n");
          //
          if (!(vnc->tilebuffer)) {
           /* Create new tilebuffer */
           vnc->tilebuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,16,16,32,
                                                   vnc->rmask,vnc->gmask,vnc->bmask,0);
           if (vnc->tilebuffer) {                                  
            SDL_SetAlpha(vnc->tilebuffer,0,0);
            DBMESSAGE ("Created new tilebuffer.\n");
           } else {
            DBERROR ("Error creating tilebuffer.\n");
            return 0;
           }
          }
          //
          /* Iterate over all tiles */
          // row loop
          for (hy=0; hy<serverRectangle.height; hy += 16) {
           /* Determine height of tile */
           if ((hy+16)>serverRectangle.height) {
            by=serverRectangle.height % 16;
           } else {
            by=16;
           }
           // column loop
           for (hx=0; hx<serverRectangle.width; hx += 16) {
            /* Determine width of tile */
            if ((hx+16)>serverRectangle.width) {
             bx=serverRectangle.width % 16;
            } else {
             bx=16;
            }
            result = Recv(vnc->socket,&serverHextile,1,0);
            if (result==1) {    
             if (serverHextile.mode & 1) {
              /* Read raw data for tile in lines */
              bytes_to_read = bx*by*4;
              if ((bx==16) && (by==16)) {
               // complete tile
               result = Recv(vnc->socket,(unsigned char *)vnc->tilebuffer->pixels,bytes_to_read,0);
              } else {
               // partial tile
               result = 0;
               target=(unsigned char *)vnc->tilebuffer->pixels;
               rowindex=by;
               while (rowindex) {
                result +=  Recv(vnc->socket,target,bx*4,0);
                target += 16*4;
                rowindex--;
               }
              }
              if (result==bytes_to_read) {
               trec.x=hx;
               trec.y=hy;
               trec.w=16;
               trec.h=16;
               SDL_BlitSurface(vnc->tilebuffer, NULL, vnc->scratchbuffer, &trec);
              } else {
               DBERROR ("Error on pixel data. Got %i of %i bytes.\n",result,bytes_to_read);
               return 0;
              }            
             } else {
              /* no raw data */
              if (serverHextile.mode & 2) {
               /* Read background */
               result = Recv(vnc->socket,&serverHextileBg,4,0);
               if (result==4) {
                /* All OK */
               } else {
                DBERROR ("Error on Hextile background. Got %i of %i bytes.\n",result,4);
                return 0;
               }    
              }
              SDL_FillRect(vnc->tilebuffer,NULL,serverHextileBg.color);              
              if (serverHextile.mode & 4) {
               /* Read foreground */
               result = Recv(vnc->socket,&serverHextileFg,4,0);
               if (result==4) {
                /* All OK */
               } else {
                DBERROR ("Error on Hextile foreground. Got %i of %i bytes.\n",result,4);
                return 0;
               }    
              }
              if (serverHextile.mode & 8) {
               result = Recv(vnc->socket,&serverHextileSubrects,1,0);
               if (result==1) {
                /* All OK */
               } else {
                DBERROR ("Error on Hextile subrects. Got %i of %i bytes.\n",result,1);
                return 0;
               }
               /* Read subrects */
               num_subrectangles=0;
               while (num_subrectangles<serverHextileSubrects.number) {
                num_subrectangles++;
                // 
                /* Check color mode */
                if (serverHextile.mode & 16) {
                 /* Colored subrect */
                 result = Recv(vnc->socket,&serverHextileColored,6,0);
                 if (result==6) {
                  /* Render colored subrect */
                  srec.x=(serverHextileColored.xy >> 4) & 0x0f;
                  srec.y=serverHextileColored.xy & 0x0f;
                  srec.w=((serverHextileColored.wh >> 4) & 0x0f)+1;
                  srec.h=(serverHextileColored.wh & 0x0f)+1;
                  SDL_FillRect(vnc->tilebuffer,&srec,serverHextileColored.color);
                 } else {
                  DBERROR ("Error on Hextile color subrect data. Got %i of %i bytes.\n",result,6);
                  return 0;
                 }
                } else {
                 /* Non-colored Subrect */
                 result = Recv(vnc->socket,&serverHextileRect,2,0);
                 if (result==2) {
                  /* Render colored subrect */
                  srec.x=(serverHextileRect.xy >> 4) & 0x0f;
                  srec.y=serverHextileRect.xy & 0x0f;
                  srec.w=((serverHextileRect.wh >> 4) & 0x0f)+1;
                  srec.h=(serverHextileRect.wh & 0x0f)+1;
                  SDL_FillRect(vnc->tilebuffer,&srec,serverHextileFg.color);
                 } else {
                  DBERROR ("Error on Hextile subrect data. Got %i of %i bytes.\n",result,2);
                  return 0;
                 }
                } // color mode check
               } // subrect loop
               //
              } // have subrects
              /* Draw tile */
              trec.x=hx;
              trec.y=hy;
              trec.w=16;
              trec.h=16;
              SDL_BlitSurface(vnc->tilebuffer, NULL, vnc->scratchbuffer, &trec);
             } // raw data check
            } else {