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

/**************************** 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);
}