📄 vncclient.cpp
字号:
m_tvinfo->SendInfo(tvSendAll);
m_tvinfo->RequestInfo(tvSendAll);
m_tvinfo->FinishTeamviewerInfo();
// UNLOCK INITIAL SETUP
// Initial negotiation is complete, so set the protocol ready flag
m_client->EnableProtocol();
// Add a fullscreen update to the client's update list
// sf@2002 - Scaling
// m_client->m_update_tracker.add_changed(m_client->m_fullscreen);
{ // RealVNC 336
omni_mutex_lock l(m_client->GetUpdateLock());
m_client->m_update_tracker.add_changed(m_client->m_ScaledScreen);
}
// Clear the CapsLock and NumLock keys
if (m_client->m_keyboardenabled)
{
ClearKeyState(VK_CAPITAL);
// *** JNW - removed because people complain it's wrong
//ClearKeyState(VK_NUMLOCK);
ClearKeyState(VK_SCROLL);
}
// Display client controlwindow
m_client->m_ClientControl = new vncClientControl;
if (m_client->m_ClientControl != NULL)
m_client->m_ClientControl->Init(m_client, m_server);
// Set the input thread to a high priority
set_priority(omni_thread::PRIORITY_HIGH);
}
bool autopush_running = false;
#ifndef _DEBUG
try
{
#endif
// MAIN LOOP
while (connected)
{
rfbClientToServerMsg msg;
// Ensure that we're running in the correct desktop
if (!vncService::InputDesktopSelected() && !vncService::SelectDesktop(NULL))
{
Sleep(100); // wait some time so that the desktop thread can detect if the desktop is locked
if(m_client->m_server->DesktopLocked())
continue; // if it is locked continue the loop
else
break; // else quit it
}
// sf@2002 - v1.1.2
int nTO = 1; // Type offset
// Try to read a message ID
if (!m_socket->ReadExact((char *)&msg.type, sizeof(msg.type)))
{
connected = FALSE;
break;
}
connected=true;
if(m_client->m_fFileTransferStarted)
{
if(msg.type != rfbFileTransfer)
{
m_client->LogFileOperation(IDS_FILETRANS_FINISHED, "", "");
m_client->m_fFileTransferStarted = FALSE;
}
}
else
{
if(msg.type == rfbFileTransfer)
{
SendMessage(m_client->m_ClientControl->m_hwndClientControl,WM_SHOW_FILETRANSFER_LOG,0,0);
m_client->LogFileOperation(IDS_FILETRANS_STARTED, "", "");
m_client->m_fFileTransferStarted = TRUE;
}
}
// What to do is determined by the message id
switch(msg.type)
{
case rfbSetPixelFormat:
// Read the rest of the message:
if (!m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbSetPixelFormatMsg-nTO))
{
connected = FALSE;
break;
}
// Swap the relevant bits.
msg.spf.format.redMax = Swap16IfLE(msg.spf.format.redMax);
msg.spf.format.greenMax = Swap16IfLE(msg.spf.format.greenMax);
msg.spf.format.blueMax = Swap16IfLE(msg.spf.format.blueMax);
// sf@2005 - Additional param for Grey Scale transformation
m_client->m_encodemgr.EnableGreyPalette((msg.spf.format.pad1 == 1));
// Prevent updates while the pixel format is changed
m_client->DisableProtocol();
// Tell the buffer object of the change
if (!m_client->m_encodemgr.SetClientFormat(msg.spf.format))
{
vnclog.Print(LL_CONNERR, VNCLOG("remote pixel format invalid"));
connected = FALSE;
}
// Set the palette-changed flag, just in case...
m_client->m_palettechanged = TRUE;
// Re-enable updates
m_client->EnableProtocol();
break;
case rfbSetEncodings:
// Read the rest of the message:
if (!m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbSetEncodingsMsg-nTO))
{
connected = FALSE;
break;
}
// RDV cache
m_client->m_encodemgr.EnableCache(FALSE);
// RDV XOR and client detection
m_client->m_encodemgr.AvailableXOR(FALSE);
m_client->m_encodemgr.AvailableZRLE(FALSE);
m_client->m_encodemgr.AvailableTight(FALSE);
// sf@2002 - Tight
m_client->m_encodemgr.SetQualityLevel(-1);
m_client->m_encodemgr.SetCompressLevel(6);
m_client->m_encodemgr.EnableLastRect(FALSE);
// Tight - CURSOR HANDLING
m_client->m_encodemgr.EnableXCursor(FALSE);
m_client->m_encodemgr.EnableRichCursor(FALSE);
m_server->EnableXRichCursor(FALSE);
m_client->m_cursor_update_pending = FALSE;
m_client->m_cursor_update_sent = FALSE;
// Prevent updates while the encoder is changed
m_client->DisableProtocol();
// Read in the preferred encodings
msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings);
{
int x;
BOOL encoding_set = FALSE;
// By default, don't use copyrect!
m_client->m_update_tracker.enable_copyrect(false);
for (x=0; x<msg.se.nEncodings; x++)
{
CARD32 encoding;
// Read an encoding in
if (!m_socket->ReadExact((char *)&encoding, sizeof(encoding)))
{
connected = FALSE;
break;
}
// Is this the CopyRect encoding (a special case)?
if (Swap32IfLE(encoding) == rfbEncodingCopyRect)
{
m_client->m_update_tracker.enable_copyrect(true);
continue;
}
// Is this a NewFBSize encoding request?
if (Swap32IfLE(encoding) == rfbEncodingNewFBSize) {
m_client->m_use_NewSWSize = TRUE;
continue;
}
// CACHE RDV
if (Swap32IfLE(encoding) == rfbEncodingCacheEnable)
{
m_client->m_encodemgr.EnableCache(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("Cache protocol extension enabled"));
continue;
}
// XOR zlib
if (Swap32IfLE(encoding) == rfbEncodingXOREnable) {
m_client->m_encodemgr.AvailableXOR(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("XOR protocol extension enabled"));
continue;
}
// Is this a CompressLevel encoding?
if ((Swap32IfLE(encoding) >= rfbEncodingCompressLevel0) &&
(Swap32IfLE(encoding) <= rfbEncodingCompressLevel9))
{
// Client specified encoding-specific compression level
int level = (int)(Swap32IfLE(encoding) - rfbEncodingCompressLevel0);
m_client->m_encodemgr.SetCompressLevel(level);
vnclog.Print(LL_INTINFO, VNCLOG("compression level requested: %d"), level);
continue;
}
// Is this a QualityLevel encoding?
if ((Swap32IfLE(encoding) >= rfbEncodingQualityLevel0) &&
(Swap32IfLE(encoding) <= rfbEncodingQualityLevel9))
{
// Client specified image quality level used for JPEG compression
int level = (int)(Swap32IfLE(encoding) - rfbEncodingQualityLevel0);
m_client->m_encodemgr.SetQualityLevel(level);
vnclog.Print(LL_INTINFO, VNCLOG("image quality level requested: %d"), level);
continue;
}
// Is this a LastRect encoding request?
if (Swap32IfLE(encoding) == rfbEncodingLastRect) {
m_client->m_encodemgr.EnableLastRect(TRUE); // We forbid Last Rect for now
vnclog.Print(LL_INTINFO, VNCLOG("LastRect protocol extension enabled"));
continue;
}
// Is this an XCursor encoding request?
if (Swap32IfLE(encoding) == rfbEncodingXCursor) {
m_client->m_encodemgr.EnableXCursor(TRUE);
m_server->EnableXRichCursor(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("X-style cursor shape updates enabled"));
continue;
}
// Is this a RichCursor encoding request?
if (Swap32IfLE(encoding) == rfbEncodingRichCursor) {
m_client->m_encodemgr.EnableRichCursor(TRUE);
m_server->EnableXRichCursor(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("Full-color cursor shape updates enabled"));
continue;
}
// RDV - We try to detect which type of viewer tries to connect
if (Swap32IfLE(encoding) == rfbEncodingZRLE) {
m_client->m_encodemgr.AvailableZRLE(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("ZRLE found "));
// continue;
}
if (Swap32IfLE(encoding) == rfbEncodingTight) {
m_client->m_encodemgr.AvailableTight(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("Tight found"));
// continue;
}
// Have we already found a suitable encoding?
if (!encoding_set)
{
// No, so try the buffer to see if this encoding will work...
omni_mutex_lock l(m_client->GetUpdateLock());
if (m_client->m_encodemgr.SetEncoding(Swap32IfLE(encoding),FALSE))
encoding_set = TRUE;
}
}
// If no encoding worked then default to RAW!
if (!encoding_set)
{
vnclog.Print(LL_INTINFO, VNCLOG("defaulting to raw encoder"));
omni_mutex_lock l(m_client->GetUpdateLock());
if (!m_client->m_encodemgr.SetEncoding(Swap32IfLE(rfbEncodingRaw),FALSE))
{
vnclog.Print(LL_INTERR, VNCLOG("failed to select raw encoder!"));
connected = FALSE;
}
}
// sf@2002 - For now we disable cache protocole when more than one client are connected
// (But the cache buffer (if exists) is kept intact (for XORZlib usage))
if (m_server->AuthClientCount() > 1)
m_server->DisableCacheForAllClients();
}
// Re-enable updates
m_client->client_settings_passed=true;
m_client->EnableProtocol();
break;
case rfbFramebufferUpdateRequest:
// Read the rest of the message:
if (!m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbFramebufferUpdateRequestMsg-nTO))
{
connected = FALSE;
break;
}
/*{
m_client->Sendtimer.stop();
int sendtime=m_client->Sendtimer.read()*1000;
if (m_client->Totalsend>1500 && sendtime!=0)
{
//vnclog.Print(LL_SOCKERR, VNCLOG("Send Size %i %i %i %i"),m_socket->Totalsend,sendtime,m_socket->Totalsend/sendtime,m_client->m_encodemgr.m_encoding);
m_client->timearray[m_client->m_encodemgr.m_encoding][m_client->roundrobin_counter]=sendtime;
m_client->sizearray[m_client->m_encodemgr.m_encoding][m_client->roundrobin_counter]=m_client->Totalsend;
m_client->Sendtimer.reset();
for (int j=0;j<17;j++)
{
int totsize=0;
int tottime=0;
for (int i=0;i<31;i++)
{
totsize+=m_client->sizearray[j][i];
tottime+=m_client->timearray[j][i];
}
if (tottime!=0 && totsize>1500)
vnclog.Print(LL_SOCKERR, VNCLOG("Send Size %i %i %i %i"),totsize,tottime,totsize/tottime,j);
}
m_client->roundrobin_counter++;
if (m_client->roundrobin_counter>30) m_client->roundrobin_counter=0;
}
m_client->Sendtimer.reset();
m_client->Totalsend=0;
}*/
{
rfb::Rect update;
// Get the specified rectangle as the region to send updates for
update.tl.x = (Swap16IfLE(msg.fur.x) + m_client->m_SWOffsetx) * m_client->m_nScale;
update.tl.y = (Swap16IfLE(msg.fur.y) + m_client->m_SWOffsety) * m_client->m_nScale;
update.br.x = update.tl.x + Swap16IfLE(msg.fur.w) * m_client->m_nScale;
update.br.y = update.tl.y + Swap16IfLE(msg.fur.h) * m_client->m_nScale;
rfb::Region2D update_rgn = update;
// vnclog.Print(LL_SOCKERR, VNCLOG("Update asked for region %i %i %i %i %i"),update.tl.x,update.tl.y,update.br.x,update.br.y,m_client->m_SWOffsetx);
// RealVNC 336
if (update_rgn.is_empty()) {
vnclog.Print(LL_INTERR, VNCLOG("FATAL! client update region is empty!"));
connected = FALSE;
break;
}
{
omni_mutex_lock l(m_client->GetUpdateLock());
// Add the requested area to the incremental update cliprect
m_client->m_incr_rgn = m_client->m_incr_rgn.union_(update_rgn);
// Is this request for a full update?
if (!msg.fur.incremental)
{
// Yes, so add the region to the update tracker
m_client->m_update_tracker.add_changed(update_rgn);
// Tell the desktop grabber to fetch the region's latest state
m_client->m_encodemgr.m_buffer->m_desktop->QueueRect(update);
}
/* RealVNC 336 (removed)
// Check that this client has an update thread
// The update thread never dissappears, and this is the only
// thread allowed to create it, so this can be done without locking.
if (!m_client->m_updatethread)
{
m_client->m_updatethread = new vncClientUpdateThread;
connected = (m_client->m_updatethread &&
m_client->m_updatethread->Init(m_client));
}
*/
// Kick the update thread (and create it if not there already)
//Pushprotokoll - ab v1.86 wieder abgeschaltet
if (!m_autopush)
{
//Client has to send one incremental update after the first fullupdaterequest
//because server does not know client version when first full request is sent
if (m_tvinfo->getPartnerInfo(tvVersion)>="1.85" && m_tvinfo->getPartnerInfo(tvVersion)<"1.86")
m_autopush = true;
m_client->m_encodemgr.m_buffer->m_desktop->TriggerUpdate();
m_client->TriggerUpdateThread();
}
}
}
break;
case rfbKeyEvent:
// Read the rest of the message:
if (m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbKeyEventMsg-nTO))
{
if (m_client->m_keyboardenabled)
{
msg.ke.key = Swap32IfLE(msg.ke.key);
// do not allow remote input to TeamViewer windows
HWND active = GetForegroundWindow();
while(GetParent(active))
active = GetParent(active);
if(active == SessionDialog::Hwnd() ||
active == this->m_client->m_ClientControl->m_hwndClientControl)
{
break;
}
// Get the keymapper to do the work
// m_client->m_keymap.DoXkeysym(msg.ke.key, msg.ke.down);
vncKeymap::keyEvent(msg.ke.key, msg.ke.down);
m_client->m_remoteevent = TRUE;
}
}
else
connected = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -