virtdisp.cpp

来自「老外的一个开源项目」· C++ 代码 · 共 1,089 行 · 第 1/3 页

CPP
1,089
字号
	HDC			dc,	dcMem;
	DWORD		dwThreadID;
	long		inaddr;	
    HBITMAP		hbm, hbmOld;
    WORD		*pwSrc, *pwDst = NULL;
	int			i, offset, cWords;
	int			cSent;
	WORD		Color, RepeatCount;
	struct {
		BITMAPINFOHEADER bmih;
		RGBQUAD rgq[256];
	} bmi;
	DWORD		dwCRC, dwOldCRC = 0xf1f1;
	CERRECTUPDATE	RectObj;
	CERPALUPDATE	PalObj;
    PALETTEENTRY PalEntry;
	

	if (DEBUG_FLAG) ShowErr (TEXT("About to do gethostbyname\r\n"));
	WideCharToMultiByte(CP_ACP, 0, v_szHostname, -1,
			szHostName, sizeof(szHostName), NULL, NULL);



	if ((inaddr = inet_addr(szHostName)) == -1L) {
		pHost = gethostbyname(szHostName);
		if (pHost) {
			/*
			 * If we find a host entry, set up the internet address
			 */
			inaddr = *(long *)pHost->h_addr;
		} else {
			ShowErr (TEXT("Can't find '%hs'\r\n"), szHostName);
			return -2;
		}

	}

	// Initialize default values
	memset ((char *)&SockAddr, 0, sizeof(SockAddr));
	SockAddr.sin_family = AF_INET;
	SockAddr.sin_port = htons((u_short)dwSockPort);
	SockAddr.sin_addr.S_un.S_addr = inaddr;

	Sock = socket (AF_INET, SOCK_STREAM, 0);
	if (INVALID_SOCKET == Sock) {
		ShowErr (TEXT("Can't create socket\r\n"));
		return -3;
	}

	if (DEBUG_FLAG) ShowErr (TEXT("About to connect, RemoteAddr=0x%X\r\n"), SockAddr.sin_addr.S_un.S_addr);
	
	Status = connect (Sock, (SOCKADDR *)&SockAddr, sizeof(SockAddr));
	if (SOCKET_ERROR == Status) {
		ShowErr (TEXT("Can't connect\r\n"));
		return -4;
	}


	if (DEBUG_FLAG) ShowErr (TEXT("Connected, Remote Addr=%hs\r\n"), inet_ntoa(SockAddr.sin_addr));

	if (send (Sock, (char *)&v_Info, sizeof(v_Info), 0) != sizeof(v_Info)) {
		DEBUGMSG (1, (TEXT("Error %d from send of Info\r\n"), WSAGetLastError()));
	}

	// Start the input thread.
	v_hInputThread = CreateThread (NULL, 0, DoInput, (LPVOID)Sock, 0, &dwThreadID);

	dc = GetDC(NULL);
	
    bmi.bmih.biSize = sizeof(bmi.bmih);
    bmi.bmih.biWidth = cXScreen;
    bmi.bmih.biHeight = -(int)cYScreen;
    bmi.bmih.biPlanes = 1;
	bmi.bmih.biBitCount = (BYTE)cScreenDepth;
    bmi.bmih.biSizeImage = 0;
    bmi.bmih.biXPelsPerMeter = 0;
    bmi.bmih.biYPelsPerMeter = 0;
    bmi.bmih.biClrUsed = 0;
    bmi.bmih.biClrImportant = 0;

	switch (cScreenDepth) {
	case 16 :
		bmi.bmih.biCompression = BI_BITFIELDS;

		// Set the bit masks

		// Before directly accessing the display memory for 16-bit displays,
		// you have to know how the display controller interprets the 16-bit color mask.
		// There are two possible flag settings: KfDirect555 and kfDirect565.
		// The 555 translates into a color mask XRRRRRGG.GGGBBBBB for Red-Green-Blue in a short variable,
		// while 565 translates into RRRRRXGG.GGGBBBBB.
		// XRRRRRGG.GGGBBBBB 0x7C00 0x03E0 0x1F
		// RRRRRXGG.GGGBBBBB 0xF800 0x03E0 0x1F
		// RRRRRGGG.GGXBBBBB 0xF800 0x07C0 0x1F (HP Device)


		// 8/15/00 changed mask to 0x07e0 since it made it work on WinME as well as NT
		*(DWORD *)(&bmi.rgq[0]) = 0xF800;
		*(DWORD *)(&bmi.rgq[1]) = 0x07e0;
		*(DWORD *)(&bmi.rgq[2]) = 0x001F;
		break;

	case 8 :
		bmi.bmih.biCompression = BI_RGB;

	    for (i=0; i < 256; i++) {
	        GetSystemPaletteEntries (dc, i, 1, &PalEntry);
	        bmi.rgq[i].rgbRed = PalEntry.peRed;
	        bmi.rgq[i].rgbGreen = PalEntry.peGreen;
	        bmi.rgq[i].rgbBlue = PalEntry.peBlue;
	        bmi.rgq[i].rgbReserved = 0;
	    }
		// We need to send the palette data to the host.
		PalObj.dwObjType = CEROBJ_PALETTE;
		PalObj.dwSize = sizeof(bmi.rgq);
		if (send (Sock, (char *)&PalObj, sizeof(PalObj), 0) != sizeof(PalObj)) {
			ShowErr (TEXT("Unable to send PalObj, Error %d\r\n"), WSAGetLastError());
			closesocket (Sock);
			Sock = INVALID_SOCKET;
			return -1;
		}
		if (send (Sock, (char *)bmi.rgq, sizeof(bmi.rgq), 0) != sizeof(bmi.rgq)) {
			ShowErr (TEXT("Unable to send Palette data, Error %d\r\n"), WSAGetLastError());
			closesocket (Sock);
			Sock = INVALID_SOCKET;
			return -1;
		}
		break;

	case 4 :	
	case 2 :
		// Assume gray-scale.
		bmi.bmih.biCompression = BI_RGB;

        if (2 == cScreenDepth) {
            // Hardcode the palette 
            bmi.rgq[0].rgbBlue = bmi.rgq[0].rgbGreen = bmi.rgq[0].rgbRed = 0x00;
            bmi.rgq[0].rgbReserved = 0x00;
            bmi.rgq[1].rgbBlue = bmi.rgq[1].rgbGreen = bmi.rgq[1].rgbRed = 0x80;
            bmi.rgq[1].rgbReserved = 0x00;
            bmi.rgq[2].rgbBlue = bmi.rgq[2].rgbGreen = bmi.rgq[2].rgbRed = 0xC0;
            bmi.rgq[2].rgbReserved = 0x00;                    
            bmi.rgq[3].rgbBlue = bmi.rgq[3].rgbGreen = bmi.rgq[3].rgbRed = 0xFF;
            bmi.rgq[3].rgbReserved = 0x00;
            for (i=4; i<16; i++) {
                bmi.rgq[i].rgbBlue = bmi.rgq[i].rgbGreen 
                                     = bmi.rgq[i].rgbRed = bmi.rgq[i].rgbReserved = 0x00;
            }
        } else {
            for (i=0; i < 16; i++) {
                bmi.rgq[i].rgbBlue = bmi.rgq[i].rgbGreen = bmi.rgq[i].rgbRed =
                    i ? (BYTE) ((0x10*i)-1) : 0;
                bmi.rgq[i].rgbReserved = 0x00;
            }
        }

		// We need to send the palette data to the host.
		// We'll send a 4 bit palette since it will get converted to a 4 bit
		// bitmap up there
		PalObj.dwObjType = CEROBJ_PALETTE;
		PalObj.dwSize = 16*sizeof(bmi.rgq[0]);
		if (send (Sock, (char *)&PalObj, sizeof(PalObj), 0) != sizeof(PalObj)) {
			ShowErr (TEXT("Unable to send PalObj, Error %d\r\n"), WSAGetLastError());
			closesocket (Sock);
			Sock = INVALID_SOCKET;
			return -1;
		}
		// Only send the first 16 palette entries
		if (send (Sock, (char *)bmi.rgq, 16*sizeof(bmi.rgq[0]), 0) != 16*sizeof(bmi.rgq[0])) {
			ShowErr (TEXT("Unable to send Palette data, Error %d\r\n"), WSAGetLastError());
			closesocket (Sock);
			Sock = INVALID_SOCKET;
			return -1;
		}
		break;
		
		
	default :
		ShowErr (TEXT("Unsupported screen depth %d, write more code\r\n"), cScreenDepth);
		closesocket (Sock);
		Sock = INVALID_SOCKET;
		return -1;
	}

	// Now map the frame buffer and start copying.
	RectObj.dwObjType = CEROBJ_RECT;
	RectObj.rect.left = 0;
	RectObj.rect.top = 0;
	RectObj.rect.right = cXScreen;
	RectObj.rect.bottom = cYScreen;

    hbm = CreateDIBSection (dc, (PBITMAPINFO)&bmi, DIB_RGB_COLORS, (PVOID *)&pwSrc, NULL, 0);

	dcMem = CreateCompatibleDC (dc);

	hbmOld = (HBITMAP)SelectObject (dcMem, (HGDIOBJ)hbm);


	// Worst case is that I need twice the original buffer for the compressed image
	pwDst = (WORD *)LocalAlloc (LMEM_FIXED, 2*cXScreen*cYScreen*cScreenDepth/8);

	if (NULL == pwDst) {
		ShowErr (TEXT("Unable to allocate destination buffer\r\n"));
		closesocket (Sock);
		Sock = INVALID_SOCKET;
		// This will skip the loop and clean up
	}
	
	cWords = (int)cXScreen*cYScreen*cScreenDepth/16;
	while (INVALID_SOCKET != Sock) {
		// Get the scren image
		BitBlt (dcMem, 0, 0, cXScreen, cYScreen, dc, 0, 0, SRCCOPY);

		// Compress the image, walk a word at a time
		offset = 0;
		for (i=0; i < cWords; ) {
			RepeatCount = 1;
			Color = pwSrc[i];
			i++;
			while ((i < cWords) && (RepeatCount < 0xF000)) {
				if (Color != pwSrc[i]) {
					break;
				}
				i++;
				RepeatCount++;
			}
			pwDst[offset++] = RepeatCount;
			pwDst[offset++] = Color;
		}


		dwCRC = ComputeCRC ((PBYTE)pwDst, offset*sizeof(WORD));
		if (dwCRC != dwOldCRC) {
			// Send the rec info
			RectObj.dwSize = offset;
			if (send (Sock, (char *)&RectObj, sizeof(RectObj), 0) != sizeof(RectObj)) {
				DEBUGMSG (1, (TEXT("Error %d from send of RectInfo\r\n"), WSAGetLastError()));
				break;
			}

			for (i=0; i < (int)(offset*sizeof(WORD)); i += cSent) {
				if (INVALID_SOCKET == Sock) {
					break;
				}
				cSent = send (Sock, ((char *)pwDst)+i, offset*sizeof(WORD)-i, 0);
				if (cSent == SOCKET_ERROR) {
					DEBUGMSG (1, (TEXT("Error %d from send of screen data\r\n"), WSAGetLastError()));
					break;
				}
			}
			if (i != (int)(offset*sizeof(WORD))) {
				break;
			}
			
			dwOldCRC = dwCRC;

			if (v_fPaletteChanged && (8 == cScreenDepth)) {
				v_fPaletteChanged = FALSE;

				for (i=0; i < 256; i++) {
					GetSystemPaletteEntries (dc, i, 1, &PalEntry);
					bmi.rgq[i].rgbRed = PalEntry.peRed;
					bmi.rgq[i].rgbGreen = PalEntry.peGreen;
					bmi.rgq[i].rgbBlue = PalEntry.peBlue;
					bmi.rgq[i].rgbReserved = 0;
				}

				// We need to send the palette data to the host.
				PalObj.dwObjType = CEROBJ_PALETTE;
				PalObj.dwSize = sizeof(bmi.rgq);
				if (send (Sock, (char *)&PalObj, sizeof(PalObj), 0) != sizeof(PalObj)) {
					//					ShowErr (TEXT("Unable to send PalObj, Error %d\r\n"), WSAGetLastError());
					break;
				}
				if (send (Sock, (char *)bmi.rgq, sizeof(bmi.rgq), 0) != sizeof(bmi.rgq)) {
					//					ShowErr (TEXT("Unable to send Palette data, Error %d\r\n"), WSAGetLastError());
					break;
				}
			}
		} else {
			dwSkip++;
		}
		
		dwTotal++;
		
		Sleep (v_dwRefreshTime);
	}

	SelectObject (dcMem, (HGDIOBJ)hbmOld);
	DeleteObject ((HGDIOBJ)hbm);
	DeleteDC (dcMem);
	ReleaseDC (NULL, dc);
	
	if (pwDst) {
		LocalFree (pwDst);
	}
	if (INVALID_SOCKET != Sock) {
		closesocket (Sock);
		Sock = INVALID_SOCKET;
	}
	if (INVALID_HANDLE_VALUE != v_hInputThread) {
		DEBUGMSG (1, (TEXT("DoConnect: Waiting for input thread to exit\r\n")));
		WaitForSingleObject (v_hInputThread, INFINITE);
		CloseHandle (v_hInputThread);
		v_hInputThread = INVALID_HANDLE_VALUE;
	}

	if (INVALID_HANDLE_VALUE != v_hConnectThread) {
		// Hey, that's me.  Just close it
		CloseHandle (v_hConnectThread);
		v_hConnectThread = INVALID_HANDLE_VALUE;
	}
//	PostMessage (v_hWnd, IDM_CHK_STAT, 0, 0);
	PostMessage (v_hWnd, WM_CLOSE, 0, 0);
	DEBUGMSG (1, (TEXT("DoConnect thread exiting\r\n")));
	return 0;
}

// Following from aygshell.h in Rapier
typedef BOOL (*LPFSHSipPreference)(HWND hwnd, SIPSTATE st);

#define SHFS_SHOWTASKBAR            0x0001
#define SHFS_HIDETASKBAR            0x0002
#define SHFS_SHOWSIPBUTTON          0x0004
#define SHFS_HIDESIPBUTTON          0x0008
#define SHFS_SHOWSTARTICON          0x0010
#define SHFS_HIDESTARTICON          0x0020

typedef BOOL (*LPFSHFullScreen)(HWND hwndRequester, DWORD dwState);

#define SHCMBF_EMPTYBAR      0x0001
#define SHCMBF_HIDDEN        0x0002 // create it hidden
#define SHCMBF_HIDESIPBUTTON 0x0004
typedef struct tagSHMENUBARINFO
{
    DWORD cbSize;               // IN  - Indicates which members of struct are valid
	HWND hwndParent;            // IN
    DWORD dwFlags;              // IN  - Some features we want
    UINT nToolBarId;            // IN  - Which toolbar are we using
    HINSTANCE hInstRes;         // IN  - Instance that owns the resources
    int nBmpId;
    int cBmpImages;             // IN  - Count of bitmap images
	HWND hwndMB;                // OUT
} SHMENUBARINFO, *PSHMENUBARINFO;

typedef BOOL  (*LPFSHCreateMenuBar)(SHMENUBARINFO *pmbi);

LPFSHSipPreference	pfSipPref = NULL;
LPFSHFullScreen		pfFullScreen = NULL;
LPFSHCreateMenuBar	pfCreateMenu = NULL;

void
InitSIPStuff ()
{
	HINSTANCE	hAYGShell;

	if (hAYGShell = LoadLibrary(TEXT("aygshell.dll"))) {
		pfSipPref = (LPFSHSipPreference)GetProcAddress (hAYGShell, TEXT("SHSipPreference"));
		pfFullScreen = (LPFSHFullScreen)GetProcAddress (hAYGShell, TEXT("SHFullScreen"));
		pfCreateMenu = (LPFSHCreateMenuBar)GetProcAddress (hAYGShell, TEXT("SHCreateMenuBar"));
		if (pfSipPref && pfFullScreen && pfCreateMenu) {
			// Must be a PocketPC app?

⌨️ 快捷键说明

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