📄 vncclient.cpp
字号:
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\n"));
continue;
}
// XOR zlib
if (Swap32IfLE(encoding) == rfbEncodingXOREnable) {
m_client->m_encodemgr.AvailableXOR(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("XOR protocol extension enabled\n"));
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\n"), 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\n"), 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\n"));
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\n"));
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\n"));
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 \n"));
// continue;
}
if (Swap32IfLE(encoding) == rfbEncodingTight) {
m_client->m_encodemgr.AvailableTight(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("Tight found\n"));
// 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\n"));
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!\n"));
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\n"),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\n"),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
// Modif sf@2002 - Scaling.
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.tl.x = 0;
// update.tl.y = 0;
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;
// update.br.x = 2880;
// update.br.y = 1200;
rfb::Region2D update_rgn = update;
// vnclog.Print(LL_SOCKERR, VNCLOG("Update asked for region %i %i %i %i %i\n"),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!\n"));
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)
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);
// 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;
}
}
break;
case rfbPointerEvent:
// Read the rest of the message:
if (m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbPointerEventMsg-nTO))
{
if (m_client->m_pointerenabled)
{
// 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;
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 \n"),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 \n"),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;
// 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();
}
}
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;
}
break;
// Modif sf@2002 - Scaling
// Server Scaling Message received
case rfbPalmVNCSetScaleFactor:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -