|
|
#include "precomp.h"
//
// SDP.CPP
// Screen Data Player
//
// Copyright(c) Microsoft 1997-
//
#define MLZ_FILE_ZONE ZONE_CORE
//
// SDP_ReceivedPacket()
//
void ASShare::SDP_ReceivedPacket ( ASPerson * pasPerson, PS20DATAPACKET pPacket ) { PSDPACKET pBitmap; LPBYTE pBits; RECT rectRDB; HRGN regionRDB = NULL;
DebugEntry(ASShare::SDP_ReceivedPacket);
ValidateView(pasPerson);
ASSERT(m_usrPBitmapBuffer);
pBitmap = (PSDPACKET)pPacket;
//
// At some point, we'd like to be able to pass an ARRAY of screen
// data blocks, if they'd fit in a packet of size TSHR_MAX_SEND_PKT
//
ASSERT(pBitmap->header.padding == 0);
//
// Now try to decompress the packet.
//
if (pBitmap->compressed) { if (!BD_DecompressBitmap(&(pBitmap->data[0]), m_usrPBitmapBuffer, pBitmap->dataSize, pBitmap->realWidth, pBitmap->realHeight, pBitmap->format)) { //
// Could not decompress.
//
ERROR_OUT(( "Could not decompress")); DC_QUIT; } else { pBits = m_usrPBitmapBuffer; } } else { pBits = pBitmap->data; }
//
// The position (like all protocol coordinates) is specified in virtual
// desktop coordinates. Convert it to RDB coordinates.
//
RECT_FROM_TSHR_RECT16(&rectRDB, pBitmap->position); OffsetRect(&rectRDB, -pasPerson->m_pView->m_dsScreenOrigin.x, -pasPerson->m_pView->m_dsScreenOrigin.y);
TRACE_OUT(("Received screen data rect {%d, %d, %d, %d}", rectRDB.left, rectRDB.top, rectRDB.right, rectRDB.bottom ));
//
// We must ensure that data written to the ScreenBitmap is not clipped
// (any orders processed earlier will have used clipping).
//
OD_ResetRectRegion(pasPerson);
//
// Play screen data into the remote desktop bitmap.
//
SDPPlayScreenDataToRDB(pasPerson, pBitmap, pBits, &rectRDB);
//
// Construct a region equivalent to the update rectangle in RDB coords.
// INCLUSIVE COORDS
//
regionRDB = CreateRectRgn(rectRDB.left, rectRDB.top, rectRDB.right + 1, rectRDB.bottom + 1); if (regionRDB == NULL) { ERROR_OUT(( "Failed to create region")); DC_QUIT; }
//
// Hatch the bitmap data area, if enabled.
//
if (m_usrHatchScreenData) { SDPDrawHatchedRegion(pasPerson->m_pView->m_usrDC, regionRDB, USR_HATCH_COLOR_RED ); }
//
// Now pass the region we have updated to the SWP. (We must convert it
// back to VD coordinates before we pass it
//
OffsetRgn(regionRDB, pasPerson->m_pView->m_dsScreenOrigin.x, pasPerson->m_pView->m_dsScreenOrigin.y);
VIEW_InvalidateRgn(pasPerson, regionRDB);
DC_EXIT_POINT: if (regionRDB != NULL) { //
// Free the region.
//
DeleteRgn(regionRDB); }
DebugExitVOID(ASShare::SDP_ReceivedPacket); }
//
// FUNCTION: SDPDrawHatchedRegion(...)
//
// DESCRIPTION:
//
// Draws a hatched region on the specified surface in the given color.
//
// PARAMETERS:
//
// surface - the surface to draw on
//
// region - the region to hatch
//
// hatchColor - the color to hatch in
//
// RETURNS: Nothing.
//
//
void ASShare::SDPDrawHatchedRegion ( HDC hdc, HRGN region, UINT hatchColor ) { HBRUSH hbrHatch; UINT brushStyle; UINT oldBkMode; UINT oldRop2; POINT oldOrigin; COLORREF hatchColorRef = 0;
DebugEntry(ASShare::SDPDrawHatchedRegion);
//
// Set the brush style to the appropriate value.
//
switch (hatchColor) { case USR_HATCH_COLOR_RED: { brushStyle = HS_BDIAGONAL; } break;
case USR_HATCH_COLOR_BLUE: { brushStyle = HS_FDIAGONAL; } break;
default: { brushStyle = HS_BDIAGONAL; } break; }
//
// Cycle the color to use. Note that the hatchColor parameter is now
// in fact just used to set the hatching direction.
//
m_usrHatchColor++; m_usrHatchColor %= 7; switch (m_usrHatchColor) { case 0: hatchColorRef = RGB(0xff,0x00,0x00); break; case 1: hatchColorRef = RGB(0x00,0xff,0x00); break; case 2: hatchColorRef = RGB(0xff,0xff,0x00); break; case 3: hatchColorRef = RGB(0x00,0x00,0xff); break; case 4: hatchColorRef = RGB(0xff,0x00,0xff); break; case 5: hatchColorRef = RGB(0x00,0xff,0xff); break; case 6: hatchColorRef = RGB(0xff,0xff,0xff); break; }
//
// Create the brush, set the background mode etc.
//
hbrHatch = CreateHatchBrush(brushStyle, hatchColorRef); oldBkMode = SetBkMode(hdc, TRANSPARENT); oldRop2 = SetROP2(hdc, R2_COPYPEN); SetBrushOrgEx(hdc, 0, 0, &oldOrigin);
//
// Fill the region.
//
FillRgn(hdc, region, hbrHatch);
//
// Reset everything.
//
SetBrushOrgEx(hdc, oldOrigin.x, oldOrigin.y, NULL); SetROP2(hdc, oldRop2); SetBkMode(hdc, oldBkMode); DeleteBrush(hbrHatch);
DebugExitVOID(ASShare::SDPDrawHatchedRegion); }
//
//
// SDPPlayScreenDataToRDB()
//
// DESCRIPTION:
//
// Play the contents of a screen data packet into the specified person ID's
// remote desktop bitmap.
//
// PARAMETERS:
//
// personID - ID of person whose RDB is the target for the screen data
// pBitmapUpdate - pointer to protocol update packet
// pBits - pointer to uncompressed screen data
// pPosition - returns updated rectangle in RDB coordinates
//
// RETURNS:
//
// None
//
//
void ASShare::SDPPlayScreenDataToRDB ( ASPerson * pasPerson, PSDPACKET pBitmap, LPBYTE pBits, LPRECT pRectRDB ) { UINT width; UINT height; HPALETTE hOldPalette; LPTSHR_UINT16 pIndexTable; UINT cColors; UINT i; BITMAPINFO_ours bitmapInfo; UINT dibFormat;
DebugEntry(ASShare::SDPPlayScreenDataToRDB);
ValidateView(pasPerson);
//
// Calculate the extent of the actual area to be updated. This is an
// area less than or equal to the stock DIB allocated to contain it and
// is defined in the position field of the bitmap packet.
//
width = pRectRDB->right - pRectRDB->left + 1; height = pRectRDB->bottom - pRectRDB->top + 1;
//
// Put the DIB data into a Device Dependent bitmap.
//
USR_InitDIBitmapHeader((BITMAPINFOHEADER *)&bitmapInfo, pBitmap->format);
bitmapInfo.bmiHeader.biWidth = pBitmap->realWidth; bitmapInfo.bmiHeader.biHeight = pBitmap->realHeight;
//
// Select and realize the current remote palette into the device
// context.
//
hOldPalette = SelectPalette(pasPerson->m_pView->m_usrDC, pasPerson->pmPalette, FALSE); RealizePalette(pasPerson->m_pView->m_usrDC);
//
// The DIB_PAL_COLORS option requires a table of indexes into the
// currently selected palette to follow the bmi header (in place of the
// color table).
//
if (pBitmap->format <= 8) { pIndexTable = (LPTSHR_UINT16)&(bitmapInfo.bmiColors[0]); cColors = (1 << pBitmap->format); for (i = 0; i < cColors; i++) { *pIndexTable++ = (TSHR_UINT16)i; }
dibFormat = DIB_PAL_COLORS; } else { dibFormat = DIB_RGB_COLORS; }
//
// We go from the bitmap to the screen bitmap in one go.
//
if (!StretchDIBits(pasPerson->m_pView->m_usrDC, pRectRDB->left, pRectRDB->top, width, height, 0, 0, width, height, pBits, (BITMAPINFO *)&bitmapInfo, dibFormat, SRCCOPY)) { ERROR_OUT(( "StretchDIBits failed")); }
//
// Reinstate the old palette.
//
SelectPalette(pasPerson->m_pView->m_usrDC, hOldPalette, FALSE);
DebugExitVOID(ASShare::SDPPlayScreenDataToRDB); }
//
// SDP_DrawHatchedRect(...)
//
void ASShare::SDP_DrawHatchedRect ( HDC surface, int x, int y, int width, int height, UINT color ) { HRGN hrgn;
DebugEntry(ASShare::SDP_DrawHatchedRect);
//
// Create the exclusive region.
//
hrgn = CreateRectRgn(x, y, x + width, y + height); if (hrgn) { //
// Now draw the hatched region.
//
SDPDrawHatchedRegion(surface, hrgn, color);
//
// Finally delete the region.
//
DeleteRgn(hrgn); }
DebugExitVOID(ASShare::SDP_DrawHatchedRect); }
|