Exemplo n.º 1
0
Bool
HandleRFBServerMessage()
{
  rfbServerToClientMsg msg;

  if (!ReadFromRFBServer((char *)&msg, 1))
    return False;

  switch (msg.type) {

  case rfbSetColourMapEntries:
  {
    int i;
    CARD16 rgb[3];
    XColor xc;

    if (!ReadFromRFBServer(((char *)&msg) + 1,
			   sz_rfbSetColourMapEntriesMsg - 1))
      return False;

    msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
    msg.scme.nColours = Swap16IfLE(msg.scme.nColours);

    for (i = 0; i < msg.scme.nColours; i++) {
      if (!ReadFromRFBServer((char *)rgb, 6))
	return False;
      xc.pixel = msg.scme.firstColour + i;
      xc.red = Swap16IfLE(rgb[0]);
      xc.green = Swap16IfLE(rgb[1]);
      xc.blue = Swap16IfLE(rgb[2]);
      xc.flags = DoRed|DoGreen|DoBlue;
      XStoreColor(dpy, cmap, &xc);
    }

    break;
  }

  case rfbFramebufferUpdate:
  {
    rfbFramebufferUpdateRectHeader rect;
    int linesToRead;
    int bytesPerLine;
    int i;
    int usecs;

    if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
			   sz_rfbFramebufferUpdateMsg - 1))
      return False;

    msg.fu.nRects = Swap16IfLE(msg.fu.nRects);

    for (i = 0; i < msg.fu.nRects; i++) {
      if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
	return False;

      rect.encoding = Swap32IfLE(rect.encoding);
      if (rect.encoding == rfbEncodingLastRect)
	break;

      rect.r.x = Swap16IfLE(rect.r.x);
      rect.r.y = Swap16IfLE(rect.r.y);
      rect.r.w = Swap16IfLE(rect.r.w);
      rect.r.h = Swap16IfLE(rect.r.h);

      if (rect.encoding == rfbEncodingXCursor ||
	  rect.encoding == rfbEncodingRichCursor) {
	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
			      rect.encoding)) {
	  return False;
	}
	continue;
      }

      if (rect.encoding == rfbEncodingPointerPos) {
	if (!HandleCursorPos(rect.r.x, rect.r.y)) {
	  return False;
	}
	continue;
      }

      if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
	  (rect.r.y + rect.r.h > si.framebufferHeight))
	{
	  fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
	  return False;
	}

      if (rect.r.h * rect.r.w == 0) {
	fprintf(stderr,"Zero size rect - ignoring\n");
	continue;
      }

      /* If RichCursor encoding is used, we should prevent collisions
	 between framebuffer updates and cursor drawing operations. */
      SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);

      switch (rect.encoding) {

      case rfbEncodingRaw:

	bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
	linesToRead = BUFFER_SIZE / bytesPerLine;

	while (rect.r.h > 0) {
	  if (linesToRead > rect.r.h)
	    linesToRead = rect.r.h;

	  if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
	    return False;

	  CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
			   linesToRead);

	  rect.r.h -= linesToRead;
	  rect.r.y += linesToRead;

	}
	break;

      case rfbEncodingCopyRect:
      {
	rfbCopyRect cr;

	if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
	  return False;

	cr.srcX = Swap16IfLE(cr.srcX);
	cr.srcY = Swap16IfLE(cr.srcY);

	/* If RichCursor encoding is used, we should extend our
	   "cursor lock area" (previously set to destination
	   rectangle) to the source rectangle as well. */
	SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);

	if (appData.copyRectDelay != 0) {
	  XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, srcGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	  XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, dstGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	  XSync(dpy,False);
	  usleep(appData.copyRectDelay * 1000);
	  XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, dstGC, rect.r.x,  rect.r.y, rect.r.w, rect.r.h);
#endif
	  XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, srcGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	}

	XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
#if VNC_CAPTURE
    myxcparea(dpy, gc, cr.srcX,  cr.srcY, rect.r.w, rect.r.h,rect.r.x,rect.r.y);
#endif

	break;
      }

      case rfbEncodingRRE:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingCoRRE:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingHextile:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingZlib:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
     }

      case rfbEncodingTight:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      default:
	fprintf(stderr,"Unknown rect encoding %d\n",
		(int)rect.encoding);
	return False;
      }

      /* Now we may discard "soft cursor locks". */
      SoftCursorUnlockScreen();
    }

#ifdef MITSHM
    /* if using shared memory PutImage, make sure that the X server has
       updated its framebuffer before we reuse the shared memory.  This is
       mainly to avoid copyrect using invalid screen contents - not sure
       if we'd need it otherwise. */

    if (appData.useShm)
      XSync(dpy, False);
#endif

    if (!SendIncrementalFramebufferUpdateRequest())
      return False;

    break;
  }

  case rfbBell:
  {
    Window toplevelWin;

    XBell(dpy, 0);

    if (appData.raiseOnBeep) {
      toplevelWin = XtWindow(toplevel);
      XMapRaised(dpy, toplevelWin);
    }

    break;
  }

  case rfbServerCutText:
  {
    if (!ReadFromRFBServer(((char *)&msg) + 1,
			   sz_rfbServerCutTextMsg - 1))
      return False;

    msg.sct.length = Swap32IfLE(msg.sct.length);

    if (serverCutText)
      free(serverCutText);

    serverCutText = malloc(msg.sct.length+1);

    if (!ReadFromRFBServer(serverCutText, msg.sct.length))
      return False;

    serverCutText[msg.sct.length] = 0;

    newServerCutText = True;

    break;
  }

  default:
    fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
    return False;
  }

  return True;
}
Exemplo n.º 2
0
static Bool
HandleHextileBPP (int rx, int ry, int rw, int rh)
{
  CARDBPP bg, fg;
  XGCValues gcv;
  int i;
  CARD8 *ptr;
  int x, y, w, h;
  int sx, sy, sw, sh;
  CARD8 subencoding;
  CARD8 nSubrects;

  for (y = ry; y < ry+rh; y += 16) {
    for (x = rx; x < rx+rw; x += 16) {
      w = h = 16;
      if (rx+rw - x < 16)
	w = rx+rw - x;
      if (ry+rh - y < 16)
	h = ry+rh - y;

      if (!ReadFromRFBServer((char *)&subencoding, 1))
	return False;

      if (subencoding & rfbHextileRaw) {
	if (!ReadFromRFBServer(buffer, w * h * (BPP / 8)))
	  return False;

	CopyDataToScreen(buffer, x, y, w, h);
	continue;
      }

      if (subencoding & rfbHextileBackgroundSpecified)
	if (!ReadFromRFBServer((char *)&bg, sizeof(bg)))
	  return False;

#if (BPP == 8)
      if (appData.useBGR233)
	gcv.foreground = BGR233ToPixel[bg];
      else
#endif
	gcv.foreground = bg;

      XChangeGC(dpy, gc, GCForeground, &gcv);
      XFillRectangle(dpy, desktopWin, gc, x, y, w, h);
#if VNC_CAPTURE
      myxfillrec(dpy, gc, x, y, w, h);
#endif

      if (subencoding & rfbHextileForegroundSpecified)
	if (!ReadFromRFBServer((char *)&fg, sizeof(fg)))
	  return False;

      if (!(subencoding & rfbHextileAnySubrects)) {
	continue;
      }

      if (!ReadFromRFBServer((char *)&nSubrects, 1))
	return False;

      ptr = (CARD8 *)buffer;

      if (subencoding & rfbHextileSubrectsColoured) {
	if (!ReadFromRFBServer(buffer, nSubrects * (2 + (BPP / 8))))
	  return False;

	for (i = 0; i < nSubrects; i++) {
	  GET_PIXEL(fg, ptr);
	  sx = rfbHextileExtractX(*ptr);
	  sy = rfbHextileExtractY(*ptr);
	  ptr++;
	  sw = rfbHextileExtractW(*ptr);
	  sh = rfbHextileExtractH(*ptr);
	  ptr++;
#if (BPP == 8)
	  if (appData.useBGR233)
	    gcv.foreground = BGR233ToPixel[fg];
	  else
#endif
	    gcv.foreground = fg;

	  XChangeGC(dpy, gc, GCForeground, &gcv);
	  XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh);
#if VNC_CAPTURE
      myxfillrec(dpy, gc,x+sx, y+sy, sw, sh);
#endif
	}

      } else {
	if (!ReadFromRFBServer(buffer, nSubrects * 2))
	  return False;

#if (BPP == 8)
	if (appData.useBGR233)
	  gcv.foreground = BGR233ToPixel[fg];
	else
#endif
	  gcv.foreground = fg;

	XChangeGC(dpy, gc, GCForeground, &gcv);

	for (i = 0; i < nSubrects; i++) {
	  sx = rfbHextileExtractX(*ptr);
	  sy = rfbHextileExtractY(*ptr);
	  ptr++;
	  sw = rfbHextileExtractW(*ptr);
	  sh = rfbHextileExtractH(*ptr);
	  ptr++;
	  XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh);
#if VNC_CAPTURE
      myxfillrec(dpy, gc,x+sx, y+sy, sw, sh);
#endif

	}
      }
    }
  }

  return True;
}
Exemplo n.º 3
0
Bool
HandleRFBServerMessage()
{
  rfbServerToClientMsg msg;

  if (!ReadFromRFBServer((char *)&msg, 1))
    return False;

  switch (msg.type) {

  case rfbSetColourMapEntries:
  {
    fprintf(stderr, "Received unsupported rfbSetColourMapEntries\n");
    return False; /* unsupported */
  }

  case rfbFramebufferUpdate:
  {
    rfbFramebufferUpdateRectHeader rect;
    int linesToRead;
    int bytesPerLine;
    int i;

    if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
			   sz_rfbFramebufferUpdateMsg - 1))
      return False;

    msg.fu.nRects = Swap16IfLE(msg.fu.nRects);

    for (i = 0; i < msg.fu.nRects; i++) {
      if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
	return False;

      rect.r.x = Swap16IfLE(rect.r.x);
      rect.r.y = Swap16IfLE(rect.r.y);
      rect.r.w = Swap16IfLE(rect.r.w);
      rect.r.h = Swap16IfLE(rect.r.h);

      rect.encoding = Swap32IfLE(rect.encoding);

      if (rect.encoding == rfbEncodingXCursor) {
	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rfbEncodingXCursor)) {
	  return False;
	}
        continue;
      }
      if (rect.encoding == rfbEncodingRichCursor) {
	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rfbEncodingRichCursor)) {
	  return False;
	}
        continue;
      }

      if (rect.encoding == rfbEncodingPointerPos) {
	if (!HandleCursorPos(rect.r.x, rect.r.y)) {
	  return False;
	}
        appData.gotCursorPos = 1;
	continue;
      }

      if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
	  (rect.r.y + rect.r.h > si.framebufferHeight))
	{
	  fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
	  return False;
	}

      if ((rect.r.h * rect.r.w) == 0) {
	fprintf(stderr,"Zero size rect - ignoring\n");
	continue;
      }

      /* If RichCursor encoding is used, we should prevent collisions
	 between framebuffer updates and cursor drawing operations. */
      SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);

      switch (rect.encoding) {

      case rfbEncodingRaw:

	bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
	linesToRead = BUFFER_SIZE / bytesPerLine;

	while (rect.r.h > 0) {
	  if (linesToRead > rect.r.h)
	    linesToRead = rect.r.h;

	  if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
	    return False;
	  CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
			   linesToRead);

	  rect.r.h -= linesToRead;
	  rect.r.y += linesToRead;

	}
	break;

      case rfbEncodingCopyRect:
      {
	rfbCopyRect cr;
          char *buffer;

	if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
	  return False;

          if (!BufferWritten()) {
            /* Ignore attempts to do copy-rect when we have nothing to
             * copy from.
             */
            break;
        }

 	cr.srcX = Swap16IfLE(cr.srcX);
	cr.srcY = Swap16IfLE(cr.srcY);

	/* If RichCursor encoding is used, we should extend our
	   "cursor lock area" (previously set to destination
	   rectangle) to the source rectangle as well. */
	SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);

        buffer = CopyScreenToData(cr.srcX, cr.srcY, rect.r.w, rect.r.h);
        CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
        free(buffer);

	break;
      }

      case rfbEncodingRRE:
      {
	if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	break;
      }

      case rfbEncodingCoRRE:
      {
	if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	  return False;
	break;
      }

      case rfbEncodingHextile:
      {
	if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	break;
      }

      case rfbEncodingZlib:
      {
	if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	break;
     }

      case rfbEncodingTight:
      {
	if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	break;
      }

      case rfbEncodingZRLE:
        if (!zrleDecode(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
          return False;
	break;

      default:
	fprintf(stderr,"Unknown rect encoding %d\n",
		(int)rect.encoding);
	return False;
      }

      /* Now we may discard "soft cursor locks". */
      SoftCursorUnlockScreen();

        /* Done. Save the screen image. */
    }

      /* RealVNC sometimes returns an initial black screen. */
      if (BufferIsBlank() && appData.ignoreBlank) {
          if (!appData.quiet && appData.ignoreBlank != 1) {
              /* user did not specify either -quiet or -ignoreblank */
              fprintf(stderr, "Warning: discarding received blank screen (use -allowblank to accept,\n   or -ignoreblank to suppress this message)\n");
              appData.ignoreBlank = 1;
          }
          RequestNewUpdate();
      } else {
          return False;
      }

    break;
  }

  case rfbBell:
    /* ignore */
    break;

  case rfbServerCutText:
  {
    if (!ReadFromRFBServer(((char *)&msg) + 1,
			   sz_rfbServerCutTextMsg - 1))
      return False;

    msg.sct.length = Swap32IfLE(msg.sct.length);

    if (serverCutText)
      free(serverCutText);

    serverCutText = malloc(msg.sct.length+1);

    if (!ReadFromRFBServer(serverCutText, msg.sct.length))
      return False;

    serverCutText[msg.sct.length] = 0;

    newServerCutText = True;

    break;
  }

  default:
    fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
    return False;
  }

  return True;
}
Exemplo n.º 4
0
inline Bool
HandleRFBServerMessage()
{
	rfbServerToClientMsg msg;

	if(!ReadExact(rfbsock, (char *)&msg, 1))
		return False;

	dprintf("HandleRFBServerMessage %d\n",msg.type);
	switch(msg.type)
	{
		case rfbSetColourMapEntries:
			{
				dprintf("rfbSetColourMapEntries\n");
				int i;
				CARD16 rgb[3];
				XColor xc;

				if(!ReadExact(rfbsock, ((char *)&msg.scme) + 1,
								  sz_rfbSetColourMapEntriesMsg - 1))
					return False;

				msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
				msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
				
				INIT_PALETTE(msg.scme.nColours);
				
				for(i = 0; i < msg.scme.nColours; i++)
				{
					xc.pixel = msg.scme.firstColour + i;
					if(addUseAlpha)
					{	
					    if(!ReadExact(rfbsock, (char *)rgb, 8))
						return False;
					    xc.transp = ((double)(0xff - (Swap16IfLE(rgb[0]) >> 8))) / ((double)0xff / (double)0xA0);
					    xc.red = Swap16IfLE(rgb[1]) >> 8;
					    xc.green = Swap16IfLE(rgb[2]) >> 8;
					    xc.blue = Swap16IfLE(rgb[3]) >> 8;
					}
					else
					{
					    if(!ReadExact(rfbsock, (char *)rgb, 6))
						return False;
					    xc.transp = 0;
					    xc.red = Swap16IfLE(rgb[0]) >> 8;
					    xc.green = Swap16IfLE(rgb[1]) >> 8;
					    xc.blue = Swap16IfLE(rgb[2]) >> 8;
					}
					xc.flags = DoRed|DoGreen|DoBlue;
					INSERT_COLOUR (xc);
				}
				STORE_PALETTE(NULL);
				
				break;
			}

		case rfbFramebufferUpdate:
			{
				dprintf("rfbFramebufferUpdate\n");
				//ShowOsd(True);
				rfbFramebufferUpdateRectHeader rect;
				int linesToRead;
				int bytesPerLine;
				int i;

				if(!ReadExact(rfbsock, ((char *)&msg.fu) + 1,
								  sz_rfbFramebufferUpdateMsg - 1))
					return False;

				msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
				dprintf("# Rect %d\n",msg.fu.nRects);
				for(i = 0; i < msg.fu.nRects; i++)
				{
					if(!ReadExact(rfbsock, (char *)&rect,
									  sz_rfbFramebufferUpdateRectHeader))
						return False;

					rect.r.x = Swap16IfLE(rect.r.x);
					rect.r.y = Swap16IfLE(rect.r.y);
					rect.r.w = Swap16IfLE(rect.r.w);
					rect.r.h = Swap16IfLE(rect.r.h);
					rect.encoding = Swap32IfLE(rect.encoding);
					dprintf("Rect x/y/w/h %d/%d/%d/%d %u\n",rect.r.x,rect.r.y,rect.r.w,rect.r.h, (uint)rect.encoding);

					if((rect.r.x + rect.r.w > si.framebufferWidth) ||
						(rect.r.y + rect.r.h > si.framebufferHeight))
					{
						fprintf(stderr,"%s: rect too large: %dx%d at (%d, %d)\n",
								  programName, rect.r.w, rect.r.h, rect.r.x, rect.r.y);
						return False;
					}

					if((rect.r.h * rect.r.w) == 0)
					{
						fprintf(stderr,"%s: zero size rect - ignoring\n",programName);
						continue;
					}
					switch(rect.encoding)
					{
						
						case rfbEncodingRaw:
							bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
							linesToRead = BUFFER_SIZE / bytesPerLine;

							while(rect.r.h > 0)
							{
								if(linesToRead > rect.r.h)
									linesToRead = rect.r.h;

								if(!ReadExact(rfbsock, buffer,bytesPerLine * linesToRead))
									return False;

								CopyDataToScreen((CARD8 *)buffer, rect.r.x, rect.r.y,
													  rect.r.w, linesToRead);

								rect.r.h -= linesToRead;
								rect.r.y += linesToRead;

							}
							break;

						case rfbEncodingCopyRect:
							{
								dprintf("rfbEncodingCopyRect\n");
								rfbCopyRect cr;

								if(!ReadExact(rfbsock, (char *)&cr, sz_rfbCopyRect))
									return False;

								cr.srcX = Swap16IfLE(cr.srcX);
								cr.srcY = Swap16IfLE(cr.srcY);

								COPY_AREA (cr.srcX, cr.srcY, rect.r.w, rect.r.h, rect.r.x, rect.r.y);

								break;
							}

						case rfbEncodingRRE:
							{
								dprintf("RRE\n");
								rfbRREHeader hdr;
								CARD8 pix8;
								CARD16 pix16;
								CARD32 pix32;
								rfbRectangle subrect;
								int j;
								int dataSize;
								char *netbuff;
								char *p;

								if(!ReadExact(rfbsock, (char *)&hdr, sz_rfbRREHeader))
									return False;

								hdr.nSubrects = Swap32IfLE(hdr.nSubrects);

								switch(myFormat.bitsPerPixel)
								{
									
									case 8:
										if(!ReadExact(rfbsock, (char *)&pix8, 1))
											return False;

										FILL_RECTNOREDRAW (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix8);
										
										dataSize = (sizeof(pix8) + sz_rfbRectangle) * hdr.nSubrects;
										netbuff = malloc(dataSize + 256);
										if(!ReadExact(rfbsock, netbuff, dataSize))
										    return False;
										    
										p = netbuff;

										for(j = 0; j < hdr.nSubrects; j++)
										{
											memcpy((char*)&pix8, p, sizeof(pix8));
											p += sizeof(pix8);
											
											memcpy((char*)&subrect, p, sz_rfbRectangle);
											p += sz_rfbRectangle;

											subrect.x = Swap16IfLE(subrect.x);
											subrect.y = Swap16IfLE(subrect.y);
											subrect.w = Swap16IfLE(subrect.w);
											subrect.h = Swap16IfLE(subrect.h);

											FILL_RECTNOREDRAW (rect.r.x + subrect.x, rect.r.y + subrect.y, 
														  subrect.w, subrect.h, pix8);
										}
										free(netbuff);
										REDRAWBOX(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
										break;

									case 16:
										if(!ReadExact(rfbsock, (char *)&pix16, 2))
											return False;

										FILL_RECTNOREDRAW (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix16);
										
										dataSize = (sizeof(pix16) + sz_rfbRectangle) * hdr.nSubrects;
										netbuff = malloc(dataSize + 256);
										if(!ReadExact(rfbsock, netbuff, dataSize))
										    return False;
										    
										p = netbuff;
										
										for(j = 0; j < hdr.nSubrects; j++)
										{
											memcpy((char*)&pix16, p, sizeof(pix16));
											p += sizeof(pix16);
											
											memcpy((char*)&subrect, p, sz_rfbRectangle);
											p += sz_rfbRectangle;

											subrect.x = Swap16IfLE(subrect.x);
											subrect.y = Swap16IfLE(subrect.y);
											subrect.w = Swap16IfLE(subrect.w);
											subrect.h = Swap16IfLE(subrect.h);

											FILL_RECTNOREDRAW (rect.r.x + subrect.x, rect.r.y + subrect.y, 
														  subrect.w, subrect.h, pix16);
										}
										free(netbuff);
										REDRAWBOX(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
										break;

									case 32:
										if(!ReadExact(rfbsock, (char *)&pix32, 4))
											return False;

										FILL_RECTNOREDRAW (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix32);
										
										dataSize = (sizeof(pix32) + sz_rfbRectangle) * hdr.nSubrects;
										netbuff = malloc(dataSize + 256);
										if(!ReadExact(rfbsock, netbuff, dataSize))
										    return False;
										    
										p = netbuff;

										for(j = 0; j < hdr.nSubrects; j++)
										{
											memcpy((char*)&pix32, p, sizeof(pix32));
											p += sizeof(pix32);
											
											memcpy((char*)&subrect, p, sz_rfbRectangle);
											p += sz_rfbRectangle;

											subrect.x = Swap16IfLE(subrect.x);
											subrect.y = Swap16IfLE(subrect.y);
											subrect.w = Swap16IfLE(subrect.w);
											subrect.h = Swap16IfLE(subrect.h);

											FILL_RECTNOREDRAW (rect.r.x + subrect.x, rect.r.y + subrect.y, 
														  subrect.w, subrect.h, pix32);
										}
										free(netbuff);
										REDRAWBOX(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
										break;
								}
								break;
							}

						case rfbEncodingCoRRE:
							{
								dprintf("rfbEncodingCoRRE\n");
								rfbRREHeader hdr;
								CARD8 pix8;
								CARD16 pix16;
								CARD32 pix32;
								int j;
								CARD8 *ptr;
								register int x, y, w, h;

								if(!ReadExact(rfbsock, (char *)&hdr, sz_rfbRREHeader))
									return False;

								hdr.nSubrects = Swap32IfLE(hdr.nSubrects);

								switch(myFormat.bitsPerPixel)
								{
									
									case 8:
										if(!ReadExact(rfbsock, (char *)&pix8, 1))
											return False;

										FILL_RECT (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix8);

										if(!ReadExact(rfbsock, buffer, hdr.nSubrects * 5))
											return False;

										ptr = (CARD8 *)buffer;

										for(j = 0; j < hdr.nSubrects; j++)
										{
											pix8 = *ptr++;
											x = *ptr++;
											y = *ptr++;
											w = *ptr++;
											h = *ptr++;
											FILL_RECT (rect.r.x + x, rect.r.y + y, w, h, pix8);
										}
										break;

									case 16:
										if(!ReadExact(rfbsock, (char *)&pix16, 2))
											return False;

										FILL_RECT (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix16);

										if(!ReadExact(rfbsock, buffer, hdr.nSubrects * 6))
											return False;

										ptr = (CARD8 *)buffer;

										for(j = 0; j < hdr.nSubrects; j++)
										{
											pix16 = *(CARD16 *)ptr;
											ptr += 2;
											x = *ptr++;
											y = *ptr++;
											w = *ptr++;
											h = *ptr++;
											FILL_RECT (rect.r.x + x, rect.r.y + y, w, h, pix16);
										}
										break;

									case 32:
										if(!ReadExact(rfbsock, (char *)&pix32, 4))
											return False;

										FILL_RECT (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix32);

										if(!ReadExact(rfbsock, buffer, hdr.nSubrects * 8))
											return False;

										ptr = (CARD8 *)buffer;

										for(j = 0; j < hdr.nSubrects; j++)
										{
											pix32 = *(CARD32 *)ptr;
											ptr += 4;
											x = *ptr++;
											y = *ptr++;
											w = *ptr++;
											h = *ptr++;
											FILL_RECT (rect.r.x + x, rect.r.y + y, w, h, pix32);
										}
										break;
								}
								break;
							}

						case rfbEncodingHextile:
							{
								dprintf("Hextile\n");
								switch(myFormat.bitsPerPixel)
								{
									case 8:
										if(!HandleHextileEncoding8(rect.r.x, rect.r.y,
																			rect.r.w, rect.r.h))
											return False;
										break;
									case 16:
										if(!HandleHextileEncoding16(rect.r.x, rect.r.y,
																			 rect.r.w, rect.r.h))
											return False;
										break;
									case 32:
										if(!HandleHextileEncoding32(rect.r.x, rect.r.y,
																			 rect.r.w, rect.r.h))
											return False;
										break;
								}
								break;
							}

						default:
							printf("vnc: unknown rect encoding %u\n",(uint)rect.encoding);
							return False;
					}
				}

				//sendUpdateRequest = True;
				break;
			}

		case rfbBell:
			BELL;
			//ShowOsd(False);
			break;

		case rfbServerCutText:
			{
				char *str;

				if(!ReadExact(rfbsock, ((char *)&msg.sct) + 1,
								  sz_rfbServerCutTextMsg - 1))
					return False;

				msg.sct.length = Swap32IfLE(msg.sct.length);

				str = malloc(msg.sct.length);

				if(!ReadExact(rfbsock, str, msg.sct.length))
				{
					free(str);
					return False;
				}
/*
	XSelectInput(dpy, DefaultRootWindow(dpy), 0);
	XStoreBytes(dpy, str, msg.sct.length);
	XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime);
	XSelectInput(dpy, DefaultRootWindow(dpy), PropertyChangeMask);
*/
				free(str);

				break;
			}
		case rfbReSizeFrameBuffer:
			{
				if(!ReadExact(rfbsock, ((char *)&msg.rsfb) + 1,
								  sz_rfbReSizeFrameBufferMsg - 1))
					return False;
				dprintf("rfbReSizeFrameBuffer: %d/%d | %d/%d\n",msg.rsfb.buffer_w,msg.rsfb.buffer_h,msg.rsfb.desktop_w,msg.rsfb.desktop_h);
				si.framebufferWidth = Swap16IfLE(msg.rsfb.buffer_w);
				si.framebufferHeight = Swap16IfLE(msg.rsfb.buffer_h);
				FILL_RECT(0, 0, si.framebufferWidth, si.framebufferHeight, 0);
				if(!SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
															si.framebufferHeight, False))
					return False;
			}
			break;
		default:
			printf("%s: unknown message type %d from VNC server\n",
					  programName,msg.type);
			return False;
	}