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.

626 lines
20 KiB

  1. /**MOD+**********************************************************************/
  2. /* Module: wopint.c */
  3. /* */
  4. /* Purpose: Output Painter internal functions */
  5. /* */
  6. /* Copyright(C) Microsoft Corporation 1997-1999 */
  7. /* */
  8. /****************************************************************************/
  9. #include <adcg.h>
  10. extern "C" {
  11. #define TRC_GROUP TRC_GROUP_CORE
  12. #define TRC_FILE "wopint"
  13. #include <atrcapi.h>
  14. }
  15. #include "autil.h"
  16. #include "wui.h"
  17. #include "op.h"
  18. #include "uh.h"
  19. #include "cd.h"
  20. #include "or.h"
  21. #include "aco.h"
  22. /**PROC+*********************************************************************/
  23. /* Name: OPRealizePaletteInWindow */
  24. /* */
  25. /* Purpose: Realizes the current palette in a given window */
  26. /* */
  27. /* Returns: The number of palette entries changed */
  28. /* */
  29. /* Params: hwnd - handle of the window to realize the current palette in */
  30. /* */
  31. /**PROC-*********************************************************************/
  32. DCUINT DCINTERNAL COP::OPRealizePaletteInWindow(HWND hwnd)
  33. {
  34. HDC hdc;
  35. HPALETTE hpalOld;
  36. DCUINT rc;
  37. DC_BEGIN_FN("OPRealizePaletteInWindow");
  38. hdc = GetWindowDC(hwnd);
  39. TRC_ASSERT(hdc, (TB,_T("GetWindowDC returned NULL\n")));
  40. if(NULL == hdc)
  41. {
  42. return 0;
  43. }
  44. hpalOld = SelectPalette(hdc, _pUh->UH_GetCurrentPalette(), FALSE);
  45. rc = RealizePalette(hdc);
  46. SelectPalette(hdc, hpalOld, FALSE);
  47. ReleaseDC(hwnd, hdc);
  48. DC_END_FN();
  49. return(rc);
  50. }
  51. /**PROC+*********************************************************************/
  52. /* Name: OPStaticWndProc */
  53. /* */
  54. /* Purpose: Output Window WndProc (static delegator) */
  55. /* */
  56. /* Returns: Usual WndProc return values */
  57. /* */
  58. /* Params: Usual WndProc parameters */
  59. /* */
  60. /**PROC-*********************************************************************/
  61. LRESULT CALLBACK COP::OPStaticWndProc (HWND hwnd, UINT message,
  62. WPARAM wParam, LPARAM lParam)
  63. {
  64. COP* pOP = (COP*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  65. if(WM_CREATE == message)
  66. {
  67. //pull out the this pointer and stuff it in the window class
  68. LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
  69. pOP = (COP*)lpcs->lpCreateParams;
  70. SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR)pOP);
  71. }
  72. //
  73. // Delegate the message to the appropriate instance
  74. //
  75. if(pOP)
  76. {
  77. return pOP->OPWndProc(hwnd, message, wParam, lParam);
  78. }
  79. else
  80. {
  81. return DefWindowProc(hwnd, message, wParam, lParam);
  82. }
  83. }
  84. //
  85. // Start the process of dimming the window
  86. //
  87. BOOL COP::OPStartDimmingWindow()
  88. {
  89. BOOL fRet = FALSE;
  90. DC_BEGIN_FN("OPStartDimmingWindow");
  91. if (_fDimWindow) {
  92. DC_QUIT;
  93. }
  94. _fDimWindow = TRUE;
  95. if (!CUT::UT_IsScreen8bpp()) {
  96. //
  97. // High color so do the cool grayed dimming anim
  98. //
  99. _iDimWindowStepsLeft = DIM_WINDOW_STEPS;
  100. _nDimWindowTimerID = SetTimer(OP_GetOutputWindowHandle(),
  101. DIM_WINDOW_TIMERID,
  102. DIM_WINDOW_TICK, NULL);
  103. if (!_nDimWindowTimerID) {
  104. TRC_ERR((TB,_T("SetTimer for dimming window failed: 0x%x"),
  105. GetLastError()));
  106. DC_QUIT;
  107. }
  108. }
  109. else {
  110. //
  111. // 8bpp so do the win9x style shutdown grill
  112. //
  113. HDC hdcToDim = _pUh->UH_GetDisconnectBitmapDC();
  114. HWND hwndOutput = OP_GetOutputWindowHandle();
  115. RECT cliRect;
  116. DCSIZE size;
  117. GetClientRect(hwndOutput, &cliRect);
  118. size.width = cliRect.right - cliRect.left;
  119. size.height = cliRect.bottom - cliRect.top;
  120. if (hdcToDim) {
  121. GrillWindow(hdcToDim, size);
  122. }
  123. else {
  124. TRC_ERR((TB,_T("Didn't get a DC to dim")));
  125. }
  126. }
  127. DC_EXIT_POINT:
  128. DC_END_FN();
  129. return fRet;
  130. }
  131. //
  132. // Stop dimming the output window contents
  133. //
  134. BOOL COP::OPStopDimmingWindow()
  135. {
  136. BOOL fRet = FALSE;
  137. HWND hwnd = OP_GetOutputWindowHandle();
  138. DC_BEGIN_FN("OPStopDimmingWindow");
  139. if (_nDimWindowTimerID) {
  140. KillTimer(hwnd,
  141. _nDimWindowTimerID);
  142. _nDimWindowTimerID = 0;
  143. }
  144. _fDimWindow = FALSE;
  145. fRet = TRUE;
  146. DC_END_FN();
  147. return fRet;
  148. }
  149. const WORD c_GrayBits[] = {0x5555, 0xAAAA, 0x5555, 0xAAAA,
  150. 0x5555, 0xAAAA, 0x5555, 0xAAAA};
  151. HBRUSH COP::CreateDitheredBrush()
  152. {
  153. DC_BEGIN_FN("CreateDitheredBrush");
  154. HBITMAP hbmp = CreateBitmap(8, 8, 1, 1, c_GrayBits);
  155. if (hbmp)
  156. {
  157. HBRUSH hbr = CreatePatternBrush(hbmp);
  158. DeleteObject(hbmp);
  159. return hbr;
  160. }
  161. DC_END_FN();
  162. return NULL;
  163. }
  164. //
  165. // Overlays the image in the window with a grill
  166. // aka like the Win2k shutdown effect
  167. //
  168. VOID COP::GrillWindow(HDC hdc, DCSIZE& size)
  169. {
  170. #ifndef OS_WINCE
  171. RECT rc;
  172. #endif
  173. DC_BEGIN_FN("GrillWindow");
  174. static const int ROP_DPna = 0x000A0329;
  175. HBRUSH hbr = CreateDitheredBrush();
  176. if (hbr)
  177. {
  178. #ifndef OS_WINCE
  179. RECT rc;
  180. #endif
  181. HBRUSH hbrOld = (HBRUSH)SelectObject(hdc, hbr);
  182. PatBlt(hdc, 0, 0, size.width, size.height, ROP_DPna);
  183. SelectObject(hdc, hbrOld);
  184. DeleteObject(hbr);
  185. }
  186. DC_END_FN();
  187. }
  188. //
  189. // Grays the image in the window
  190. // like the XP shutdown effect
  191. //
  192. VOID COP::DimWindow(HDC hdc)
  193. {
  194. #ifndef OS_WINCE
  195. RECT rc;
  196. #endif
  197. HBITMAP dstBitmap;
  198. DIBSECTION dibSection;
  199. PBYTE pDstBits;
  200. DC_BEGIN_FN("GrayWindow");
  201. dstBitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
  202. if (dstBitmap != NULL) {
  203. if (sizeof(dibSection) !=
  204. GetObject(dstBitmap, sizeof(dibSection), &dibSection)) {
  205. TRC_ERR((TB, _T("GetObject failed")));
  206. DC_QUIT;
  207. }
  208. }
  209. pDstBits = (PBYTE)dibSection.dsBm.bmBits;
  210. if (24 == dibSection.dsBm.bmBitsPixel) {
  211. DimBits24(pDstBits,
  212. dibSection.dsBm.bmWidth * dibSection.dsBm.bmHeight,
  213. 0xd5);
  214. }
  215. else if (16 == dibSection.dsBm.bmBitsPixel) {
  216. DimBits16(pDstBits,
  217. dibSection.dsBm.bmWidth * dibSection.dsBm.bmHeight,
  218. 0xd5);
  219. }
  220. else if (15 == dibSection.dsBm.bmBitsPixel) {
  221. DimBits15(pDstBits,
  222. dibSection.dsBm.bmWidth * dibSection.dsBm.bmHeight,
  223. 0xd5);
  224. }
  225. DC_EXIT_POINT:
  226. DC_END_FN();
  227. }
  228. VOID COP::DimBits24(PBYTE pSrc, int cLen, int Amount)
  229. {
  230. for (int i = cLen - 1; i >= 0; i--)
  231. {
  232. ULONG B = (ULONG)*pSrc;
  233. ULONG G = (ULONG)*(pSrc+1);
  234. ULONG R = (ULONG)*(pSrc+2);
  235. ULONG ulGray = (54*R+183*G+19*B) >> 8;
  236. ULONG ulTemp = ulGray * (0xff - Amount);
  237. R = (R*Amount+ulTemp) >> 8;
  238. G = (G*Amount+ulTemp) >> 8;
  239. B = (B*Amount+ulTemp) >> 8;
  240. *pSrc++ = (BYTE)B;
  241. *pSrc++ = (BYTE)G;
  242. *pSrc++ = (BYTE)R;
  243. }
  244. }
  245. #define rgb555(r,g,b) (( ((WORD)(r) << 10) & TS_RED_MASK_15BPP) | \
  246. (((WORD)(g) << 5) & TS_GREEN_MASK_15BPP) | \
  247. ((WORD)(b) & TS_BLUE_MASK_15BPP))
  248. #define rgb565(r,g,b) (( ((WORD)(r) << 11) & TS_RED_MASK_16BPP) | \
  249. (((WORD)(g) << 5) & TS_GREEN_MASK_16BPP) | \
  250. ((WORD)(b) & TS_BLUE_MASK_16BPP))
  251. VOID COP::DimBits16(PBYTE pSrc, int cLen, int Amount)
  252. {
  253. ULONG R,G,B;
  254. USHORT color;
  255. #ifndef OS_WINCE
  256. ULONG ulGray, ulTemp;
  257. #endif
  258. //
  259. // All our 16bpp bitmaps are 565
  260. //
  261. // Do the conversion in a cheesy way by upsampling to 24bpp first
  262. //
  263. for (int i = cLen - 1; i >= 0; i--)
  264. {
  265. memcpy(&color, pSrc, 2);
  266. B = (color & TS_BLUE_MASK_16BPP);
  267. G = ((color & TS_GREEN_MASK_16BPP) >> 5) / 2;
  268. R = ((color & TS_RED_MASK_16BPP) >> 11);
  269. ULONG ulGray = (54*R+183*G+19*B) >> 8;
  270. ULONG ulTemp = ulGray * (0xff - Amount);
  271. R = ((R*Amount+ulTemp) >> 8) / 2;
  272. G = ((G*Amount+ulTemp) >> 8) / 2;
  273. B = ((B*Amount+ulTemp) >> 8) / 2;
  274. color = rgb565(R,G,B);
  275. memcpy(pSrc, &color, 2);
  276. pSrc+=2;
  277. }
  278. }
  279. VOID COP::DimBits15(PBYTE pSrc, int cLen, int Amount)
  280. {
  281. ULONG R,G,B;
  282. USHORT color;
  283. ULONG ulGray, ulTemp;
  284. ULONG scaleAmt = Amount/8;
  285. //
  286. // All our 15bpp bitmaps are 555
  287. //
  288. for (int i = cLen - 1; i >= 0; i--)
  289. {
  290. memcpy(&color, pSrc, 2);
  291. B = (color & TS_BLUE_MASK_15BPP);
  292. G = (color & TS_GREEN_MASK_15BPP) >> 5;
  293. R = (color & TS_RED_MASK_15BPP) >> 5;
  294. ulGray = (R+G+B) / 3;
  295. ulTemp = ulGray * (0xFF/8 - scaleAmt);
  296. R = (R*scaleAmt+ulTemp) >> 8;
  297. G = (G*scaleAmt+ulTemp) >> 8;
  298. B = (B*scaleAmt+ulTemp) >> 8;
  299. color = rgb555(R,G,B);
  300. memcpy(pSrc, &color, 2);
  301. pSrc+=2;
  302. }
  303. }
  304. /**PROC+*********************************************************************/
  305. /* Name: OPWndProc */
  306. /* */
  307. /* Purpose: Output Window WndProc */
  308. /* */
  309. /* Returns: Usual WndProc return values */
  310. /* */
  311. /* Params: Usual WndProc parameters */
  312. /* */
  313. /**PROC-*********************************************************************/
  314. LRESULT CALLBACK COP::OPWndProc( HWND hwnd,
  315. UINT message,
  316. WPARAM wParam,
  317. LPARAM lParam )
  318. {
  319. LRESULT rc = 0;
  320. DC_BEGIN_FN("OPWndProc");
  321. switch (message)
  322. {
  323. case WM_PAINT:
  324. {
  325. HDC hdc;
  326. PAINTSTRUCT ps;
  327. HPALETTE hpalOld;
  328. DCSIZE desktopSize;
  329. #ifdef DC_PERF
  330. UTPERFCOUNTER counter1;
  331. UTPERFCOUNTER counter2;
  332. #endif
  333. TRC_NRM((TB, _T("WM_PAINT")));
  334. #ifdef DC_PERF
  335. _pUt->UT_QueryPerformanceCounter(&counter1);
  336. #endif
  337. hdc = BeginPaint(hwnd, &ps);
  338. if (hdc == NULL)
  339. {
  340. TRC_SYSTEM_ERROR("BeginPaint failed");
  341. break;
  342. }
  343. #ifdef DISABLE_SHADOW_IN_FULLSCREEN
  344. if (!_pUh->_UH.DontUseShadowBitmap &&
  345. _pUh->UH_ShadowBitmapIsEnabled() ||
  346. _fDimWindow)
  347. #else
  348. if (_pUh->UH_ShadowBitmapIsEnabled() || _fDimWindow)
  349. #endif // DISABLE_SHADOW_IN_FULLSCREEN
  350. {
  351. #ifndef SMART_SIZING
  352. BOOL rcBlt;
  353. #endif // SMART_SIZING
  354. TRC_DBG((TB, _T("Paint from shadow bitmap")));
  355. hpalOld = SelectPalette(hdc, _pUh->UH_GetCurrentPalette(), FALSE);
  356. RealizePalette(hdc);
  357. _pUi->UI_GetDesktopSize(&desktopSize);
  358. #ifdef SMART_SIZING
  359. OP_CopyShadowToDC(hdc, 0, 0, desktopSize.width,
  360. desktopSize.height);
  361. #else // SMART_SIZING
  362. rcBlt = BitBlt(hdc,
  363. 0, 0,
  364. desktopSize.width,
  365. desktopSize.height,
  366. !_fDimWindow ? _pUh->UH_GetShadowBitmapDC() :
  367. _pUh->UH_GetDisconnectBitmapDC(),
  368. 0, 0,
  369. SRCCOPY);
  370. if (!rcBlt)
  371. {
  372. /********************************************************/
  373. /* Failed to paint. */
  374. /********************************************************/
  375. TRC_ERR((TB, _T("BitBlt failed")));
  376. }
  377. #endif // SMART_SIZING
  378. SelectPalette(hdc, hpalOld, FALSE);
  379. }
  380. else
  381. {
  382. /************************************************************/
  383. /* Shadow Bitmap disabled - have to get the output resent */
  384. /* from the server. */
  385. /* */
  386. /* A. TRIVIAL IMPLEMENTATION: */
  387. /* */
  388. /* Send an UpdateRectPDU to the server for */
  389. /* */
  390. /* ps.rcPaint */
  391. /* */
  392. /* B. ADVANCED IMPLEMENTATION (Win32 only) */
  393. /* */
  394. /* Send a set of UpdateRectPDUs to the server for the */
  395. /* rects returned by: */
  396. /* */
  397. /* GetUpdateRgn (this must be called BEFORE BeginPaint) */
  398. /* GetRgnData (returns rectangles in region) */
  399. /* */
  400. /* If there are too many rects in region (Q: what is too */
  401. /* many?) then simply revert to Plan A. */
  402. /* */
  403. /************************************************************/
  404. TRC_DBG((TB, _T("Paint using UpdateRectPDU")));
  405. if ( (ps.rcPaint.right > ps.rcPaint.left ) &&
  406. (ps.rcPaint.bottom > ps.rcPaint.top) )
  407. {
  408. _pCd->CD_DecoupleNotification(CD_SND_COMPONENT,
  409. _pOr,
  410. CD_NOTIFICATION_FUNC(COR,OR_RequestUpdate),
  411. &ps.rcPaint,
  412. sizeof(RECT));
  413. }
  414. #ifdef OS_WINCE
  415. _pUh->_UH.ulNumAOTRects = 0;
  416. SetRectEmpty(&_pUh->_UH.rcaAOT[MAX_AOT_RECTS-1]);
  417. EnumWindows(StaticEnumTopLevelWindowsProc, (LPARAM)this);
  418. #endif
  419. }
  420. EndPaint(hwnd, &ps);
  421. #ifdef DC_PERF
  422. _pUt->UT_QueryPerformanceCounter(&time2);
  423. TRC_NRM((TB, _T("WM_PAINT: %u"),
  424. _pUt->UT_PerformanceCounterDiff(&counter1, &counter2) ));
  425. #endif
  426. _OP.lastPaintTime = _pUt->UT_GetCurrentTimeMS();
  427. }
  428. break;
  429. case WM_LBUTTONDOWN:
  430. case WM_RBUTTONDOWN:
  431. case WM_MBUTTONDOWN:
  432. case WM_KEYDOWN:
  433. case WM_SYSKEYDOWN:
  434. {
  435. //
  436. // If we are dimming then beep on input
  437. //
  438. if (_fDimWindow) {
  439. MessageBeep((UINT)-1);
  440. }
  441. }
  442. break;
  443. case WM_TIMER:
  444. {
  445. switch (wParam)
  446. {
  447. case DIM_WINDOW_TIMERID:
  448. {
  449. BOOL fStopDimming = FALSE;
  450. if (_fDimWindow) {
  451. _iDimWindowStepsLeft--;
  452. if (_iDimWindowStepsLeft >= 0) {
  453. //
  454. // Dim the window some more
  455. //
  456. HDC hdcToDim = _pUh->UH_GetDisconnectBitmapDC();
  457. if (hdcToDim) {
  458. DimWindow(hdcToDim);
  459. InvalidateRect(OP_GetOutputWindowHandle(),
  460. NULL,
  461. FALSE);
  462. }
  463. else {
  464. TRC_ERR((TB,
  465. _T("hdcToDim is NULL. Not dimming!")));
  466. fStopDimming = TRUE;
  467. }
  468. }
  469. else {
  470. fStopDimming = TRUE;
  471. }
  472. }
  473. else {
  474. fStopDimming = TRUE;
  475. }
  476. if (fStopDimming) {
  477. //
  478. // Stop the dimming
  479. //
  480. KillTimer(hwnd, _nDimWindowTimerID);
  481. }
  482. }
  483. break;
  484. }
  485. }
  486. break;
  487. default:
  488. {
  489. rc = DefWindowProc(hwnd, message, wParam, lParam);
  490. }
  491. break;
  492. }
  493. DC_END_FN();
  494. return(rc);
  495. } /* OPWndProc */
  496. #ifdef OS_WINCE
  497. BOOL CALLBACK COP::StaticEnumTopLevelWindowsProc (HWND hwnd, LPARAM lParam)
  498. {
  499. COP* pOP = (COP*)lParam;
  500. return pOP->EnumTopLevelWindowsProc(hwnd);
  501. }
  502. BOOL COP::EnumTopLevelWindowsProc (HWND hwnd)
  503. {
  504. DC_BEGIN_FN("EnumTopLevelWindowsProc");
  505. if ( (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) &&
  506. (GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE) )
  507. {
  508. RECT rectWindow;
  509. GetWindowRect(hwnd, &rectWindow);
  510. if (!IsRectEmpty(&rectWindow))
  511. {
  512. if (_pUh->_UH.ulNumAOTRects < MAX_AOT_RECTS - 1)
  513. {
  514. _pUh->_UH.rcaAOT[_pUh->_UH.ulNumAOTRects++] = rectWindow;
  515. }
  516. else
  517. {
  518. TRC_ASSERT((_pUh->_UH.ulNumAOTRects == MAX_AOT_RECTS - 1),
  519. (TB,_T("_pUh->_UH.ulNumAOTRects is invalid!\n")));
  520. if (IsRectEmpty(&_pUh->_UH.rcaAOT[_pUh->_UH.ulNumAOTRects]))
  521. {
  522. _pUh->_UH.rcaAOT[_pUh->_UH.ulNumAOTRects] = rectWindow;
  523. }
  524. else
  525. {
  526. UnionRect(&_pUh->_UH.rcaAOT[_pUh->_UH.ulNumAOTRects],
  527. &_pUh->_UH.rcaAOT[_pUh->_UH.ulNumAOTRects], &rectWindow);
  528. }
  529. }
  530. }
  531. }
  532. DC_END_FN();
  533. return TRUE;
  534. }
  535. #endif