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