⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clientconnection.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		if (!BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, 			ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top, 			m_hBitmapDC, ps.rcPaint.left+m_hScrollPos, ps.rcPaint.top+m_vScrollPos, SRCCOPY)) 		{			log.Print(0, _T("Blit error %d\n"), GetLastError());			// throw ErrorException("Error in blit!\n");		}	}		EndPaint(m_hwnd, &ps);}inline void ClientConnection::UpdateScrollbars() {	// We don't update the actual scrollbar info in full-screen mode	// because it causes them to flicker.	bool setInfo = !InFullScreenMode();	SCROLLINFO scri;	scri.cbSize = sizeof(scri);	scri.fMask = SIF_ALL;	scri.nMin = 0;	scri.nMax = m_hScrollMax; 	scri.nPage= m_cliwidth;	scri.nPos = m_hScrollPos; 		if (setInfo) 		SetScrollInfo(m_hwnd, SB_HORZ, &scri, TRUE);		scri.cbSize = sizeof(scri);	scri.fMask = SIF_ALL;	scri.nMin = 0;	scri.nMax = m_vScrollMax;     	scri.nPage= m_cliheight;	scri.nPos = m_vScrollPos; 		if (setInfo) 		SetScrollInfo(m_hwnd, SB_VERT, &scri, TRUE);}void ClientConnection::ShowConnInfo(){	TCHAR buf[2048];#ifndef UNDER_CE	char kbdname[9];	GetKeyboardLayoutName(kbdname);#else	TCHAR *kbdname = _T("(n/a)");#endif	_stprintf(		buf,		_T("Connected to: %s:\n\r")		_T("Host: %s port: %d\n\r\n\r")		_T("Desktop geometry: %d x %d x %d\n\r")		_T("Using depth: %d\n\r")		_T("Line speed estimate: %d kbit/s\n")		_T("Current protocol version: %d.%d\n\r\n\r")		_T("Current keyboard name: %s\n\r"),		m_desktopName, m_host, m_port,		m_si.framebufferWidth, m_si.framebufferHeight,                m_si.format.depth,		m_myFormat.depth, kbitsPerSecond,		m_majorVersion, m_minorVersion,		kbdname);	MessageBox(NULL, buf, _T("VNC connection info"), MB_ICONINFORMATION | MB_OK);}// ********************************************************************//  Methods after this point are generally called by the worker thread.//  They finish the initialisation, then chiefly read data from the server.// ********************************************************************void* ClientConnection::run_undetached(void* arg) {	log.Print(9,_T("Update-processing thread started\n"));	m_threadStarted = true;	try {		SendFullFramebufferUpdateRequest();		RealiseFullScreenMode();		m_running = true;		UpdateWindow(m_hwnd);		
		while (!m_bKillThread) {                  rdr::U8 msgType = fis->readU8();				                  switch (msgType) {			case rfbFramebufferUpdate:				ReadScreenUpdate();				break;			case rfbSetColourMapEntries:		        log.Print(3, _T("rfbSetColourMapEntries read but not supported\n") );				throw WarningException("Unhandled SetColormap message type received!\n");				break;			case rfbBell:				ReadBell();				break;			case rfbServerCutText:				ReadServerCutText();				break;			default:                          log.Print(3, _T("Unknown message type x%02x\n"), msgType );                          throw WarningException("Unhandled message type received!\n");                          break;			/*			default:                log.Print(3, _T("Unknown message type x%02x\n"), msgType );				throw WarningException("Unhandled message type received!\n");			*/			}		}                log.Print(4, _T("Update-processing thread finishing\n") );	} catch (WarningException) {		PostMessage(m_hwnd, WM_CLOSE, 0, 0);	} catch (QuietException &e) {		e.Report();		PostMessage(m_hwnd, WM_CLOSE, 0, 0);	} catch (rdr::Exception& e) {          log.Print(0,"rdr::Exception: %s\n",e.str());          PostMessage(m_hwnd, WM_CLOSE, 0, 0);	}	return this;}//// Requesting screen updates from the server//inline voidClientConnection::SendFramebufferUpdateRequest(int x, int y, int w, int h, bool incremental){    rfbFramebufferUpdateRequestMsg fur;    fur.type = rfbFramebufferUpdateRequest;    fur.incremental = incremental ? 1 : 0;    fur.x = Swap16IfLE(x);    fur.y = Swap16IfLE(y);    fur.w = Swap16IfLE(w);    fur.h = Swap16IfLE(h);	log.Print(10, _T("Request %s update\n"), incremental ? _T("incremental") : _T("full"));    WriteExact((char *)&fur, sz_rfbFramebufferUpdateRequestMsg);}inline void ClientConnection::SendIncrementalFramebufferUpdateRequest(){    SendFramebufferUpdateRequest(0, 0, m_si.framebufferWidth,					m_si.framebufferHeight, true);}inline void ClientConnection::SendFullFramebufferUpdateRequest(){    SendFramebufferUpdateRequest(0, 0, m_si.framebufferWidth,					m_si.framebufferHeight, false);}void ClientConnection::SendAppropriateFramebufferUpdateRequest(){	if (m_pendingFormatChange) {		log.Print(3, _T("Requesting new pixel format\n") );		rfbPixelFormat oldFormat = m_myFormat;		SetupPixelFormat();		SetFormatAndEncodings();		m_pendingFormatChange = false;		// If the pixel format has changed, request whole screen		if (!PF_EQ(m_myFormat, oldFormat)) {			SendFullFramebufferUpdateRequest();			} else {			SendIncrementalFramebufferUpdateRequest();		}	} else {		if (!m_dormant)			SendIncrementalFramebufferUpdateRequest();	}}// A ScreenUpdate message has been receivedvoid ClientConnection::ReadScreenUpdate(){  fis->startTiming();	rfbFramebufferUpdateMsg sut;	ReadExact(((char *) &sut)+1, sz_rfbFramebufferUpdateMsg-1);    sut.nRects = Swap16IfLE(sut.nRects);    //if (sut.nRects == 0) return;  XXX tjr removed this - is this OK?		for (UINT i=0; i < sut.nRects; i++) {		rfbFramebufferUpdateRectHeader surh;		ReadExact((char *) &surh, 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);				switch (surh.encoding) {		case rfbEncodingRaw:			ReadRawRect(&surh);			break;		case rfbEncodingCopyRect:			ReadCopyRect(&surh);			break;		case rfbEncodingRRE:			ReadRRERect(&surh);			break;		case rfbEncodingCoRRE:			ReadCoRRERect(&surh);			break;		case rfbEncodingHextile:			ReadHextileRect(&surh);			break;  		case rfbEncodingZRLE:  			zrleDecode(surh.r.x, surh.r.y, surh.r.w, surh.r.h);  			break;		default:			log.Print(0, _T("Unknown encoding %d - not supported!\n"), surh.encoding);			break;		}				RECT rect;				if (m_opts.m_scaling) {			// If we're scaling, we transform the coordinates of the rectangle received			// into the corresponding window coords, and invalidate *that* region.						// First, we adjust coords to avoid rounding down when scaling.			int n = m_opts.m_scale_num;			int d = m_opts.m_scale_den;			int left   = (surh.r.x / d) * d;			int top    = (surh.r.y / d) * d;			int right  = (surh.r.x + surh.r.w + d - 1) / d * d; // round up			int bottom = (surh.r.y + surh.r.h + d - 1) / d * d; // round up			// Then we scale the rectangle, which should now give whole numbers			rect.left   = (left   * n / d) - m_hScrollPos;			rect.top    = (top    * n / d) - m_vScrollPos;			rect.right  = (right  * n / d) - m_hScrollPos;			rect.bottom = (bottom * n / d) - m_vScrollPos;;		} else {			rect.left   = surh.r.x - m_hScrollPos;			rect.top    = surh.r.y - m_vScrollPos;			rect.right  = rect.left + surh.r.w;			rect.bottom = rect.top  + surh.r.h;		}		InvalidateRect(m_hwnd, &rect, FALSE);	}	        fis->stopTiming();        kbitsPerSecond = fis->kbitsPerSecond();        if (m_opts.autoDetect) {          // Above 10Mbps, switch to hextile          // Below 4Mbps, switch to ZRLE          // Above 1Mbps, switch from 8bit          //fprintf(stderr," kbps %d     \r",kbitsPerSecond);          if (kbitsPerSecond > 10000) {            if (m_opts.m_PreferredEncoding != rfbEncodingHextile) {              fprintf(stderr,"Throughput %d kbit/s - changing to Hextile\n",                      kbitsPerSecond);              m_opts.m_PreferredEncoding = rfbEncodingHextile;              m_pendingFormatChange = true;            }          } else if (kbitsPerSecond < 4000) {            if (m_opts.m_PreferredEncoding != rfbEncodingZRLE) {              fprintf(stderr,"Throughput %d kbit/s - changing to ZRLE\n",                      kbitsPerSecond);              m_opts.m_PreferredEncoding = rfbEncodingZRLE;              m_pendingFormatChange = true;            }          }          if (kbitsPerSecond > 1000) {            if (m_opts.m_Use8Bit) {              fprintf(stderr,"Throughput %d kbit/s - changing from 8bit\n",                      kbitsPerSecond);              m_opts.m_Use8Bit = false;              m_pendingFormatChange = true;            }          }        }	// Inform the other thread that an update is needed.	PostMessage(m_hwnd, WM_REGIONUPDATED, NULL, NULL);}	void ClientConnection::SetDormant(bool newstate){	log.Print(5, _T("%s dormant mode\n"), newstate ? _T("Entering") : _T("Leaving"));	m_dormant = newstate;	if (!m_dormant)		SendIncrementalFramebufferUpdateRequest();}// The server has copied some text to the clipboard - put it // in the local clipboard too.void ClientConnection::ReadServerCutText() {	rfbServerCutTextMsg sctm;	log.Print(6, _T("Read remote clipboard change\n"));	ReadExact(((char *) &sctm)+1, sz_rfbServerCutTextMsg-1);	int len = Swap32IfLE(sctm.length);		CheckBufferSize(len);	if (len == 0) {		m_netbuf[0] = '\0';	} else {		ReadString(m_netbuf, len);	}	UpdateLocalClipboard(m_netbuf, len);}void ClientConnection::ReadBell() {	rfbBellMsg bm;	ReadExact(((char *) &bm)+1, sz_rfbBellMsg-1);	#ifdef UNDER_CE	MessageBeep( MB_OK );	#else	if (! ::PlaySound("VNCViewerBell", NULL, 		SND_APPLICATION | SND_ALIAS | SND_NODEFAULT | SND_ASYNC) ) {		::Beep(440, 125);	}	#endif	if (m_opts.m_DeiconifyOnBell) {		if (IsIconic(m_hwnd)) {			SetDormant(false);			ShowWindow(m_hwnd, SW_SHOWNORMAL);		}	}	log.Print(6, _T("Bell!\n"));}// General utilities -------------------------------------------------// Reads the number of bytes specified into the buffer givenvoid ClientConnection::ReadExact(char *inbuf, int wanted){	try {		fis->readBytes(inbuf, wanted);	} catch (rdr::Exception& e) {		log.Print(0, "rdr::Exception: %s\n",e.str());		throw QuietException(e.str());	}}// Read the number of bytes and return them zero terminated in the buffer inline void ClientConnection::ReadString(char *buf, int length){	if (length > 0)		ReadExact(buf, length);	buf[length] = '\0';    log.Print(10, _T("Read a %d-byte string\n"), length);}// Sends the number of bytes specified from the bufferinline void ClientConnection::WriteExact(char *buf, int bytes){	if (bytes == 0) return;	omni_mutex_lock l(m_writeMutex);	log.Print(10, _T("  writing %d bytes\n"), bytes);	int i = 0;    int j;    while (i < bytes) {		j = send(m_sock, buf+i, bytes-i, 0);		if (j == SOCKET_ERROR || j==0) {			LPVOID lpMsgBuf;			int err = ::GetLastError();			FormatMessage(     				FORMAT_MESSAGE_ALLOCATE_BUFFER | 				FORMAT_MESSAGE_FROM_SYSTEM |     				FORMAT_MESSAGE_IGNORE_INSERTS, NULL,				err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language				(LPTSTR) &lpMsgBuf, 0, NULL ); // Process any inserts in lpMsgBuf.			log.Print(1, _T("Socket error %d: %s\n"), err, lpMsgBuf);			LocalFree( lpMsgBuf );			m_running = false;			throw WarningException("WriteExact: Socket error while writing.");		}		i += j;    }}// Makes sure netbuf is at least as big as the specified size.// Note that netbuf itself may change as a result of this call.// Throws an exception on failure.inline void ClientConnection::CheckBufferSize(int bufsize){	if (m_netbufsize > bufsize) return;	omni_mutex_lock l(m_bufferMutex);	char *newbuf = new char[bufsize+256];;	if (newbuf == NULL) {		throw ErrorException("Insufficient memory to allocate network buffer.");	}	// Only if we're successful...	if (m_netbuf != NULL)		delete [] m_netbuf;	m_netbuf = newbuf;	m_netbufsize=bufsize + 256;	log.Print(4, _T("bufsize expanded to %d\n"), m_netbufsize);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -