Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

386 lines
9.2 KiB

  1. #include "precomp.h"
  2. //
  3. // SDP.CPP
  4. // Screen Data Player
  5. //
  6. // Copyright(c) Microsoft 1997-
  7. //
  8. #define MLZ_FILE_ZONE ZONE_CORE
  9. //
  10. // SDP_ReceivedPacket()
  11. //
  12. void ASShare::SDP_ReceivedPacket
  13. (
  14. ASPerson * pasPerson,
  15. PS20DATAPACKET pPacket
  16. )
  17. {
  18. PSDPACKET pBitmap;
  19. LPBYTE pBits;
  20. RECT rectRDB;
  21. HRGN regionRDB = NULL;
  22. DebugEntry(ASShare::SDP_ReceivedPacket);
  23. ValidateView(pasPerson);
  24. ASSERT(m_usrPBitmapBuffer);
  25. pBitmap = (PSDPACKET)pPacket;
  26. //
  27. // At some point, we'd like to be able to pass an ARRAY of screen
  28. // data blocks, if they'd fit in a packet of size TSHR_MAX_SEND_PKT
  29. //
  30. ASSERT(pBitmap->header.padding == 0);
  31. //
  32. // Now try to decompress the packet.
  33. //
  34. if (pBitmap->compressed)
  35. {
  36. if (!BD_DecompressBitmap(&(pBitmap->data[0]), m_usrPBitmapBuffer,
  37. pBitmap->dataSize, pBitmap->realWidth, pBitmap->realHeight,
  38. pBitmap->format))
  39. {
  40. //
  41. // Could not decompress.
  42. //
  43. ERROR_OUT(( "Could not decompress"));
  44. DC_QUIT;
  45. }
  46. else
  47. {
  48. pBits = m_usrPBitmapBuffer;
  49. }
  50. }
  51. else
  52. {
  53. pBits = pBitmap->data;
  54. }
  55. //
  56. // The position (like all protocol coordinates) is specified in virtual
  57. // desktop coordinates. Convert it to RDB coordinates.
  58. //
  59. RECT_FROM_TSHR_RECT16(&rectRDB, pBitmap->position);
  60. OffsetRect(&rectRDB, -pasPerson->m_pView->m_dsScreenOrigin.x,
  61. -pasPerson->m_pView->m_dsScreenOrigin.y);
  62. TRACE_OUT(("Received screen data rect {%d, %d, %d, %d}",
  63. rectRDB.left,
  64. rectRDB.top,
  65. rectRDB.right,
  66. rectRDB.bottom ));
  67. //
  68. // We must ensure that data written to the ScreenBitmap is not clipped
  69. // (any orders processed earlier will have used clipping).
  70. //
  71. OD_ResetRectRegion(pasPerson);
  72. //
  73. // Play screen data into the remote desktop bitmap.
  74. //
  75. SDPPlayScreenDataToRDB(pasPerson, pBitmap, pBits, &rectRDB);
  76. //
  77. // Construct a region equivalent to the update rectangle in RDB coords.
  78. // INCLUSIVE COORDS
  79. //
  80. regionRDB = CreateRectRgn(rectRDB.left, rectRDB.top,
  81. rectRDB.right + 1, rectRDB.bottom + 1);
  82. if (regionRDB == NULL)
  83. {
  84. ERROR_OUT(( "Failed to create region"));
  85. DC_QUIT;
  86. }
  87. //
  88. // Hatch the bitmap data area, if enabled.
  89. //
  90. if (m_usrHatchScreenData)
  91. {
  92. SDPDrawHatchedRegion(pasPerson->m_pView->m_usrDC, regionRDB, USR_HATCH_COLOR_RED );
  93. }
  94. //
  95. // Now pass the region we have updated to the SWP. (We must convert it
  96. // back to VD coordinates before we pass it
  97. //
  98. OffsetRgn(regionRDB, pasPerson->m_pView->m_dsScreenOrigin.x,
  99. pasPerson->m_pView->m_dsScreenOrigin.y);
  100. VIEW_InvalidateRgn(pasPerson, regionRDB);
  101. DC_EXIT_POINT:
  102. if (regionRDB != NULL)
  103. {
  104. //
  105. // Free the region.
  106. //
  107. DeleteRgn(regionRDB);
  108. }
  109. DebugExitVOID(ASShare::SDP_ReceivedPacket);
  110. }
  111. //
  112. // FUNCTION: SDPDrawHatchedRegion(...)
  113. //
  114. // DESCRIPTION:
  115. //
  116. // Draws a hatched region on the specified surface in the given color.
  117. //
  118. // PARAMETERS:
  119. //
  120. // surface - the surface to draw on
  121. //
  122. // region - the region to hatch
  123. //
  124. // hatchColor - the color to hatch in
  125. //
  126. // RETURNS: Nothing.
  127. //
  128. //
  129. void ASShare::SDPDrawHatchedRegion
  130. (
  131. HDC hdc,
  132. HRGN region,
  133. UINT hatchColor
  134. )
  135. {
  136. HBRUSH hbrHatch;
  137. UINT brushStyle;
  138. UINT oldBkMode;
  139. UINT oldRop2;
  140. POINT oldOrigin;
  141. COLORREF hatchColorRef = 0;
  142. DebugEntry(ASShare::SDPDrawHatchedRegion);
  143. //
  144. // Set the brush style to the appropriate value.
  145. //
  146. switch (hatchColor)
  147. {
  148. case USR_HATCH_COLOR_RED:
  149. {
  150. brushStyle = HS_BDIAGONAL;
  151. }
  152. break;
  153. case USR_HATCH_COLOR_BLUE:
  154. {
  155. brushStyle = HS_FDIAGONAL;
  156. }
  157. break;
  158. default:
  159. {
  160. brushStyle = HS_BDIAGONAL;
  161. }
  162. break;
  163. }
  164. //
  165. // Cycle the color to use. Note that the hatchColor parameter is now
  166. // in fact just used to set the hatching direction.
  167. //
  168. m_usrHatchColor++;
  169. m_usrHatchColor %= 7;
  170. switch (m_usrHatchColor)
  171. {
  172. case 0: hatchColorRef = RGB(0xff,0x00,0x00); break;
  173. case 1: hatchColorRef = RGB(0x00,0xff,0x00); break;
  174. case 2: hatchColorRef = RGB(0xff,0xff,0x00); break;
  175. case 3: hatchColorRef = RGB(0x00,0x00,0xff); break;
  176. case 4: hatchColorRef = RGB(0xff,0x00,0xff); break;
  177. case 5: hatchColorRef = RGB(0x00,0xff,0xff); break;
  178. case 6: hatchColorRef = RGB(0xff,0xff,0xff); break;
  179. }
  180. //
  181. // Create the brush, set the background mode etc.
  182. //
  183. hbrHatch = CreateHatchBrush(brushStyle, hatchColorRef);
  184. oldBkMode = SetBkMode(hdc, TRANSPARENT);
  185. oldRop2 = SetROP2(hdc, R2_COPYPEN);
  186. SetBrushOrgEx(hdc, 0, 0, &oldOrigin);
  187. //
  188. // Fill the region.
  189. //
  190. FillRgn(hdc, region, hbrHatch);
  191. //
  192. // Reset everything.
  193. //
  194. SetBrushOrgEx(hdc, oldOrigin.x, oldOrigin.y, NULL);
  195. SetROP2(hdc, oldRop2);
  196. SetBkMode(hdc, oldBkMode);
  197. DeleteBrush(hbrHatch);
  198. DebugExitVOID(ASShare::SDPDrawHatchedRegion);
  199. }
  200. //
  201. //
  202. // SDPPlayScreenDataToRDB()
  203. //
  204. // DESCRIPTION:
  205. //
  206. // Play the contents of a screen data packet into the specified person ID's
  207. // remote desktop bitmap.
  208. //
  209. // PARAMETERS:
  210. //
  211. // personID - ID of person whose RDB is the target for the screen data
  212. // pBitmapUpdate - pointer to protocol update packet
  213. // pBits - pointer to uncompressed screen data
  214. // pPosition - returns updated rectangle in RDB coordinates
  215. //
  216. // RETURNS:
  217. //
  218. // None
  219. //
  220. //
  221. void ASShare::SDPPlayScreenDataToRDB
  222. (
  223. ASPerson * pasPerson,
  224. PSDPACKET pBitmap,
  225. LPBYTE pBits,
  226. LPRECT pRectRDB
  227. )
  228. {
  229. UINT width;
  230. UINT height;
  231. HPALETTE hOldPalette;
  232. LPTSHR_UINT16 pIndexTable;
  233. UINT cColors;
  234. UINT i;
  235. BITMAPINFO_ours bitmapInfo;
  236. UINT dibFormat;
  237. DebugEntry(ASShare::SDPPlayScreenDataToRDB);
  238. ValidateView(pasPerson);
  239. //
  240. // Calculate the extent of the actual area to be updated. This is an
  241. // area less than or equal to the stock DIB allocated to contain it and
  242. // is defined in the position field of the bitmap packet.
  243. //
  244. width = pRectRDB->right - pRectRDB->left + 1;
  245. height = pRectRDB->bottom - pRectRDB->top + 1;
  246. //
  247. // Put the DIB data into a Device Dependent bitmap.
  248. //
  249. USR_InitDIBitmapHeader((BITMAPINFOHEADER *)&bitmapInfo, pBitmap->format);
  250. bitmapInfo.bmiHeader.biWidth = pBitmap->realWidth;
  251. bitmapInfo.bmiHeader.biHeight = pBitmap->realHeight;
  252. //
  253. // Select and realize the current remote palette into the device
  254. // context.
  255. //
  256. hOldPalette = SelectPalette(pasPerson->m_pView->m_usrDC, pasPerson->pmPalette, FALSE);
  257. RealizePalette(pasPerson->m_pView->m_usrDC);
  258. //
  259. // The DIB_PAL_COLORS option requires a table of indexes into the
  260. // currently selected palette to follow the bmi header (in place of the
  261. // color table).
  262. //
  263. if (pBitmap->format <= 8)
  264. {
  265. pIndexTable = (LPTSHR_UINT16)&(bitmapInfo.bmiColors[0]);
  266. cColors = (1 << pBitmap->format);
  267. for (i = 0; i < cColors; i++)
  268. {
  269. *pIndexTable++ = (TSHR_UINT16)i;
  270. }
  271. dibFormat = DIB_PAL_COLORS;
  272. }
  273. else
  274. {
  275. dibFormat = DIB_RGB_COLORS;
  276. }
  277. //
  278. // We go from the bitmap to the screen bitmap in one go.
  279. //
  280. if (!StretchDIBits(pasPerson->m_pView->m_usrDC,
  281. pRectRDB->left,
  282. pRectRDB->top,
  283. width,
  284. height,
  285. 0,
  286. 0,
  287. width,
  288. height,
  289. pBits,
  290. (BITMAPINFO *)&bitmapInfo,
  291. dibFormat,
  292. SRCCOPY))
  293. {
  294. ERROR_OUT(( "StretchDIBits failed"));
  295. }
  296. //
  297. // Reinstate the old palette.
  298. //
  299. SelectPalette(pasPerson->m_pView->m_usrDC, hOldPalette, FALSE);
  300. DebugExitVOID(ASShare::SDPPlayScreenDataToRDB);
  301. }
  302. //
  303. // SDP_DrawHatchedRect(...)
  304. //
  305. void ASShare::SDP_DrawHatchedRect
  306. (
  307. HDC surface,
  308. int x,
  309. int y,
  310. int width,
  311. int height,
  312. UINT color
  313. )
  314. {
  315. HRGN hrgn;
  316. DebugEntry(ASShare::SDP_DrawHatchedRect);
  317. //
  318. // Create the exclusive region.
  319. //
  320. hrgn = CreateRectRgn(x, y, x + width, y + height);
  321. if (hrgn)
  322. {
  323. //
  324. // Now draw the hatched region.
  325. //
  326. SDPDrawHatchedRegion(surface, hrgn, color);
  327. //
  328. // Finally delete the region.
  329. //
  330. DeleteRgn(hrgn);
  331. }
  332. DebugExitVOID(ASShare::SDP_DrawHatchedRect);
  333. }