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.

274 lines
7.0 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: snapshot.c
  3. *
  4. * Screen/Window SnapShotting Routines
  5. *
  6. * Copyright (c) 1985 - 1999, Microsoft Corporation
  7. *
  8. * History:
  9. * 26-Nov-1991 DavidPe Ported from Win 3.1 sources
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /***************************************************************************\
  14. * xxxSnapWindow
  15. *
  16. * Effects: Snaps either the desktop hwnd or the active front most window. If
  17. * any other window is specified, we will snap it but it will be clipped.
  18. *
  19. \***************************************************************************/
  20. BOOL xxxSnapWindow(
  21. PWND pwnd)
  22. {
  23. PTHREADINFO ptiCurrent;
  24. RECT rc;
  25. HDC hdcScr = NULL;
  26. HDC hdcMem = NULL;
  27. BOOL fRet;
  28. HBITMAP hbmOld;
  29. HBITMAP hbm;
  30. HANDLE hPal;
  31. LPLOGPALETTE lppal;
  32. int palsize;
  33. int iFixedPaletteEntries;
  34. BOOL fSuccess;
  35. PWND pwndT;
  36. TL tlpwndT;
  37. PWINDOWSTATION pwinsta;
  38. TL tlpwinsta;
  39. CheckLock(pwnd);
  40. UserAssert(pwnd != NULL);
  41. ptiCurrent = PtiCurrent();
  42. /*
  43. * If this is a thread of winlogon, don't do the snapshot.
  44. */
  45. if (PsGetCurrentProcessId() == gpidLogon) {
  46. return FALSE;
  47. }
  48. /*
  49. * Get the affected windowstation
  50. */
  51. if (!NT_SUCCESS(ReferenceWindowStation(
  52. PsGetCurrentThread(),
  53. NULL,
  54. WINSTA_READSCREEN,
  55. &pwinsta,
  56. TRUE)) ||
  57. pwinsta->dwWSF_Flags & WSF_NOIO) {
  58. return FALSE;
  59. }
  60. /*
  61. * If the window is on another windowstation, do nothing.
  62. */
  63. if (pwnd->head.rpdesk->rpwinstaParent != pwinsta) {
  64. return FALSE;
  65. }
  66. /*
  67. * Get the parent of any child windows.
  68. */
  69. while (TestWF(pwnd, WFCHILD)) {
  70. pwnd = pwnd->spwndParent;
  71. UserAssert(pwnd != NULL);
  72. }
  73. /*
  74. * Lock the windowstation before we leave the critical section
  75. */
  76. ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);
  77. /*
  78. * Open the clipboard and empty it.
  79. *
  80. * pwndDesktop is made the owner of the clipboard, instead of the
  81. * currently active window; -- SANKAR -- 20th July, 1989 --
  82. */
  83. pwndT = ptiCurrent->rpdesk->pDeskInfo->spwnd;
  84. ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT);
  85. fSuccess = _OpenClipboard(pwndT, NULL);
  86. ThreadUnlock(&tlpwndT);
  87. if (!fSuccess) {
  88. ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
  89. return FALSE;
  90. }
  91. xxxEmptyClipboard(pwinsta);
  92. /*
  93. * Use the whole window.
  94. */
  95. CopyRect(&rc, &pwnd->rcWindow);
  96. /*
  97. * Only snap what is on the screen.
  98. */
  99. if (!IntersectRect(&rc, &rc, &gpDispInfo->rcScreen)) {
  100. fRet = FALSE;
  101. goto SnapExit;
  102. }
  103. rc.right -= rc.left;
  104. rc.bottom -= rc.top;
  105. /*
  106. * Figure out how far offset from window origin visible part is
  107. */
  108. if (pwnd != PWNDDESKTOP(pwnd)) {
  109. rc.left -= pwnd->rcWindow.left;
  110. rc.top -= pwnd->rcWindow.top;
  111. }
  112. /*
  113. * Get the entire window's DC.
  114. */
  115. hdcScr = _GetWindowDC(pwnd);
  116. if (!hdcScr)
  117. goto MemoryError;
  118. /*
  119. * Create the memory DC.
  120. */
  121. hdcMem = GreCreateCompatibleDC(hdcScr);
  122. if (!hdcMem)
  123. goto MemoryError;
  124. /*
  125. * Create the destination bitmap. If it fails, then attempt
  126. * to create a monochrome bitmap.
  127. * Did we have enough memory?
  128. */
  129. if (SYSMET(SAMEDISPLAYFORMAT)) {
  130. hbm = GreCreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
  131. } else {
  132. hbm = GreCreateBitmap(rc.right, rc.bottom, 1, gpDispInfo->BitCountMax, NULL);
  133. }
  134. if (!hbm) {
  135. hbm = GreCreateBitmap(rc.right, rc.bottom, 1, 1, NULL);
  136. if (!hbm)
  137. goto MemoryError;
  138. }
  139. /*
  140. * Select the bitmap into the memory DC.
  141. */
  142. hbmOld = GreSelectBitmap(hdcMem, hbm);
  143. /*
  144. * Snap!!!
  145. * Check the return value because the process taking the snapshot
  146. * may not have access to read the screen.
  147. */
  148. fRet = GreBitBlt(hdcMem, 0, 0, rc.right, rc.bottom, hdcScr, rc.left, rc.top, SRCCOPY | CAPTUREBLT, 0);
  149. /*
  150. * Restore the old bitmap into the memory DC.
  151. */
  152. GreSelectBitmap(hdcMem, hbmOld);
  153. /*
  154. * If the blt failed, leave now.
  155. */
  156. if (!fRet) {
  157. goto SnapExit;
  158. }
  159. _SetClipboardData(CF_BITMAP, hbm, FALSE, TRUE);
  160. /*
  161. * If this is a palette device, let's throw the current system palette
  162. * into the clipboard also. Useful if the user just snapped a window
  163. * containing palette colors...
  164. */
  165. if (TEST_PUSIF(PUSIF_PALETTEDISPLAY)) {
  166. int i;
  167. int iPalSize;
  168. palsize = GreGetDeviceCaps(hdcScr, SIZEPALETTE);
  169. /*
  170. * Determine the number of system colors.
  171. */
  172. if (GreGetSystemPaletteUse(hdcScr) == SYSPAL_STATIC)
  173. iFixedPaletteEntries = GreGetDeviceCaps(hdcScr, NUMRESERVED);
  174. else
  175. iFixedPaletteEntries = 2;
  176. lppal = (LPLOGPALETTE)UserAllocPoolWithQuota(
  177. (LONG)(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * palsize),
  178. TAG_CLIPBOARD);
  179. if (lppal != NULL) {
  180. lppal->palVersion = 0x300;
  181. lppal->palNumEntries = (WORD)palsize;
  182. if (GreGetSystemPaletteEntries(hdcScr,
  183. 0,
  184. palsize,
  185. lppal->palPalEntry)) {
  186. iPalSize = palsize - iFixedPaletteEntries / 2;
  187. for (i = iFixedPaletteEntries / 2; i < iPalSize; i++) {
  188. /*
  189. * Any non system palette enteries need to have the NOCOLLAPSE
  190. * flag set otherwise bitmaps containing different palette
  191. * indices but same colors get messed up.
  192. */
  193. lppal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
  194. }
  195. if (hPal = GreCreatePalette(lppal))
  196. _SetClipboardData(CF_PALETTE, hPal, FALSE, TRUE);
  197. }
  198. UserFreePool(lppal);
  199. }
  200. }
  201. PlayEventSound(USER_SOUND_SNAPSHOT);
  202. fRet = TRUE;
  203. SnapExit:
  204. /*
  205. * Release the window/client DC.
  206. */
  207. if (hdcScr) {
  208. _ReleaseDC(hdcScr);
  209. }
  210. xxxCloseClipboard(pwinsta);
  211. Unlock(&pwinsta->spwndClipOwner);
  212. /*
  213. * Delete the memory DC.
  214. */
  215. if (hdcMem) {
  216. GreDeleteDC(hdcMem);
  217. }
  218. ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
  219. return fRet;
  220. MemoryError:
  221. /*
  222. * Display an error message box.
  223. */
  224. ClientNoMemoryPopup();
  225. fRet = FALSE;
  226. goto SnapExit;
  227. }