Initial code for NtUserGetDC

svn path=/trunk/; revision=3387
This commit is contained in:
Jason Filby 2002-08-24 11:09:17 +00:00
parent 34b85a88a2
commit 1231d02b03
9 changed files with 197 additions and 23 deletions

View file

@ -1291,6 +1291,8 @@ extern "C" {
#define DCX_EXCLUDERGN (0x40L)
#define DCX_INTERSECTRGN (0x80L)
#define DCX_VALIDATE (0x200000L)
#define DCX_USESTYLE (0x00010000L)
#define DCX_NORECOMPUTE (0x00100000L)
/* GetDeviceCaps */
#define DRIVERVERSION (0)

View file

@ -1,5 +1,9 @@
#define WIN_NCACTIVATED (0x0080)
#define DCX_KEEPCLIPRGN (0x40000)
#define DCX_USESTYLE (0x10000)
#define DCX_WINDOWPAINT (0x20000)
/* internal DCX flags */
#define DCX_DCEEMPTY 0x00000800
#define DCX_DCEBUSY 0x00001000
#define DCX_DCEDIRTY 0x00002000
#define DCX_WINDOWPAINT 0x00020000
#define DCX_KEEPCLIPRGN 0x00040000
#define DCX_NOCLIPCHILDREN 0x00080000

View file

@ -23,6 +23,7 @@
#define GO_METAFILE_DC_MAGIC 0x4f51
#define GO_ENHMETAFILE_MAGIC 0x4f52
#define GO_ENHMETAFILE_DC_MAGIC 0x4f53
#define GO_DCE_MAGIC 0x4f54
#define GO_MAGIC_DONTCARE 0xffff
/* (RJJ) swiped stock handles from wine */

View file

@ -616,11 +616,9 @@ NtUserGetCursorInfo(
DWORD
STDCALL
NtUserGetDC(
DWORD Unknown0);
NtUserGetDC(HWND hWnd);
HDC STDCALL
NtUserGetDCEx(HWND hWnd, HANDLE hRegion, ULONG Flags);
HDC STDCALL NtUserGetDCEx(HWND hWnd, HANDLE hRegion, ULONG Flags);
DWORD
STDCALL

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dc.c,v 1.6 2002/06/13 20:36:40 dwelch Exp $
/* $Id: dc.c,v 1.7 2002/08/24 11:09:17 jfilby Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/input.c
@ -39,7 +39,7 @@ STDCALL
GetDC(
HWND hWnd)
{
return (HDC)0;
return NtUserGetDC(hWnd);
}
HDC
@ -49,7 +49,7 @@ GetDCEx(
HRGN hrgnClip,
DWORD flags)
{
return (HDC)0;
return NtUserGetDCEx(hWnd, hrgnClip, flags);
}
HDC
STDCALL

View file

@ -6,6 +6,7 @@
#include <include/class.h>
#include <include/msgqueue.h>
#include <include/winsta.h>
#include <include/dce.h>
typedef struct _INTERNALPOS
{
@ -72,6 +73,8 @@ typedef struct _WINDOW_OBJECT
LIST_ENTRY ThreadListEntry;
/* Pointer to the parent window. */
struct _WINDOW_OBJECT* Parent;
/* DC Entries (DCE) */
PDCE dce;
} WINDOW_OBJECT, *PWINDOW_OBJECT;
/* Window flags. */

View file

@ -825,16 +825,6 @@ NtUserGetCursorInfo(
return 0;
}
DWORD
STDCALL
NtUserGetDC(
DWORD Unknown0)
{
UNIMPLEMENTED
return 0;
}
DWORD
STDCALL
NtUserGetDoubleClickTime(VOID)
@ -1424,6 +1414,7 @@ NtUserScrollDC(
DWORD Unknown4,
DWORD Unknown5,
DWORD Unknown6)
{
UNIMPLEMENTED

View file

@ -1,4 +1,4 @@
/* $Id: windc.c,v 1.2 2002/07/17 21:04:57 dwelch Exp $
/* $Id: windc.c,v 1.3 2002/08/24 11:09:17 jfilby Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -20,12 +20,19 @@
#include <include/msgqueue.h>
#include <include/window.h>
#include <include/rect.h>
#include <include/dce.h>
#define NDEBUG
#include <debug.h>
static PDCE firstDCE;
/* FUNCTIONS *****************************************************************/
VOID DCE_FreeWindowDCE(HWND);
INT DCE_ExcludeRgn(HDC, HWND, HRGN);
BOOL DCE_InvalidateDCE(HWND, const PRECTL);
BOOL STATIC
DceGetVisRect(PWINDOW_OBJECT Window, BOOL ClientArea, RECT* Rect)
{
@ -225,10 +232,167 @@ NtUserReleaseDC(HWND hWnd, HDC hDc)
}
DWORD
STDCALL
NtUserGetDC(HWND hWnd)
{
if (!hWnd)
return NtUserGetDCEx(0, 0, DCX_CACHE | DCX_WINDOW);
return NtUserGetDCEx(hWnd, 0, DCX_USESTYLE);
}
HDC STDCALL
NtUserGetDCEx(HWND hWnd, HANDLE hRegion, ULONG Flags)
{
HDC hdc = 0;
HDCE hdce;
PDCE dce;
DWORD dcxFlags = 0;
BOOL bUpdateVisRgn = TRUE;
BOOL bUpdateClipOrigin = FALSE;
HWND parent, full;
PWINDOW_OBJECT Window;
DPRINT("hWnd %04x, hRegion %04x, Flags %08x\n", hWnd, hRegion, (unsigned)Flags);
if (!hWnd) hWnd = W32kGetDesktopWindow();
if (!(Window = W32kGetWindowObject(hWnd))) return 0;
// fixup flags
if (Flags & (DCX_WINDOW | DCX_PARENTCLIP)) Flags |= DCX_CACHE;
if (Flags & DCX_USESTYLE)
{
Flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP);
if(Window->Style & WS_CLIPSIBLINGS)
Flags |= DCX_CLIPSIBLINGS;
if (!(Flags & DCX_WINDOW))
{
if (Window->ExStyle & CS_PARENTDC) Flags |= DCX_PARENTCLIP;
if (Window->Style & WS_CLIPCHILDREN &&
!(Window->Style & WS_MINIMIZE)) Flags |= DCX_CLIPCHILDREN;
if (!Window->dce) Flags |= DCX_CACHE;
}
}
if (Flags & DCX_WINDOW) Flags &= ~DCX_CLIPCHILDREN;
parent = W32kGetParentWindow(hWnd);
if (!parent || (parent == W32kGetDesktopWindow()))
Flags = (Flags & ~DCX_PARENTCLIP) | DCX_CLIPSIBLINGS;
// it seems parent clip is ignored when clipping siblings or children
if (Flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) Flags &= ~DCX_PARENTCLIP;
if(Flags & DCX_PARENTCLIP)
{
LONG parent_style = NtUserGetWindowLong(parent, GWL_STYLE);
if((Window->Style & WS_VISIBLE) && (parent_style & WS_VISIBLE))
{
Flags &= ~DCX_CLIPCHILDREN;
if (parent_style & WS_CLIPSIBLINGS) Flags |= DCX_CLIPSIBLINGS;
}
}
// find a suitable DCE
dcxFlags = Flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
DCX_CACHE | DCX_WINDOW);
if (Flags & DCX_CACHE)
{
PDCE dceEmpty;
PDCE dceUnused;
dceEmpty = dceUnused = NULL;
/* Strategy: First, we attempt to find a non-empty but unused DCE with
* compatible flags. Next, we look for an empty entry. If the cache is
* full we have to purge one of the unused entries.
*/
for (dce = firstDCE; (dce); dce = dce->next)
{
if ((dce->DCXflags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE)
{
dceUnused = dce;
if (dce->DCXflags & DCX_DCEEMPTY)
dceEmpty = dce;
else
if ((dce->hwndCurrent == hWnd) &&
((dce->DCXflags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)) == dcxFlags))
{
DPRINT("Found valid %08x dce [%04x], flags %08x\n",
(unsigned)dce, hWnd, (unsigned)dcxFlags);
bUpdateVisRgn = FALSE;
bUpdateClipOrigin = TRUE;
break;
}
}
}
if (!dce) dce = (dceEmpty) ? dceEmpty : dceUnused;
// if there's no dce empty or unused, allocate a new one
if (!dce)
{
hdce = DCEOBJ_AllocDCE();
if (hdce == NULL)
{
return 0;
}
dce = DCEOBJ_LockDCE(hdce);
dce->type = DCE_CACHE_DC;
}
}
else
{
dce = Window->dce;
if (dce && dce->hwndCurrent == hWnd)
{
DPRINT("skipping hVisRgn update\n");
bUpdateVisRgn = FALSE; // updated automatically, via DCHook()
}
}
if (!dce)
{
hdc = 0;
goto END;
}
if (!(Flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN))) hRegion = 0;
if (((Flags ^ dce->DCXflags) & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
(dce->hClipRgn != hRegion))
{
// if the extra clip region has changed, get rid of the old one
/* DCE_DeleteClipRgn(dce); */
}
dce->hwndCurrent = hWnd;
dce->hClipRgn = hRegion;
dce->DCXflags = Flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
DCX_CACHE | DCX_WINDOW | DCX_WINDOWPAINT |
DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_EXCLUDERGN);
dce->DCXflags |= DCX_DCEBUSY;
dce->DCXflags &= ~DCX_DCEDIRTY;
hdc = dce->hDC;
/* if (bUpdateVisRgn) SetHookFlags(hdc, DCHF_INVALIDATEVISRGN); // force update */
/* if (!USER_Driver.pGetDC(hWnd, hdc, hRegion, Flags)) hdc = 0; */
DPRINT("(%04x,%04x,0x%lx): returning %04x\n", hWnd, hRegion, Flags, hdc);
END:
/* WIN_ReleasePtr(Window); */
return hdc;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.9 2002/07/17 21:04:57 dwelch Exp $
/* $Id: window.c,v 1.10 2002/08/24 11:09:17 jfilby Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -85,6 +85,16 @@ W32kIsDesktopWindow(HWND hWnd)
return(IsDesktop);
}
HWND W32kGetDesktopWindow()
{
return W32kGetActiveDesktop()->DesktopWindow;
}
HWND W32kGetParentWindow(HWND hWnd)
{
return W32kGetWindowObject(hWnd)->ParentHandle;
}
PWINDOW_OBJECT
W32kGetWindowObject(HWND hWnd)
{
@ -776,6 +786,7 @@ NtUserSetInternalWindowPos(DWORD Unknown0,
UNIMPLEMENTED
return 0;
}
DWORD STDCALL