예제 #1
0
/**
* Draw a triangle into a verticies buffer based on type. Draws a plane with the
* three verticies. Updates number of triangles for rendering.
* 
* @param v1 vertex
* @param v2 vertex
* @param v3 vertex
* @param type tile type
*/
void WorldNode::AddPlane(const CustomVertex& v1, const CustomVertex& v2, const CustomVertex& v3, const TileType& type)
{
    switch(type)
    {

    case kFloor:
        CheckBufferSize(m_iFloorCVCount, &m_iFloorCVBufferSize, &m_FloorCVBuffer);
        m_FloorCVBuffer[m_iFloorCVCount++] = v1;
        m_FloorCVBuffer[m_iFloorCVCount++] = v2;
        m_FloorCVBuffer[m_iFloorCVCount++] = v3;
        m_iFloorTriangleCount++;
        break;

    case kWall:
        CheckBufferSize(m_iWallCVCount, &m_iWallCVBufferSize, &m_WallCVBuffer);
        m_WallCVBuffer[m_iWallCVCount++] = v1;
        m_WallCVBuffer[m_iWallCVCount++] = v2;
        m_WallCVBuffer[m_iWallCVCount++] = v3;
        m_iWallTriangleCount++;
        break;

    default:
        break;

    }
}
예제 #2
0
void ClientConnection::ReadUltraRect(rfbFramebufferUpdateRectHeader *pfburh) {

	UINT numpixels = pfburh->r.w * pfburh->r.h;
    // this assumes at least one byte per pixel. Naughty.
	UINT numRawBytes = numpixels * m_minPixelBytes;
	UINT numCompBytes;
	lzo_uint new_len;

	rfbZlibHeader hdr;

	// Read in the rfbZlibHeader
	omni_mutex_lock l(m_bitmapdcMutex);
	ReadExact((char *)&hdr, sz_rfbZlibHeader);

	numCompBytes = Swap32IfLE(hdr.nBytes);

	// Read in the compressed data
    CheckBufferSize(numCompBytes);
	ReadExact(m_netbuf, numCompBytes);
	CheckZlibBufferSize(numRawBytes);
	lzo1x_decompress((BYTE*)m_netbuf,numCompBytes,(BYTE*)m_zlibbuf,&new_len,NULL);
	SoftCursorLockArea(pfburh->r.x, pfburh->r.y,pfburh->r.w,pfburh->r.h);
	if (!Check_Rectangle_borders(pfburh->r.x, pfburh->r.y,pfburh->r.w,pfburh->r.h)) return;
	if (m_DIBbits) ConvertAll(pfburh->r.w,pfburh->r.h,pfburh->r.x, pfburh->r.y,m_myFormat.bitsPerPixel/8,(BYTE *)m_zlibbuf,(BYTE *)m_DIBbits,m_si.framebufferWidth);

}
예제 #3
0
void ToppyFramework::Print(const void *fmt, va_list args)
{
	char buf[2048];
	_vsnprintf(buf, 2048, (LPCTSTR)fmt, args);

	CheckBufferSize(buf, 255, "TAP_Print");

    LogUser((const char*)fmt, args);
	return;
}
//
// sf@2002 
// - Read a cache rects zipped block coming from the server
// - Restore all these cache rects on the screen
void ClientConnection::ReadCacheZip(rfbFramebufferUpdateRectHeader *pfburh,HRGN *prgn)
{
	UINT nNbCacheRects = pfburh->r.x;

	UINT numRawBytes = nNbCacheRects * sz_rfbRectangle;
	numRawBytes += (numRawBytes/100) + 8;
	UINT numCompBytes;

	rfbZlibHeader hdr;
	// Read in the rfbZlibHeader
	ReadExact((char *)&hdr, sz_rfbZlibHeader);
	numCompBytes = Swap32IfLE(hdr.nBytes);

	// Check the net buffer
	CheckBufferSize(numCompBytes);

	// Read the compressed data
	ReadExact((char *)m_netbuf, numCompBytes);

	// Verify buffer space for cache rects list
	CheckZipBufferSize(numRawBytes);

	int nRet = uncompress((unsigned char*)m_zipbuf,// Dest  
						  (unsigned long*)&numRawBytes,// Dest len
						  (unsigned char*)m_netbuf,	// Src
						  numCompBytes	// Src len
						 );							    
	if (nRet != 0)
	{
		return;		
	}

	// Read all the cache rects
	rfbRectangle theRect;
	
	BYTE* p = m_zipbuf;
	for (UINT i = 0 ; i < nNbCacheRects; i++)
	{
		memcpy((BYTE*)&theRect, p, sz_rfbRectangle);
		p += sz_rfbRectangle;

		RECT cacherect;
		cacherect.left = Swap16IfLE(theRect.x);
		cacherect.right = Swap16IfLE(theRect.x) + Swap16IfLE(theRect.w);
		cacherect.top = Swap16IfLE(theRect.y);
		cacherect.bottom = Swap16IfLE(theRect.y) + Swap16IfLE(theRect.h);

		SoftCursorLockArea(cacherect.left, cacherect.top, cacherect.right - cacherect.left, cacherect.bottom - cacherect.top);
		RestoreArea(cacherect);
		InvalidateRegion(&cacherect,prgn);
	}

}
예제 #5
0
void ClientConnection::ReadUltraZip(rfbFramebufferUpdateRectHeader *pfburh,HRGN *prgn)
{
	UINT nNbCacheRects = pfburh->r.x;
	UINT numRawBytes = pfburh->r.y+pfburh->r.w*65535;
	UINT numCompBytes;
	lzo_uint new_len;
	rfbZlibHeader hdr;
	// Read in the rfbZlibHeader
	omni_mutex_lock l(m_bitmapdcMutex);
	ReadExact((char *)&hdr, sz_rfbZlibHeader);
	numCompBytes = Swap32IfLE(hdr.nBytes);
	// Check the net buffer
	CheckBufferSize(numCompBytes);
	// Read the compressed data
	ReadExact((char *)m_netbuf, numCompBytes);

	// Verify buffer space for cache rects list
	CheckZlibBufferSize(numRawBytes+500);

	lzo1x_decompress((BYTE*)m_netbuf,numCompBytes,(BYTE*)m_zlibbuf,&new_len,NULL);
	BYTE* pzipbuf = m_zlibbuf;
	for (UINT i = 0 ; i < nNbCacheRects; i++)
	{
		rfbFramebufferUpdateRectHeader surh;
		memcpy((char *) &surh,pzipbuf, sz_rfbFramebufferUpdateRectHeader);
		surh.r.x = Swap16IfLE(surh.r.x);
		surh.r.y = Swap16IfLE(surh.r.y);
		surh.r.w = Swap16IfLE(surh.r.w);
		surh.r.h = Swap16IfLE(surh.r.h);
		surh.encoding = Swap32IfLE(surh.encoding);
		pzipbuf += sz_rfbFramebufferUpdateRectHeader;

		RECT rect;
		rect.left = surh.r.x;
		rect.right = surh.r.x + surh.r.w;
		rect.top = surh.r.y;
		rect.bottom = surh.r.y + surh.r.h;
		//border check
		if (!Check_Rectangle_borders(rect.left,rect.top,surh.r.w,surh.r.h)) return;

		SoftCursorLockArea(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
		
		 if ( surh.encoding==rfbEncodingRaw)
			{
				UINT numpixels = surh.r.w * surh.r.h;							  
				if (m_DIBbits) ConvertAll(surh.r.w,surh.r.h,surh.r.x, surh.r.y,m_myFormat.bitsPerPixel/8,(BYTE *)pzipbuf,(BYTE *)m_DIBbits,m_si.framebufferWidth);
				pzipbuf +=numpixels*m_myFormat.bitsPerPixel/8;
				if (!m_opts.m_Directx)InvalidateRegion(&rect,prgn);
			}
	}

}
예제 #6
0
/* remap the supplied data into out, which must be pre-allocated */
void CPCMRemap::Remap(void *data, void *out, unsigned int samples, float gain /*= 1.0f*/)
{
  CheckBufferSize(samples * m_outChannels * sizeof(float));

  //set output buffer to 0
  memset(out, 0, samples * m_outChannels * m_inSampleSize);

  //set intermediate buffer to 0
  memset(m_buf, 0, m_bufsize);

  ProcessInput(data, out, samples, gain);
  AddGain(m_buf, samples * m_outChannels, gain);
  ProcessLimiter(samples, gain);
  ProcessOutput(out, samples, gain);
}
예제 #7
0
void ClientConnection::ReadRawRect(rfbFramebufferUpdateRectHeader *pfburh) {

	UINT numpixels = pfburh->r.w * pfburh->r.h;
    // this assumes at least one byte per pixel. Naughty.
	UINT numbytes = numpixels * m_minPixelBytes;
	// Read in the whole thing
    CheckBufferSize(numbytes);
	ReadExact(m_netbuf, numbytes);
	if (UltraFast && m_DIBbits)
	{
	boost::recursive_mutex::scoped_lock l(m_bitmapdcMutex);
	ConvertAll(pfburh->r.w,pfburh->r.h,pfburh->r.x, pfburh->r.y,m_myFormat.bitsPerPixel/8,(BYTE *)m_netbuf,(BYTE *)m_DIBbits,m_si.framebufferWidth);
	return;
	}


	SETUP_COLOR_SHORTCUTS;

	{
		// No other threads can use bitmap DC
		boost::recursive_mutex::scoped_lock l(m_bitmapdcMutex);
		ObjectSelector b(m_hBitmapDC, m_hBitmap);							  \
		PaletteSelector p(m_hBitmapDC, m_hPalette);							  \

		// This big switch is untidy but fast
		switch (m_myFormat.bitsPerPixel) {
		case 8:
			SETPIXELS(m_netbuf, 8, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)
				break;
		case 16:
			SETPIXELS(m_netbuf, 16, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)
				break;
		case 24:
		case 32:
			SETPIXELS(m_netbuf, 32, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)            
				break;
		default:
			//vnclog.Print(0, _T("Invalid number of bits per pixel: %d\n"), m_myFormat.bitsPerPixel);
			Log.Add(_ERROR_, "Invalid number of bits per pixel: %d", m_myFormat.bitsPerPixel);
			return;
		}
		
	}
}
예제 #8
0
	void IndexBuffer::Build()
	{
		size_t size;
		if (!CheckBufferSize(&size))
		{
			return;
		}

		bool sameSize = (size == _heapSize);

		// Perform memory copy.
		size_t offset = 0;
		size_t totalIndices = 0;
		std::unique_ptr<char> memory(new char[size]);
		for (auto it = _instances.begin(); it != _instances.end(); ++it)
		{
			IndexBufferInstance* instance = static_cast<IndexBufferInstance*>(*it);
			std::vector<int> indices = instance->GetIndices();
			size_t copySize = instance->GetSize();

			instance->SetOffset(totalIndices);
			totalIndices += instance->Count();
			memcpy(memory.get() + offset, &indices[0], copySize);
			offset += copySize;
		}

		_heapSize = size_t(offset);
		PrepareHeapResource(D3D12_RESOURCE_STATE_INDEX_BUFFER);

		HeapManager::Upload(this, memory.get());

		// Initialize the index buffer view.
		if (!sameSize)
		{
			_indexBufferView = {};
			_indexBufferView.BufferLocation = _pResource->GetGPUVirtualAddress();
			_indexBufferView.Format = DXGI_FORMAT_R32_UINT;
			_indexBufferView.SizeInBytes = UINT(_heapSize);
		}
	}
예제 #9
0
	void VertexBuffer::Build()
	{
		size_t size;
		if (!CheckBufferSize(&size))
		{
			return;
		}

		bool sameSize = (size == _heapSize);

		// Perform memory copy.
		size_t offset = 0;
		size_t totalVertices = 0;
		std::unique_ptr<char> memory(new char[size]);
		for (auto it = _instances.begin(); it != _instances.end(); ++it)
		{
			VertexBufferInstance* instance = static_cast<VertexBufferInstance*>(*it);
			std::vector<Vertex> vertices = instance->GetVertices();
			size_t copySize = instance->GetSize();

			instance->SetOffset(totalVertices);
			totalVertices += instance->Count();
			memcpy(memory.get() + offset, &vertices[0], copySize);
			offset += copySize;
		}

		_heapSize = size_t(offset);
		PrepareHeapResource(D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
		HeapManager::Upload(this, memory.get());

		// Initialize the vertex buffer view.
		if (!sameSize)
		{
			_vertexBufferView = {};
			_vertexBufferView.BufferLocation = _pResource->GetGPUVirtualAddress();
			_vertexBufferView.StrideInBytes = sizeof(Vertex);
			_vertexBufferView.SizeInBytes = UINT(_heapSize);
		}
	}
예제 #10
0
void ClientConnection::ReadRawRect(rfbFramebufferUpdateRectHeader *pfburh) {

	UINT numpixels = pfburh->r.w * pfburh->r.h;
    // this assumes at least one byte per pixel. Naughty.
	UINT numbytes = numpixels * m_minPixelBytes;
	// Read in the whole thing
    CheckBufferSize(numbytes);
	ReadExact(m_netbuf, numbytes);

	SETUP_COLOR_SHORTCUTS;

	{
		// No other threads can use bitmap DC
		omni_mutex_lock l(m_bitmapdcMutex);
		ObjectSelector b(m_hBitmapDC, m_hBitmap);							  \
		PaletteSelector p(m_hBitmapDC, m_hPalette);							  \

		// This big switch is untidy but fast
		switch (m_myFormat.bitsPerPixel) {
		case 8:
			SETPIXELS(m_netbuf, 8, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)
				break;
		case 16:
			SETPIXELS(m_netbuf, 16, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)
				break;
		case 24:
		case 32:
			SETPIXELS(m_netbuf, 32, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)            
				break;
		default:
			vnclog.Print(0, _T("Invalid number of bits per pixel: %d\n"), m_myFormat.bitsPerPixel);
			return;
		}
		
	}
}
예제 #11
0
void ClientConnection::ReadCoRRERect(rfbFramebufferUpdateRectHeader *pfburh)
{
    // An RRE rect is always followed by a background color
    // For speed's sake we read them together into a buffer.
    char tmpbuf[sz_rfbRREHeader+4];			// biggest pixel is 4 bytes long
    rfbRREHeader *prreh = (rfbRREHeader *) tmpbuf;
    CARD8 *pcolor = (CARD8 *) tmpbuf + sz_rfbRREHeader;
    ReadExact(tmpbuf, sz_rfbRREHeader + m_minPixelBytes);

    prreh->nSubrects = Swap32IfLE(prreh->nSubrects);

    SETUP_COLOR_SHORTCUTS;

    COLORREF color;
    switch (m_myFormat.bitsPerPixel) {
    case 8:
        color = COLOR_FROM_PIXEL8_ADDRESS(pcolor);
        break;
    case 16:
        color = COLOR_FROM_PIXEL16_ADDRESS(pcolor);
        break;
    case 24:
    case 32:
        color = COLOR_FROM_PIXEL32_ADDRESS(pcolor);
        break;
    }

    // Draw the background of the rectangle
    FillSolidRect(pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h, color);

    if (prreh->nSubrects == 0) return;

    // Draw the sub-rectangles
    rfbCoRRERectangle *pRect;
    rfbRectangle rect;

    // The size of an CoRRE subrect including color info
    int subRectSize = m_minPixelBytes + sz_rfbCoRRERectangle;

    // Read subrects into the buffer
    CheckBufferSize(subRectSize * prreh->nSubrects);
    ReadExact(m_netbuf, subRectSize * prreh->nSubrects);
    BYTE *p = (BYTE *) m_netbuf;

    {
        boost::recursive_mutex::scoped_lock l(m_bitmapdcMutex);
        \
        ObjectSelector b(m_hBitmapDC, m_hBitmap);
        \
        PaletteSelector ps(m_hBitmapDC, m_hPalette);
        \

        for (CARD32 i = 0; i < prreh->nSubrects; i++) {

            pRect = (rfbCoRRERectangle *) (p + m_minPixelBytes);

            switch (m_myFormat.bitsPerPixel) {
            case 8:
                color = COLOR_FROM_PIXEL8_ADDRESS(p);
                break;
            case 16:
                color = COLOR_FROM_PIXEL16_ADDRESS(p);
                break;
            case 32:
                color = COLOR_FROM_PIXEL32_ADDRESS(p);
                break;
            };

            // color = COLOR_FROM_PIXEL8_ADDRESS(netbuf);
            rect.x = pRect->x + pfburh->r.x;
            rect.y = pRect->y + pfburh->r.y;
            rect.w = pRect->w;
            rect.h = pRect->h;
            FillSolidRect(rect.x, rect.y, rect.w, rect.h, color);
            p+=subRectSize;
        }
    }

}
예제 #12
0
void ClientConnection::zrleDecode(int x, int y, int w, int h)
{
  try {
    CheckBufferSize(rfbZRLETileWidth * rfbZRLETileHeight * 4);
    omni_mutex_lock l(m_bitmapdcMutex);

	if( zywrle ){
	  if( !m_opts.m_enableJpegCompression ){
		  zywrle_level = 1;
	  }else if( m_opts.m_jpegQualityLevel < 3 ){
		  zywrle_level = 3;
	  }else if( m_opts.m_jpegQualityLevel < 6 ){
		  zywrle_level = 2;
	  }else{
		  zywrle_level = 1;
	  }
	}else{
	  zywrle_level = 0;
	}

    switch (m_myFormat.bitsPerPixel) {

    case 8:
      zrleDecode8NE(x,y,w,h,fis,zis,(rdr::U8*)m_netbuf);
      break;

    case 16:
      if( m_myFormat.greenMax > 0x1F ){
        zrleDecode16LE(x,y,w,h,fis,zis,(rdr::U16*)m_netbuf);
	  }else{
        zrleDecode15LE(x,y,w,h,fis,zis,(rdr::U16*)m_netbuf);
	  }
      break;

    case 32:
      bool fitsInLS3Bytes
        = ((m_myFormat.redMax   << m_myFormat.redShift)   < (1<<24) &&
           (m_myFormat.greenMax << m_myFormat.greenShift) < (1<<24) &&
           (m_myFormat.blueMax  << m_myFormat.blueShift)  < (1<<24));

      bool fitsInMS3Bytes = (m_myFormat.redShift   > 7  &&
                             m_myFormat.greenShift > 7  &&
                             m_myFormat.blueShift  > 7);

      if ((fitsInLS3Bytes && !m_myFormat.bigEndian) ||
          (fitsInMS3Bytes && m_myFormat.bigEndian))
      {
        zrleDecode24ALE(x,y,w,h,fis,zis,(rdr::U32*)m_netbuf);
      }
      else if ((fitsInLS3Bytes && m_myFormat.bigEndian) ||
               (fitsInMS3Bytes && !m_myFormat.bigEndian))
      {
        zrleDecode24BLE(x,y,w,h,fis,zis,(rdr::U32*)m_netbuf);
      }
      else
      {
        zrleDecode32LE(x,y,w,h,fis,zis,(rdr::U32*)m_netbuf);
      }
      break;
    }

  } catch (rdr::Exception& e) {
    fprintf(stderr,"ZRLE decoder exception: %s\n",e.str());
    throw;
  }
}
예제 #13
0
void ClientConnection::ReadZlibRect(rfbFramebufferUpdateRectHeader *pfburh,int XOR) {

	UINT numpixels = pfburh->r.w * pfburh->r.h;
    // this assumes at least one byte per pixel. Naughty.
	UINT numRawBytes = numpixels * m_minPixelBytes;
	UINT numCompBytes;
	int inflateResult;

	rfbZlibHeader hdr;

	// Read in the rfbZlibHeader
	ReadExact((char *)&hdr, sz_rfbZlibHeader);

	numCompBytes = Swap32IfLE(hdr.nBytes);

	// Read in the compressed data
    CheckBufferSize(numCompBytes);
	ReadExact(m_netbuf, numCompBytes);

	// Verify enough buffer space for screen update.
	CheckZlibBufferSize(numRawBytes);

	m_decompStream.next_in = (unsigned char *)m_netbuf;
	m_decompStream.avail_in = numCompBytes;
	m_decompStream.next_out = m_zlibbuf;
	m_decompStream.avail_out = numRawBytes;
	m_decompStream.data_type = Z_BINARY;
		
	// Insure the inflator is initialized
	if ( m_decompStreamInited == false ) {
		m_decompStream.total_in = 0;
		m_decompStream.total_out = 0;
		m_decompStream.zalloc = Z_NULL;
		m_decompStream.zfree = Z_NULL;
		m_decompStream.opaque = Z_NULL;

		inflateResult = inflateInit( &m_decompStream );
		if ( inflateResult != Z_OK ) {
			vnclog.Print(0, _T("zlib inflateInit error: %d\n"), inflateResult);
			return;
		}
		m_decompStreamInited = true;
	}

	// Decompress screen data
	inflateResult = inflate( &m_decompStream, Z_SYNC_FLUSH );
	if ( inflateResult < 0 ) {
		vnclog.Print(0, _T("zlib inflate error: %d\n"), inflateResult);
		return;
	}
	SETUP_COLOR_SHORTCUTS;
	if (XOR==3)
	{
		mybool *maskbuffer=(mybool *)m_zlibbuf;
		BYTE *color=m_zlibbuf+(((pfburh->r.w*pfburh->r.h)+7)/8);
		BYTE *color2=m_zlibbuf+(((pfburh->r.w*pfburh->r.h)+7)/8)+m_myFormat.bitsPerPixel/8;
		// No other threads can use bitmap DC
		omni_mutex_lock l(m_bitmapdcMutex);						  

		// This big switch is untidy but fast
		switch (m_myFormat.bitsPerPixel) {
		case 8:
			SETXORMONOPIXELS(maskbuffer,color2, color,8, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)
				break;
		case 16:
			SETXORMONOPIXELS(maskbuffer,color2, color,16, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)
				break;
		case 24:
		case 32:
			SETXORMONOPIXELS(maskbuffer,color2, color,32, pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h)            
				break;
		default:
			vnclog.Print(0, _T("Invalid number of bits per pixel: %d\n"), m_myFormat.bitsPerPixel);
			return;
		}
	}
void ClientConnection::ReadRRERect(rfbFramebufferUpdateRectHeader *pfburh)
{
	// An RRE rect is always followed by a background color
	// For speed's sake we read them together into a buffer.
	char tmpbuf[sz_rfbRREHeader+4];			// biggest pixel is 4 bytes long
    rfbRREHeader *prreh = (rfbRREHeader *) tmpbuf;
	CARD8 *pcolor = (CARD8 *) tmpbuf + sz_rfbRREHeader;
	ReadExact(tmpbuf, sz_rfbRREHeader + m_minPixelBytes);

	prreh->nSubrects = Swap32IfLE(prreh->nSubrects);
	
	SETUP_COLOR_SHORTCUTS;
    COLORREF color;
    switch (m_myFormat.bitsPerPixel) {
        case 8:
            color = COLOR_FROM_PIXEL8_ADDRESS(pcolor); break;
        case 16:
			color = COLOR_FROM_PIXEL16_ADDRESS(pcolor); break;
        case 24:
        case 32:
            color = COLOR_FROM_PIXEL32_ADDRESS(pcolor); break;
    }

	// No other threads can use bitmap DC
	omni_mutex_lock l(m_bitmapdcMutex);
		
	// Draw the background of the rectangle
	FillSolidRect_ultra(pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h, m_myFormat.bitsPerPixel,pcolor);
	
    if (prreh->nSubrects == 0) return;
	
	// Draw the sub-rectangles
    rfbRectangle rect, *pRect;
	// The size of an RRE subrect including color info
	int subRectSize = m_minPixelBytes + sz_rfbRectangle;
    
	// Read subrects into the buffer 
	CheckBufferSize(subRectSize * prreh->nSubrects);
    ReadExact(m_netbuf, subRectSize * prreh->nSubrects);
	BYTE *p = (BYTE *) m_netbuf;
	for (CARD32 i = 0; i < prreh->nSubrects; i++) {
		pRect = (rfbRectangle *) (p + m_minPixelBytes);
		
		switch (m_myFormat.bitsPerPixel) {
		case 8:
			color = COLOR_FROM_PIXEL8_ADDRESS(p); break;
		case 16:
			color = COLOR_FROM_PIXEL16_ADDRESS(p); break;
		case 32:
			color = COLOR_FROM_PIXEL32_ADDRESS(p); break;
		};
		
		rect.x = (CARD16) (Swap16IfLE(pRect->x) + pfburh->r.x);
		rect.y = (CARD16) (Swap16IfLE(pRect->y) + pfburh->r.y);
		rect.w = Swap16IfLE(pRect->w);
		rect.h = Swap16IfLE(pRect->h);
		
		FillSolidRect_ultra(rect.x, rect.y, rect.w, rect.h, m_myFormat.bitsPerPixel,p);
		p+=subRectSize;
	}
}