📄 vncdesktop.cpp
字号:
{
vnclog.Print(LL_INTINFO, VNCLOG("InitBitmap Failed\n"));
return FALSE;
}
if (!ThunkBitmapInfo())
{
vnclog.Print(LL_INTINFO, VNCLOG("ThunkBitmapInfo Failed\n"));
return FALSE;
}
//if (m_server->Driver())
EnableOptimisedBlits();
if (!SetPixFormat())
{
vnclog.Print(LL_INTINFO, VNCLOG("SetPixFormat Failed\n"));
return FALSE;
}
if (!SetPixShifts())
{
vnclog.Print(LL_INTINFO, VNCLOG("SetPixShift Failed\n"));
return FALSE;
}
if (!SetPalette())
{
vnclog.Print(LL_INTINFO, VNCLOG("SetPalette Failed\n"));
return FALSE;
}
if (!InitWindow())
{
vnclog.Print(LL_INTINFO, VNCLOG("InitWindow failed\n"));
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())
{
vnclog.Print(LL_INTINFO, VNCLOG("Removing real Dib buffer and replace by driver communication buffer\n"));
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\n"));
}
// else
// {
// if(ReleaseDC(NULL, m_hrootdc) == 0)
// {
// vnclog.Print(LL_INTERR, VNCLOG("failed to ReleaseDC\n"));
// }
// }
m_hrootdc = NULL;
}
if (m_hmemdc != NULL)
{
// Release our device context
if (!DeleteDC(m_hmemdc))
{
vnclog.Print(LL_INTERR, VNCLOG("failed to DeleteDC hmemdc\n"));
}
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\n"));
}
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()
{
if (vncService::InputDesktopSelected())
return TRUE;
// Ask for the current input desktop
return vncService::SelectDesktop(NULL);
}
// 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...\n"));
// 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\n"));
// 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);
}
break;
}
}
}
//
// Modif sf@2002 - Single Window
//
BOOL CALLBACK EnumWindowsHnd(HWND hwnd, LPARAM arg)
{
int nRet;
char buffer[128];
char szNameAppli[16];
strcpy(szNameAppli, (LPSTR)(((vncDesktop*)arg)->GetServerPointer()->GetWindowName()));
szNameAppli[15]=0;
nRet = GetWindowText(hwnd, buffer, sizeof(buffer));
if (nRet > 0)
{
if ( !strnicmp(buffer, szNameAppli, lstrlen(szNameAppli)))
{
((vncDesktop*)arg)->m_Single_hWnd = hwnd;
return FALSE;
}
else
return TRUE;
}
return TRUE;
}
BOOL
vncDesktop::InitBitmap()
{
// Get the device context for the whole screen and find it's size
DriverType=NONE;
if (OSVersion()==1) //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
if (m_server->SingleWindow() && m_Single_hWnd==NULL)
{
EnumWindows((WNDENUMPROC)EnumWindowsHnd, (LPARAM) this);
}
if (m_hrootdc == NULL) {
vnclog.Print(LL_INTERR, VNCLOG("No driver used \n"));
//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;
if (current_monitor==1)
{
m_hrootdc = CreateDC(("DISPLAY"),mymonitor[0].device,NULL,NULL);
m_ScreenOffsetx=mymonitor[0].offsetx;
m_ScreenOffsety=mymonitor[0].offsety;
}
if (current_monitor==2)
{
m_hrootdc =CreateDC(("DISPLAY"),mymonitor[1].device,NULL,NULL);
m_ScreenOffsetx=mymonitor[1].offsetx;
m_ScreenOffsety=mymonitor[1].offsety;
}
if (current_monitor==3)
{
m_hrootdc = GetDC(NULL);
m_ScreenOffsetx=mymonitor[2].offsetx;
m_ScreenOffsety=mymonitor[2].offsety;;
}
if (m_hrootdc == NULL) {
vnclog.Print(LL_INTERR, VNCLOG("Failed m_rootdc \n"));
return FALSE;
}
}
m_bmrect = rfb::Rect(0, 0,GetDeviceCaps(m_hrootdc, HORZRES),GetDeviceCaps(m_hrootdc, VERTRES));
vnclog.Print(LL_INTINFO, VNCLOG("bitmap dimensions are %d x %d\n"), 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)\n"), 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)\n"), GetLastError());
return FALSE;
}
vnclog.Print(LL_INTINFO, VNCLOG("created memory bitmap\n"));
// 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) {
vnclog.Print(LL_INTERR, VNCLOG("unable to get display format\n"));
return FALSE;
}
result = ::GetDIBits(m_hmemdc, m_membitmap, 0, 1, NULL, &m_bminfo.bmi, DIB_RGB_COLORS);
if (result == 0) {
vnclog.Print(LL_INTERR, VNCLOG("unable to get display colour info\n"));
return FALSE;
}
vnclog.Print(LL_INTINFO, VNCLOG("got bitmap format\n"));
// Henceforth we want to use a top-down scanning representation
m_bminfo.bmi.bmiHeader.biHeight = - abs(m_bminfo.bmi.bmiHeader.biHeight);
// Is the bitmap palette-based or truecolour?
m_bminfo.truecolour = (GetDeviceCaps(m_hmemdc, RASTERCAPS) & RC_PALETTE) == 0;
InvalidateRect(NULL,NULL,TRUE);
return TRUE;
}
BOOL
vncDesktop::ThunkBitmapInfo()
{
// If we leave the pixel format intact, the blist can be optimised (Will Dean's patch)
m_formatmunged = FALSE;
// HACK ***. Optimised blits don't work with palette-based displays, yet
if (!m_bminfo.truecolour) {
m_formatmunged = TRUE;
}
// Attempt to force the actual format into one we can handle
// We can handle 8-bit-palette and 16/32-bit-truecolour modes
switch (m_bminfo.bmi.bmiHeader.biBitCount)
{
case 1:
case 4:
vnclog.Print(LL_INTINFO, VNCLOG("DBG:used/bits/planes/comp/size = %d/%d/%d/%d/%d\n"),
(int)m_bminfo.bmi.bmiHeader.biClrUsed,
(int)m_bminfo.bmi.bmiHeader.biBitCount,
(int)m_bminfo.bmi.bmiHeader.biPlanes,
(int)m_bminfo.bmi.bmiHeader.biCompression,
(int)m_bminfo.bmi.bmiHeader.biSizeImage);
// Correct the BITMAPINFO header to the format we actually want
m_bminfo.bmi.bmiHeader.biClrUsed = 0;
m_bminfo.bmi.bmiHeader.biPlanes = 1;
m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;
m_bminfo.bmi.bmiHeader.biBitCount = 8;
m_bminfo.bmi.bmiHeader.biSizeImage =
abs((m_bminfo.bmi.bmiHeader.biWidth *
m_bminfo.bmi.bmiHeader.biHeight *
m_bminfo.bmi.bmiHeader.biBitCount)/ 8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -