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

📄 vncdesktop.cpp

📁 teamviewer source code vc++
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		vnclog.Print(LL_INTERR, VNCLOG("unable to get display format"));
		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"));
		return FALSE;
	}
	vnclog.Print(LL_INTINFO, VNCLOG("got bitmap format"));

	// 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"),
			(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);
		m_bminfo.bmi.bmiHeader.biClrImportant = 0;
		m_bminfo.truecolour = FALSE;

		// Display format is non-VNC compatible - use the slow blit method
		m_formatmunged = TRUE;
		break;	
	case 24:
		// Update the bitmapinfo header
		m_bminfo.bmi.bmiHeader.biBitCount = 32;
		m_bminfo.bmi.bmiHeader.biPlanes = 1;
		m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;
		m_bminfo.bmi.bmiHeader.biSizeImage =
			abs((m_bminfo.bmi.bmiHeader.biWidth *
				m_bminfo.bmi.bmiHeader.biHeight *
				m_bminfo.bmi.bmiHeader.biBitCount)/ 8);
		// Display format is non-VNC compatible - use the slow blit method
		m_formatmunged = TRUE;
		break;
	}

	return TRUE;
}

BOOL
vncDesktop::SetPixFormat()
{
 // If we are using a memory bitmap then check how many planes it uses
  // The VNC code can only handle formats with a single plane (CHUNKY pixels)
  if (!m_DIBbits) {
	  vnclog.Print(LL_INTINFO, VNCLOG("DBG:display context has %d planes!"),
      GetDeviceCaps(m_hrootdc, PLANES));
	  vnclog.Print(LL_INTINFO, VNCLOG("DBG:memory context has %d planes!"),
      GetDeviceCaps(m_hmemdc, PLANES));
	  if (GetDeviceCaps(m_hmemdc, PLANES) != 1)
	  {
		  MessageBox(
			  NULL,
			  "vncDesktop : current display is PLANAR, not CHUNKY!\n"
			  "WinVNC cannot be used with this graphics device driver",
			  szAppName,
			  MB_ICONSTOP | MB_OK
			  );
		  return FALSE;
	  }
  }
	
	
	// Examine the bitmapinfo structure to obtain the current pixel format
	m_scrinfo.format.trueColour = m_bminfo.truecolour;
	m_scrinfo.format.bigEndian = 0;

	// Set up the native buffer width, height and format
	m_scrinfo.framebufferWidth = (CARD16) (m_bmrect.br.x - m_bmrect.tl.x);		// Swap endian before actually sending
	m_scrinfo.framebufferHeight = (CARD16) (m_bmrect.br.y - m_bmrect.tl.y);	// Swap endian before actually sending
	m_scrinfo.format.bitsPerPixel = (CARD8) m_bminfo.bmi.bmiHeader.biBitCount;
	m_scrinfo.format.depth        = (CARD8) m_bminfo.bmi.bmiHeader.biBitCount;

	// Calculate the number of bytes per row
	m_bytesPerRow = m_scrinfo.framebufferWidth * m_scrinfo.format.bitsPerPixel / 8;

	return TRUE;
}

BOOL
vncDesktop::SetPixShifts()
{
	// Sort out the colour shifts, etc.
	DWORD redMask=0, blueMask=0, greenMask = 0;

	switch (m_bminfo.bmi.bmiHeader.biBitCount)
	{
	case 16:
		// Standard 16-bit display
		if (m_bminfo.bmi.bmiHeader.biCompression == BI_RGB)
		{
			// each word single pixel 5-5-5
			redMask = 0x7c00; greenMask = 0x03e0; blueMask = 0x001f;
		}
		else
		{
			if (m_bminfo.bmi.bmiHeader.biCompression == BI_BITFIELDS)
			{
				redMask =   *(DWORD *) &m_bminfo.bmi.bmiColors[0];
				greenMask = *(DWORD *) &m_bminfo.bmi.bmiColors[1];
				blueMask =  *(DWORD *) &m_bminfo.bmi.bmiColors[2];
			}
		}
		break;

	case 32:
		// Standard 24/32 bit displays
		if (m_bminfo.bmi.bmiHeader.biCompression == BI_RGB)
		{
			redMask = 0xff0000; greenMask = 0xff00; blueMask = 0x00ff;
		}
		else
		{
			if (m_bminfo.bmi.bmiHeader.biCompression == BI_BITFIELDS)
			{
				redMask =   *(DWORD *) &m_bminfo.bmi.bmiColors[0];
				greenMask = *(DWORD *) &m_bminfo.bmi.bmiColors[1];
				blueMask =  *(DWORD *) &m_bminfo.bmi.bmiColors[2];
			}
		}
		break;

	default:
		// Other pixel formats are only valid if they're palette-based
		if (m_bminfo.truecolour)
		{
			vnclog.Print(LL_INTERR, VNCLOG("unsupported truecolour pixel format for setpixshifts"));
			return FALSE;
		}
		return TRUE;
	}

	// Convert the data we just retrieved
	MaskToMaxAndShift(redMask, m_scrinfo.format.redMax, m_scrinfo.format.redShift);
	MaskToMaxAndShift(greenMask, m_scrinfo.format.greenMax, m_scrinfo.format.greenShift);
	MaskToMaxAndShift(blueMask, m_scrinfo.format.blueMax, m_scrinfo.format.blueShift);

	return TRUE;
}

BOOL
vncDesktop::SetPalette()
{
	// Lock the current display palette into the memory DC we're holding
	// *** CHECK THIS FOR LEAKS!
	if (!m_bminfo.truecolour)
	{
		if (!m_DIBbits)
		{
			// - Handle the palette for a non DIB-Section
			
			LOGPALETTE *palette;
			UINT size = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
			
			palette = (LOGPALETTE *) new char[size];
			if (palette == NULL) {
				vnclog.Print(LL_INTERR, VNCLOG("unable to allocate logical palette"));
				return FALSE;
			}
			
			// Initialise the structure
			palette->palVersion = 0x300;
			palette->palNumEntries = 256;
			
			// Get the system colours
			if (GetSystemPaletteEntries(m_hrootdc,
				0, 256, palette->palPalEntry) == 0)
			{
				vnclog.Print(LL_INTERR, VNCLOG("unable to get system palette entries"));
				delete [] palette;
				return FALSE;
			}
			
			// Create a palette from those
			HPALETTE pal = CreatePalette(palette);
			if (pal == NULL)
			{
				vnclog.Print(LL_INTERR, VNCLOG("unable to create HPALETTE"));
				delete [] palette;
				return FALSE;
			}
			
			// Select the palette into our memory DC
			HPALETTE oldpalette = SelectPalette(m_hmemdc, pal, FALSE);
			if (oldpalette == NULL)
			{
				vnclog.Print(LL_INTERR, VNCLOG("unable to select() HPALETTE"));
				delete [] palette;
				DeleteObject(pal);
				return FALSE;
			}
			
			// Worked, so realise the palette
			if (RealizePalette(m_hmemdc) == GDI_ERROR)
				vnclog.Print(LL_INTWARN, VNCLOG("warning - failed to RealizePalette"));
			
			// It worked!
			delete [] palette;
			DeleteObject(oldpalette);
			
			vnclog.Print(LL_INTINFO, VNCLOG("initialised palette OK"));
			return TRUE;
		}
		else
		{
			// - Handle a DIB-Section's palette
			
			// - Fetch the system palette for the framebuffer
			PALETTEENTRY syspalette[256];
			UINT entries = ::GetSystemPaletteEntries(m_hrootdc, 0, 256, syspalette);
			vnclog.Print(LL_INTERR, VNCLOG("framebuffer has %u palette entries"), entries);
			
			// - Store it and convert it to RGBQUAD format
			RGBQUAD dibpalette[256];
			unsigned int i;
			for (i=0;i<entries;i++) {
				dibpalette[i].rgbRed = syspalette[i].peRed;
				dibpalette[i].rgbGreen = syspalette[i].peGreen;
				dibpalette[i].rgbBlue = syspalette[i].peBlue;
				dibpalette[i].rgbReserved = 0;
			}
			
			// - Set the rest of the palette to something nasty but usable
			for (i=entries;i<256;i++) {
				dibpalette[i].rgbRed = i % 2 ? 255 : 0;
				dibpalette[i].rgbGreen = i/2 % 2 ? 255 : 0;
				dibpalette[i].rgbBlue = i/4 % 2 ? 255 : 0;
				dibpalette[i].rgbReserved = 0;
			}
			
			// - Update the DIB section to use the same palette
			HDC bitmapDC=::CreateCompatibleDC(m_hrootdc);
			if (!bitmapDC) {
				vnclog.Print(LL_INTERR, VNCLOG("unable to create temporary DC"), GetLastError());
				return FALSE;
			}
			HBITMAP old_bitmap = (HBITMAP)::SelectObject(bitmapDC, m_membitmap);
			if (!old_bitmap) {
				vnclog.Print(LL_INTERR, VNCLOG("unable to select DIB section into temporary DC"), GetLastError());
				return FALSE;
			}
			UINT entries_set = ::SetDIBColorTable(bitmapDC, 0, 256, dibpalette);
			if (entries_set == 0) {
				vnclog.Print(LL_INTERR, VNCLOG("unable to set DIB section palette"), GetLastError());
				return FALSE;
			}
			if (!::SelectObject(bitmapDC, old_bitmap)) {
				vnclog.Print(LL_INTERR, VNCLOG("unable to restore temporary DC bitmap"), GetLastError());
				return FALSE;
			}
		}
    }
 
	// Not a palette based local screen - forget it!
	vnclog.Print(LL_INTERR, VNCLOG("no palette data for truecolour display"));
	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
DWORD WINAPI Driverwatch(LPVOID lpParam)
{
	//Mouse shape changed
	if(OSVersion() == OSVERSION_2000_XP_VISTA)
	{
		HANDLE event;
		//DrvWatch *mywatch=(DrvWatch*)lpParam;
		HWND hwnd=(HWND)lpParam;
		event=NULL;
		while (event==NULL)
		{
			event = OpenEvent (SYNCHRONIZE, FALSE, "VncEvent") ;
			Sleep(900);
			if (!IsWindow(hwnd)) 
			{
				if (event) CloseHandle(event);
				return 0;
			}
		}
		SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
		for (;;)
		{
		if (WaitForSingleObject(event, 2000) == WAIT_OBJECT_0)
			{
				PostMessage(hwnd, WM_USER, 0, 0);
			}
		if (!IsWindow(hwnd) || !g_Desktop_running)
		{
			if (event) CloseHandle(event);
			break;
		}
		}
	}
	return 0;
}
////////////////////////////////////////////////////////////////////////////////
DWORD WINAPI Driverwatch2(LPVOID lpParam)
{
	//new screen update
	if(OSVersion() == OSVERSION_2000_XP_VISTA)
	{
		HANDLE event;
		//DrvWatch *mywatch=(DrvWatch*)lpParam;
		HWND hwnd=(HWND)lpParam;
		event=NULL;
		while (event==NULL)
		{
			event = OpenEvent (SYNCHRONIZE, FALSE, "VncEvent2") ;
			Sleep(900);
			if (!IsWindow(hwnd)) 
			{
				if (event) CloseHandle(event);
				return 0;
			}
		}
		SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
		counterwatch=0;
		for (;;)
		{
		if (WaitForSingleObject(event, 50) == WAIT_OBJECT_0)
			{
				//if (!g_update_triggered)
				PostMessage(hwnd, WM_TIMER, 0, 0);
				Sleep(100);
			}
		else
			{
				counterwatch++;
				if (counterwatch==100)
					{
						PostMessage(hwnd, WM_USER+2, 0, 0);
						counterwatch=0;
				}
			}
		if (!IsWindow(hwnd) || !g_Desktop_running) 
			{
				if (event) CloseHandle(event);
				break;
			}
		}
	}
	return 0;
}
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK DesktopWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);

ATOM m_wndClass = 0;

BOOL
vncDesktop::InitWindow()
{
	if (m_wndClass == 0) {
		// Create the window class
		WNDCLASSEX wndclass;

		wndclass.cbSize			= sizeof(wndclass);
		wndclass.style			= 0;
		wndclass.lpfnWndProc	= &DesktopWndProc;
		wndclass.cbClsExtra		= 0;
		wndclass.cbWndExtra		= 0;
		wndclass.hInstance		= hAppInstance;
		wndclass.hIcon			= NULL;
		wndclass.hCursor		= NULL;
		wndclass.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
		wndclass.lpszMenuName	= (const char *) NULL;
		wndclass.lpszClassName	= szDesktopSink;
		wndclass.hIconSm		= NULL;

		// Register it
		m_wndClass = RegisterClassEx(&wndclass);
		if (!m_wndClass) {
			vnclog.Print(LL_INTERR, VNCLOG("failed to register window class"));
			return FALSE;
		}
	}

	// And create a window
	m_hwnd = CreateWindow(szDesktopSink,
				"WinVNC",
				WS_OVERLAPPEDWINDOW,
				CW_USEDEFAULT,
				CW_USEDEFAULT,
				400, 200,
				NULL,
				NULL,
				hAppInstance,
				NULL);

	if (m_hwnd == NULL) {
		vnclog.Print(LL_INTERR, VNCLOG("failed to create hook window"));
		return FALSE;
	}

	// Set the "this" pointer for the window
	SetWindowLong(m_hwnd, GWL_USERDATA, (long)this);

	// Enable clipboard hooking
	m_hnextviewer = SetClipboardViewer(m_hwnd);
	StopDriverWatches=false;
		DrvWatch mywatch;
		mywatch.stop=&StopDriverWatches;
		mywatch.hwnd=m_hwnd;
	if (VideoBuffer())
	{
		DWORD myword;
		HANDLE T1=CreateThread(NULL,0,Driverwatch,m_hwnd,0,&myword);
//		HANDLE T2=CreateThread(NULL,0,Driverwatch2,m_hwnd,0,&myword);
//		CloseHandle(T2);
		CloseHandle(T1);
	}

	return TRUE;
}

void
vncDesktop::EnableOptimisedBlits()
{
	vnclog.Print(LL_INTINFO, VNCLOG("attempting to enable DIBsection blits"));

	// Create a new DIB section
	//HBITMAP tempbitmap=NULL;
	HBITMAP tempbitmap = CreateDIBSection(m_hmemdc, &m_bminfo.bmi, DIB_RGB_COLORS, &m_DIBbits, NULL, 0);
	if (tempbitmap == NULL) {
		vnclog.Print(LL_INTINFO, VNCLOG("failed to build DIB section - reverting to slow blits"));
		m_DIBbits = NULL;
		return;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -