📄 vncdesktop.cpp
字号:
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("InitVideo driver Called no Temp_Resolution"));
if (DriverWantedSet)
{
m_server->Driver(DriverWanted);
m_server->Hook(HookWanted);
DriverWantedSet=false;
}
if (m_server->Driver())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("Driver option enabled "));
if(!vncService::IsWinNT())
{
InitVideoDriver();
}
}
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("Driver option dsiabled "));
if (m_Origpolling) m_server->PollFullScreen(m_Origpolling);
m_OrigpollingSet=false;
}
else
{
m_Origpolling=m_server->PollFullScreen();
m_OrigpollingSet=true;
m_server->PollFullScreen(TRUE);
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("InitVideo driver Called Temp_Resolution"));
}
if (VideoBuffer())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("Break log"));
}
if (!InitBitmap())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("InitBitmap Failed"));
return FALSE;
}
if (!ThunkBitmapInfo())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("ThunkBitmapInfo Failed"));
return FALSE;
}
//if (m_server->Driver())
EnableOptimisedBlits();
if (!SetPixFormat())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("SetPixFormat Failed"));
return FALSE;
}
if (!SetPixShifts())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("SetPixShift Failed"));
return FALSE;
}
if (!SetPalette())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("SetPalette Failed"));
return FALSE;
}
if (!InitWindow())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("InitWindow failed"));
return FALSE;
}
if (VideoBuffer())
{
pchanges_buf=NULL;
GETCHANGESBUF *pcommbuffer=m_videodriver->CreateCommunicationBuffer(m_bminfo.bmi.bmiHeader.biSizeImage);
// we need to check again, communication service can be down
// In that case driver can not be used
if (VideoBuffer())
{
if(!silent)
vnclog.Print(LL_INTINFO, VNCLOG("Removing real Dib buffer and replace by driver communication buffer"));
if (m_membitmap != NULL)
{
DeleteObject(m_membitmap);
m_membitmap = NULL;
}
m_DIBbits=pcommbuffer->UserbufferBegin;
pchanges_buf=pcommbuffer->buffer;
InvalidateRect(NULL,NULL,TRUE);
}
}
// Start a timer to handle Polling Mode. The timer will cause
// an "idle" event once every 1/10 second, which is necessary if Polling
// Mode is being used, to cause TriggerUpdate to be called.
m_timerid = SetTimer(m_hwnd, 1, 100, NULL);
// Initialise the buffer object
m_buffer.SetDesktop(this);
GetQuarterSize();
// Everything is ok, so return TRUE
return TRUE;
}
// Routine to shutdown all the hooks and stuff
BOOL
vncDesktop::Shutdown()
{
// If we created a timer then kill it
if (m_timerid != NULL)
KillTimer(NULL, m_timerid);
// If we created a window then kill it and the hooks
if(m_hwnd != NULL)
{
// Remove the system hooks
if (UnSetHooks) UnSetHooks(GetCurrentThreadId());
// The window is being closed - remove it from the viewer list
ChangeClipboardChain(m_hwnd, m_hnextviewer);
// Close the hook window
DestroyWindow(m_hwnd);
m_hwnd = NULL;
m_hnextviewer = NULL;
}
// Now free all the bitmap stuff
if (m_hrootdc != NULL)
{
// Release our device context
// if m_hrootdc was created with createdc, we need to use deletedc to release
// if (VideoBuffer())
{
if (!DeleteDC(m_hrootdc))
vnclog.Print(LL_INTERR, VNCLOG("failed to DeleteDC hrootdc"));
}
// else
// {
// if(ReleaseDC(NULL, m_hrootdc) == 0)
// {
// vnclog.Print(LL_INTERR, VNCLOG("failed to ReleaseDC"));
// }
// }
m_hrootdc = NULL;
}
if (m_hmemdc != NULL)
{
// Release our device context
if (!DeleteDC(m_hmemdc))
{
vnclog.Print(LL_INTERR, VNCLOG("failed to DeleteDC hmemdc"));
}
m_hmemdc = NULL;
}
if (m_membitmap != NULL)
{
// Release the custom bitmap, if any
if (!DeleteObject(m_membitmap))
{
vnclog.Print(LL_INTERR, VNCLOG("failed to DeleteObject"));
}
m_membitmap = NULL;
}
// Modif rdv@2002 - v1.1.x - videodriver
//if (!Temp_Resolution)
ShutdownVideoDriver();
/*else if (m_videodriver!=NULL)
{
m_videodriver->StopMirroring();
m_videodriver->RemoveCommunicationBuffer();
m_hookswitch=true;
Hookdll_Changed=true;
pchanges_buf=NULL;
m_DIBbits=NULL;
}*/
// ***
// vncService::SelectHomeWinStation();
return TRUE;
}
// Routine to ensure we're on the correct NT desktop
BOOL
vncDesktop::InitDesktop(BOOL silent)
{
if (vncService::InputDesktopSelected(silent))
return TRUE;
// Ask for the current input desktop
return vncService::SelectDesktop(NULL, silent);
}
// Routine used to close the screen saver, if it's active...
BOOL CALLBACK
KillScreenSaverFunc(HWND hwnd, LPARAM lParam)
{
char buffer[256];
// - ONLY try to close Screen-saver windows!!!
if ((GetClassName(hwnd, buffer, 256) != 0) &&
(strcmp(buffer, "WindowsScreenSaverClass") == 0))
PostMessage(hwnd, WM_CLOSE, 0, 0);
return TRUE;
}
void
vncDesktop::KillScreenSaver()
{
OSVERSIONINFO osversioninfo;
osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo);
// Get the current OS version
if (!GetVersionEx(&osversioninfo))
return;
vnclog.Print(LL_INTINFO, VNCLOG("KillScreenSaver..."));
// How to kill the screen saver depends on the OS
switch (osversioninfo.dwPlatformId)
{
case VER_PLATFORM_WIN32_WINDOWS:
{
// Windows 95
// Fidn the ScreenSaverClass window
HWND hsswnd = FindWindow ("WindowsScreenSaverClass", NULL);
if (hsswnd != NULL)
PostMessage(hsswnd, WM_CLOSE, 0, 0);
break;
}
case VER_PLATFORM_WIN32_NT:
{
// Windows NT
// Find the screensaver desktop
HDESK hDesk = OpenDesktop(
"Screen-saver",
0,
FALSE,
DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS
);
if (hDesk != NULL)
{
vnclog.Print(LL_INTINFO, VNCLOG("Killing ScreenSaver"));
// Close all windows on the screen saver desktop
EnumDesktopWindows(hDesk, (WNDENUMPROC) &KillScreenSaverFunc, 0);
CloseDesktop(hDesk);
// Pause long enough for the screen-saver to close
//Sleep(2000);
// Reset the screen saver so it can run again
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE);
}
SetLastError(0); // if no screensaver was active do not log error
break;
}
}
}
//
// Modif sf@2002 - Single Window
//
BOOL CALLBACK EnumWindowsHnd(HWND hwnd, LPARAM arg)
{
int nRet;
char buffer[128];
char szNameAppli[128];
// to prevent a deadlock that occurs when GetWindowName() is called while the message handling function
// is waiting for a lock we ignore the windows that belong to our process
DWORD window_pid;
GetWindowThreadProcessId(hwnd, &window_pid);
if(window_pid == GetCurrentProcessId())
return TRUE;
strncpy(szNameAppli, (LPSTR)(((vncDesktop*)arg)->GetServerPointer()->GetWindowName()), 128);
szNameAppli[127]=0;
nRet = GetWindowText(hwnd, buffer, sizeof(buffer));
if (nRet > 0)
{
if ( !strnicmp(buffer, szNameAppli, lstrlen(szNameAppli)))
{
//((vncDesktop*)arg)->m_Single_hWnd = hwnd;
((vncDesktop*)arg)->SetSW(hwnd);
return FALSE;
}
else
return TRUE;
}
return TRUE;
}
void vncDesktop::SearchSingleWindowByName()
{
if (m_server->SingleWindow() && m_Single_hWnd==NULL)
{
EnumWindows((WNDENUMPROC)EnumWindowsHnd, (LPARAM) this);
}
}
BOOL
vncDesktop::InitBitmap()
{
// Get the device context for the whole screen and find it's size
DriverType=NONE;
if (!vncService::IsWinNT()) //XP W2k
{
if (VideoBuffer())
{
pEnumDisplayDevices pd;
LPSTR driverName = "Winvnc video hook driver";
BOOL DriverFound;
DEVMODE devmode;
FillMemory(&devmode, sizeof(DEVMODE), 0);
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
BOOL change = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
HMODULE hUser32=LoadLibrary("USER32");
pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
if (pd)
{
LPSTR deviceName=NULL;
DISPLAY_DEVICE dd;
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);
devmode.dmDeviceName[0] = '\0';
INT devNum = 0;
BOOL result;
DriverFound=false;
while (result = (*pd)(NULL,devNum, &dd,0))
{
if (strcmp((const char *)&dd.DeviceString[0], driverName) == 0)
{
DriverFound=true;
break;
}
devNum++;
}
if (DriverFound)
{
deviceName = (LPSTR)&dd.DeviceName[0];
m_hrootdc = CreateDC("DISPLAY",deviceName,NULL,NULL);
BOOL change = EnumDisplaySettings(deviceName,ENUM_CURRENT_SETTINGS,&devmode);
m_ScreenOffsetx=devmode.dmPosition.x;
m_ScreenOffsety=devmode.dmPosition.y;
if (m_hrootdc) DriverType=MIRROR;
Checkmonitors();
asked_display=m_buffer.GetDisplay();
current_monitor=1;
if (asked_display==2 && nr_monitors>1) current_monitor=2;
if (asked_display==3 && nr_monitors>1) current_monitor=3;
}
}
if (hUser32) FreeLibrary(hUser32);
}//VIDEOBUFFER
}//OS
// RDV SINGLE WINDOW
SearchSingleWindowByName();
if (m_hrootdc == NULL) {
vnclog.Print(LL_INTERR, VNCLOG("No driver used "));
//Multi-Monitor changes
Checkmonitors();
asked_display=m_buffer.GetDisplay();
current_monitor=1;
if (asked_display==2 && nr_monitors>1) current_monitor=2;
if (asked_display==3 && nr_monitors>1) current_monitor=3;
if (current_monitor==3) current_monitor=1;
vnclog.Print(LL_INTINFO, VNCLOG("current_monitor = %d, mymonitor[%d] = %s"),
current_monitor, current_monitor-1, mymonitor[0].device);
if(current_monitor<3 && strlen(mymonitor[current_monitor-1].device) > 0)
m_hrootdc = CreateDC(("DISPLAY"),mymonitor[current_monitor-1].device,NULL,NULL);
else
m_hrootdc = GetDC(NULL);
vnclog.Print(LL_INTINFO, VNCLOG("m_hrootdc = %d, lasterror = %d"), m_hrootdc, GetLastError());
m_ScreenOffsetx=mymonitor[current_monitor-1].offsetx;
m_ScreenOffsety=mymonitor[current_monitor-1].offsety;
if (m_hrootdc == NULL) {
vnclog.Print(LL_INTERR, VNCLOG("Failed m_rootdc "));
return FALSE;
}
}
m_bmrect = rfb::Rect(0, 0,GetDeviceCaps(m_hrootdc, HORZRES),GetDeviceCaps(m_hrootdc, VERTRES));
//if(current_monitor==3)
// m_bmrect = rfb::Rect(0, 0, mymonitor[2].Width, mymonitor[2].Height);
vnclog.Print(LL_INTINFO, VNCLOG("bitmap dimensions are %d x %d"), m_bmrect.br.x, m_bmrect.br.y);
// Create a compatible memory DC
m_hmemdc = CreateCompatibleDC(m_hrootdc);
if (m_hmemdc == NULL) {
vnclog.Print(LL_INTERR, VNCLOG("failed to create compatibleDC(%d)"), GetLastError());
return FALSE;
}
// Check that the device capabilities are ok
if ((GetDeviceCaps(m_hrootdc, RASTERCAPS) & RC_BITBLT) == 0)
{
MessageBox(
NULL,
"vncDesktop : root device doesn't support BitBlt\n"
"WinVNC cannot be used with this graphic device driver",
szAppName,
MB_ICONSTOP | MB_OK
);
return FALSE;
}
if ((GetDeviceCaps(m_hmemdc, RASTERCAPS) & RC_DI_BITMAP) == 0)
{
MessageBox(
NULL,
"vncDesktop : memory device doesn't support GetDIBits\n"
"WinVNC cannot be used with this graphics device driver",
szAppName,
MB_ICONSTOP | MB_OK
);
return FALSE;
}
// Create the bitmap to be compatible with the ROOT DC!!!
m_membitmap = CreateCompatibleBitmap(m_hrootdc, m_bmrect.br.x, m_bmrect.br.y);
if (m_membitmap == NULL) {
vnclog.Print(LL_INTERR, VNCLOG("failed to create memory bitmap(%d)"), GetLastError());
return FALSE;
}
vnclog.Print(LL_INTINFO, VNCLOG("created memory bitmap"));
// Get the bitmap's format and colour details
int result;
memset(&m_bminfo, 0, sizeof(m_bminfo));
m_bminfo.bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_bminfo.bmi.bmiHeader.biBitCount = 0;
result = ::GetDIBits(m_hmemdc, m_membitmap, 0, 1, NULL, &m_bminfo.bmi, DIB_RGB_COLORS);
if (result == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -