|
|
/**************************** Module Header ********************************\
* Module Name: mngray.c * * Copyright (c) 1985 - 1999, Microsoft Corporation * * Server-side version of DrawState. * * History: * 06-Jan-1993 FritzS Created \***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/***************************************************************************\
* * CreateCompatiblePublicDC * * This is used in several callback routines to the lpk(s). We can't * pass G_TERM(pDispInfo)->hdcGray, HDCBITS() or gfade.hdc to the client since * they are public DCs. * We can't just change the owner since we're about to leave the * critical section. Some other thread may enter before we return * and use hdcGray, HDCBITS() or gfade.hdc. Instead, we create a compatible * dc with the same font and bitmap that are currently selected in hdcGray, * HDCBITS() or gfade.hdc). Pass that to the client lpk. * * If the function returns successfully , then the dc and bitmap object are * guaranteed to be successfully created. * * History: * * Dec-16-1997 Samer Arafeh [samera] * Jan-20-1998 Samer Arafeh [samera] Add support for both hdcGray and HDCBITS() * May-05-2000 MHamid Add support for gfade.hdc * \***************************************************************************/ HDC CreateCompatiblePublicDC( HDC hdcPublic, HBITMAP *pbmPublicDC) { HDC hdcCompatible = 0; HBITMAP hbmCompatible, hbm = NULL; BITMAP bmBits; HFONT hFont;
/*
* If it is not public DC just return it. */ if(GreGetObjectOwner((HOBJ)hdcPublic, DC_TYPE) != OBJECT_OWNER_PUBLIC) { return hdcPublic; }
if ((hdcCompatible = GreCreateCompatibleDC(hdcPublic)) == NULL) { RIPMSG1(RIP_WARNING, "CreateCompatiblePublicDC: GreCreateCompatibleDC Failed %lX", hdcPublic); return (HDC)NULL; }
if (!GreSetDCOwner(hdcCompatible, OBJECT_OWNER_CURRENT)) { RIPMSG1(RIP_WARNING, "CreateCompatiblePublicDC: SetDCOwner Failed %lX", hdcCompatible); GreDeleteDC(hdcCompatible); return (HDC)NULL; }
hbm = NtGdiGetDCObject(hdcPublic, LO_BITMAP_TYPE);
GreExtGetObjectW(hbm, sizeof(BITMAP), &bmBits);
hbmCompatible = GreCreateCompatibleBitmap(hdcPublic, bmBits.bmWidth, bmBits.bmHeight);
//
// Check whether bitmap couldn't be created or can't
// be set to OBJECT_OWNER_CURRENT, then fail and
// do necessary cleanup now!
//
if( (hbmCompatible == NULL) || (!GreSetBitmapOwner(hbmCompatible, OBJECT_OWNER_CURRENT)) ) {
RIPMSG1(RIP_WARNING, "CreateCompatiblePublicDC: GreCreateCompatibleBitmap Failed %lX", hbmCompatible); GreDeleteDC( hdcCompatible );
if( hbmCompatible ) { GreDeleteObject( hbmCompatible ); }
return (HDC)NULL; }
GreSelectBitmap(hdcCompatible, hbmCompatible); /*
* Make sure we use the same font and text alignment. */ hFont = GreSelectFont(hdcPublic, ghFontSys); GreSelectFont(hdcPublic, hFont); GreSelectFont(hdcCompatible, hFont); GreSetTextAlign(hdcCompatible, GreGetTextAlign(hdcPublic)); /*
* Copy any information already written into G_TERM(pDispInfo)->hdcGray. */
//
// Mirror the created DC if the hdcGray is currently mirrored,
// so that TextOut won't get mirrored on User Client DCs
//
if (GreGetLayout(hdcPublic) & LAYOUT_RTL) { GreSetLayout(hdcCompatible, bmBits.bmWidth - 1, LAYOUT_RTL); } GreBitBlt(hdcCompatible, 0, 0, bmBits.bmWidth, bmBits.bmHeight, hdcPublic, 0, 0, SRCCOPY, 0);
*pbmPublicDC = hbmCompatible ; // for later deletion, by the server side
return hdcCompatible; }
/***************************************************************************\
* * xxxDrawState() * * Generic state drawing routine. Does simple drawing into same DC if * normal state; uses offscreen bitmap otherwise. * * We do drawing for these simple types ourselves: * (1) Text * lData is string pointer. * wData is string length * (2) Icon * LOWORD(lData) is hIcon * (3) Bitmap * LOWORD(lData) is hBitmap * (4) Glyph (internal) * LOWORD(lData) is OBI_ value, one of * OBI_CHECKMARK * OBI_BULLET * OBI_MENUARROW * right now * * Other types are required to draw via the callback function, and are * allowed to stick whatever they want in lData and wData. * * We apply the following effects onto the image: * (1) Normal (nothing) * (2) Default (drop shadow) * (3) Union (gray string dither) * (4) Disabled (embossed) * * Note that we do NOT stretch anything. We just clip. * \***************************************************************************/ BOOL xxxDrawState( HDC hdcDraw, HBRUSH hbrFore, LPARAM lData, int x, int y, int cx, int cy, UINT uFlags) { HFONT hFont; HFONT hFontSave = NULL; HDC hdcT; HBITMAP hbmpT; POINT ptOrg; BOOL fResult; int oldAlign; DWORD dwOldLayout=0;
/*
* These require monochrome conversion * * Enforce monochrome: embossed doesn't look great with 2 color displays */ if ((uFlags & DSS_DISABLED) && ((gpsi->BitCount == 1) || SYSMET(SLOWMACHINE))) {
uFlags &= ~DSS_DISABLED; uFlags |= DSS_UNION; }
if (uFlags & (DSS_INACTIVE | DSS_DISABLED | DSS_DEFAULT | DSS_UNION)) uFlags |= DSS_MONO;
/*
* Validate flags - we only support DST_COMPLEX in kernel */ if ((uFlags & DST_TYPEMASK) != DST_COMPLEX) { RIPMSG1(RIP_ERROR, "xxxDrawState: invalid DST_ type %x", (uFlags & DST_TYPEMASK)); return FALSE; }
/*
* Optimize: nothing to draw */ if (!cx || !cy) { return TRUE; }
/*
* Setup drawing dc */ if (uFlags & DSS_MONO) {
hdcT = gpDispInfo->hdcGray; /*
* First turn off mirroring on hdcGray if any. */ GreSetLayout(hdcT, -1, 0); /*
* Set the hdcGray layout to be equal to the screen hdcDraw layout. */ dwOldLayout = GreGetLayout(hdcDraw); if (dwOldLayout != GDI_ERROR) { GreSetLayout(hdcT, cx, dwOldLayout); }
/*
* Is our scratch bitmap big enough? We need potentially * cx+1 by cy pixels for default etc. */ if ((gpDispInfo->cxGray < cx + 1) || (gpDispInfo->cyGray < cy)) {
if (hbmpT = GreCreateBitmap(max(gpDispInfo->cxGray, cx + 1), max(gpDispInfo->cyGray, cy), 1, 1, 0L)) {
HBITMAP hbmGray;
hbmGray = GreSelectBitmap(gpDispInfo->hdcGray, hbmpT); GreDeleteObject(hbmGray);
GreSetBitmapOwner(hbmpT, OBJECT_OWNER_PUBLIC);
gpDispInfo->cxGray = max(gpDispInfo->cxGray, cx + 1); gpDispInfo->cyGray = max(gpDispInfo->cyGray, cy);
} else { cx = gpDispInfo->cxGray - 1; cy = gpDispInfo->cyGray; } }
GrePatBlt(gpDispInfo->hdcGray, 0, 0, gpDispInfo->cxGray, gpDispInfo->cyGray, WHITENESS);
GreSetTextCharacterExtra(gpDispInfo->hdcGray, GreGetTextCharacterExtra(hdcDraw));
oldAlign = GreGetTextAlign(hdcT); GreSetTextAlign(hdcT, (oldAlign & ~(TA_RTLREADING |TA_CENTER |TA_RIGHT)) | (GreGetTextAlign(hdcDraw) & (TA_RTLREADING |TA_CENTER |TA_RIGHT))); /*
* Setup font */ if (GreGetHFONT(hdcDraw) != ghFontSys) { hFont = GreSelectFont(hdcDraw, ghFontSys); GreSelectFont(hdcDraw, hFont); hFontSave = GreSelectFont(gpDispInfo->hdcGray, hFont); } } else { hdcT = hdcDraw; /*
* Adjust viewport */ GreGetViewportOrg(hdcT, &ptOrg); GreSetViewportOrg(hdcT, ptOrg.x+x, ptOrg.y+y, NULL);
}
/*
* Now, draw original image */ fResult = xxxRealDrawMenuItem(hdcT, (PGRAYMENU)lData, cx, cy);
/*
* The callbacks could have altered the attributes of hdcGray */ if (hdcT == gpDispInfo->hdcGray) { GreSetBkColor(gpDispInfo->hdcGray, RGB(255, 255, 255)); GreSetTextColor(gpDispInfo->hdcGray, RGB(0, 0, 0)); GreSelectBrush(gpDispInfo->hdcGray, ghbrBlack); GreSetBkMode(gpDispInfo->hdcGray, OPAQUE); }
/*
* Clean up */ if (uFlags & DSS_MONO) {
/*
* Reset font */ if (hFontSave) GreSelectFont(hdcT, hFontSave); GreSetTextAlign(hdcT, oldAlign); } else { /*
* Reset DC. */ GreSetViewportOrg(hdcT, ptOrg.x, ptOrg.y, NULL); return TRUE; }
/*
* UNION state * Dither over image * We want white pixels to stay white, in either dest or pattern. */ if (uFlags & DSS_UNION) {
POLYPATBLT PolyData;
PolyData.x = 0; PolyData.y = 0; PolyData.cx = cx; PolyData.cy = cy; PolyData.BrClr.hbr = gpsi->hbrGray;
GrePolyPatBlt(gpDispInfo->hdcGray, PATOR, &PolyData, 1, PPB_BRUSH); }
if (uFlags & DSS_INACTIVE) {
BltColor(hdcDraw, SYSHBR(3DSHADOW), gpDispInfo->hdcGray, x, y, cx, cy, 0, 0, BC_INVERT);
} else if (uFlags & DSS_DISABLED) {
/*
* Emboss * Draw over-1/down-1 in hilight color, and in same position in shadow. */
BltColor(hdcDraw, SYSHBR(3DHILIGHT), gpDispInfo->hdcGray, x+1, y+1, cx, cy, 0, 0, BC_INVERT);
BltColor(hdcDraw, SYSHBR(3DSHADOW), gpDispInfo->hdcGray, x, y, cx, cy, 0, 0, BC_INVERT);
} else if (uFlags & DSS_DEFAULT) {
BltColor(hdcDraw, hbrFore, gpDispInfo->hdcGray, x, y, cx, cy, 0, 0, BC_INVERT);
BltColor(hdcDraw, hbrFore, gpDispInfo->hdcGray, x+1, y, cx, cy, 0, 0, BC_INVERT);
} else {
BltColor(hdcDraw, hbrFore, gpDispInfo->hdcGray, x, y, cx, cy, 0, 0, BC_INVERT); }
if ((uFlags & DSS_MONO)){ /*
* Set the hdcGray layout to 0, it is a public DC. */ GreSetLayout(hdcT, -1, 0); } return fResult; }
/***************************************************************************\
* BltColor * * <brief description> * * History: * 13-Nov-1990 JimA Ported from Win3. \***************************************************************************/
VOID BltColor( HDC hdc, HBRUSH hbr, HDC hdcSrce, int xO, int yO, int cx, int cy, int xO1, int yO1, UINT uBltFlags) { HBRUSH hbrSave; DWORD textColorSave; DWORD bkColorSave; DWORD ROP;
/*
* Set the Text and Background colors so that bltColor handles the * background of buttons (and other bitmaps) properly. * Save the HDC's old Text and Background colors. This causes problems * with Omega (and probably other apps) when calling GrayString which * uses this routine... */ textColorSave = GreSetTextColor(hdc, 0x00000000L); bkColorSave = GreSetBkColor(hdc, 0x00FFFFFFL);
if (hbr != NULL) hbrSave = GreSelectBrush(hdc, hbr); if (uBltFlags & BC_INVERT) ROP = 0xB8074AL; else ROP = 0xE20746L;
if (uBltFlags & BC_NOMIRROR) ROP |= NOMIRRORBITMAP;
GreBitBlt(hdc, xO, yO, cx, cy, hdcSrce ? hdcSrce : gpDispInfo->hdcGray, xO1, yO1, ROP, 0x00FFFFFF);
if (hbr != NULL) GreSelectBrush(hdc, hbrSave);
/*
* Restore saved colors */ GreSetTextColor(hdc, textColorSave); GreSetBkColor(hdc, bkColorSave); }
|