⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 videodriver.cpp

📁 Web VNC samples delphi
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

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 + -