///////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002 Ultr@VNC Team Members. All Rights Reserved. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // If the source code for the program is not available from the place from // which you received this file, check // http://ultravnc.sourceforge.net/ // //////////////////////////////////////////////////////////////////////////// // // CACHERect Encoding // // . #include "stdhdrs.h" #include "vncviewer.h" #include "ClientConnection.h" // #include "zlib\zlib.h" void ClientConnection::ReadCacheRect(rfbFramebufferUpdateRectHeader *pfburh) { rfbCacheRect cr; ReadExact((char *) &cr, sz_rfbCacheRect); cr.special = Swap16IfLE(cr.special); RECT rect; rect.left=pfburh->r.x; rect.right=pfburh->r.x+pfburh->r.w; rect.top=pfburh->r.y; rect.bottom=pfburh->r.y+pfburh->r.h; RestoreArea(rect); } void ClientConnection::SaveArea(RECT &r) { if (!m_opts.m_fEnableCache) return; // sf@2002 int x = r.left; int y = r.top; int w = r.right - r.left; int h = r.bottom - r.top; omni_mutex_lock l(m_bitmapdcMutex); ObjectSelector b1(m_hBitmapDC, m_hBitmap); PaletteSelector ps1(m_hBitmapDC, m_hPalette); ObjectSelector b2(m_hCacheBitmapDC, m_hCacheBitmap); PaletteSelector ps2(m_hCacheBitmapDC, m_hPalette); if (m_hCacheBitmapDC!=NULL) if (!BitBlt(m_hCacheBitmapDC, x, y, w, h, m_hBitmapDC, x, y, SRCCOPY)) { vnclog.Print(0, _T("Error saving screen\n")); } } void ClientConnection::RestoreArea(RECT &r) { int x = r.left; int y = r.top; int w = r.right - r.left; int h = r.bottom - r.top; HBITMAP m_hTempBitmap=NULL; HDC m_hTempBitmapDC=NULL; omni_mutex_lock l(m_bitmapdcMutex); ObjectSelector b1(m_hBitmapDC, m_hBitmap); PaletteSelector ps1(m_hBitmapDC, m_hPalette); m_hTempBitmapDC = CreateCompatibleDC(m_hBitmapDC); m_hTempBitmap = CreateCompatibleBitmap(m_hBitmapDC, w, h); ObjectSelector b3(m_hTempBitmapDC, m_hTempBitmap); PaletteSelector ps3(m_hTempBitmapDC, m_hPalette); ObjectSelector b2(m_hCacheBitmapDC, m_hCacheBitmap); PaletteSelector ps2(m_hCacheBitmapDC, m_hPalette); if (!BitBlt(m_hTempBitmapDC, 0, 0, w, h, m_hBitmapDC, x, y, SRCCOPY)) { vnclog.Print(0, _T("Error saving temp bitmap\n")); } if (!BitBlt(m_hBitmapDC, x, y, w, h, m_hCacheBitmapDC, x, y, SRCCOPY)) { vnclog.Print(0, _T("Error restoring screen\n")); } if (!BitBlt(m_hCacheBitmapDC, x, y, w, h, m_hTempBitmapDC, 0, 0, SRCCOPY)) { vnclog.Print(0, _T("Error restoring screen under cursor\n")); } DeleteDC(m_hTempBitmapDC); if (m_hTempBitmap != NULL) DeleteObject(m_hTempBitmap); if (m_hCacheBitmapDC != NULL) DeleteObject(m_hTempBitmapDC); } // // sf@2002 // void ClientConnection::ClearCache() { if (!m_opts.m_fEnableCache) return; if (!BitBlt(m_hCacheBitmapDC, 0, 0, m_si.framebufferWidth, m_si.framebufferHeight, 0, 0, 0, BLACKNESS)) { vnclog.Print(0, _T("Cache: Error Clearing Cache buffer bitmap\n")); } vnclog.Print(0, _T("Cache: Reset Cache\n")); } // // 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 (int 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); } }