mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
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.
svn path=/trunk/; revision=31293
This commit is contained in:
parent
26c115dc6a
commit
721122fed7
|
@ -25,14 +25,15 @@ typedef enum
|
|||
|
||||
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 @@ typedef struct tagDCE
|
|||
#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
|
||||
|
|
|
@ -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@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;
|
||||
HRGN VisRgn;
|
||||
|
||||
VisRgn = VIS_ComputeVisibleRegion(Window,
|
||||
0 == (Flags & DCX_WINDOW),
|
||||
0 != (Flags & DCX_CLIPCHILDREN),
|
||||
0 != (Flags & DCX_CLIPSIBLINGS));
|
||||
VisRgn = VIS_ComputeVisibleRegion( Window,
|
||||
0 == (Flags & DCX_WINDOW),
|
||||
0 != (Flags & DCX_CLIPCHILDREN),
|
||||
0 != (Flags & DCX_CLIPSIBLINGS));
|
||||
|
||||
if (VisRgn == NULL)
|
||||
if (VisRgn == NULL)
|
||||
VisRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||
|
||||
return VisRgn;
|
||||
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);
|
||||
}
|
||||
|
||||
PDCE FASTCALL
|
||||
DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type)
|
||||
{
|
||||
PDCE pDce;
|
||||
PWINDOW Wnd = NULL;
|
||||
PDCE pDce;
|
||||
PWINDOW Wnd = NULL;
|
||||
PVOID Class = NULL;
|
||||
|
||||
if (Window)
|
||||
Wnd = Window->Wnd;
|
||||
if (Window) Wnd = Window->Wnd;
|
||||
|
||||
pDce = ExAllocatePoolWithTag(PagedPool, sizeof(DCE), TAG_PDCE);
|
||||
if(!pDce)
|
||||
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;
|
||||
pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
|
||||
pDce->hClipRgn = NULL;
|
||||
pDce->pProcess = NULL;
|
||||
pDce->Class = Class;
|
||||
pDce->Count = 1;
|
||||
|
||||
KeEnterCriticalRegion();
|
||||
pDce->next = FirstDce;
|
||||
FirstDce = pDce;
|
||||
KeLeaveCriticalRegion();
|
||||
KeEnterCriticalRegion();
|
||||
if (FirstDce == NULL)
|
||||
{
|
||||
FirstDce = pDce;
|
||||
InitializeListHead(&FirstDce->List);
|
||||
}
|
||||
else
|
||||
InsertTailList(&FirstDce->List, &pDce->List);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
DCU_SetDcUndeletable(pDce->hDC);
|
||||
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_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)
|
||||
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 @@ DceSetDrawable(PWINDOW_OBJECT Window OPTIONAL, HDC hDC, ULONG Flags,
|
|||
dc->w.DCOrgX = Wnd->ClientRect.left;
|
||||
dc->w.DCOrgY = Wnd->ClientRect.top;
|
||||
}
|
||||
}
|
||||
DC_UnlockDc(dc);
|
||||
}
|
||||
DC_UnlockDc(dc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -282,6 +237,7 @@ DceReleaseDC(DCE* dce, BOOL EndPaint)
|
|||
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 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
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 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
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 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
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 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
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;
|
||||
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))
|
||||
{
|
||||
DCE *ret;
|
||||
DPRINT1("Change ownership for DCE!\n");
|
||||
|
||||
if (NULL == pdce)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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))
|
||||
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 (pdce->hClipRgn && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
|
||||
else
|
||||
{
|
||||
NtGdiDeleteObject(pdce->hClipRgn);
|
||||
DPRINT1("Attempted to change ownership of an DCEhDC 0x%x currently being destroyed!!!\n",pdce->hDC);
|
||||
Hit = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
DCE_Cleanup(pdce);
|
||||
ExFreePoolWithTag(pdce, TAG_PDCE);
|
||||
if (!Hit) IntGdiDeleteDC(pdce->hDC, TRUE);
|
||||
|
||||
if (pdce->hClipRgn && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
|
||||
{
|
||||
NtGdiDeleteObject(pdce->hClipRgn);
|
||||
}
|
||||
|
||||
if (FirstDce == NULL)
|
||||
{
|
||||
ExFreePoolWithTag(defaultDCstate, TAG_DC);
|
||||
defaultDCstate = NULL;
|
||||
}
|
||||
return ret;
|
||||
RemoveEntryList(&pdce->List);
|
||||
ExFreePoolWithTag(pdce, TAG_PDCE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -758,26 +622,33 @@ DceFreeDCE(PDCE pdce, BOOLEAN Force)
|
|||
void FASTCALL
|
||||
DceFreeWindowDCE(PWINDOW_OBJECT Window)
|
||||
{
|
||||
DCE *pDCE;
|
||||
PDCE pDCE;
|
||||
|
||||
pDCE = FirstDce;
|
||||
KeEnterCriticalRegion();
|
||||
while (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*/
|
||||
else
|
||||
{
|
||||
DceDeleteClipRgn(pDCE);
|
||||
pDCE->hwndCurrent = 0;
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -795,14 +666,13 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
|
|||
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 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
|
|||
return;
|
||||
}
|
||||
pDCE = FirstDce;
|
||||
while (pDCE)
|
||||
if(!pDCE) return; // Another null test!
|
||||
do
|
||||
{
|
||||
if (0 == (pDCE->DCXFlags & DCX_DCEEMPTY))
|
||||
{
|
||||
|
@ -841,7 +712,7 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
|
|||
CurrentWindow = UserGetWindowObject(pDCE->hwndCurrent);
|
||||
if (NULL == CurrentWindow)
|
||||
{
|
||||
pDCE = pDCE->next;
|
||||
pDCE = (PDCE) pDCE->List.Flink;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -849,11 +720,7 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
|
|||
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 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
|
|||
|
||||
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)); \
|
||||
|
@ -992,7 +979,6 @@ NtUserEnumDisplaySettings(
|
|||
|
||||
#undef COPY_DEVMODE_VALUE_TO_CALLER
|
||||
|
||||
|
||||
LONG
|
||||
STDCALL
|
||||
NtUserChangeDisplaySettings(
|
||||
|
|
|
@ -1785,12 +1785,10 @@ AllocErr:
|
|||
/* 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;
|
||||
|
|
Loading…
Reference in a new issue