mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Initial code for NtUserGetDC
svn path=/trunk/; revision=3387
This commit is contained in:
parent
34b85a88a2
commit
1231d02b03
9 changed files with 197 additions and 23 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue