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.

484 lines
13 KiB

  1. /**************************** Module Header ********************************\
  2. * Module Name: mngray.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * Server-side version of DrawState.
  7. *
  8. * History:
  9. * 06-Jan-1993 FritzS Created
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /***************************************************************************\
  14. *
  15. * CreateCompatiblePublicDC
  16. *
  17. * This is used in several callback routines to the lpk(s). We can't
  18. * pass G_TERM(pDispInfo)->hdcGray, HDCBITS() or gfade.hdc to the client since
  19. * they are public DCs.
  20. * We can't just change the owner since we're about to leave the
  21. * critical section. Some other thread may enter before we return
  22. * and use hdcGray, HDCBITS() or gfade.hdc. Instead, we create a compatible
  23. * dc with the same font and bitmap that are currently selected in hdcGray,
  24. * HDCBITS() or gfade.hdc). Pass that to the client lpk.
  25. *
  26. * If the function returns successfully , then the dc and bitmap object are
  27. * guaranteed to be successfully created.
  28. *
  29. * History:
  30. *
  31. * Dec-16-1997 Samer Arafeh [samera]
  32. * Jan-20-1998 Samer Arafeh [samera] Add support for both hdcGray and HDCBITS()
  33. * May-05-2000 MHamid Add support for gfade.hdc
  34. *
  35. \***************************************************************************/
  36. HDC CreateCompatiblePublicDC(
  37. HDC hdcPublic,
  38. HBITMAP *pbmPublicDC)
  39. {
  40. HDC hdcCompatible = 0;
  41. HBITMAP hbmCompatible, hbm = NULL;
  42. BITMAP bmBits;
  43. HFONT hFont;
  44. /*
  45. * If it is not public DC just return it.
  46. */
  47. if(GreGetObjectOwner((HOBJ)hdcPublic, DC_TYPE) != OBJECT_OWNER_PUBLIC) {
  48. return hdcPublic;
  49. }
  50. if ((hdcCompatible = GreCreateCompatibleDC(hdcPublic)) == NULL) {
  51. RIPMSG1(RIP_WARNING, "CreateCompatiblePublicDC: GreCreateCompatibleDC Failed %lX", hdcPublic);
  52. return (HDC)NULL;
  53. }
  54. if (!GreSetDCOwner(hdcCompatible, OBJECT_OWNER_CURRENT)) {
  55. RIPMSG1(RIP_WARNING, "CreateCompatiblePublicDC: SetDCOwner Failed %lX", hdcCompatible);
  56. GreDeleteDC(hdcCompatible);
  57. return (HDC)NULL;
  58. }
  59. hbm = NtGdiGetDCObject(hdcPublic, LO_BITMAP_TYPE);
  60. GreExtGetObjectW(hbm, sizeof(BITMAP), &bmBits);
  61. hbmCompatible = GreCreateCompatibleBitmap(hdcPublic,
  62. bmBits.bmWidth,
  63. bmBits.bmHeight);
  64. //
  65. // Check whether bitmap couldn't be created or can't
  66. // be set to OBJECT_OWNER_CURRENT, then fail and
  67. // do necessary cleanup now!
  68. //
  69. if( (hbmCompatible == NULL) ||
  70. (!GreSetBitmapOwner(hbmCompatible, OBJECT_OWNER_CURRENT)) ) {
  71. RIPMSG1(RIP_WARNING, "CreateCompatiblePublicDC: GreCreateCompatibleBitmap Failed %lX", hbmCompatible);
  72. GreDeleteDC( hdcCompatible );
  73. if( hbmCompatible ) {
  74. GreDeleteObject( hbmCompatible );
  75. }
  76. return (HDC)NULL;
  77. }
  78. GreSelectBitmap(hdcCompatible, hbmCompatible);
  79. /*
  80. * Make sure we use the same font and text alignment.
  81. */
  82. hFont = GreSelectFont(hdcPublic, ghFontSys);
  83. GreSelectFont(hdcPublic, hFont);
  84. GreSelectFont(hdcCompatible, hFont);
  85. GreSetTextAlign(hdcCompatible, GreGetTextAlign(hdcPublic));
  86. /*
  87. * Copy any information already written into G_TERM(pDispInfo)->hdcGray.
  88. */
  89. //
  90. // Mirror the created DC if the hdcGray is currently mirrored,
  91. // so that TextOut won't get mirrored on User Client DCs
  92. //
  93. if (GreGetLayout(hdcPublic) & LAYOUT_RTL) {
  94. GreSetLayout(hdcCompatible, bmBits.bmWidth - 1, LAYOUT_RTL);
  95. }
  96. GreBitBlt(hdcCompatible, 0, 0, bmBits.bmWidth, bmBits.bmHeight, hdcPublic, 0, 0, SRCCOPY, 0);
  97. *pbmPublicDC = hbmCompatible ; // for later deletion, by the server side
  98. return hdcCompatible;
  99. }
  100. /***************************************************************************\
  101. *
  102. * xxxDrawState()
  103. *
  104. * Generic state drawing routine. Does simple drawing into same DC if
  105. * normal state; uses offscreen bitmap otherwise.
  106. *
  107. * We do drawing for these simple types ourselves:
  108. * (1) Text
  109. * lData is string pointer.
  110. * wData is string length
  111. * (2) Icon
  112. * LOWORD(lData) is hIcon
  113. * (3) Bitmap
  114. * LOWORD(lData) is hBitmap
  115. * (4) Glyph (internal)
  116. * LOWORD(lData) is OBI_ value, one of
  117. * OBI_CHECKMARK
  118. * OBI_BULLET
  119. * OBI_MENUARROW
  120. * right now
  121. *
  122. * Other types are required to draw via the callback function, and are
  123. * allowed to stick whatever they want in lData and wData.
  124. *
  125. * We apply the following effects onto the image:
  126. * (1) Normal (nothing)
  127. * (2) Default (drop shadow)
  128. * (3) Union (gray string dither)
  129. * (4) Disabled (embossed)
  130. *
  131. * Note that we do NOT stretch anything. We just clip.
  132. *
  133. \***************************************************************************/
  134. BOOL xxxDrawState(
  135. HDC hdcDraw,
  136. HBRUSH hbrFore,
  137. LPARAM lData,
  138. int x,
  139. int y,
  140. int cx,
  141. int cy,
  142. UINT uFlags)
  143. {
  144. HFONT hFont;
  145. HFONT hFontSave = NULL;
  146. HDC hdcT;
  147. HBITMAP hbmpT;
  148. POINT ptOrg;
  149. BOOL fResult;
  150. int oldAlign;
  151. DWORD dwOldLayout=0;
  152. /*
  153. * These require monochrome conversion
  154. *
  155. * Enforce monochrome: embossed doesn't look great with 2 color displays
  156. */
  157. if ((uFlags & DSS_DISABLED) &&
  158. ((gpsi->BitCount == 1) || SYSMET(SLOWMACHINE))) {
  159. uFlags &= ~DSS_DISABLED;
  160. uFlags |= DSS_UNION;
  161. }
  162. if (uFlags & (DSS_INACTIVE | DSS_DISABLED | DSS_DEFAULT | DSS_UNION))
  163. uFlags |= DSS_MONO;
  164. /*
  165. * Validate flags - we only support DST_COMPLEX in kernel
  166. */
  167. if ((uFlags & DST_TYPEMASK) != DST_COMPLEX) {
  168. RIPMSG1(RIP_ERROR, "xxxDrawState: invalid DST_ type %x", (uFlags & DST_TYPEMASK));
  169. return FALSE;
  170. }
  171. /*
  172. * Optimize: nothing to draw
  173. */
  174. if (!cx || !cy) {
  175. return TRUE;
  176. }
  177. /*
  178. * Setup drawing dc
  179. */
  180. if (uFlags & DSS_MONO) {
  181. hdcT = gpDispInfo->hdcGray;
  182. /*
  183. * First turn off mirroring on hdcGray if any.
  184. */
  185. GreSetLayout(hdcT, -1, 0);
  186. /*
  187. * Set the hdcGray layout to be equal to the screen hdcDraw layout.
  188. */
  189. dwOldLayout = GreGetLayout(hdcDraw);
  190. if (dwOldLayout != GDI_ERROR) {
  191. GreSetLayout(hdcT, cx, dwOldLayout);
  192. }
  193. /*
  194. * Is our scratch bitmap big enough? We need potentially
  195. * cx+1 by cy pixels for default etc.
  196. */
  197. if ((gpDispInfo->cxGray < cx + 1) || (gpDispInfo->cyGray < cy)) {
  198. if (hbmpT = GreCreateBitmap(max(gpDispInfo->cxGray, cx + 1), max(gpDispInfo->cyGray, cy), 1, 1, 0L)) {
  199. HBITMAP hbmGray;
  200. hbmGray = GreSelectBitmap(gpDispInfo->hdcGray, hbmpT);
  201. GreDeleteObject(hbmGray);
  202. GreSetBitmapOwner(hbmpT, OBJECT_OWNER_PUBLIC);
  203. gpDispInfo->cxGray = max(gpDispInfo->cxGray, cx + 1);
  204. gpDispInfo->cyGray = max(gpDispInfo->cyGray, cy);
  205. } else {
  206. cx = gpDispInfo->cxGray - 1;
  207. cy = gpDispInfo->cyGray;
  208. }
  209. }
  210. GrePatBlt(gpDispInfo->hdcGray,
  211. 0,
  212. 0,
  213. gpDispInfo->cxGray,
  214. gpDispInfo->cyGray,
  215. WHITENESS);
  216. GreSetTextCharacterExtra(gpDispInfo->hdcGray,
  217. GreGetTextCharacterExtra(hdcDraw));
  218. oldAlign = GreGetTextAlign(hdcT);
  219. GreSetTextAlign(hdcT, (oldAlign & ~(TA_RTLREADING |TA_CENTER |TA_RIGHT))
  220. | (GreGetTextAlign(hdcDraw) & (TA_RTLREADING |TA_CENTER |TA_RIGHT)));
  221. /*
  222. * Setup font
  223. */
  224. if (GreGetHFONT(hdcDraw) != ghFontSys) {
  225. hFont = GreSelectFont(hdcDraw, ghFontSys);
  226. GreSelectFont(hdcDraw, hFont);
  227. hFontSave = GreSelectFont(gpDispInfo->hdcGray, hFont);
  228. }
  229. } else {
  230. hdcT = hdcDraw;
  231. /*
  232. * Adjust viewport
  233. */
  234. GreGetViewportOrg(hdcT, &ptOrg);
  235. GreSetViewportOrg(hdcT, ptOrg.x+x, ptOrg.y+y, NULL);
  236. }
  237. /*
  238. * Now, draw original image
  239. */
  240. fResult = xxxRealDrawMenuItem(hdcT, (PGRAYMENU)lData, cx, cy);
  241. /*
  242. * The callbacks could have altered the attributes of hdcGray
  243. */
  244. if (hdcT == gpDispInfo->hdcGray) {
  245. GreSetBkColor(gpDispInfo->hdcGray, RGB(255, 255, 255));
  246. GreSetTextColor(gpDispInfo->hdcGray, RGB(0, 0, 0));
  247. GreSelectBrush(gpDispInfo->hdcGray, ghbrBlack);
  248. GreSetBkMode(gpDispInfo->hdcGray, OPAQUE);
  249. }
  250. /*
  251. * Clean up
  252. */
  253. if (uFlags & DSS_MONO) {
  254. /*
  255. * Reset font
  256. */
  257. if (hFontSave)
  258. GreSelectFont(hdcT, hFontSave);
  259. GreSetTextAlign(hdcT, oldAlign);
  260. } else {
  261. /*
  262. * Reset DC.
  263. */
  264. GreSetViewportOrg(hdcT, ptOrg.x, ptOrg.y, NULL);
  265. return TRUE;
  266. }
  267. /*
  268. * UNION state
  269. * Dither over image
  270. * We want white pixels to stay white, in either dest or pattern.
  271. */
  272. if (uFlags & DSS_UNION) {
  273. POLYPATBLT PolyData;
  274. PolyData.x = 0;
  275. PolyData.y = 0;
  276. PolyData.cx = cx;
  277. PolyData.cy = cy;
  278. PolyData.BrClr.hbr = gpsi->hbrGray;
  279. GrePolyPatBlt(gpDispInfo->hdcGray, PATOR, &PolyData, 1, PPB_BRUSH);
  280. }
  281. if (uFlags & DSS_INACTIVE) {
  282. BltColor(hdcDraw,
  283. SYSHBR(3DSHADOW),
  284. gpDispInfo->hdcGray,
  285. x,
  286. y,
  287. cx,
  288. cy,
  289. 0,
  290. 0,
  291. BC_INVERT);
  292. } else if (uFlags & DSS_DISABLED) {
  293. /*
  294. * Emboss
  295. * Draw over-1/down-1 in hilight color, and in same position in shadow.
  296. */
  297. BltColor(hdcDraw,
  298. SYSHBR(3DHILIGHT),
  299. gpDispInfo->hdcGray,
  300. x+1,
  301. y+1,
  302. cx,
  303. cy,
  304. 0,
  305. 0,
  306. BC_INVERT);
  307. BltColor(hdcDraw,
  308. SYSHBR(3DSHADOW),
  309. gpDispInfo->hdcGray,
  310. x,
  311. y,
  312. cx,
  313. cy,
  314. 0,
  315. 0,
  316. BC_INVERT);
  317. } else if (uFlags & DSS_DEFAULT) {
  318. BltColor(hdcDraw,
  319. hbrFore,
  320. gpDispInfo->hdcGray,
  321. x,
  322. y,
  323. cx,
  324. cy,
  325. 0,
  326. 0,
  327. BC_INVERT);
  328. BltColor(hdcDraw,
  329. hbrFore,
  330. gpDispInfo->hdcGray,
  331. x+1,
  332. y,
  333. cx,
  334. cy,
  335. 0,
  336. 0,
  337. BC_INVERT);
  338. } else {
  339. BltColor(hdcDraw,
  340. hbrFore,
  341. gpDispInfo->hdcGray,
  342. x,
  343. y,
  344. cx,
  345. cy,
  346. 0,
  347. 0,
  348. BC_INVERT);
  349. }
  350. if ((uFlags & DSS_MONO)){
  351. /*
  352. * Set the hdcGray layout to 0, it is a public DC.
  353. */
  354. GreSetLayout(hdcT, -1, 0);
  355. }
  356. return fResult;
  357. }
  358. /***************************************************************************\
  359. * BltColor
  360. *
  361. * <brief description>
  362. *
  363. * History:
  364. * 13-Nov-1990 JimA Ported from Win3.
  365. \***************************************************************************/
  366. VOID BltColor(
  367. HDC hdc,
  368. HBRUSH hbr,
  369. HDC hdcSrce,
  370. int xO,
  371. int yO,
  372. int cx,
  373. int cy,
  374. int xO1,
  375. int yO1,
  376. UINT uBltFlags)
  377. {
  378. HBRUSH hbrSave;
  379. DWORD textColorSave;
  380. DWORD bkColorSave;
  381. DWORD ROP;
  382. /*
  383. * Set the Text and Background colors so that bltColor handles the
  384. * background of buttons (and other bitmaps) properly.
  385. * Save the HDC's old Text and Background colors. This causes problems
  386. * with Omega (and probably other apps) when calling GrayString which
  387. * uses this routine...
  388. */
  389. textColorSave = GreSetTextColor(hdc, 0x00000000L);
  390. bkColorSave = GreSetBkColor(hdc, 0x00FFFFFFL);
  391. if (hbr != NULL)
  392. hbrSave = GreSelectBrush(hdc, hbr);
  393. if (uBltFlags & BC_INVERT)
  394. ROP = 0xB8074AL;
  395. else
  396. ROP = 0xE20746L;
  397. if (uBltFlags & BC_NOMIRROR)
  398. ROP |= NOMIRRORBITMAP;
  399. GreBitBlt(hdc,
  400. xO,
  401. yO,
  402. cx,
  403. cy,
  404. hdcSrce ? hdcSrce : gpDispInfo->hdcGray,
  405. xO1,
  406. yO1,
  407. ROP,
  408. 0x00FFFFFF);
  409. if (hbr != NULL)
  410. GreSelectBrush(hdc, hbrSave);
  411. /*
  412. * Restore saved colors
  413. */
  414. GreSetTextColor(hdc, textColorSave);
  415. GreSetBkColor(hdc, bkColorSave);
  416. }