Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
7caa1f6b
Commit
7caa1f6b
authored
Mar 02, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Beginnings of inter-process GetDC support.
Use a standard list for the DCE list. Small cleanups.
parent
a9e0fb1b
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
78 additions
and
88 deletions
+78
-88
dce.h
include/dce.h
+3
-13
dce.c
windows/dce.c
+75
-75
No files found.
include/dce.h
View file @
7caa1f6b
...
...
@@ -36,20 +36,10 @@ typedef enum
DCE_WINDOW_DC
/* This is a window DC (style CS_OWNDC) */
}
DCE_TYPE
;
struct
tagDCE
;
typedef
struct
tagDCE
{
struct
tagDCE
*
next
;
HDC
hDC
;
HWND
hwndCurrent
;
HWND
hwndDC
;
HRGN
hClipRgn
;
DCE_TYPE
type
;
DWORD
DCXflags
;
}
DCE
;
extern
DCE
*
DCE_AllocDCE
(
HWND
hWnd
,
DCE_TYPE
type
);
extern
DCE
*
DCE_FreeDCE
(
DCE
*
dce
);
extern
struct
tagDCE
*
DCE_AllocDCE
(
HWND
hWnd
,
DCE_TYPE
type
);
extern
void
DCE_FreeDCE
(
struct
tagDCE
*
dce
);
extern
void
DCE_FreeWindowDCE
(
HWND
);
extern
BOOL
DCE_InvalidateDCE
(
HWND
,
const
RECT
*
);
...
...
windows/dce.c
View file @
7caa1f6b
...
...
@@ -34,16 +34,27 @@
#include "dce.h"
#include "win.h"
#include "user_private.h"
#include "wine/debug.h"
#include "windef.h"
#include "wingdi.h"
#include "wownt32.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
dc
);
static
DCE
*
firstDCE
;
typedef
struct
tagDCE
{
struct
list
entry
;
HDC
hDC
;
HWND
hwndCurrent
;
HRGN
hClipRgn
;
DCE_TYPE
type
;
DWORD
DCXflags
;
}
DCE
;
static
struct
list
dce_list
=
LIST_INIT
(
dce_list
);
static
void
DCE_DeleteClipRgn
(
DCE
*
);
static
INT
DCE_ReleaseDC
(
DCE
*
);
...
...
@@ -58,7 +69,7 @@ static void DCE_DumpCache(void)
USER_Lock
();
for
(
dce
=
firstDCE
;
dce
;
dce
=
dce
->
next
)
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
DCE
,
entry
)
{
TRACE
(
"
\t
[0x%08x] hWnd %p, dcx %08x, %s %s
\n
"
,
(
unsigned
)
dce
,
dce
->
hwndCurrent
,
(
unsigned
)
dce
->
DCXflags
,
...
...
@@ -95,6 +106,7 @@ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
dce
->
hwndCurrent
=
hWnd
;
dce
->
hClipRgn
=
0
;
dce
->
type
=
type
;
if
(
type
!=
DCE_CACHE_DC
)
/* owned or class DC */
{
...
...
@@ -110,8 +122,7 @@ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
else
dce
->
DCXflags
=
DCX_CACHE
|
DCX_DCEEMPTY
;
USER_Lock
();
dce
->
next
=
firstDCE
;
firstDCE
=
dce
;
list_add_head
(
&
dce_list
,
&
dce
->
entry
);
USER_Unlock
();
return
dce
;
}
...
...
@@ -120,19 +131,12 @@ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
/***********************************************************************
* DCE_FreeDCE
*/
DCE
*
DCE_FreeDCE
(
DCE
*
dce
)
void
DCE_FreeDCE
(
DCE
*
dce
)
{
DCE
**
ppDCE
,
*
ret
;
if
(
!
dce
)
return
NULL
;
if
(
!
dce
)
return
;
USER_Lock
();
ppDCE
=
&
firstDCE
;
while
(
*
ppDCE
&&
(
*
ppDCE
!=
dce
))
ppDCE
=
&
(
*
ppDCE
)
->
next
;
if
(
*
ppDCE
==
dce
)
*
ppDCE
=
dce
->
next
;
ret
=
*
ppDCE
;
list_remove
(
&
dce
->
entry
);
USER_Unlock
();
SetDCHook
(
dce
->
hDC
,
NULL
,
0L
);
...
...
@@ -140,8 +144,6 @@ DCE* DCE_FreeDCE( DCE *dce )
DeleteDC
(
dce
->
hDC
);
if
(
dce
->
hClipRgn
)
DeleteObject
(
dce
->
hClipRgn
);
HeapFree
(
GetProcessHeap
(),
0
,
dce
);
return
ret
;
}
/***********************************************************************
...
...
@@ -151,54 +153,44 @@ DCE* DCE_FreeDCE( DCE *dce )
*/
void
DCE_FreeWindowDCE
(
HWND
hwnd
)
{
DCE
*
pDCE
;
struct
list
*
ptr
,
*
next
;
WND
*
pWnd
=
WIN_GetPtr
(
hwnd
);
pDCE
=
firstDCE
;
while
(
pDCE
)
{
if
(
pDCE
->
hwndCurrent
==
hwnd
)
LIST_FOR_EACH_SAFE
(
ptr
,
next
,
&
dce_list
)
{
if
(
pDCE
==
pWnd
->
dce
)
/* owned or Class DCE*/
{
if
(
pWnd
->
clsStyle
&
CS_OWNDC
)
/* owned DCE*/
DCE
*
pDCE
=
LIST_ENTRY
(
ptr
,
DCE
,
entry
);
if
(
pDCE
->
hwndCurrent
!=
hwnd
)
continue
;
switch
(
pDCE
->
type
)
{
pDCE
=
DCE_FreeDCE
(
pDCE
);
case
DCE_WINDOW_DC
:
DCE_FreeDCE
(
pDCE
);
pWnd
->
dce
=
NULL
;
continue
;
}
else
if
(
pDCE
->
DCXflags
&
(
DCX_INTERSECTRGN
|
DCX_EXCLUDERGN
)
)
/* Class DCE*/
break
;
case
DCE_CLASS_DC
:
if
(
pDCE
->
DCXflags
&
(
DCX_INTERSECTRGN
|
DCX_EXCLUDERGN
)
)
{
if
(
USER_Driver
.
pReleaseDC
)
USER_Driver
.
pReleaseDC
(
pDCE
->
hwndCurrent
,
pDCE
->
hDC
);
DCE_DeleteClipRgn
(
pDCE
);
pDCE
->
hwndCurrent
=
0
;
}
}
else
{
break
;
case
DCE_CACHE_DC
:
if
(
pDCE
->
DCXflags
&
DCX_DCEBUSY
)
/* shared cache DCE */
{
/* FIXME: AFAICS we are doing the right thing here so
* this should be a WARN. But this is best left as an ERR
* because the 'application error' is likely to come from
* another part of Wine (i.e. it's our fault after all).
* We should change this to WARN when Wine is more stable
* (for 1.0?).
*/
ERR
(
"[%p] GetDC() without ReleaseDC()!
\n
"
,
hwnd
);
WARN
(
"[%p] GetDC() without ReleaseDC()!
\n
"
,
hwnd
);
DCE_ReleaseDC
(
pDCE
);
}
if
(
pDCE
->
hwndCurrent
&&
USER_Driver
.
pReleaseDC
)
USER_Driver
.
pReleaseDC
(
pDCE
->
hwndCurrent
,
pDCE
->
hDC
);
pDCE
->
DCXflags
&=
DCX_CACHE
;
pDCE
->
DCXflags
|=
DCX_DCEEMPTY
;
pDCE
->
hwndCurrent
=
0
;
break
;
}
}
pDCE
=
pDCE
->
next
;
}
WIN_ReleasePtr
(
pWnd
);
}
...
...
@@ -280,7 +272,7 @@ BOOL DCE_InvalidateDCE(HWND hwnd, const RECT* pRectUpdate)
/* walk all DCEs and fixup non-empty entries */
for
(
dce
=
firstDCE
;
(
dce
);
dce
=
dce
->
next
)
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
DCE
,
entry
)
{
if
(
dce
->
DCXflags
&
DCX_DCEEMPTY
)
continue
;
if
((
dce
->
hwndCurrent
==
hwndScope
)
&&
!
(
dce
->
DCXflags
&
DCX_CLIPCHILDREN
))
...
...
@@ -341,7 +333,8 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
DWORD
dcxFlags
=
0
;
BOOL
bUpdateVisRgn
=
TRUE
;
BOOL
bUpdateClipOrigin
=
FALSE
;
HWND
parent
,
full
;
HWND
parent
;
LONG
window_style
;
TRACE
(
"hwnd %p, hrgnClip %p, flags %08lx
\n
"
,
hwnd
,
hrgnClip
,
flags
);
...
...
@@ -353,13 +346,16 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
}
if
(
!
hwnd
)
hwnd
=
GetDesktopWindow
();
if
(
!
(
full
=
WIN_IsCurrentProcess
(
hwnd
)))
else
hwnd
=
WIN_GetFullHandle
(
hwnd
);
if
(
!
(
wndPtr
=
WIN_GetPtr
(
hwnd
)))
return
0
;
if
(
wndPtr
==
WND_OTHER_PROCESS
)
{
FIXME
(
"not supported yet on other process window %p
\n
"
,
hwnd
)
;
return
0
;
wndPtr
=
NULL
;
USER_Lock
()
;
}
hwnd
=
full
;
if
(
!
(
wndPtr
=
WIN_GetPtr
(
hwnd
)))
return
0
;
window_style
=
GetWindowLongW
(
hwnd
,
GWL_STYLE
)
;
/* fixup flags */
...
...
@@ -369,16 +365,16 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
{
flags
&=
~
(
DCX_CLIPCHILDREN
|
DCX_CLIPSIBLINGS
|
DCX_PARENTCLIP
);
if
(
w
ndPtr
->
dwS
tyle
&
WS_CLIPSIBLINGS
)
if
(
w
indow_s
tyle
&
WS_CLIPSIBLINGS
)
flags
|=
DCX_CLIPSIBLINGS
;
if
(
!
(
flags
&
DCX_WINDOW
)
)
{
if
(
wndPtr
->
clsStyle
&
CS_PARENTDC
)
flags
|=
DCX_PARENTCLIP
;
if
(
GetClassLongW
(
hwnd
,
GCL_STYLE
)
&
CS_PARENTDC
)
flags
|=
DCX_PARENTCLIP
;
if
(
wndPtr
->
dwStyle
&
WS_CLIPCHILDREN
&&
!
(
wndPtr
->
dwStyle
&
WS_MINIMIZE
)
)
flags
|=
DCX_CLIPCHILDREN
;
if
(
!
wndPtr
->
dce
)
flags
|=
DCX_CACHE
;
if
(
window_style
&
WS_CLIPCHILDREN
&&
!
(
window_style
&
WS_MINIMIZE
))
flags
|=
DCX_CLIPCHILDREN
;
if
(
!
wndPtr
||
!
wndPtr
->
dce
)
flags
|=
DCX_CACHE
;
}
}
...
...
@@ -394,7 +390,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if
(
flags
&
DCX_PARENTCLIP
)
{
LONG
parent_style
=
GetWindowLongW
(
parent
,
GWL_STYLE
);
if
(
(
w
ndPtr
->
dwS
tyle
&
WS_VISIBLE
)
&&
(
parent_style
&
WS_VISIBLE
)
)
if
(
(
w
indow_s
tyle
&
WS_VISIBLE
)
&&
(
parent_style
&
WS_VISIBLE
)
)
{
flags
&=
~
DCX_CLIPCHILDREN
;
if
(
parent_style
&
WS_CLIPSIBLINGS
)
flags
|=
DCX_CLIPSIBLINGS
;
...
...
@@ -408,17 +404,14 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if
(
flags
&
DCX_CACHE
)
{
DCE
*
dceEmpty
;
DCE
*
dceUnused
;
dceEmpty
=
dceUnused
=
NULL
;
DCE
*
dceEmpty
=
NULL
,
*
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
)
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
DCE
,
entry
)
{
if
((
dce
->
DCXflags
&
(
DCX_CACHE
|
DCX_DCEBUSY
))
==
DCX_CACHE
)
{
...
...
@@ -440,7 +433,8 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
}
}
if
(
!
dce
)
dce
=
(
dceEmpty
)
?
dceEmpty
:
dceUnused
;
if
(
&
dce
->
entry
==
&
dce_list
)
/* nothing found */
dce
=
dceEmpty
?
dceEmpty
:
dceUnused
;
/* if there's no dce empty or unused, allocate a new one */
if
(
!
dce
)
...
...
@@ -488,7 +482,8 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
TRACE
(
"(%p,%p,0x%lx): returning %p
\n
"
,
hwnd
,
hrgnClip
,
flags
,
hdc
);
END:
WIN_ReleasePtr
(
wndPtr
);
if
(
wndPtr
)
WIN_ReleasePtr
(
wndPtr
);
else
USER_Unlock
();
return
hdc
;
}
...
...
@@ -533,17 +528,19 @@ INT WINAPI ReleaseDC( HWND hwnd, HDC hdc )
DCE
*
dce
;
INT
nRet
=
0
;
USER_Lock
();
dce
=
firstDCE
;
TRACE
(
"%p %p
\n
"
,
hwnd
,
hdc
);
while
(
dce
&&
(
dce
->
hDC
!=
hdc
))
dce
=
dce
->
next
;
if
(
dce
)
USER_Lock
();
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
DCE
,
entry
)
{
if
(
dce
->
hDC
==
hdc
)
{
if
(
dce
->
DCXflags
&
DCX_DCEBUSY
)
nRet
=
DCE_ReleaseDC
(
dce
);
break
;
}
}
USER_Unlock
();
return
nRet
;
...
...
@@ -615,14 +612,17 @@ BOOL16 WINAPI DCHook16( HDC16 hDC, WORD code, DWORD data, LPARAM lParam )
HWND
WINAPI
WindowFromDC
(
HDC
hDC
)
{
DCE
*
dce
;
HWND
hwnd
;
HWND
hwnd
=
0
;
USER_Lock
();
dce
=
firstDCE
;
while
(
dce
&&
(
dce
->
hDC
!=
hDC
))
dce
=
dce
->
next
;
hwnd
=
dce
?
dce
->
hwndCurrent
:
0
;
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
DCE
,
entry
)
{
if
(
dce
->
hDC
==
hDC
)
{
hwnd
=
dce
->
hwndCurrent
;
break
;
}
}
USER_Unlock
();
return
hwnd
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment