📄 vncclient.cpp
字号:
break;
case rfbPointerEvent:
// Read the rest of the message:
if (m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbPointerEventMsg-nTO))
{
// do not accept input while single window is pending
if(m_client->m_encodemgr.m_buffer->m_desktop->m_stop_input_while_sw)
break;
DWORD timeSinceLastMouseMove=timeGetTime() - lastMouseMove;
if (m_client->m_pointerenabled && timeSinceLastMouseMove > 1000) // && false)// m_client->m_encodemgr.m_buffer->m_desktop->l
{
// Convert the coords to Big Endian
// Modif sf@2002 - Scaling
msg.pe.x = (Swap16IfLE(msg.pe.x) + m_client->m_SWOffsetx+m_client->m_ScreenOffsetx) * m_client->m_nScale;
msg.pe.y = (Swap16IfLE(msg.pe.y) + m_client->m_SWOffsety+m_client->m_ScreenOffsety) * m_client->m_nScale;
// Work out the flags for this event
DWORD flags = MOUSEEVENTF_ABSOLUTE;
// do not allow remote control of TeamViewer windows
POINT p;
p.x = msg.pe.x;
p.y = msg.pe.y;
HWND over = WindowFromPoint(p);
while(GetParent(over))
over = GetParent(over);
if(over == SessionDialog::Hwnd())
{
msg.pe.buttonMask = 0;
}
if (msg.pe.x != m_client->m_ptrevent.x ||
msg.pe.y != m_client->m_ptrevent.y)
flags |= MOUSEEVENTF_MOVE;
if ( (msg.pe.buttonMask & rfbButton1Mask) !=
(m_client->m_ptrevent.buttonMask & rfbButton1Mask) )
{
if (GetSystemMetrics(SM_SWAPBUTTON))
flags |= (msg.pe.buttonMask & rfbButton1Mask)
? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
else
flags |= (msg.pe.buttonMask & rfbButton1Mask)
? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
}
if ( (msg.pe.buttonMask & rfbButton2Mask) !=
(m_client->m_ptrevent.buttonMask & rfbButton2Mask) )
{
flags |= (msg.pe.buttonMask & rfbButton2Mask)
? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
}
if ( (msg.pe.buttonMask & rfbButton3Mask) !=
(m_client->m_ptrevent.buttonMask & rfbButton3Mask) )
{
if (GetSystemMetrics(SM_SWAPBUTTON))
flags |= (msg.pe.buttonMask & rfbButton3Mask)
? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
else
flags |= (msg.pe.buttonMask & rfbButton3Mask)
? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
}
// Treat buttons 4 and 5 presses as mouse wheel events
DWORD wheel_movement = 0;
if (m_client->m_encodemgr.IsMouseWheelTight())
{
if ((msg.pe.buttonMask & rfbButton4Mask) != 0 &&
(m_client->m_ptrevent.buttonMask & rfbButton4Mask) == 0)
{
flags |= MOUSEEVENTF_WHEEL;
wheel_movement = (DWORD)+120;
}
else if ((msg.pe.buttonMask & rfbButton5Mask) != 0 &&
(m_client->m_ptrevent.buttonMask & rfbButton5Mask) == 0)
{
flags |= MOUSEEVENTF_WHEEL;
wheel_movement = (DWORD)-120;
}
}
else
{
// RealVNC 335 Mouse wheel support
if (msg.pe.buttonMask & rfbWheelUpMask) {
flags |= MOUSEEVENTF_WHEEL;
wheel_movement = WHEEL_DELTA;
}
if (msg.pe.buttonMask & rfbWheelDownMask) {
flags |= MOUSEEVENTF_WHEEL;
wheel_movement = -WHEEL_DELTA;
}
}
// Generate coordinate values
// bug fix John Latino
// offset for multi display
int screenX, screenY, screenDepth;
m_server->GetScreenInfo(screenX, screenY, screenDepth);
// vnclog.Print(LL_INTINFO, VNCLOG("########mouse :%i %i %i %i "),screenX, screenY,m_client->m_ScreenOffsetx,m_client->m_ScreenOffsety );
if (m_client->m_display_type==1)
{//primary display always have (0,0) as corner
unsigned long x = (msg.pe.x * 65535) / (screenX-1);
unsigned long y = (msg.pe.y * 65535) / (screenY-1);
// Do the pointer event
::mouse_event(flags, (DWORD) x, (DWORD) y, wheel_movement, 0);
// vnclog.Print(LL_INTINFO, VNCLOG("########mouse_event :%i %i "),x,y);
}
else
{//second or spanned
if (m_client->Sendinput)
{
INPUT evt;
evt.type = INPUT_MOUSE;
msg.pe.x=msg.pe.x-GetSystemMetrics(SM_XVIRTUALSCREEN);
msg.pe.y=msg.pe.y-GetSystemMetrics(SM_YVIRTUALSCREEN);
evt.mi.dx = (msg.pe.x * 65535) / (GetSystemMetrics(SM_CXVIRTUALSCREEN)-1);
evt.mi.dy = (msg.pe.y* 65535) / (GetSystemMetrics(SM_CYVIRTUALSCREEN)-1);
evt.mi.dwFlags = flags | MOUSEEVENTF_VIRTUALDESK;
evt.mi.dwExtraInfo = 0;
evt.mi.mouseData = wheel_movement;
evt.mi.time = 0;
m_client->Sendinput(1, &evt, sizeof(evt));
}
else
{
POINT cursorPos; GetCursorPos(&cursorPos);
ULONG oldSpeed, newSpeed = 10;
ULONG mouseInfo[3];
if (flags & MOUSEEVENTF_MOVE)
{
flags &= ~MOUSEEVENTF_ABSOLUTE;
SystemParametersInfo(SPI_GETMOUSE, 0, &mouseInfo, 0);
SystemParametersInfo(SPI_GETMOUSESPEED, 0, &oldSpeed, 0);
ULONG idealMouseInfo[] = {10, 0, 0};
SystemParametersInfo(SPI_SETMOUSESPEED, 0, &newSpeed, 0);
SystemParametersInfo(SPI_SETMOUSE, 0, &idealMouseInfo, 0);
}
::mouse_event(flags, msg.pe.x-cursorPos.x, msg.pe.y-cursorPos.y, wheel_movement, 0);
if (flags & MOUSEEVENTF_MOVE)
{
SystemParametersInfo(SPI_SETMOUSE, 0, &mouseInfo, 0);
SystemParametersInfo(SPI_SETMOUSESPEED, 0, &oldSpeed, 0);
}
}
}
// Save the old position
m_client->m_ptrevent = msg.pe;
// Staudenmeyer: save event position so it is not mistaken for local input later
lastRemoteMouseEventPosition.x=msg.pe.x;
lastRemoteMouseEventPosition.y=msg.pe.y;
// Flag that a remote event occurred
m_client->m_remoteevent = TRUE;
// Tell the desktop hook system to grab the screen...
m_client->m_encodemgr.m_buffer->m_desktop->TriggerUpdate();
}
}
else
connected = FALSE;
break;
case rfbClientCutText:
// Read the rest of the message:
if (m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbClientCutTextMsg-nTO))
{
// Allocate storage for the text
const UINT length = Swap32IfLE(msg.cct.length);
char *text = new char [length+1];
if (text == NULL)
break;
text[length] = 0;
// Read in the text
if (!m_socket->ReadExact(text, length)) {
delete [] text;
break;
}
// Get the server to update the local clipboard
m_server->UpdateLocalClipText(text);
// Free the clip text we read
delete [] text;
}
else
connected = FALSE;
break;
// Modif sf@2002 - Scaling
// Server Scaling Message received
case rfbPalmVNCSetScaleFactor:
m_client->m_fPalmVNCScaling = true;
case rfbSetScale: // Specific PalmVNC SetScaleFactor
{
// m_client->m_fPalmVNCScaling = false;
// Read the rest of the message
if (m_client->m_fPalmVNCScaling)
{
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbPalmVNCSetScaleFactorMsg - nTO))
{
connected = FALSE;
break;
}
}
else
{
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetScaleMsg - nTO))
{
connected = FALSE;
break;
}
}
// Only accept reasonable scales...
if (msg.ssc.scale >= 1 || msg.ssc.scale <= 9)
{
if(!m_client->SetScaling(msg.ssc.scale))
connected = FALSE;
}
}
break;
// TR@2004 - ModeChange
// Request to change the connection mode was received
case rfbModeChangeRequest:
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbModeChangeMsg - nTO))
{
connected = FALSE;
break;
}
if ( !(msg.mchange.newmode & rfbMC_Servermodes))
{
// a change to a viewer mode was requested
// disable server data updates
m_client->DisableProtocol();
// Finally, it's safe to kill the update thread here
if (m_client->m_updatethread) {
m_client->m_updatethread->Kill();
m_client->m_updatethread->join(NULL);
m_client->m_updatethread = NULL;
}
// accept mode change
rfbModeChangeMsg mchange;
mchange.type = rfbModeChange;
mchange.newmode = msg.mchange.newmode | rfbMC_Servermodes; // switch the partner to the corresponding server mode
m_socket->SendExact((char *)&mchange, sz_rfbModeChangeMsg);
// Clientmodus aktivieren
//!!!!!! app wird nicht gel鰏cht
VNCviewerApp32 *app = VNCviewerApp32::Instance();
// sofort 黚er bestehenden Socket verbinden
app->NewConnection((SOCKET)m_socket->sock,msg.mchange.newmode,
m_client->connectionLogUser, m_client->connectionLogStartTime, m_client->m_ActiveMode);
m_client->keepSocket=TRUE;
// Serververbindung beenden
connected= FALSE;
} else // andere Varianten ignorieren
break;
break;
// TR@2004 - read client磗 screen dimensions
// Client sends screen dimensions so we can display the area the client can see
case rfbDisplayDimensions:
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbDisplayDimensionsMsg - nTO))
{
connected = FALSE;
break;
}
// NOT YET IMPLEMENTED
break;
// Set Server Input
case rfbSetServerInput:
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetServerInputMsg - nTO))
{
connected = FALSE;
break;
}
if (m_client->m_keyboardenabled)
{
if (msg.sim.status==1) m_client->m_encodemgr.m_buffer->m_desktop->SetDisableInput(true);
if (msg.sim.status==0) m_client->m_encodemgr.m_buffer->m_desktop->SetDisableInput(false);
}
break;
// Set Single Window
case rfbSetSW:
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetSWMsg - nTO))
{
connected = FALSE;
break;
}
if (Swap16IfLE(msg.sw.x)<5 && Swap16IfLE(msg.sw.y)<5)
{
m_client->m_encodemgr.m_buffer->m_desktop->SetSW(1,1);
break;
}
m_client->m_encodemgr.m_buffer->m_desktop->SetSW(
(Swap16IfLE(msg.sw.x) + m_client->m_SWOffsetx+m_client->m_ScreenOffsetx) * m_client->m_nScale,
(Swap16IfLE(msg.sw.y) + m_client->m_SWOffsety+m_client->m_ScreenOffsety) * m_client->m_nScale);
break;
// Modif sf@2002 - TextChat
case rfbTextChat:
m_client->m_pTextChat->ProcessTextChatMsg(nTO);
break;
// Modif sf@2002 - FileTransfer
// File Transfer Message
case rfbFileTransfer:
{
// TR@2004: maybe we have to accept the incoming filetransfer request
if (m_client->FileTransferEnabled()==0)
{
if (m_server->FileTransferEnabled()==1)
// no query
m_client->SetFileTransferEnabled(1);
if (m_server->FileTransferEnabled()==2)
{
// query user - we use the same query restrictions as with incoming conns
vncAcceptDialog *acceptDlg = new vncAcceptDialog(m_server->QueryTimeout(),m_server->QueryAccept());
AcceptDialogResult result=acceptDlg->DoDialog();
if(result==AcceptWithTimeout) // yes, filetransfer allowed
{
m_client->SetFileTransferEnabled(1);
m_client->m_fileTransferDialogTimedOut=true;
}
else if(result==Accept) // yes, filetransfer allowed
{
m_client->SetFileTransferEnabled(1);
}
else // not allowed
if(m_client->ActiveMode() == rfbMC_FiletransferServer)
{
m_client->Kill(); // quit if we are only a filetransferserver
break;
}
}
}
// sf@2004 - An unlogged user can't access to FT
bool fUserOk = true;
if (m_server->FTUserImpersonation())
{
fUserOk = m_client->DoFTUserImpersonation();
}
omni_mutex_lock l(m_client->GetUpdateLock());
// Read the rest of the message:
m_client->m_fFileTransferRunning = TRUE;
if (m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbFileTransferMsg - nTO))
{
switch (msg.ft.contentType)
{
// A new file is received from the client
// case rfbFileHeader:
case rfbFileTransferOffer:
{
omni_mutex_lock l(m_client->GetUpdateLock());
if (m_client->FileTransferEnabled()==0 || !fUserOk) break;
// bool fError = false;
const UINT length = Swap32IfLE(msg.ft.length);
memset(m_client->m_szFullDestName, 0, sizeof(m_client->m_szFullDestName));
if (length > sizeof(m_client->m_szFullDestName)) break;
// Read in the Name of the file to create
if (!m_socket->ReadExact(m_client->m_szFullDestName, length))
{
//MessageBox(NULL, "1. Abort !", "Ultra WinVNC", MB_OK);
// vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Failed to receive FileName from Viewer. Abort !"));
break;
}
// sf@2004 - Improving huge files size handling
CARD32 sizeL = Swap32IfLE(msg.ft.size);
CARD32 sizeH = 0;
CARD32 sizeHtmp = 0;
if (!m_socket->ReadExact((char*)&sizeHtmp, sizeof(CARD32)))
{
//MessageBox(NULL, "2. Abort !", "Ultra WinVNC", MB_OK);
//vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Failed to receive SizeH from Viewer. Abort !"));
break;
}
sizeH = Swap32IfLE(sizeHtmp);
if(m_client->FileTransferEnabled() == -1) // filetransfer forbidden
break;
// Parse the FileTime
char *p = strrchr(m_client->m_szFullDestName, ',');
if (p == NULL)
m_client->m_szFileTime[0] = '\0';
else
{
strcpy(m_client->m_szFileTime, p+1);
*p = '\0';
}
// sf@2004 - Directory Delta Transfer
// If the offered file is a zipped directory, we test if it already exists here
// and create the zip accordingly. This way we can generate the checksums for it.
// m_client->CheckAndZipDirectoryForChecksuming
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -