📄 vncdesktopthread.cpp
字号:
if (m_desktop->VideoBuffer() && m_desktop->m_hookdriver)
m_desktop->m_buffer.SetAccuracy(4);
BOOL idle_skip = TRUE;
ULONG idle_skip_count = 0;
//init vars
m_desktop->m_SWSizeChanged=FALSE;
m_desktop->m_SWtoDesktop=FALSE;
m_desktop->m_SWmoved=FALSE;
m_desktop->Hookdll_Changed = true;
m_desktop->m_displaychanged=false;
m_desktop->m_hookswitch=false;
m_desktop->m_hookinited = FALSE;
// Set driver cursor state
XRichCursorEnabled=m_desktop->m_server->IsXRichCursorEnabled();
if (!XRichCursorEnabled && m_desktop->m_videodriver) m_desktop->m_videodriver->HardwareCursor();
if (XRichCursorEnabled && m_desktop->m_videodriver) m_desktop->m_videodriver->NoHardwareCursor();
if (XRichCursorEnabled) m_server->UpdateCursorShape();
InvalidateRect(NULL,NULL,TRUE);
oldtick=timeGetTime();
//*******************************************************
// END INIT
//*******************************************************
// START PROCESSING DESKTOP MESSAGES
#ifndef _DEBUG
try
{
#endif
MSG msg;
while (TRUE)
{
// vnclog.Print(0,VNCLOG("vncDesktopThread while(TRUE)"));
if (!PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
// MAX 30fps
newtick = timeGetTime(); // Better resolution than GetTickCount ;)
if ((newtick-oldtick)<33)
{
Sleep(33-(newtick-oldtick));
continue;
}
oldtick=newtick;
// vnclog.Print(0,VNCLOG("vncDesktopThread tick"));
if (m_desktop->VideoBuffer() && m_desktop->m_hookdriver) handle_driver_changes(rgncache,updates);
m_desktop->m_update_triggered = FALSE;
g_update_triggered = FALSE;
if (m_desktop->m_timerid==NULL) m_desktop->m_timerid = SetTimer(m_desktop->m_hwnd, 1, 100, NULL);
//*******************************************************
// HOOKDLL START STOP need to be executed from the thread
//*******************************************************
if (m_desktop->Hookdll_Changed && !m_desktop->m_hookswitch)
{
vnclog.Print(LL_INTERR, VNCLOG("Hook changed "));
m_desktop->StartStophookdll(m_desktop->On_Off_hookdll);
if (m_desktop->On_Off_hookdll)
m_desktop->m_hOldcursor = NULL; // Force mouse cursor grabbing if hookdll On
// Todo: in case of hookdriver Off - Hoodll On -> hookdriver On - Hoodll Off
// we must send an empty mouse cursor to the clients so they get rid of their local
// mouse cursor bitmap
m_desktop->Hookdll_Changed=false;
}
//*******************************************************
// SCREEN DISPLAY HAS CHANGED, RESTART DRIVER (IF Used)
//*******************************************************
if ( m_desktop->m_displaychanged || //WM_DISPLAYCHANGE
!vncService::InputDesktopSelected() || //handle logon and screensaver desktops
m_desktop->m_SWtoDesktop || //switch from SW to full desktop or visa versa
m_desktop->m_hookswitch|| //hook change request
m_desktop->asked_display!=m_desktop->m_buffer.GetDisplay() //monitor change request
)
{
// We need to wait until viewer has send if he support Size changes
if (!m_server->All_clients_initialalized())
{
Sleep(30);
vnclog.Print(LL_INTERR, VNCLOG("Wait for viewer init "));
}
//logging
if (m_desktop->m_displaychanged) vnclog.Print(LL_INTERR, VNCLOG("++++Screensize changed "));
if (m_desktop->m_SWtoDesktop) vnclog.Print(LL_INTERR, VNCLOG("m_SWtoDesktop "));
if (m_desktop->m_hookswitch) vnclog.Print(LL_INTERR, VNCLOG("m_hookswitch "));
if (m_desktop->asked_display!=m_desktop->m_buffer.GetDisplay()) vnclog.Print(LL_INTERR, VNCLOG("desktop switch %i %i "),m_desktop->asked_display,m_desktop->m_buffer.GetDisplay());
if (!vncService::InputDesktopSelected()) vnclog.Print(LL_INTERR, VNCLOG("++++InputDesktopSelected "));
//Disable driver for logon and screensaver windows
//if (!vncService::InputDesktopSelected()) m_desktop->Temp_Resolution=true;
BOOL screensize_changed=false;
BOOL monitor_changed=false;
rfbServerInitMsg oldscrinfo;
//*******************************************************
// Lock Buffers from here
//*******************************************************
{
if (XRichCursorEnabled) m_server->UpdateCursorShape();
/// We lock all buffers,,and also back the client thread update mechanism
omni_mutex_lock l(m_desktop->m_update_lock);
// We remove all queue updates from the tracker
m_server->Clear_Update_Tracker();
// Also clear the current updates
rgncache.clear();
// Also clear the copy_rect updates
clipped_updates.clear();
// TESTTESTTEST
// Are all updates cleared....old updates could generate bounding errors
// any other queues to clear ? Yep cursor positions
m_desktop->m_cursorpos.tl.x=0;
m_desktop->m_cursorpos.tl.y=0;
m_desktop->m_cursorpos.br.x=0;
m_desktop->m_cursorpos.br.y=0;
//keep a copy of the old screen size, so we can check for changes later on
oldscrinfo = m_desktop->m_scrinfo;
if (m_desktop->asked_display!=m_desktop->m_buffer.GetDisplay())
{
m_desktop->Checkmonitors();
m_desktop->asked_display=m_desktop->m_buffer.GetDisplay();
int old_monitor=m_desktop->current_monitor;
m_desktop->current_monitor=1;
if (m_desktop->asked_display==2 && m_desktop->nr_monitors>1) m_desktop->current_monitor=2;
if (m_desktop->asked_display==3 && m_desktop->nr_monitors>1) m_desktop->current_monitor=3;
vnclog.Print(LL_INTERR, VNCLOG("OLd Current mon %i %i "),old_monitor,m_desktop->current_monitor);
if ( old_monitor!=m_desktop->current_monitor) monitor_changed=true;
}
//*******************************************************
// Reinitialize buffers,color, etc
// monitor change, for non driver, use another buffer
//*******************************************************
if (m_desktop->m_displaychanged || !vncService::InputDesktopSelected() || m_desktop->m_hookswitch || (monitor_changed && !m_desktop->m_videodriver))
{
// Attempt to close the old hooks
// shutdown(true) driver is reinstalled without shutdown,(shutdown need a 640x480x8 switch)
vnclog.Print(LL_INTERR, VNCLOG("m_desktop->Shutdown"));
monitor_changed=false;
if (!m_desktop->Shutdown())
{
vnclog.Print(LL_INTERR, VNCLOG("Shutdown KillAuthClients"));
m_server->KillAuthClients();
break;
}
bool fHookDriverWanted = m_desktop->m_hookdriver;
vnclog.Print(LL_INTERR, VNCLOG("m_desktop->Startup"));
if (!m_desktop->Startup())
{
vnclog.Print(LL_INTERR, VNCLOG("waiting for m_desktop->Startup()"));
m_server->SendTVCommandToClients(tvSecureDesktop, "TRUE");
m_server->SetDesktopLocked(true);
while(!m_desktop->Startup(TRUE))
Sleep(100);
m_server->SetDesktopLocked(false);
m_server->SendTVCommandToClients(tvSecureDesktop, "FALSE");
vnclog.Print(LL_INTERR, VNCLOG("m_desktop->Startup() successful"));
}
if (m_desktop->m_videodriver)
{
if (!XRichCursorEnabled) m_desktop->m_videodriver->HardwareCursor();
else m_desktop->m_videodriver->NoHardwareCursor();
}
m_server->SetScreenOffset(m_desktop->m_ScreenOffsetx,m_desktop->m_ScreenOffsety,m_desktop->nr_monitors);
// sf@2003 - After a new Startup(), we check if the required video driver
// is actually available. If not, we force hookdll
// No need for m_hookswitch again because the driver is NOT available anyway.
// All the following cases are now handled:
// 1. Desktop thread starts with "Video Driver" checked and no video driver available...
// -> HookDll forced (handled by the first InitHookSettings() after initial Startup() call
// 2. Desktop Thread starts without "Video Driver" checked but available driver
// then the user checks "Video Driver" -> Video Driver used
// 3. Desktop thread starts with "Video Driver" and available driver used
// Then driver is switched off (-> hookDll)
// Then the driver is switched on again (-> hook driver used again)
// 4. Desktop thread starts without "Video Driver" checked and no driver available
// then the users checks "Video Driver"
if (fHookDriverWanted && m_desktop->m_videodriver == NULL)
{
vnclog.Print(LL_INTERR, VNCLOG("m_videodriver == NULL "));
m_desktop->SethookMechanism(true, false); // InitHookSettings() would work as well;
}
}
//*******************************************************
// end reinit
//*******************************************************
if ((m_desktop->m_scrinfo.framebufferWidth != oldscrinfo.framebufferWidth) ||
(m_desktop->m_scrinfo.framebufferHeight != oldscrinfo.framebufferHeight ||
m_desktop->m_SWtoDesktop==TRUE ))
{
screensize_changed=true;
vnclog.Print(LL_INTINFO, VNCLOG("SCR: new screen format %dx%dx%d"),
m_desktop->m_scrinfo.framebufferWidth,
m_desktop->m_scrinfo.framebufferHeight,
m_desktop->m_scrinfo.format.bitsPerPixel);
}
m_desktop->m_displaychanged = FALSE;
m_desktop->m_hookswitch = FALSE;
m_desktop->Hookdll_Changed = m_desktop->On_Off_hookdll; // Set the hooks again if necessary !
m_desktop->m_SWtoDesktop=FALSE;
//****************************************************************************
//************* SCREEN SIZE CHANGED
//****************************************************************************
if (screensize_changed)
{
vnclog.Print(LL_INTERR, VNCLOG("Size changed"));
POINT CursorPos;
m_desktop->SWinit();
m_desktop->GetQuarterSize();
GetCursorPos(&CursorPos);
CursorPos.x -= m_desktop->m_ScreenOffsetx;
CursorPos.y -= m_desktop->m_ScreenOffsety;
m_desktop->m_cursorpos.tl = CursorPos;
m_desktop->m_cursorpos.br = rfb::Point(GetSystemMetrics(SM_CXCURSOR),
GetSystemMetrics(SM_CYCURSOR)).translate(CursorPos);
m_server->SetSWOffset(m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety);
// Adjust the UpdateTracker clip region
updates.set_clip_region(m_desktop->m_Cliprect);
m_desktop->m_buffer.ClearCache();
}
if (monitor_changed)
{
// we are using the driver, so a monitor change is a view change, like a special kind of single window
// m_desktop->current_monitor is the new monitor we want to see
// monitor size mymonitor[m_desktop->current_monitor-1]
// m_SWOffset is used by the encoders to send the correct coordinates to the viewer
// Cliprect, buffer coordinates
m_desktop->m_SWOffsetx=m_desktop->mymonitor[m_desktop->current_monitor-1].offsetx-m_desktop->mymonitor[2].offsetx;
m_desktop->m_SWOffsety=m_desktop->mymonitor[m_desktop->current_monitor-1].offsety-m_desktop->mymonitor[2].offsety;
m_server->SetSWOffset(m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety);
m_desktop->m_Cliprect.tl.x=m_desktop->mymonitor[m_desktop->current_monitor-1].offsetx-m_desktop->mymonitor[2].offsetx;
m_desktop->m_Cliprect.tl.y=m_desktop->mymonitor[m_desktop->current_monitor-1].offsety-m_desktop->mymonitor[2].offsety;
m_desktop->m_Cliprect.br.x=m_desktop->mymonitor[m_desktop->current_monitor-1].offsetx+
m_desktop->mymonitor[m_desktop->current_monitor-1].Width-m_desktop->mymonitor[2].offsetx;
m_desktop->m_Cliprect.br.y=m_desktop->mymonitor[m_desktop->current_monitor-1].offsety+
m_desktop->mymonitor[m_desktop->current_monitor-1].Height-m_desktop->mymonitor[2].offsety;
vnclog.Print(LL_INTERR, VNCLOG("***********###############************ %i %i %i %i %i %i"),m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety
,m_desktop->m_Cliprect.tl.x,m_desktop->m_Cliprect.tl.y,m_desktop->m_Cliprect.br.x,m_desktop->m_Cliprect.br.y);
rgncache = rgncache.union_(rfb::Region2D(m_desktop->m_Cliprect));
updates.set_clip_region(m_desktop->m_Cliprect);
m_desktop->m_buffer.ClearCache();
m_desktop->m_buffer.BlackBack();
}
m_desktop->m_buffer.ClearCache();
m_desktop->m_buffer.BlackBack();
InvalidateRect(NULL,NULL,TRUE);
rgncache = rgncache.union_(rfb::Region2D(m_desktop->m_Cliprect));
}
//*******************************************************
// End Lock updates
// SetNewSWSize also Lock, else we get a deathlock
//*******************************************************
if (memcmp(&m_desktop->m_scrinfo.format, &oldscrinfo.format, sizeof(rfbPixelFormat)) != 0)
{
vnclog.Print(LL_INTERR, VNCLOG("Format changed"));
m_server->UpdatePalette();
m_server->UpdateLocalFormat();
}
if (screensize_changed)
{
screensize_changed=false;
m_server->SetNewSWSize(m_desktop->m_scrinfo.framebufferWidth,m_desktop->m_scrinfo.framebufferHeight,FALSE);
m_server->SetScreenOffset(m_desktop->m_ScreenOffsetx,m_desktop->m_ScreenOffsety,m_desktop->nr_monitors);
}
if (monitor_changed)
{
monitor_changed=false;
m_server->SetNewSWSize(m_desktop->mymonitor[m_desktop->current_monitor-1].Width,m_desktop->mymonitor[m_desktop->current_monitor-1].Height,TRUE);
}
}
//*******************************************************
// END SCREEN DISPLAY HAS CHANGED
//*******************************************************
// m_server->SetSWOffset(m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety);
//*******************************************************************
// SINGLE WINDOW
// size SW changed
// Position change -->change offsets
//*******************************************************************
bool SWSizeChanged=false;
if (m_server->SingleWindow())
{
omni_mutex_lock l(m_desktop->m_update_lock);
m_desktop->GetQuarterSize();
m_server->SetSWOffset(m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety);
//SW size changed
if (m_desktop->m_SWSizeChanged)
{
SWSizeChanged=true;
m_desktop->m_SWSizeChanged=FALSE;
m_desktop->GetQuarterSize();
rgncache = rgncache.union_(rfb::Region2D(m_desktop->m_Cliprect));
// vnclog.Print(LL_INTINFO, VNCLOG("4 %i %i %i %i "),m_desktop->m_Cliprect.br.x,m_desktop->m_Cliprect.br.y,m_desktop->m_Cliprect.tl.x,m_desktop->m_Cliprect.tl.y);
updates.set_clip_region(m_desktop->m_Cliprect);
m_server->SetSWOffset(m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety);
m_desktop->m_buffer.ClearCache();
m_desktop->m_buffer.BlackBack();
}
//SW position changed
if (m_desktop->m_SWmoved)
{
m_desktop->m_SWmoved=FALSE;
updates.set_clip_region(m_desktop->m_Cliprect);
m_server->SetSWOffset(m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety);
rgncache = rgncache.union_(rfb::Region2D(m_desktop->m_Cliprect));
// vnclog.Print(LL_INTINFO, VNCLOG("5 %i %i %i %i "),m_desktop->m_Cliprect.br.x,m_desktop->m_Cliprect.br.y,m_desktop->m_Cliprect.tl.x,m_desktop->m_Cliprect.tl.y);
m_desktop->m_buffer.ClearCache();
m_desktop->m_buffer.BlackBack();
}
}
if (m_server->SingleWindow() && SWSizeChanged)
{
m_server->SetNewSWSize(m_desktop->m_SWWidth,m_desktop->m_SWHeight,FALSE);
m_server->SetScreenOffset(m_desktop->m_ScreenOffsetx,m_desktop->m_ScreenOffsety,m_desktop->nr_monitors);
}
////////////////////////////////////////////////////////////////////////////////
// END DYNAMIC CHANGES
////////////////////////////////////////////////////////////////////////////////
//
// CALCULATE CHANGES
m_desktop->m_UltraEncoder_used=m_desktop->m_server->IsThereAUltraEncodingClient();
if (m_desktop->m_server->UpdateWanted())
{
//TEST4
// Re-render the mouse's old location if it's moved
BOOL cursormoved = FALSE;
POINT cursorpos;
if (GetCursorPos(&cursorpos) &&
((cursorpos.x != oldcursorpos.x) ||
(cursorpos.y != oldcursorpos.y)))
{
if(cursorpos.x!=lastRemoteMouseEventPosition.x && cursorpos.y!=lastRemoteMouseEventPosition.y)
{
lastMouseMove = timeGetTime();
}
cursormoved = TRUE;
oldcursorpos = rfb::Point(cursorpos);
}
//****************************************************************************
//************* Polling ---- no driver
//****************************************************************************
if (!m_desktop->m_hookdriver)
{
// POLL PROBLEM AREAS
// We add specific areas of the screen to the region cache,
// causing them to be fetched for processing.
DWORD lTime = timeGetTime();
if (cursormoved)
{
m_lLastMouseMoveTime = lTime;
}
m_desktop->m_buffer.SetAccuracy(m_desktop->m_server->TurboMode() ? 8 : 4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -