📄 vncdesktop.cpp
字号:
// The display resolution is changing
// We must kick off any clients since their screen size will be wrong
// WE change the clients screensize, if they support it.
vnclog.Print(LL_INTERR, VNCLOG("WM_DISPLAYCHANGE"));
// We First check if the Resolution changed is caused by a temp resolution switch
// For a temp resolution we don't use the driver, to fix the mirror driver
// to the new change, a resolution switch is needed, preventing screensaver locking.
if (_this->m_videodriver != NULL)
{
_this->Temp_Resolution=_this->m_videodriver->Tempres();
_this->m_videodriver->Temp_Resolution=_this->m_videodriver->Tempres();
}
else _this->Temp_Resolution=false;
if (_this->m_videodriver != NULL) //Video driver active
{
if (!_this->m_videodriver->blocked)
{
_this->m_displaychanged = TRUE;
if ( _this->Temp_Resolution)
{
_this->m_hookdriver=false;
vnclog.Print(LL_INTERR, VNCLOG("Temp Resolution switch detected"));
}
else
{
_this->m_hookdriver=true;
_this->m_videodriver->blocked=true;
vnclog.Print(LL_INTERR, VNCLOG("Resolution switch detected, driver active"));
}
}
else
{
//Remove display change, cause by driver activation
_this->m_videodriver->blocked=false;
vnclog.Print(LL_INTERR, VNCLOG("Resolution switch by driver activation removed"));
}
}
else
{
_this->m_displaychanged = TRUE;
_this->m_hookdriver=true;
vnclog.Print(LL_INTERR, VNCLOG("Resolution switch detected, driver NOT active"));
}
return 0;
case WM_SYSCOLORCHANGE:
case WM_PALETTECHANGED:
// The palette colours have changed, so tell the server
// Get the system palette
if (!_this->SetPalette())
PostQuitMessage(0);
// Update any palette-based clients, too
_this->m_server->UpdatePalette();
return 0;
// CLIPBOARD MESSAGES
case WM_CHANGECBCHAIN:
// The clipboard chain has changed - check our nextviewer handle
if ((HWND)wParam == _this->m_hnextviewer)
_this->m_hnextviewer = (HWND)lParam;
else
if (_this->m_hnextviewer != NULL)
SendMessage(_this->m_hnextviewer,
WM_CHANGECBCHAIN,
wParam, lParam);
return 0;
case WM_DRAWCLIPBOARD:
// The clipboard contents have changed
if((GetClipboardOwner() != _this->Window()) &&
_this->m_initialClipBoardSeen &&
_this->m_clipboard_active)
{
LPSTR cliptext = NULL;
// Open the clipboard
if (OpenClipboard(_this->Window()))
{
// Get the clipboard data
HGLOBAL cliphandle = GetClipboardData(CF_TEXT);
if (cliphandle != NULL)
{
LPSTR clipdata = (LPSTR) GlobalLock(cliphandle);
// Copy it into a new buffer
if (clipdata == NULL)
cliptext = NULL;
else
cliptext = strdup(clipdata);
// Release the buffer and close the clipboard
GlobalUnlock(cliphandle);
}
CloseClipboard();
}
if (cliptext != NULL)
{
int cliplen = strlen(cliptext);
LPSTR unixtext = (char *)malloc(cliplen+1);
if(!unixtext)
{
vnclog.Print(LL_INTERR, VNCLOG("malloc == NULL"));
}
else
{
// Replace CR-LF with LF - never send CR-LF on the wire,
// since Unix won't like it
int unixpos=0;
for (int x=0; x<cliplen; x++)
{
if (cliptext[x] != '\x0d')
{
unixtext[unixpos] = cliptext[x];
unixpos++;
}
}
unixtext[unixpos] = 0;
// Now send the unix text to the server
_this->m_server->UpdateClipText(unixtext);
free(unixtext);
}
// Free the clip text
free(cliptext);
cliptext = NULL;
}
}
_this->m_initialClipBoardSeen = TRUE;
if (_this->m_hnextviewer != NULL)
{
// Pass the message to the next window in clipboard viewer chain.
return SendMessage(_this->m_hnextviewer, WM_DRAWCLIPBOARD, 0,0);
}
return 0;
default:
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
return 0;
}
bool vncDesktop::bBlockStatus = false;
bool vncDesktop::BlockInput(bool doBlock)
{
if (doBlock == bBlockStatus)
return false;
HRESULT hRes = 0;
SetLastError(0);
if (pbi)
{
Sleep(500);
(*pbi)(doBlock);
if (doBlock)
vnclog.Print(LL_STATE, VNCLOG("Thread %i blocked input!"),GetCurrentThreadId());
else
vnclog.Print(LL_STATE, VNCLOG("Thread %i released input!"),GetCurrentThreadId());
hRes = GetLastError();
if (hRes != 0)
vnclog.Print(LL_ALL, VNCLOG("Cannot block input on machine. %i"),hRes);
bBlockStatus = doBlock;
return true;
}
return false;
}
// Modif rdv@2002 Dis/enable input
void
vncDesktop::SetDisableInput(bool enabled)
{
// TR@2004: BlankMonitorEnabled()-Property has different meaning in roVNC:
// If set, remote user is allowed to disable input on server side
if (!m_server->BlankMonitorEnabled())
return;
m_server->SetInputIsDisabled(enabled);
typedef DWORD (WINAPI *PSLWA)(HWND, DWORD, BYTE, DWORD);
PSLWA pSetLayeredWindowAttributes;
HMODULE hDLL = LoadLibrary ("user32");
pSetLayeredWindowAttributes = (PSLWA) GetProcAddress(hDLL,"SetLayeredWindowAttributes");
if (!pSetLayeredWindowAttributes) m_server->BlackAlphaBlending(false);
if (VideoBuffer())m_server->BlackAlphaBlending(false);
HRESULT hRes = 0;
//BlockInput block everything on non w2k and XP
//if hookdll is used, he take care of input blocking
if (OSVersion() == OSVERSION_2000_XP_VISTA)
{
BlockInput(enabled);
}
else
{
m_server->DisableLocalInputs(enabled);
On_Off_hookdll=true;
}
// Also Turn Off the Monitor if allowed ("Blank Screen", "Blank Monitor")
if (m_server->MonitorIsBlanked() && enabled)
{
if (!m_server->BlackAlphaBlending())
{
SetProcessShutdownParameters(0x100, 0);
SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0, &OldPowerOffTimeout, 0);
SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, 100, NULL, 0);
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 1, NULL, 0);
Sleep(1000);
SendMessage(m_hwnd,WM_SYSCOMMAND,SC_MONITORPOWER,(LPARAM)MONITOR_OFF);
}
else
{
HANDLE ThreadHandle2;
DWORD dwTId;
ThreadHandle2 = CreateThread(NULL, 0, BlackWindow, NULL, 0, &dwTId);
CloseHandle(ThreadHandle2);
}
}
else // Monitor On
{
if (!m_server->BlackAlphaBlending())
{
if (OldPowerOffTimeout!=0)
SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, OldPowerOffTimeout, NULL, 0);
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, NULL, 0);
SendMessage(m_hwnd,WM_SYSCOMMAND,SC_MONITORPOWER,(LPARAM)MONITOR_ON);
OldPowerOffTimeout=0;
}
else
{
HWND Blackhnd = FindWindow(("blackscreen"), 0);
if (Blackhnd) PostMessage(Blackhnd, WM_CLOSE, 0, 0);
}
}
}
// SW
void vncDesktop::SetSW(int x,int y)
{
POINT point;
point.x=x;
point.y=y;
omni_mutex_lock l(m_update_lock);
m_stop_input_while_sw = true;
vnclog.Print(LL_INTERR, VNCLOG("SETW %i %i"),x,y);
if (x <= 5 && y<=5 && x>-5 && y>-5)
{
SetSW(NULL);
return;
}
m_Single_hWnd=WindowFromPoint(point);
if (m_Single_hWnd==GetDesktopWindow())
{
LPGETMONITORINFO GetMonitorInfo=NULL;
LPMONITOTFROMPOINT MonitorFromPoint=NULL;
MONITORINFO monitorinfo;
monitorinfo.cbSize=sizeof(MONITORINFO);
GetMonitorInfo=(LPGETMONITORINFO) GetProcAddress(LoadLibrary("user32.dll"), "GetMonitorInfoA");
MonitorFromPoint=(LPMONITOTFROMPOINT) GetProcAddress(LoadLibrary("user32.dll"), "MonitorFromPointA");
if (GetMonitorInfo && MonitorFromPoint)
{
HMONITOR hmonitor=MonitorFromPoint(point,MONITOR_DEFAULTTONEAREST);
GetMonitorInfo(hmonitor,&monitorinfo);
if (monitorinfo.dwFlags ==MONITORINFOF_PRIMARY)
{
m_buffer.Display(1);
m_buffer.Display(-2);
m_Single_hWnd=NULL;
}
else
{
m_buffer.Display(-1);
m_buffer.Display(2);
m_Single_hWnd=NULL;
}
}
return;
}
if (m_Single_hWnd==NULL)
m_server->SingleWindow(false);
else
{
HWND parent;
while((parent=GetParent(m_Single_hWnd))!=NULL)
m_Single_hWnd=parent;
m_server->SingleWindow(true);
}
}
void vncDesktop::SetSW(HWND window)
{
omni_mutex_lock l(m_update_lock);
m_stop_input_while_sw = true;
m_Single_hWnd = window;
if(window == NULL)
{
switch(asked_display)
{
case 1:
m_buffer.Display(-1);
m_buffer.Display(2);
break;
case 2:
m_buffer.Display(1);
m_buffer.Display(2);
break;
case 3:
m_buffer.Display(1);
m_buffer.Display(-2);
break;
}
}
else
m_server->SingleWindow(true);
GetQuarterSize();
}
/***************************************************************************
* Ultravnc use 2 different software hooking methods
* hookdll: Hook the messages between the windows (nt,9.x)
* ddihook: Hook the messages to the video buffer (9.x)
* Driver hooking
* Driver hooking is done at kernel level.
* and exist of 2 parts
* update mechanism: rectangles are send from kernel to vnc (shared mem)
* shared video buffer: direct access the memeory without bitblit
* m_hookdriver: use driver update mechanism (ddihook in case of 9.x)
* m_hookdll: use software update mechanism
***************************************************************************/
// Modif rdv@2002 - v1.1.x - videodriver
BOOL vncDesktop::VideoBuffer()
{
//Always access the shared mememory thru this function
// Check NULL
if (m_videodriver==NULL) return FALSE;
if (IsBadReadPtr(m_videodriver,1)) return FALSE;
// If we reach this place, the driver was active
if (m_videodriver->driver_succes) return true;
if (!m_videodriver->driver_succes && Temp_Resolution) return false;
if (!m_videodriver->driver_succes && !Temp_Resolution)
{
m_videodriver->StopMirroring();
m_hookswitch=true;
Hookdll_Changed=true;
return FALSE;
}
return FALSE;
}
DWORD WINAPI Warningbox_non_locked(LPVOID lpParam)
{
MessageBox(NULL,"Current driver to old for this version \nUpdate driver or disable Video hook driver\n in the server properties window","",0);
return 0;
}
// Modif rdv@2002 - v1.1.x - videodriver
BOOL vncDesktop::InitVideoDriver()
{
omni_mutex_lock l(m_videodriver_lock);
if(OSVersion() != OSVERSION_2000_XP_VISTA )
return true; //we need w2k or xp
vnclog.Print(LL_INTERR, VNCLOG("Driver option is enabled"));
// If m_videodriver exist, the driver was activated.
// This does not mean he is still active
// Screen switching disable the driver at kernel level
// The pointers to the shared memory still exist, but no more memeory
// associated...This is the biggest risk when using the driver
//
/* if (!RestartDriver)
{
m_hookdriver=false;
m_hookdll=true;
return false;
}*/
// First check driver version
if (m_videodriver!=NULL)
{
vnclog.Print(LL_INTERR, VNCLOG("Closing pending driver driver version"));
if (m_videodriver!=NULL) delete m_videodriver;
}
m_videodriver=new vncVideoDriver;
//try to use the mirror driver if he is still active
/* if (m_videodriver->ExistMirrorDriver())
{
char buffer[256];
if (m_videodriver->GetDllProductVersion("vncdrv.dll",buffer,254))
{
DWORD myword;
if (strcmp(buffer,"1.00.18")<0)
{
HANDLE T1=CreateThread(NULL,0,Warningbox_non_locked,m_hwnd,0,&myword);
CloseHandle(T1);
vnclog.Print(LL_INTERR, VNCLOG("Wrong driver version"));
if (m_videodriver!=NULL) delete m_videodriver;
m_videodriver=NULL;
m_hookdriver=false;
m_hookdll=true;
m_server->Driver(false);
m_server->Hook(true);
return false;
}
}
}*/
if (m_videodriver->IsMirrorDriverActive())
{
// This should normal not happen
vnclog.Print(LL_INTERR, VNCLOG("Use active Mirror driver"));
m_videodriver->StartMirroring();
m_hookdriver=true;
m_hookdll=false;
}
else // no drivers where active, so start the mirror driver
{
Checkmonitors();
nr_monitors=GetNrMonitors();
if (nr_monitors==1)
{
m_ScreenOffsetx=mymonitor[0].offsetx;
m_ScreenOffsety=mymonitor[0].offsety;
m_videodriver->Activate_video_driver(true,mymonitor[0].offsetx,mymonitor[0].offsety,mymonitor[0].Width,mymonitor[0].Height);
}
if (nr_monitors>1)
{
m_ScreenOffsetx=mymonitor[2].offsetx;
m_ScreenOffsety=mymonitor[2].offsety;
m_videodriver->Activate_video_driver(true,m
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -