Author: jimtabor
Date: Mon Dec 17 23:23:31 2007
New Revision: 31293
URL:
http://svn.reactos.org/svn/reactos?rev=31293&view=rev
Log:
First restructure and reorder the code. Identify bugs and make corrections. Found
DCX_CACHE sets to owned DCEs, we do not hold dcattr after ReleaseDC as we should and did
not handle ClassDCs correctly. Will continue.
Modified:
trunk/reactos/subsystems/win32/win32k/include/dce.h
trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/subsystems/win32/win32k/include/dce.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/dce.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/dce.h Mon Dec 17 23:23:31 2007
@@ -25,14 +25,15 @@
typedef struct tagDCE
{
- struct tagDCE *next;
+ LIST_ENTRY List;
HDC hDC;
HWND hwndCurrent;
HWND hwndDC;
HRGN hClipRgn;
- DCE_TYPE type;
+ PVOID Class;
DWORD DCXFlags;
PEPROCESS pProcess;
+ DWORD Count;
HANDLE Self;
} DCE; /* PDCE already declared at top of file */
@@ -40,7 +41,7 @@
#define DCX_DCEEMPTY 0x00000800
#define DCX_DCEBUSY 0x00001000
#define DCX_DCEDIRTY 0x00002000
-#define DCX_DCOWNED 0x00008000
+#define DCX_DCPOWNED 0x00008000
#define DCX_USESTYLE 0x00010000
#define DCX_KEEPCLIPRGN 0x00040000
#define DCX_NOCLIPCHILDREN 0x00080000
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/windc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/windc.c Mon Dec 17 23:23:31 2007
@@ -1,30 +1,10 @@
/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: subsystems/win32/win32k/ntuser/windc.c
+ * PURPOSE: Keyboard layout management
+ * COPYRIGHT: Copyright 2007 ReactOS
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * PURPOSE: Window classes
- * FILE: subsys/win32k/ntuser/class.c
- * PROGRAMER: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
- * REVISION HISTORY:
- * 06-06-2001 CSH Created
*/
/* INCLUDES ******************************************************************/
@@ -40,187 +20,162 @@
static PDCE FirstDce = NULL;
static PDC defaultDCstate = NULL;
-//static INT DCECount = 0;
+//static INT DCECount = 0; // Count of DCE in system.
#define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \
DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)
/* FUNCTIONS *****************************************************************/
+//
+// This should be moved to dc.c or dcutil.c.
+//
HDC FASTCALL
DceCreateDisplayDC(VOID)
{
- HDC hDC;
- UNICODE_STRING DriverName;
- RtlInitUnicodeString(&DriverName, L"DISPLAY");
- hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
- return hDC;
-}
-
-VOID FASTCALL
-DceInit(VOID)
-{
-
+ HDC hDC;
+ UNICODE_STRING DriverName;
+ RtlInitUnicodeString(&DriverName, L"DISPLAY");
+ hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
+//
+// If NULL, first time through! Build the default window dc!
+//
+ if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
+ { // This is a cheesy way to do this.
+ PDC dc = DC_LockDc ( hDC );
+ defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
+ RtlZeroMemory(defaultDCstate, sizeof(DC));
+ IntGdiCopyToSaveState(dc, defaultDCstate);
+ DC_UnlockDc( dc );
+ }
+ return hDC;
}
static
HRGN FASTCALL
DceGetVisRgn(PWINDOW_OBJECT Window, ULONG Flags, HWND hWndChild, ULONG CFlags)
{
- HRGN VisRgn;
-
- VisRgn = VIS_ComputeVisibleRegion(Window,
- 0 == (Flags & DCX_WINDOW),
- 0 != (Flags & DCX_CLIPCHILDREN),
- 0 != (Flags & DCX_CLIPSIBLINGS));
-
- if (VisRgn == NULL)
+ HRGN VisRgn;
+
+ VisRgn = VIS_ComputeVisibleRegion( Window,
+ 0 == (Flags & DCX_WINDOW),
+ 0 != (Flags & DCX_CLIPCHILDREN),
+ 0 != (Flags & DCX_CLIPSIBLINGS));
+
+ if (VisRgn == NULL)
VisRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
- return VisRgn;
-}
-
-/*
- * NtUserGetWindowDC
- *
- * The NtUserGetWindowDC function retrieves the device context (DC) for the
- * entire window, including title bar, menus, and scroll bars. A window device
- * context permits painting anywhere in a window, because the origin of the
- * device context is the upper-left corner of the window instead of the client
- * area.
- *
- * Status
- * @implemented
- */
-
-DWORD STDCALL
-NtUserGetWindowDC(HWND hWnd)
-{
- return (DWORD)NtUserGetDCEx(hWnd, 0, DCX_USESTYLE | DCX_WINDOW);
-}
-
-DWORD FASTCALL
-UserGetWindowDC(PWINDOW_OBJECT Wnd)
-{
- return (DWORD)UserGetDCEx(Wnd, 0, DCX_USESTYLE | DCX_WINDOW);
-}
-
-HDC STDCALL
-NtUserGetDC(HWND hWnd)
-{
-#if 0
- if (!hWnd)
- { // MSDN:
- //"hWnd [in] Handle to the window whose DC is to be retrieved.
- // If this value is NULL, GetDC retrieves the DC for the entire screen."
- hWnd = IntGetDesktopWindow();
- if (hWnd)
- return NtUserGetDCEx(hWnd, NULL, DCX_CACHE | DCX_WINDOW);
- else
- return NULL;
- }
- return NtUserGetDCEx(hWnd, NULL, DCX_USESTYLE);
-#endif
-// We have a problem here!
- return NtUserGetDCEx(hWnd, NULL, NULL == hWnd ? DCX_CACHE | DCX_WINDOW :
DCX_USESTYLE);
-}
+ return VisRgn;
+}
+
PDCE FASTCALL
DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type)
{
- PDCE pDce;
- PWINDOW Wnd = NULL;
-
- if (Window)
- Wnd = Window->Wnd;
-
- pDce = ExAllocatePoolWithTag(PagedPool, sizeof(DCE), TAG_PDCE);
- if(!pDce)
+ PDCE pDce;
+ PWINDOW Wnd = NULL;
+ PVOID Class = NULL;
+
+ if (Window) Wnd = Window->Wnd;
+
+ if (Wnd) Class = Wnd->Class;
+
+ if (Type == DCE_CLASS_DC)
+ {
+ PDCE pdce;
+ KeEnterCriticalRegion();
+ pdce = FirstDce;
+ do
+ {
+ if (pdce->Class == Class)
+ {
+ pdce->Count++;
+ KeLeaveCriticalRegion();
+ return pdce;
+ }
+ pdce = (PDCE)pdce->List.Flink;
+ } while (pdce != FirstDce);
+ KeLeaveCriticalRegion();
+ }
+
+ pDce = ExAllocatePoolWithTag(PagedPool, sizeof(DCE), TAG_PDCE);
+ if(!pDce)
return NULL;
- pDce->hDC = DceCreateDisplayDC();
- if(!pDce->hDC)
- {
+ pDce->hDC = DceCreateDisplayDC();
+ if (!pDce->hDC)
+ {
ExFreePoolWithTag(pDce, TAG_PDCE);
return NULL;
- }
-//
-// If NULL, first time through! Build the default window dc!
-//
- if (NULL == defaultDCstate) // Ultra HAX! Dedicated to GvG!
- { // This is a cheesy way to do this.
- PDC dc = DC_LockDc ( pDce->hDC );
- defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
- RtlZeroMemory(defaultDCstate, sizeof(DC));
- IntGdiCopyToSaveState(dc, defaultDCstate);
- DC_UnlockDc( dc );
- }
-
- pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
- pDce->hClipRgn = NULL;
- pDce->pProcess = NULL;
-
- KeEnterCriticalRegion();
- pDce->next = FirstDce;
- FirstDce = pDce;
- KeLeaveCriticalRegion();
-
- DCU_SetDcUndeletable(pDce->hDC);
-
- if (Type == DCE_WINDOW_DC) //Window DCE have ownership.
- { // Process should already own it.
- pDce->pProcess = PsGetCurrentProcess();
- }
- else
- {
- PDC dc = DC_LockDc ( pDce->hDC );
- DPRINT("FREE DCATTR!!!! NOT DCE_WINDOW_DC!!!!! hDC-> %x\n",
pDce->hDC);
- MmCopyFromCaller(&dc->Dc_Attr, dc->pDc_Attr, sizeof(DC_ATTR));
- DC_UnlockDc( dc );
- DC_FreeDcAttr(pDce->hDC); // Free the dcattr!
- DC_SetOwnership(pDce->hDC, NULL); // This hDC is inaccessible!
- }
-
- if (Type != DCE_CACHE_DC)
+ }
+
+ pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
+ pDce->hClipRgn = NULL;
+ pDce->pProcess = NULL;
+ pDce->Class = Class;
+ pDce->Count = 1;
+
+ KeEnterCriticalRegion();
+ if (FirstDce == NULL)
+ {
+ FirstDce = pDce;
+ InitializeListHead(&FirstDce->List);
+ }
+ else
+ InsertTailList(&FirstDce->List, &pDce->List);
+ KeLeaveCriticalRegion();
+
+ DCU_SetDcUndeletable(pDce->hDC);
+
+ if (Type == DCE_WINDOW_DC || Type == DCE_CLASS_DC) //Window DCE have ownership.
+ { // Process should already own it.
+ pDce->pProcess = PsGetCurrentProcess();
+ }
+ else
+ {
+ PDC dc = DC_LockDc ( pDce->hDC );
+ DPRINT("FREE DCATTR!!!! NOT DCE_WINDOW_DC!!!!! hDC-> %x\n",
pDce->hDC);
+ MmCopyFromCaller(&dc->Dc_Attr, dc->pDc_Attr, sizeof(DC_ATTR));
+ DC_UnlockDc( dc );
+ DC_FreeDcAttr(pDce->hDC); // Free the dcattr!
+ DC_SetOwnership(pDce->hDC, NULL); // This hDC is inaccessible!
+ }
+
+ if (Type == DCE_CACHE_DC)
+ {
+ pDce->DCXFlags = DCX_CACHE | DCX_DCEEMPTY;
+ }
+ else
+ {
+ pDce->DCXFlags = DCX_DCEBUSY;
+ if (Wnd)
{
- pDce->DCXFlags = DCX_DCEBUSY;
-
- if (Wnd)
+ if (Type == DCE_WINDOW_DC)
{
- if (Wnd->Style & WS_CLIPCHILDREN)
- {
- pDce->DCXFlags |= DCX_CLIPCHILDREN;
- }
- if (Wnd->Style & WS_CLIPSIBLINGS)
- {
- pDce->DCXFlags |= DCX_CLIPSIBLINGS;
- }
+ if (Wnd->Style & WS_CLIPCHILDREN) pDce->DCXFlags |=
DCX_CLIPCHILDREN;
+ if (Wnd->Style & WS_CLIPSIBLINGS) pDce->DCXFlags |=
DCX_CLIPSIBLINGS;
}
}
- else
- {
- pDce->DCXFlags = DCX_CACHE | DCX_DCEEMPTY;
- }
-
- return(pDce);
+ }
+ return(pDce);
}
VOID static STDCALL
DceSetDrawable(PWINDOW_OBJECT Window OPTIONAL, HDC hDC, ULONG Flags,
BOOL SetClipOrigin)
{
- PWINDOW Wnd;
- DC *dc = DC_LockDc(hDC);
- if(!dc)
+ PWINDOW Wnd;
+ DC *dc = DC_LockDc(hDC);
+ if(!dc)
return;
- if (Window == NULL)
- {
+ if (Window == NULL)
+ {
dc->w.DCOrgX = 0;
dc->w.DCOrgY = 0;
- }
- else
- {
+ }
+ else
+ {
Wnd = Window->Wnd;
if (Flags & DCX_WINDOW)
{
@@ -232,8 +187,8 @@
dc->w.DCOrgX = Wnd->ClientRect.left;
dc->w.DCOrgY = Wnd->ClientRect.top;
}
- }
- DC_UnlockDc(dc);
+ }
+ DC_UnlockDc(dc);
}
@@ -282,6 +237,7 @@
IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
dc = DC_LockDc ( dce->hDC );
+ // Clean the DC
IntGdiCopyFromSaveState(dc, defaultDCstate, dce->hDC ); // Was SetDCState.
dce->DCXFlags &= ~DCX_DCEBUSY;
@@ -489,8 +445,14 @@
DCE* DceEmpty = NULL;
DCE* DceUnused = NULL;
KeEnterCriticalRegion();
- for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)
- {
+ Dce = FirstDce;
+ do
+ {
+// The reason for this you may ask?
+// Well, it seems ReactOS calls GetDC with out first creating a desktop DC window!
+// Need to test for null here. Not sure if this is a bug or a feature.
+ if (!Dce) break;
+
if ((Dce->DCXFlags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE)
{
DceUnused = Dce;
@@ -509,13 +471,11 @@
break;
}
}
- }
+ Dce = (PDCE)Dce->List.Flink;
+ } while (Dce != FirstDce);
KeLeaveCriticalRegion();
- if (Dce == NULL)
- {
- Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty;
- }
+ Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty;
if (Dce == NULL)
{
@@ -597,6 +557,11 @@
if (Dce->DCXFlags & DCX_CACHE)
{
DPRINT("ENTER!!!!!! DCX_CACHE!!!!!! hDC-> %x\n", Dce->hDC);
+ if (Dce->pProcess)
+ {
+ DPRINT1("POWNED!\n");
+ return NULL; // should assert here.
+ }
// Need to set ownership so Sync dcattr will work.
DC_SetOwnership( Dce->hDC, PsGetCurrentProcess());
DC_AllocateDcAttr( Dce->hDC ); // Allocate new dcattr
@@ -606,148 +571,47 @@
return(Dce->hDC);
}
-
-
-HDC STDCALL
-NtUserGetDCEx(HWND hWnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
-{
- PWINDOW_OBJECT Wnd=NULL;
- DECLARE_RETURN(HDC);
-
- DPRINT("Enter NtUserGetDCEx\n");
- UserEnterExclusive();
-
- if (hWnd && !(Wnd = UserGetWindowObject(hWnd)))
- {
- RETURN(NULL);
- }
-
- RETURN( UserGetDCEx(Wnd, ClipRegion, Flags));
-
-CLEANUP:
- DPRINT("Leave NtUserGetDCEx, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-BOOL FASTCALL
-DCE_Cleanup(PDCE pDce)
-{
- PDCE PrevInList;
- KeEnterCriticalRegion();
- if (pDce == FirstDce)
- {
- FirstDce = pDce->next;
- PrevInList = pDce;
- }
- else
- {
- for (PrevInList = FirstDce; NULL != PrevInList; PrevInList = PrevInList->next)
- {
- if (pDce == PrevInList->next)
- {
- PrevInList->next = pDce->next;
- break;
- }
- }
- assert(NULL != PrevInList);
- }
- KeLeaveCriticalRegion();
- return NULL != PrevInList;
-}
-
-HWND FASTCALL
-IntWindowFromDC(HDC hDc)
-{
- DCE *Dce;
- HWND Ret = NULL;
- KeEnterCriticalRegion();
- for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)
- {
- if(Dce->hDC == hDc)
- {
- Ret = Dce->hwndCurrent;
- break;
- }
- }
- KeLeaveCriticalRegion();
- return Ret;
-}
-
-
-INT FASTCALL
-UserReleaseDC(PWINDOW_OBJECT Window, HDC hDc, BOOL EndPaint)
-{
- DCE *dce;
- INT nRet = 0;
-
- dce = FirstDce;
-
- DPRINT("%p %p\n", Window, hDc);
- KeEnterCriticalRegion();
- while (dce && (dce->hDC != hDc))
- {
- dce = dce->next;
- }
- KeLeaveCriticalRegion();
- if (dce && (dce->DCXFlags & DCX_DCEBUSY))
- {
- nRet = DceReleaseDC(dce, EndPaint);
- }
-
- return nRet;
-}
-
-
/***********************************************************************
* DceFreeDCE
*/
PDCE FASTCALL
DceFreeDCE(PDCE pdce, BOOLEAN Force)
- {
- DCE *ret;
-
- if (NULL == pdce)
+{
+ DCE *ret;
+ BOOL Hit = FALSE;
+
+ if (NULL == pdce) return NULL;
+
+ ret = (PDCE) pdce->List.Flink;
+
+#if 0 /* FIXME */
+ SetDCHook(pdce->hDC, NULL, 0L);
+#endif
+
+ if (Force && !GDIOBJ_OwnedByCurrentProcess(GdiHandleTable, pdce->hDC))
+ {
+ DPRINT1("Change ownership for DCE!\n");
+
+ if (!IsObjectDead((HGDIOBJ) pdce->hDC))
+ DC_SetOwnership( pdce->hDC, PsGetCurrentProcess());
+ else
{
- return NULL;
+ DPRINT1("Attempted to change ownership of an DCEhDC 0x%x currently being
destroyed!!!\n",pdce->hDC);
+ Hit = TRUE;
}
-
- ret = pdce->next;
-
- #if 0 /* FIXME */
-
- SetDCHook(pdce->hDC, NULL, 0L);
- #endif
-
- if(Force && !GDIOBJ_OwnedByCurrentProcess(GdiHandleTable, pdce->hDC))
- {
- DPRINT1("Change ownership for DCE!\n");
-
- if(!IsObjectDead((HGDIOBJ) pdce->hDC))
- DC_SetOwnership( pdce->hDC, PsGetCurrentProcess());
- else
- {
- DPRINT1("Attempted to change ownership of an DCEhDC 0x%x currently being
destroyed!!!\n",pdce->hDC);
- }
- }
-
- IntGdiDeleteDC(pdce->hDC, TRUE);
+ }
+
+ if (!Hit) IntGdiDeleteDC(pdce->hDC, TRUE);
- if (pdce->hClipRgn && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
- {
+ if (pdce->hClipRgn && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
+ {
NtGdiDeleteObject(pdce->hClipRgn);
- }
-
- DCE_Cleanup(pdce);
- ExFreePoolWithTag(pdce, TAG_PDCE);
-
- if (FirstDce == NULL)
- {
- ExFreePoolWithTag(defaultDCstate, TAG_DC);
- defaultDCstate = NULL;
- }
- return ret;
+ }
+
+ RemoveEntryList(&pdce->List);
+ ExFreePoolWithTag(pdce, TAG_PDCE);
+
+ return ret;
}
/***********************************************************************
@@ -758,26 +622,33 @@
void FASTCALL
DceFreeWindowDCE(PWINDOW_OBJECT Window)
{
- DCE *pDCE;
-
- pDCE = FirstDce;
- KeEnterCriticalRegion();
- while (pDCE)
- {
+ PDCE pDCE;
+
+ pDCE = FirstDce;
+ KeEnterCriticalRegion();
+ do
+ {
if (pDCE->hwndCurrent == Window->hSelf)
{
- if (pDCE == Window->Dce) /* owned or Class DCE*/
+ if (!(pDCE->DCXFlags & DCX_CACHE)) /* owned or Class DCE*/
{
- if (Window->Wnd->Class->Style & CS_OWNDC) /* owned DCE*/
+ if (Window->Wnd->Class->Style & CS_CLASSDC ||
+ Window->Wnd->Style & CS_CLASSDC) /* Test Class first */
+ {
+ if (pDCE->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) /* Class
DCE*/
+ DceDeleteClipRgn(pDCE);
+ pDCE->hwndCurrent = 0;
+ }
+ else if (Window->Wnd->Class->Style & CS_OWNDC ||
+ Window->Wnd->Style & CS_OWNDC) /* owned DCE*/
{
pDCE = DceFreeDCE(pDCE, FALSE);
Window->Dce = NULL;
continue;
}
- else if (pDCE->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) /*
Class DCE*/
- {
- DceDeleteClipRgn(pDCE);
- pDCE->hwndCurrent = 0;
+ else
+ {
+ ASSERT(FALSE);
}
}
else
@@ -795,14 +666,13 @@
DceReleaseDC(pDCE, FALSE);
}
- pDCE->DCXFlags &= DCX_CACHE;
pDCE->DCXFlags |= DCX_DCEEMPTY;
pDCE->hwndCurrent = 0;
}
}
- pDCE = pDCE->next;
- }
- KeLeaveCriticalRegion();
+ pDCE = (PDCE) pDCE->List.Flink;
+ } while (pDCE != FirstDce);
+ KeLeaveCriticalRegion();
}
VOID FASTCALL
@@ -828,7 +698,8 @@
return;
}
pDCE = FirstDce;
- while (pDCE)
+ if(!pDCE) return; // Another null test!
+ do
{
if (0 == (pDCE->DCXFlags & DCX_DCEEMPTY))
{
@@ -841,7 +712,7 @@
CurrentWindow = UserGetWindowObject(pDCE->hwndCurrent);
if (NULL == CurrentWindow)
{
- pDCE = pDCE->next;
+ pDCE = (PDCE) pDCE->List.Flink;
continue;
}
}
@@ -849,11 +720,7 @@
dc = DC_LockDc(pDCE->hDC);
if (dc == NULL)
{
-// if (Window->hSelf != pDCE->hwndCurrent)
-// {
-// UserDerefObject(CurrentWindow);
-// }
- pDCE = pDCE->next;
+ pDCE = (PDCE) pDCE->List.Flink;
continue;
}
if (Window == CurrentWindow || IntIsChildWindow(Window, CurrentWindow))
@@ -889,14 +756,134 @@
if (Window->hSelf != pDCE->hwndCurrent)
{
- // IntEngWindowChanged(CurrentWindow, WOC_RGN_CLIENT);
+// IntEngWindowChanged(CurrentWindow, WOC_RGN_CLIENT);
// UserDerefObject(CurrentWindow);
}
}
- pDCE = pDCE->next;
- }
-}
-
+ pDCE =(PDCE) pDCE->List.Flink;
+ } while (pDCE != FirstDce);
+}
+
+HDC
+FASTCALL
+IntGetDC(PWINDOW_OBJECT Window)
+{
+ if (!Window)
+ { // MSDN:
+ //"hWnd [in] Handle to the window whose DC is to be retrieved.
+ // If this value is NULL, GetDC retrieves the DC for the entire screen."
+ Window = UserGetWindowObject(IntGetDesktopWindow());
+ if (Window)
+ return UserGetDCEx(Window, NULL, DCX_CACHE | DCX_WINDOW);
+ else
+ return NULL;
+ }
+ return UserGetDCEx(Window, NULL, DCX_USESTYLE);
+}
+
+HWND FASTCALL
+IntWindowFromDC(HDC hDc)
+{
+ DCE *Dce;
+ HWND Ret = NULL;
+ KeEnterCriticalRegion();
+ Dce = FirstDce;
+ do
+ {
+ if(Dce->hDC == hDc)
+ {
+ Ret = Dce->hwndCurrent;
+ break;
+ }
+ Dce = (PDCE)Dce->List.Flink;
+ } while (Dce != FirstDce);
+ KeLeaveCriticalRegion();
+ return Ret;
+}
+
+INT FASTCALL
+UserReleaseDC(PWINDOW_OBJECT Window, HDC hDc, BOOL EndPaint)
+{
+ PDCE dce;
+ INT nRet = 0;
+ BOOL Hit = FALSE;
+
+ DPRINT("%p %p\n", Window, hDc);
+ dce = FirstDce;
+ KeEnterCriticalRegion();
+ do
+ {
+ if (dce->hDC == hDc)
+ {
+ Hit = TRUE;
+ break;
+ }
+
+ dce = (PDCE) dce->List.Flink;
+ }
+ while (dce != FirstDce );
+ KeLeaveCriticalRegion();
+
+ if ( Hit && (dce->DCXFlags & DCX_DCEBUSY))
+ {
+ nRet = DceReleaseDC(dce, EndPaint);
+ }
+
+ return nRet;
+}
+
+DWORD FASTCALL
+UserGetWindowDC(PWINDOW_OBJECT Wnd)
+{
+ return (DWORD)UserGetDCEx(Wnd, 0, DCX_USESTYLE | DCX_WINDOW);
+}
+
+HDC STDCALL
+NtUserGetDCEx(HWND hWnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
+{
+ PWINDOW_OBJECT Wnd=NULL;
+ DECLARE_RETURN(HDC);
+
+ DPRINT("Enter NtUserGetDCEx\n");
+ UserEnterExclusive();
+
+ if (hWnd && !(Wnd = UserGetWindowObject(hWnd)))
+ {
+ RETURN(NULL);
+ }
+
+ RETURN( UserGetDCEx(Wnd, ClipRegion, Flags));
+
+CLEANUP:
+ DPRINT("Leave NtUserGetDCEx, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+/*
+ * NtUserGetWindowDC
+ *
+ * The NtUserGetWindowDC function retrieves the device context (DC) for the
+ * entire window, including title bar, menus, and scroll bars. A window device
+ * context permits painting anywhere in a window, because the origin of the
+ * device context is the upper-left corner of the window instead of the client
+ * area.
+ *
+ * Status
+ * @implemented
+ */
+DWORD STDCALL
+NtUserGetWindowDC(HWND hWnd)
+{
+ return (DWORD)NtUserGetDCEx(hWnd, 0, DCX_USESTYLE | DCX_WINDOW);
+}
+
+HDC STDCALL
+NtUserGetDC(HWND hWnd)
+{
+// We have a problem here! Should call IntGetDC.
+ return NtUserGetDCEx(hWnd, NULL, NULL == hWnd ? DCX_CACHE | DCX_WINDOW :
DCX_USESTYLE);
+}
#define COPY_DEVMODE_VALUE_TO_CALLER(dst, src, member) \
Status = MmCopyToCaller(&(dst)->member, &(src)->member, sizeof
((src)->member)); \
@@ -991,7 +978,6 @@
}
#undef COPY_DEVMODE_VALUE_TO_CALLER
-
LONG
STDCALL
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Mon Dec 17 23:23:31 2007
@@ -1785,12 +1785,10 @@
/* Insert the window into the thread's window list. */
InsertTailList (&PsGetCurrentThreadWin32Thread()->WindowListHead,
&Window->ThreadListEntry);
+ /* Handle "CS_CLASSDC", it is tested first. */
+ if (dwStyle & CS_CLASSDC) Window->Dce = DceAllocDCE(Window, DCE_CLASS_DC);
/* Allocate a DCE for this window. */
- if (dwStyle & CS_OWNDC)
- {
- Window->Dce = DceAllocDCE(Window, DCE_WINDOW_DC);
- }
- /* FIXME: Handle "CS_CLASSDC" */
+ else if (dwStyle & CS_OWNDC) Window->Dce = DceAllocDCE(Window, DCE_WINDOW_DC);
Pos.x = x;
Pos.y = y;