WindowsXP/Source/XPSP1/NT/enduser/netmeeting/as/cpi32/sdp.cpp
2024-08-03 16:30:48 +02:00

387 lines
8.9 KiB
C++

#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);
}