📄 videodriver.cpp
字号:
}
void vncVideoDriver::Deactivate()
{
_ASSERTE(IsWinNT());
if (IsWinVerOrHigher(5, 0))
{
Deactivate_NT50();
}
else
{
Deactivate_NT46();
}
}
BOOL vncVideoDriver::Activate_NT50(
BOOL fForDirectAccess,
const RECT *prcltarget)
{
HDESK hdeskInput;
HDESK hdeskCurrent;
DISPLAY_DEVICE dd;
INT devNum = 0;
if (!LookupVideoDeviceAlt(szDriverString, szDriverStringAlt, devNum, &dd))
{
vnclog.Print(LL_INTERR, VNCLOG("No '%s' or '%s' found.\n"), szDriverString, szDriverStringAlt);
return FALSE;
}
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;
if (prcltarget)
{
// we always have to set position or
// a stale position info in registry would come into effect.
devmode.dmFields |= DM_POSITION;
devmode.dmPosition.x = prcltarget->left;
devmode.dmPosition.y = prcltarget->top;
devmode.dmPelsWidth = prcltarget->right - prcltarget->left;
devmode.dmPelsHeight = prcltarget->bottom - prcltarget->top;
}
devmode.dmDeviceName[0] = '\0';
vnclog.Print(LL_INTINFO, VNCLOG("DevNum:%d\nName:%s\nString:%s\n\n"), devNum, &dd.DeviceName[0], &dd.DeviceString[0]);
vnclog.Print(LL_INTINFO, VNCLOG("Screen Top-Left Position: (%i, %i)\n"), devmode.dmPosition.x, devmode.dmPosition.y);
vnclog.Print(LL_INTINFO, VNCLOG("Screen Dimensions: (%i, %i)\n"), devmode.dmPelsWidth, devmode.dmPelsHeight);
vnclog.Print(LL_INTINFO, VNCLOG("Screen Color depth: %i\n"), devmode.dmBitsPerPel);
HKEY hKeyDevice = CreateDeviceKey(szMiniportName);
if (hKeyDevice == NULL)
return FALSE;
// TightVNC does not use these features
RegDeleteValue(hKeyDevice, ("Screen.ForcedBpp"));
RegDeleteValue(hKeyDevice, ("Pointer.Enabled"));
DWORD dwVal = fForDirectAccess ? 3 : 0;
// NOTE that old driver ignores it and mapping is always ON with it
if (RegSetValueEx(
hKeyDevice,
("Cap.DfbBackingMode"),
0,
REG_DWORD,
(unsigned char *)&dwVal,
4) != ERROR_SUCCESS)
{
vnclog.Print(LL_INTERR, VNCLOG("Can't set \"Cap.DfbBackingMode\" to %d\n"), dwVal);
return FALSE;
}
dwVal = 1;
if (RegSetValueEx(
hKeyDevice,
("Order.BltCopyBits.Enabled"),
0,
REG_DWORD,
(unsigned char *)&dwVal,
4) != ERROR_SUCCESS)
{
vnclog.Print(LL_INTERR, VNCLOG("Can't set Order.BltCopyBits.Enabled to %d\n"), dwVal);
return FALSE;
}
dwVal = 1;
if (RegSetValueEx(
hKeyDevice,
("Attach.ToDesktop"),
0,
REG_DWORD,
(unsigned char *)&dwVal,
4) != ERROR_SUCCESS)
{
vnclog.Print(LL_INTERR, VNCLOG("Can't set Attach.ToDesktop to %d\n"), dwVal);
return FALSE;
}
pChangeDisplaySettingsEx pCDS = NULL;
HINSTANCE hInstUser32 = LoadNImport("User32.DLL", "ChangeDisplaySettingsExA", pCDS);
if (!hInstUser32) return FALSE;
// Save the current desktop
hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
if (hdeskCurrent != NULL)
{
hdeskInput = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
if (hdeskInput != NULL)
SetThreadDesktop(hdeskInput);
}
// 24 bpp screen mode is MUNGED to 32 bpp.
// the underlying buffer format must be 32 bpp.
// see vncDesktop::ThunkBitmapInfo()
if (devmode.dmBitsPerPel==24) devmode.dmBitsPerPel = 32;
LONG cr = (*pCDS)(
(TCHAR *)dd.DeviceName,
&devmode,
NULL,
CDS_UPDATEREGISTRY,NULL);
if (cr != DISP_CHANGE_SUCCESSFUL)
{
vnclog.Print(
LL_INTERR,
VNCLOG("ChangeDisplaySettingsEx failed on device \"%s\" with status: 0x%x\n"),
dd.DeviceName,
cr);
}
strcpy(m_devname, (const char *)dd.DeviceName);
// Reset desktop
SetThreadDesktop(hdeskCurrent);
// Close the input desktop
CloseDesktop(hdeskInput);
RegCloseKey(hKeyDevice);
FreeLibrary(hInstUser32);
return TRUE;
}
BOOL vncVideoDriver::Activate_NT46(BOOL fForDirectAccess)
{
HKEY hKeyDevice = CreateDeviceKey(szMiniportName);
if (hKeyDevice == NULL)
return FALSE;
// TightVNC does not use these features
RegDeleteValue(hKeyDevice, ("Screen.ForcedBpp"));
RegDeleteValue(hKeyDevice, ("Pointer.Enabled"));
DWORD dwVal = fForDirectAccess ? 3 : 0;
// NOTE that old driver ignores it and mapping is always ON with it
if (RegSetValueEx(
hKeyDevice,
("Cap.DfbBackingMode"),
0,
REG_DWORD,
(unsigned char *)&dwVal,
4) != ERROR_SUCCESS)
{
vnclog.Print(LL_INTERR, VNCLOG("Can't set \"Cap.DfbBackingMode\" to %d\n"), dwVal);
return FALSE;
}
dwVal = 1;
if (RegSetValueEx(
hKeyDevice,
("Order.BltCopyBits.Enabled"),
0,
REG_DWORD,
(unsigned char *)&dwVal,
4) != ERROR_SUCCESS)
{
vnclog.Print(LL_INTERR, VNCLOG("Can't set Order.BltCopyBits.Enabled to %d\n"), dwVal);
return FALSE;
}
// NOTE: we cannot truly load the driver
// but ChangeDisplaySettings makes PDEV to reload
// and thus new settings come into effect
// TODO
strcpy(m_devname, "DISPLAY");
RegCloseKey(hKeyDevice);
return TRUE;
}
void vncVideoDriver::Deactivate_NT50()
{
HDESK hdeskInput;
HDESK hdeskCurrent;
// it is important to us to be able to deactivate
// even what we have never activated. thats why we look it up, all over
// if (!m_devname[0])
// return;
// ... and forget the name
*m_devname = 0;
DISPLAY_DEVICE dd;
INT devNum = 0;
if (!LookupVideoDeviceAlt(szDriverString, szDriverStringAlt, devNum, &dd))
{
vnclog.Print(LL_INTERR, VNCLOG("No '%s' or '%s' found.\n"), szDriverString, szDriverStringAlt);
return;
}
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;
devmode.dmDeviceName[0] = '\0';
HKEY hKeyDevice = CreateDeviceKey(szMiniportName);
if (hKeyDevice == NULL)
return;
DWORD one = 0;
if (RegSetValueEx(hKeyDevice,("Attach.ToDesktop"), 0, REG_DWORD, (unsigned char *)&one,4) != ERROR_SUCCESS)
{
vnclog.Print(LL_INTERR, VNCLOG("Can't set Attach.ToDesktop to 0x1\n"));
}
// reverting to default behavior
RegDeleteValue(hKeyDevice, ("Cap.DfbBackingMode"));
RegDeleteValue(hKeyDevice, ("Order.BltCopyBits.Enabled"));
pChangeDisplaySettingsEx pCDS = NULL;
HINSTANCE hInstUser32 = LoadNImport("User32.DLL", "ChangeDisplaySettingsExA", pCDS);
if (!hInstUser32) return;
// Save the current desktop
hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
if (hdeskCurrent != NULL)
{
hdeskInput = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
if (hdeskInput != NULL)
SetThreadDesktop(hdeskInput);
}
// 24 bpp screen mode is MUNGED to 32 bpp. see vncDesktop::ThunkBitmapInfo()
if (devmode.dmBitsPerPel==24) devmode.dmBitsPerPel = 32;
// Add 'Default.*' settings to the registry under above hKeyProfile\mirror\device
(*pCDS)((TCHAR *)dd.DeviceName, &devmode, NULL, CDS_UPDATEREGISTRY, NULL);
// Reset desktop
SetThreadDesktop(hdeskCurrent);
// Close the input desktop
CloseDesktop(hdeskInput);
RegCloseKey(hKeyDevice);
FreeLibrary(hInstUser32);
}
void vncVideoDriver::Deactivate_NT46()
{
// ... and forget the name
*m_devname = 0;
HKEY hKeyDevice = CreateDeviceKey(szMiniportName);
if (hKeyDevice == NULL)
return;
// reverting to default behavior
RegDeleteValue(hKeyDevice, ("Cap.DfbBackingMode"));
// RegDeleteValue(hKeyDevice, ("Order.BltCopyBits.Enabled"));
// TODO: remove "Order.BltCopyBits.Enabled"
// now we don't touch this important option
// because we dont apply the changed values
RegCloseKey(hKeyDevice);
}
void vncVideoDriver::HandleDriverChanges(
vncDesktop *pDesk,
vncRegion &rgn,
int xoffset,
int yoffset,
BOOL &bPointerShapeChange)
{
ULONG snapshot_counter = bufdata.buffer->counter;
if (oldCounter == snapshot_counter)
return;
if (oldCounter < snapshot_counter)
{
HandleDriverChangesSeries(
pDesk,
rgn,
xoffset, yoffset,
bufdata.buffer->pointrect + oldCounter,
bufdata.buffer->pointrect + snapshot_counter,
bPointerShapeChange);
}
else
{
HandleDriverChangesSeries(
pDesk,
rgn,
xoffset, yoffset,
bufdata.buffer->pointrect + oldCounter,
bufdata.buffer->pointrect + MAXCHANGES_BUF,
bPointerShapeChange);
HandleDriverChangesSeries(
pDesk,
rgn,
xoffset, yoffset,
bufdata.buffer->pointrect,
bufdata.buffer->pointrect + snapshot_counter,
bPointerShapeChange);
}
oldCounter = snapshot_counter;
}
void vncVideoDriver::HandleDriverChangesSeries(
vncDesktop *pDesk,
vncRegion &rgn,
int xoffset,
int yoffset,
const CHANGES_RECORD *i,
const CHANGES_RECORD *last,
BOOL &bPointerShapeChange)
{
for (; i < last; i++)
{
// TODO bPointerShapeChange
if (m_fHandleScreen2ScreenBlt && i->type == dmf_dfo_SCREEN_SCREEN)
{
// DPF(("CopyRect: (%d, %d, %d, %d)\n",
// i->rect.left,
// i->rect.top,
// i->rect.right,
// i->rect.bottom));
RECT Rc;
Rc.left = i->rect.left + xoffset;
Rc.top = i->rect.top + yoffset;
Rc.right = i->rect.right + xoffset;
Rc.bottom = i->rect.bottom + yoffset;
POINT Pt;
Pt.x = i->point.x + xoffset;
Pt.y = i->point.y + yoffset;
pDesk->CopyRect(Rc, Pt);
continue;
}
if (i->type >= dmf_dfo_SCREEN_SCREEN && i->type <= dmf_dfo_TEXTOUT)
{
// DPF(("XRect: (%d, %d, %d, %d)\n",
// i->rect.left,
// i->rect.top,
// i->rect.right,
// i->rect.bottom));
rgn.AddRect(i->rect, xoffset, yoffset);
}
}
}
VOID DebugPrint(PCHAR DebugMessage,
...)
{
va_list ap;
va_start(ap, DebugMessage);
TCHAR pb[256];
vsprintf(pb, DebugMessage, ap);
va_end(ap);
OutputDebugString(pb);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -