Hi.
This is my first attempt to implement something in win32k. Please review
and point out mistakes, if any. I commited testapps to trunk. From
testcode I
found that our current implementation has bugs and fixed them. You can see
them on screenshot:
http://i1.tinypic.com/20a9te1.jpg
In windows:
http://i1.tinypic.com/20a9thf.jpg
With my patch:
http://i1.tinypic.com/20a9to2.jpg
And now I'll ask some questions :)
1) Internal functions naming. Some functions have prefix like Int*,
User*, co_* etc., some don't have any prefix. Is there any standart?
2) Is there any difference between shared and exclusive lock?
When should I use shared lock, and when exlusive? In ntuser.h I saw this:
#define UserEnterShared() UserEnterExclusive()
I guess this is temporary hack, isn't it?
Index: subsystems/win32/win32k/ntuser/painting.c
===================================================================
--- subsystems/win32/win32k/ntuser/painting.c (revision 23134)
+++ subsystems/win32/win32k/ntuser/painting.c (working copy)
@@ -32,7 +32,7 @@
#include <w32k.h>
-#define NDEBUG
+#undef NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS **********************************************************/
@@ -1372,4 +1372,392 @@
END_CLEANUP;
}
+/* Don't know where to put this */
+BOOL FASTCALL IntGdiGradientFill(DC *dc, PTRIVERTEX pVertex, ULONG uVertex, PVOID pMesh,
ULONG uMesh, ULONG ulMode);
+ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT
fWinIni);
+BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth,
+ INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags);
+PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
+
+BOOL
+IntDrawSysMenuButton(
+ PWINDOW_OBJECT pWnd,
+ HDC hDc,
+ LPRECT lpRc,
+ BOOL Down)
+{
+ HICON hIcon;
+ PCURICON_OBJECT pIcon;
+
+ ASSERT(pWnd && lpRc);
+
+ /* Get the icon to draw. We don't care about WM_GETICON here. */
+
+ hIcon = pWnd->Class->hIconSm;
+
+ if(!hIcon)
+ {
+ DPRINT("Wnd class has no small icon.\n");
+ hIcon = pWnd->Class->hIcon;
+ }
+
+ if(!hIcon)
+ {
+ DPRINT("Wnd class hasn't any icon.\n");
+ //FIXME: Draw "winlogo" icon.
+ return FALSE;
+ }
+
+ if(!(pIcon = UserGetCurIconObject(hIcon)))
+ {
+ DPRINT1("UserGetCurIconObject() failed!\n");
+ return FALSE;
+ }
+
+ return UserDrawIconEx(hDc, lpRc->left, lpRc->top, pIcon,
+ UserGetSystemMetrics(SM_CXSMICON),
+ UserGetSystemMetrics(SM_CYSMICON),
+ 0, NULL, DI_NORMAL);
+}
+
+BOOL
+IntDrawCaptionText(HDC hDc,
+ const PUNICODE_STRING Text,
+ const LPRECT lpRc,
+ UINT uFlags)
+{
+ HFONT hOldFont = NULL, hFont = NULL;
+ COLORREF OldTextColor;
+ NONCLIENTMETRICS nclm;
+ NTSTATUS Status;
+ INT i;
+
+ #ifndef NDEBUG
+ DPRINT("%s:", __FUNCTION__);
+ for(i = 0; i < Text->Length/sizeof(WCHAR); i++)
+ DbgPrint("%C", Text->Buffer[i]);
+ DbgPrint(", %d\n", Text->Length/sizeof(WCHAR));
+ #endif
+
+ nclm.cbSize = sizeof(nclm);
+ if(!IntSystemParametersInfo(SPI_GETNONCLIENTMETRICS,
+ sizeof(NONCLIENTMETRICS), &nclm, 0))
+ {
+ DPRINT1("%s: IntSystemParametersInfo() failed!\n", __FUNCTION__);
+ return FALSE;
+ }
+
+ NtGdiSetBkMode(hDc, TRANSPARENT);
+
+ if(uFlags & DC_SMALLCAP)
+ Status = TextIntCreateFontIndirect(&nclm.lfSmCaptionFont, &hFont);
+ else Status = TextIntCreateFontIndirect(&nclm.lfCaptionFont, &hFont);
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("%s: TextIntCreateFontIndirect() failed! Status: 0x%x\n",
+ __FUNCTION__, Status);
+ return FALSE;
+ }
+
+ hOldFont = NtGdiSelectObject(hDc, hFont);
+ if(!hOldFont)
+ {
+ DPRINT1("%s: SelectObject() failed!\n", __FUNCTION__);
+ NtGdiDeleteObject(hFont);
+ return FALSE;
+ }
+
+ if(uFlags & DC_INBUTTON)
+ OldTextColor = NtGdiSetTextColor(hDc, IntGetSysColor(COLOR_BTNTEXT));
+ else OldTextColor = NtGdiSetTextColor(hDc, IntGetSysColor(uFlags & DC_ACTIVE
+ ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT));
+
+ //FIXME: If string doesn't fit to rc, truncate it and add ellipsis.
+
+ NtGdiTextOut(hDc, lpRc->left,
+ lpRc->top, Text->Buffer,
+ Text->Length/sizeof(WCHAR));
+
+ NtGdiSetTextColor(hDc, OldTextColor);
+ NtGdiSelectObject(hDc, hOldFont);
+ NtGdiDeleteObject(hFont);
+
+ return TRUE;
+}
+
+BOOL UserDrawCaption(
+ PWINDOW_OBJECT pWnd,
+ HDC hDc,
+ LPCRECT lpRc,
+ UINT uFlags)
+{
+ BOOL Ret = FALSE;
+ HBITMAP hMemBmp = NULL, hOldBmp = NULL;
+ HBRUSH hOldBrush = NULL;
+ HDC hMemDc = NULL;
+ ULONG Height;
+ UINT VCenter = 0, Padding = 0;
+ RECT r = *lpRc;
+ LONG ButtonWidth, IconWidth;
+ BOOL HasIcon;
+
+ ASSERT(pWnd != NULL);
+
+ hMemBmp = NtGdiCreateCompatibleBitmap(hDc,
+ lpRc->right - lpRc->left,
+ lpRc->bottom - lpRc->top);
+
+ if(!hMemBmp)
+ {
+ DPRINT1("%s: NtGdiCreateCompatibleBitmap() failed!\n", __FUNCTION__);
+ return FALSE;
+ }
+
+ hMemDc = NtGdiCreateCompatibleDC(hDc);
+ if(!hMemDc)
+ {
+ DPRINT1("%s: NtGdiCreateCompatibleDC() failed!\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ hOldBmp = NtGdiSelectObject(hMemDc, hMemBmp);
+ if(!hOldBmp)
+ {
+ DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ Height = UserGetSystemMetrics(SM_CYCAPTION) - 1;
+ VCenter = (lpRc->bottom - lpRc->top) / 2;
+ Padding = VCenter - (Height / 2);
+ HasIcon = (uFlags & DC_ICON) && (pWnd->Style & WS_SYSMENU)
+ && !(uFlags & DC_SMALLCAP);
+ IconWidth = UserGetSystemMetrics(SM_CXSIZE) + Padding;
+
+ r.left = Padding;
+ r.right = r.left + (lpRc->right - lpRc->left);
+ r.top = Padding;
+ r.bottom = r.top + (Height / 2);
+
+ // Draw the caption background
+ if(uFlags & DC_INBUTTON)
+ {
+ hOldBrush = NtGdiSelectObject(hMemDc,
+ IntGetSysColorBrush(uFlags & DC_ACTIVE ?
+ COLOR_BTNFACE : COLOR_BTNSHADOW));
+
+ if(!hOldBrush)
+ {
+ DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ if(!NtGdiPatBlt(hMemDc, 0, 0,
+ lpRc->right - lpRc->left,
+ lpRc->bottom - lpRc->top,
+ PATCOPY))
+ {
+ DPRINT1("%s: NtGdiPatBlt() failed!\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ if(HasIcon) r.left+=IconWidth;
+ }
+ else
+ {
+ r.right = (lpRc->right - lpRc->left);
+ if(uFlags & DC_SMALLCAP)
+ ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2;
+ else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2;
+
+ hOldBrush = NtGdiSelectObject(hMemDc,
+ IntGetSysColorBrush(uFlags & DC_ACTIVE ?
+ COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
+
+ if(!hOldBrush)
+ {
+ DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ if(HasIcon && (uFlags & DC_GRADIENT))
+ {
+ NtGdiPatBlt(hMemDc, 0, 0,
+ IconWidth+1,
+ lpRc->bottom - lpRc->top,
+ PATCOPY);
+ r.left+=IconWidth;
+ }
+ else
+ {
+ NtGdiPatBlt(hMemDc, 0, 0,
+ lpRc->right - lpRc->left,
+ lpRc->bottom - lpRc->top,
+ PATCOPY);
+ }
+
+ if(uFlags & DC_GRADIENT)
+ {
+ static GRADIENT_RECT gcap = {0, 1};
+ TRIVERTEX vert[2];
+ COLORREF Colors[2];
+ PDC pMemDc;
+
+ if(pWnd->Style & WS_SYSMENU)
+ {
+ r.right -= 3 + ButtonWidth;
+ if(!(uFlags & DC_SMALLCAP))
+ {
+ if(pWnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+ r.right -= 2 + 2 * ButtonWidth;
+ else r.right -= 2;
+ r.right -= 2;
+ }
+
+ //Draw buttons background
+ if(!NtGdiSelectObject(hMemDc,
+ IntGetSysColorBrush(uFlags & DC_ACTIVE ?
+ COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION)))
+ {
+ DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ NtGdiPatBlt(hMemDc,
+ r.right,
+ 0,
+ lpRc->right - lpRc->left - r.right,
+ lpRc->bottom - lpRc->top,
+ PATCOPY);
+ }
+
+ Colors[0] = IntGetSysColor((uFlags & DC_ACTIVE) ?
+ COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION);
+
+ Colors[1] = IntGetSysColor((uFlags & DC_ACTIVE) ?
+ COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION);
+
+ vert[0].x = r.left;
+ vert[0].y = 0;
+ vert[0].Red = (WORD)Colors[0]<<8;
+ vert[0].Green = (WORD)Colors[0] & 0xFF00;
+ vert[0].Blue = (WORD)(Colors[0]>>8) & 0xFF00;
+ vert[0].Alpha = 0;
+
+ vert[1].x = r.right;
+ vert[1].y = lpRc->bottom - lpRc->top;
+ vert[1].Red = (WORD)Colors[1]<<8;
+ vert[1].Green = (WORD)Colors[1] & 0xFF00;
+ vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
+ vert[1].Alpha = 0;
+
+ pMemDc = DC_LockDc(hMemDc);
+ if(!pMemDc)
+ {
+ DPRINT1("%s: Can't lock dc!\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap,
+ 1, GRADIENT_FILL_RECT_H))
+ {
+ DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__);
+ }
+
+ DC_UnlockDc(pMemDc);
+ } //if(uFlags & DC_GRADIENT)
+ }
+
+ if(HasIcon)
+ {
+ r.top ++;
+ r.left -= --IconWidth;
+ IntDrawSysMenuButton(pWnd, hMemDc, &r, FALSE);
+ r.left += IconWidth;
+ r.top --;
+ }
+
+ r.top ++;
+ r.left += 2;
+
+ r.bottom = r.top + Height;
+
+ if((uFlags & DC_TEXT) && pWnd->WindowName.Length)
+ {
+ if(!(uFlags & DC_GRADIENT))
+ {
+ r.right = (lpRc->right - lpRc->left);
+
+ if(uFlags & DC_SMALLCAP)
+ ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2;
+ else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2;
+
+ if(pWnd->Style & WS_SYSMENU)
+ {
+ r.right -= 3 + ButtonWidth;
+ if(! (uFlags & DC_SMALLCAP))
+ {
+ if(pWnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+ r.right -= 2 + 2 * ButtonWidth;
+ else r.right -= 2;
+ r.right -= 2;
+ }
+ }
+ }
+
+ IntDrawCaptionText(hMemDc, &pWnd->WindowName, &r, uFlags);
+ }
+
+ if(!NtGdiBitBlt(hDc, lpRc->left, lpRc->top,
+ lpRc->right - lpRc->left, lpRc->bottom - lpRc->top,
+ hMemDc, 0, 0, SRCCOPY, 0, 0))
+ {
+ DPRINT1("%s: NtGdiBitBlt() failed!\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ Ret = TRUE;
+
+cleanup:
+ if (hOldBrush) NtGdiSelectObject(hMemDc, hOldBrush);
+ if (hOldBmp) NtGdiSelectObject(hMemDc, hOldBmp);
+ if (hMemBmp) NtGdiDeleteObject(hMemBmp);
+ if (hMemDc) NtGdiDeleteObjectApp(hMemDc);
+
+ return Ret;
+}
+
+
+BOOL
+STDCALL
+NtUserDrawCaption(HWND hWnd,
+ HDC hDc,
+ LPCRECT lpRc,
+ UINT uFlags)
+{
+ PWINDOW_OBJECT pWnd;
+ RECT SafeRect;
+ BOOL Ret;
+
+ if(!NT_SUCCESS(MmCopyFromCaller(&SafeRect, lpRc, sizeof(RECT))))
+ {
+ DPRINT1("%s: MmCopyFromCaller failed!", __FUNCTION__);
+ return FALSE;
+ }
+
+ UserEnterExclusive();
+
+ if(!(pWnd = UserGetWindowObject(hWnd)))
+ {
+ UserLeave();
+ return FALSE;
+ }
+
+ Ret = UserDrawCaption(pWnd, hDc, &SafeRect, uFlags);
+
+ UserLeave();
+ return Ret;
+}
+
/* EOF */
Index: subsystems/win32/win32k/ntuser/cursoricon.c
===================================================================
--- subsystems/win32/win32k/ntuser/cursoricon.c (revision 23134)
+++ subsystems/win32/win32k/ntuser/cursoricon.c (working copy)
@@ -72,7 +72,6 @@
}
-static
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
{
PCURICON_OBJECT CurIcon;
@@ -1346,66 +1345,49 @@
(Rop3), 0)
#endif /* STRETCH_CAN_SRCCOPY_ONLY */
-/*
- * @implemented
- */
-BOOL
-STDCALL
-NtUserDrawIconEx(
- HDC hdc,
- int xLeft,
- int yTop,
- HICON hIcon,
- int cxWidth,
- int cyHeight,
+BOOL
+UserDrawIconEx(
+ HDC hDc,
+ INT xLeft,
+ INT yTop,
+ PCURICON_OBJECT pIcon,
+ INT cxWidth,
+ INT cyHeight,
UINT istepIfAniCur,
HBRUSH hbrFlickerFreeDraw,
- UINT diFlags,
- DWORD Unknown0,
- DWORD Unknown1)
+ UINT diFlags)
{
- PCURICON_OBJECT CurIcon;
- PWINSTATION_OBJECT WinSta;
+ BOOL Ret = FALSE;
HBITMAP hbmMask, hbmColor;
BITMAP bmpMask, bmpColor;
+ COLORREF oldFg, oldBg;
BOOL DoFlickerFree;
+ INT nStretchMode;
SIZE IconSize;
- COLORREF oldFg, oldBg;
- HDC hdcMem, hdcOff = (HDC)0;
- HBITMAP hbmOff = (HBITMAP)0;
- HGDIOBJ hOldOffBrush = 0, hOldOffBmp = 0, hOldMem;
- BOOL Ret = FALSE;
- INT nStretchMode;
+
+ HDC hdcOff;
+ HGDIOBJ hOldOffBrush = 0;
+ HGDIOBJ hOldOffBmp = 0;
+ HBITMAP hbmOff = 0;
+ HDC hdcMem = 0;
+ HGDIOBJ hOldMem;
+
+ hbmMask = pIcon->IconInfo.hbmMask;
+ hbmColor = pIcon->IconInfo.hbmColor;
- DECLARE_RETURN(BOOL);
+ if(istepIfAniCur)
+ DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
- DPRINT("Enter NtUserDrawIconEx\n");
- UserEnterExclusive();
-
- WinSta = IntGetWinStaObj();
- if(WinSta == NULL)
+ if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
{
- RETURN( FALSE);
+ return FALSE;
}
- if (!(CurIcon = UserGetCurIconObject(hIcon)))
+ if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
{
- ObDereferenceObject(WinSta);
- RETURN(FALSE);
+ return FALSE;
}
- hbmMask = CurIcon->IconInfo.hbmMask;
- hbmColor = CurIcon->IconInfo.hbmColor;
-
- if(istepIfAniCur)
- DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
-
- if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
- goto done;
-
- if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
- goto done;
-
if(hbmColor)
{
IconSize.cx = bmpColor.bmWidth;
@@ -1421,11 +1403,15 @@
diFlags = DI_NORMAL;
if(!cxWidth)
- cxWidth = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CXICON) :
IconSize.cx);
+ cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
+ UserGetSystemMetrics(SM_CXICON) : IconSize.cx);
+
if(!cyHeight)
- cyHeight = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CYICON) :
IconSize.cy);
+ cyHeight = ((diFlags & DI_DEFAULTSIZE) ?
+ UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
- DoFlickerFree = (hbrFlickerFreeDraw && (NtGdiGetObjectType(hbrFlickerFreeDraw)
== OBJ_BRUSH));
+ DoFlickerFree = (hbrFlickerFreeDraw &&
+ (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH));
if(DoFlickerFree)
{
@@ -1433,29 +1419,45 @@
r.right = cxWidth;
r.bottom = cyHeight;
- hdcOff = NtGdiCreateCompatibleDC(hdc);
+ hdcOff = NtGdiCreateCompatibleDC(hDc);
if(!hdcOff)
- goto done;
+ {
+ DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
+ return FALSE;
+ }
- hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyHeight);
+ hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
if(!hbmOff)
{
- NtGdiDeleteObjectApp(hdcOff);
- goto done;
+ DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n");
+ goto cleanup;
}
+
hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
+ if(!hOldOffBrush)
+ {
+ DPRINT1("NtGdiSelectObject() failed!\n");
+ goto cleanup;
+ }
+
hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
+ if(!hOldOffBmp)
+ {
+ DPRINT1("NtGdiSelectObject() failed!\n");
+ goto cleanup;
+ }
+
NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
- NtGdiSelectObject(hdcOff, hbmOff);
}
-
- hdcMem = NtGdiCreateCompatibleDC(hdc);
+ else hdcOff = hDc;
+
+ hdcMem = NtGdiCreateCompatibleDC(hDc);
if(!hdcMem)
+ {
+ DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
goto cleanup;
+ }
- if(!DoFlickerFree)
- hdcOff = hdc;
-
nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS);
oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0));
@@ -1464,13 +1466,19 @@
if(diFlags & DI_MASK)
{
hOldMem = NtGdiSelectObject(hdcMem, hbmMask);
+ if(!hOldMem)
+ {
+ DPRINT("NtGdiSelectObject() failed!\n");
+ goto cleanup;
+ }
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
(DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
0, 0, IconSize.cx, IconSize.cy,
((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE);
- if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth) &&
(diFlags & DI_IMAGE))
+ if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth)
+ && (diFlags & DI_IMAGE))
{
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
(DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
@@ -1479,9 +1487,10 @@
diFlags &= ~DI_IMAGE;
}
+
NtGdiSelectObject(hdcMem, hOldMem);
}
-
+
if(diFlags & DI_IMAGE)
{
hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask));
@@ -1496,35 +1505,72 @@
}
if(DoFlickerFree)
- NtGdiBitBlt(hdc, xLeft, yTop, cxWidth, cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
-
+ {
+ NtGdiBitBlt(hDc, xLeft, yTop, cxWidth,
+ cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
+ }
+
NtGdiSetTextColor(hdcOff, oldFg);
NtGdiSetBkColor(hdcOff, oldBg);
-
NtGdiSetStretchBltMode(hdcOff, nStretchMode);
-
+
Ret = TRUE;
-
+
cleanup:
if(DoFlickerFree)
{
- NtGdiSelectObject(hdcOff, hOldOffBmp);
- NtGdiSelectObject(hdcOff, hOldOffBrush);
- NtGdiDeleteObject(hbmOff);
- NtGdiDeleteObjectApp(hdcOff);
+ if(hOldOffBmp) NtGdiSelectObject(hdcOff, hOldOffBmp);
+ if(hOldOffBrush) NtGdiSelectObject(hdcOff, hOldOffBrush);
+ if(hbmOff) NtGdiDeleteObject(hbmOff);
+ if(hdcOff) NtGdiDeleteObjectApp(hdcOff);
}
- if(hdcMem)
- NtGdiDeleteObjectApp(hdcMem);
+
+ if(hdcMem) NtGdiDeleteObjectApp(hdcMem);
+ return Ret;
+}
-done:
- ObDereferenceObject(WinSta);
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+NtUserDrawIconEx(
+ HDC hdc,
+ int xLeft,
+ int yTop,
+ HICON hIcon,
+ int cxWidth,
+ int cyHeight,
+ UINT istepIfAniCur,
+ HBRUSH hbrFlickerFreeDraw,
+ UINT diFlags,
+ DWORD Unknown0,
+ DWORD Unknown1)
+{
+ PCURICON_OBJECT pIcon;
+ BOOL Ret;
- RETURN( Ret);
+ DPRINT("Enter NtUserDrawIconEx\n");
+ UserEnterExclusive();
+
+ if(!(pIcon = UserGetCurIconObject(hIcon)))
+ {
+ DPRINT1("UserGetCurIconObject() failed!\n");
+ UserLeave();
+ return FALSE;
+ }
+
+ Ret = UserDrawIconEx(hdc,
+ xLeft,
+ yTop,
+ pIcon,
+ cxWidth,
+ cyHeight,
+ istepIfAniCur,
+ hbrFlickerFreeDraw,
+ diFlags);
-CLEANUP:
- DPRINT("Leave NtUserDrawIconEx, ret=%i\n",_ret_);
UserLeave();
- END_CLEANUP;
+ return Ret;
}
-
Index: subsystems/win32/win32k/ntuser/ntstubs.c
===================================================================
--- subsystems/win32/win32k/ntuser/ntstubs.c (revision 23134)
+++ subsystems/win32/win32k/ntuser/ntstubs.c (working copy)
@@ -193,19 +193,6 @@
DWORD
STDCALL
-NtUserDrawCaption(
- DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-DWORD
-STDCALL
NtUserDrawCaptionTemp(
DWORD Unknown0,
DWORD Unknown1,
Index: subsystems/win32/win32k/include/intgdi.h
===================================================================
--- subsystems/win32/win32k/include/intgdi.h (revision 23134)
+++ subsystems/win32/win32k/include/intgdi.h (working copy)
@@ -188,12 +188,18 @@
BOOL FASTCALL
IntGetSysColorBrushes(HBRUSH *Brushes, UINT nBrushes);
+HGDIOBJ FASTCALL
+IntGetSysColorBrush(INT Object);
+
BOOL FASTCALL
IntGetSysColorPens(HPEN *Pens, UINT nPens);
BOOL FASTCALL
IntGetSysColors(COLORREF *Colors, UINT nColors);
+DWORD FASTCALL
+IntGetSysColor(INT nIndex);
+
/* Other Stuff */
INT FASTCALL
Index: subsystems/win32/win32k/objects/stockobj.c
===================================================================
--- subsystems/win32/win32k/objects/stockobj.c (revision 23134)
+++ subsystems/win32/win32k/objects/stockobj.c (working copy)
@@ -210,6 +210,12 @@
return nBrushes > 0;
}
+HGDIOBJ FASTCALL
+IntGetSysColorBrush(INT Object)
+{
+ return ((Object < 0) || (NUM_SYSCOLORS <= Object)) ? NULL :
SysColorBrushes[Object];
+}
+
BOOL FASTCALL
IntGetSysColorPens(HPEN *Pens, UINT nPens)
{
@@ -254,6 +260,12 @@
return nColors > 0;
}
+DWORD FASTCALL
+IntGetSysColor(INT nIndex)
+{
+ return ((nIndex < 0) || (NUM_SYSCOLORS <= nIndex)) ? 0 : SysColors[nIndex];
+}
+
VOID FASTCALL
CreateSysColorObjects(VOID)
{
Index: include/reactos/win32k/ntuser.h
===================================================================
--- include/reactos/win32k/ntuser.h (revision 23134)
+++ include/reactos/win32k/ntuser.h (working copy)
@@ -687,12 +687,11 @@
DWORD
NTAPI
NtUserDragObject(
- HWND hwnd1,
- HWND hwnd2,
- UINT u1,
- DWORD dw1,
- HCURSOR hc1
- );
+ HWND hwnd1,
+ HWND hwnd2,
+ UINT u1,
+ DWORD dw1,
+ HCURSOR hc1);
DWORD
NTAPI
@@ -702,24 +701,24 @@
DWORD Unknown2,
DWORD Unknown3);
-DWORD
+BOOL
NTAPI
NtUserDrawCaption(
- DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3);
+ HWND hWnd,
+ HDC hDc,
+ LPCRECT lpRc,
+ UINT uFlags);
DWORD
-NTAPI
+STDCALL
NtUserDrawCaptionTemp(
- DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3,
- DWORD Unknown4,
- DWORD Unknown5,
- DWORD Unknown6);
+ DWORD Unknown0,
+ DWORD Unknown1,
+ DWORD Unknown2,
+ DWORD Unknown3,
+ DWORD Unknown4,
+ DWORD Unknown5,
+ DWORD Unknown6);
BOOL
NTAPI
Index: dll/win32/user32/windows/nonclient.c
===================================================================
--- dll/win32/user32/windows/nonclient.c (revision 23134)
+++ dll/win32/user32/windows/nonclient.c (working copy)
@@ -1097,231 +1097,9 @@
BOOL WINAPI
DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags)
{
- NONCLIENTMETRICSW nclm;
- BOOL result = FALSE;
- RECT r = *lprc;
- UINT VCenter = 0, Padding = 0, Height;
- ULONG Style;
- WCHAR buffer[256];
- HFONT hFont = NULL;
- HFONT hOldFont = NULL;
- HBRUSH OldBrush = NULL;
- HDC MemDC = NULL;
- int ButtonWidth;
- COLORREF OldTextColor;
-
-#ifdef DOUBLE_BUFFER_CAPTION
- HBITMAP MemBMP = NULL, OldBMP = NULL;
-
- MemDC = CreateCompatibleDC(hDC);
- if (! MemDC) goto cleanup;
- MemBMP = CreateCompatibleBitmap(hDC, lprc->right - lprc->left, lprc->bottom
- lprc->top);
- if (! MemBMP) goto cleanup;
- OldBMP = SelectObject(MemDC, MemBMP);
- if (! OldBMP) goto cleanup;
-#else
- MemDC = hDC;
-
- OffsetViewportOrgEx(MemDC, lprc->left, lprc->top, NULL);
-#endif
-
- Style = GetWindowLongW(hWnd, GWL_STYLE);
-
- /* Windows behaves like this */
- Height = GetSystemMetrics(SM_CYCAPTION) - 1;
-
- VCenter = (lprc->bottom - lprc->top) / 2;
- Padding = VCenter - (Height / 2);
-
- r.left = Padding;
- r.right = r.left + (lprc->right - lprc->left);
- r.top = Padding;
- r.bottom = r.top + (Height / 2);
-
- // Draw the caption background
- if (uFlags & DC_INBUTTON)
- {
- OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ?
COLOR_BTNFACE : COLOR_BTNSHADOW) );
- if (! OldBrush) goto cleanup;
- if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom -
lprc->top, PATCOPY )) goto cleanup;
- }
- else
- {
- if (uFlags & DC_GRADIENT)
- {
- static GRADIENT_RECT gcap = {0, 1};
- TRIVERTEX vert[2];
- COLORREF Colors[2];
- LONG xx;
-
- r.right = (lprc->right - lprc->left);
- if (uFlags & DC_SMALLCAP)
- ButtonWidth = GetSystemMetrics(SM_CXSMSIZE) - 2;
- else
- ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2;
-
- //if (Style & WS_SYSMENU)
- //{
- // r.right -= 3 + ButtonWidth;
- // if (! (uFlags & DC_SMALLCAP))
- // {
- // if(Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
- // r.right -= 2 + 2 * ButtonWidth;
- // else
- // r.right -= 2;
- // r.right -= 2;
- // }
- //}
-
- Colors[0] = GetSysColor((uFlags & DC_ACTIVE) ? COLOR_ACTIVECAPTION :
COLOR_INACTIVECAPTION);
- Colors[1] = GetSysColor((uFlags & DC_ACTIVE) ? COLOR_GRADIENTACTIVECAPTION
: COLOR_GRADIENTINACTIVECAPTION);
-
- vert[0].x = r.left;
- vert[0].y = 0;
- vert[0].Red = GetRValue(Colors[0]) << 8;
- vert[0].Green = GetGValue(Colors[0]) << 8;
- vert[0].Blue = GetBValue(Colors[0]) << 8;
- vert[0].Alpha = 0;
-
- vert[1].x = r.right;
- vert[1].y = lprc->bottom - lprc->top;
- vert[1].Red = GetRValue(Colors[1]) << 8;
- vert[1].Green = GetGValue(Colors[1]) << 8;
- vert[1].Blue = GetBValue(Colors[1]) << 8;
- vert[1].Alpha = 0;
-
- GdiGradientFill(MemDC, vert, 2, &gcap, 1, GRADIENT_FILL_RECT_V);
-
- if ((uFlags & DC_ICON) && (Style & WS_SYSMENU) &&
!(uFlags & DC_SMALLCAP))
- {
- r.top --;
- SetBkMode( MemDC, TRANSPARENT );
- xx = GetSystemMetrics(SM_CXSIZE) + Padding;
- if (UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE))
- r.left += xx;
- r.top ++;
- }
-
- if(OldBrush)
- {
- SelectObject(MemDC, OldBrush);
- OldBrush = NULL;
- }
- //xx = lprc->right - lprc->left - r.right;
- //if(xx > 0)
- //{
- // OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ?
COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION));
- // if (!OldBrush) goto cleanup;
- // PatBlt(MemDC, r.right, 0, xx, lprc->bottom - lprc->top, PATCOPY);
- //}
- }
- else
- {
- OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ?
COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
- if (! OldBrush) goto cleanup;
- if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom -
lprc->top, PATCOPY )) goto cleanup;
- }
- }
-
- if ((uFlags & DC_ICON) && !(uFlags & DC_GRADIENT) && (Style
& WS_SYSMENU) && !(uFlags & DC_SMALLCAP))
- {
- /* For some reason the icon isn't centered correctly... */
- r.top --;
- if (UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE))
- r.left += GetSystemMetrics(SM_CXSIZE) + Padding;
- r.top ++;
- }
- r.top ++;
- r.left += 2;
-
- r.bottom = r.top + Height;
-
- if ((uFlags & DC_TEXT) && (NtUserInternalGetWindowText( hWnd, buffer,
sizeof(buffer)/sizeof(buffer[0]) )))
- {
- if(!(uFlags & DC_GRADIENT))
- {
- r.right = (lprc->right - lprc->left);
- if (uFlags & DC_SMALLCAP)
- ButtonWidth = GetSystemMetrics(SM_CXSMSIZE) - 2;
- else
- ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2;
-
- if (Style & WS_SYSMENU)
- {
- r.right -= 3 + ButtonWidth;
- if (! (uFlags & DC_SMALLCAP))
- {
- if(Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
- r.right -= 2 + 2 * ButtonWidth;
- else
- r.right -= 2;
- r.right -= 2;
- }
- }
- }
-
- nclm.cbSize = sizeof(nclm);
- if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW),
&nclm, 0)) goto cleanup;
-
- SetBkMode( MemDC, TRANSPARENT );
- if (uFlags & DC_SMALLCAP)
- hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
- else
- hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
-
- if (! hFont) goto cleanup;
-
- hOldFont = SelectObject(MemDC, hFont);
- if (! hOldFont) goto cleanup;
-
- if (uFlags & DC_INBUTTON)
- OldTextColor = SetTextColor(MemDC, GetSysColor(uFlags & DC_ACTIVE ?
COLOR_BTNTEXT : COLOR_GRAYTEXT));
- else
- OldTextColor = SetTextColor(MemDC, GetSysColor(uFlags & DC_ACTIVE ?
COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT));
-
- DrawTextW(MemDC, buffer, wcslen(buffer), &r, DT_VCENTER | DT_END_ELLIPSIS);
-
- SetTextColor(MemDC, OldTextColor);
- }
-
-#if 0
- if (uFlags & DC_BUTTONS)
- {
- // Windows XP draws the caption buttons with DC_BUTTONS
-// r.left += GetSystemMetrics(SM_CXSIZE) + 1;
-// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
-// r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
-// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
-// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
- }
-#endif
-
-#ifdef DOUBLE_BUFFER_CAPTION
- if (! BitBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left,
lprc->bottom - lprc->top,
- MemDC, 0, 0, SRCCOPY)) goto cleanup;
-#endif
-
- result = TRUE;
-
- cleanup :
- if (MemDC)
- {
- if (OldBrush) SelectObject(MemDC, OldBrush);
- if (hOldFont) SelectObject(MemDC, hOldFont);
- if (hFont) DeleteObject(hFont);
-#ifdef DOUBLE_BUFFER_CAPTION
- if (OldBMP) SelectObject(MemDC, OldBMP);
- if (MemBMP) DeleteObject(MemBMP);
- DeleteDC(MemDC);
-#else
- OffsetViewportOrgEx(MemDC, -lprc->left, -lprc->top, NULL);
-#endif
- }
-
- return result;
+ return NtUserDrawCaption(hWnd, hDC, lprc, uFlags);
}
-
/*
* @unimplemented
*/