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
4964c0f1
Commit
4964c0f1
authored
Dec 13, 2001
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Started rewrite of painting functions for multiple processes. Moved
BeginPaint to dlls/user. Fixed bug in paint count handling.
parent
9c6af0a4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
270 additions
and
153 deletions
+270
-153
Makefile.in
dlls/user/Makefile.in
+1
-0
painting.c
dlls/user/painting.c
+231
-0
wnd16.c
dlls/user/wnd16.c
+32
-0
painting.c
windows/painting.c
+6
-153
No files found.
dlls/user/Makefile.in
View file @
4964c0f1
...
...
@@ -23,6 +23,7 @@ C_SRCS = \
mouse.c
\
msg16.c
\
network.c
\
painting.c
\
property.c
\
resource.c
\
text.c
\
...
...
dlls/user/painting.c
0 → 100644
View file @
4964c0f1
/*
* Window painting functions
*
* Copyright 1993, 1994, 1995, 2001 Alexandre Julliard
* Copyright 1999 Alex Korobka
*/
#include <string.h>
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/server.h"
#include "win.h"
#include "dce.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
win
);
/***********************************************************************
* add_paint_count
*
* Add an increment (normally 1 or -1) to the current paint count of a window.
*/
static
void
add_paint_count
(
HWND
hwnd
,
int
incr
)
{
SERVER_START_REQ
(
inc_window_paint_count
)
{
req
->
handle
=
hwnd
;
req
->
incr
=
incr
;
wine_server_call
(
req
);
}
SERVER_END_REQ
;
}
/***********************************************************************
* copy_rgn
*
* copy a region, doing the right thing if the source region is 0 or 1
*/
static
HRGN
copy_rgn
(
HRGN
hSrc
)
{
if
(
hSrc
>
1
)
{
HRGN
hrgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
CombineRgn
(
hrgn
,
hSrc
,
0
,
RGN_COPY
);
return
hrgn
;
}
return
hSrc
;
}
/***********************************************************************
* get_update_regions
*
* Return update regions for the whole window and for the client area.
*/
static
void
get_update_regions
(
WND
*
win
,
HRGN
*
whole_rgn
,
HRGN
*
client_rgn
)
{
if
(
win
->
hrgnUpdate
>
1
)
{
RECT
client
,
update
;
/* check if update rgn overlaps with nonclient area */
GetRgnBox
(
win
->
hrgnUpdate
,
&
update
);
client
=
win
->
rectClient
;
OffsetRect
(
&
client
,
-
win
->
rectWindow
.
left
,
-
win
->
rectWindow
.
top
);
if
(
update
.
left
<
client
.
left
||
update
.
top
<
client
.
top
||
update
.
right
>
client
.
right
||
update
.
bottom
>
client
.
bottom
)
{
*
whole_rgn
=
copy_rgn
(
win
->
hrgnUpdate
);
*
client_rgn
=
CreateRectRgnIndirect
(
&
client
);
if
(
CombineRgn
(
*
client_rgn
,
*
client_rgn
,
win
->
hrgnUpdate
,
RGN_AND
)
==
NULLREGION
)
{
DeleteObject
(
*
client_rgn
);
*
client_rgn
=
0
;
}
}
else
{
*
whole_rgn
=
0
;
*
client_rgn
=
copy_rgn
(
win
->
hrgnUpdate
);
}
}
else
{
*
client_rgn
=
*
whole_rgn
=
win
->
hrgnUpdate
;
/* 0 or 1 */
}
}
/***********************************************************************
* begin_ncpaint
*
* Send a WM_NCPAINT message from inside BeginPaint().
* Returns update region cropped to client rectangle (and in client coords),
* and clears window update region and internal paint flag.
*/
static
HRGN
begin_ncpaint
(
HWND
hwnd
)
{
HRGN
whole_rgn
,
client_rgn
;
WND
*
wnd
=
WIN_GetPtr
(
hwnd
);
if
(
!
wnd
||
wnd
==
WND_OTHER_PROCESS
)
return
0
;
TRACE
(
"hwnd %04x [%04x] ncf %i
\n
"
,
hwnd
,
wnd
->
hrgnUpdate
,
wnd
->
flags
&
WIN_NEEDS_NCPAINT
);
get_update_regions
(
wnd
,
&
whole_rgn
,
&
client_rgn
);
if
(
whole_rgn
)
/* NOTE: WM_NCPAINT allows wParam to be 1 */
{
WIN_ReleasePtr
(
wnd
);
SendMessageA
(
hwnd
,
WM_NCPAINT
,
whole_rgn
,
0
);
if
(
whole_rgn
>
1
)
DeleteObject
(
whole_rgn
);
/* make sure the window still exists before continuing */
if
(
!
(
wnd
=
WIN_GetPtr
(
hwnd
))
||
wnd
==
WND_OTHER_PROCESS
)
{
if
(
client_rgn
>
1
)
DeleteObject
(
client_rgn
);
return
0
;
}
}
if
(
wnd
->
hrgnUpdate
||
(
wnd
->
flags
&
WIN_INTERNAL_PAINT
))
add_paint_count
(
hwnd
,
-
1
);
if
(
wnd
->
hrgnUpdate
>
1
)
DeleteObject
(
wnd
->
hrgnUpdate
);
wnd
->
hrgnUpdate
=
0
;
wnd
->
flags
&=
~
(
WIN_INTERNAL_PAINT
|
WIN_NEEDS_NCPAINT
|
WIN_NEEDS_BEGINPAINT
);
if
(
client_rgn
>
1
)
OffsetRgn
(
client_rgn
,
wnd
->
rectWindow
.
left
-
wnd
->
rectClient
.
left
,
wnd
->
rectWindow
.
top
-
wnd
->
rectClient
.
top
);
WIN_ReleasePtr
(
wnd
);
return
client_rgn
;
}
/***********************************************************************
* BeginPaint (USER32.@)
*/
HDC
WINAPI
BeginPaint
(
HWND
hwnd
,
PAINTSTRUCT
*
lps
)
{
INT
dcx_flags
;
BOOL
bIcon
;
HRGN
hrgnUpdate
;
RECT
clipRect
,
clientRect
;
HWND
full_handle
;
WND
*
wndPtr
;
if
(
!
(
full_handle
=
WIN_IsCurrentThread
(
hwnd
)))
{
if
(
IsWindow
(
hwnd
))
FIXME
(
"window %x belongs to other thread
\n
"
,
hwnd
);
return
0
;
}
hwnd
=
full_handle
;
/* send WM_NCPAINT and retrieve update region */
hrgnUpdate
=
begin_ncpaint
(
hwnd
);
if
(
!
hrgnUpdate
&&
!
IsWindow
(
hwnd
))
return
0
;
HideCaret
(
hwnd
);
bIcon
=
(
IsIconic
(
hwnd
)
&&
GetClassLongA
(
hwnd
,
GCL_HICON
));
dcx_flags
=
DCX_INTERSECTRGN
|
DCX_WINDOWPAINT
|
DCX_USESTYLE
;
if
(
bIcon
)
dcx_flags
|=
DCX_WINDOW
;
if
(
GetClassLongA
(
hwnd
,
GCL_STYLE
)
&
CS_PARENTDC
)
{
/* Don't clip the output to the update region for CS_PARENTDC window */
if
(
hrgnUpdate
>
1
)
DeleteObject
(
hrgnUpdate
);
hrgnUpdate
=
0
;
dcx_flags
&=
~
DCX_INTERSECTRGN
;
}
else
{
if
(
!
hrgnUpdate
)
/* empty region, clip everything */
{
hrgnUpdate
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
}
else
if
(
hrgnUpdate
==
1
)
/* whole client area, don't clip */
{
hrgnUpdate
=
0
;
dcx_flags
&=
~
DCX_INTERSECTRGN
;
}
}
lps
->
hdc
=
GetDCEx
(
hwnd
,
hrgnUpdate
,
dcx_flags
);
/* ReleaseDC() in EndPaint() will delete the region */
if
(
!
lps
->
hdc
)
{
WARN
(
"GetDCEx() failed in BeginPaint(), hwnd=%04x
\n
"
,
hwnd
);
DeleteObject
(
hrgnUpdate
);
return
0
;
}
/* It is possible that the clip box is bigger than the window itself,
if CS_PARENTDC flag is set. Windows never return a paint rect bigger
than the window itself, so we need to intersect the cliprect with
the window */
GetClientRect
(
hwnd
,
&
clientRect
);
GetClipBox
(
lps
->
hdc
,
&
clipRect
);
LPtoDP
(
lps
->
hdc
,
(
LPPOINT
)
&
clipRect
,
2
);
/* GetClipBox returns LP */
IntersectRect
(
&
lps
->
rcPaint
,
&
clientRect
,
&
clipRect
);
DPtoLP
(
lps
->
hdc
,
(
LPPOINT
)
&
lps
->
rcPaint
,
2
);
/* we must return LP */
TRACE
(
"hdc = %x box = (%i,%i - %i,%i)
\n
"
,
lps
->
hdc
,
lps
->
rcPaint
.
left
,
lps
->
rcPaint
.
top
,
lps
->
rcPaint
.
right
,
lps
->
rcPaint
.
bottom
);
if
(
!
(
wndPtr
=
WIN_GetPtr
(
hwnd
))
||
wndPtr
==
WND_OTHER_PROCESS
)
return
0
;
lps
->
fErase
=
!
(
wndPtr
->
flags
&
WIN_NEEDS_ERASEBKGND
);
wndPtr
->
flags
&=
~
WIN_NEEDS_ERASEBKGND
;
WIN_ReleasePtr
(
wndPtr
);
if
(
!
lps
->
fErase
)
lps
->
fErase
=
!
SendMessageA
(
hwnd
,
bIcon
?
WM_ICONERASEBKGND
:
WM_ERASEBKGND
,
(
WPARAM
)
lps
->
hdc
,
0
);
return
lps
->
hdc
;
}
/***********************************************************************
* EndPaint (USER32.@)
*/
BOOL
WINAPI
EndPaint
(
HWND
hwnd
,
const
PAINTSTRUCT
*
lps
)
{
ReleaseDC
(
hwnd
,
lps
->
hdc
);
ShowCaret
(
hwnd
);
return
TRUE
;
}
dlls/user/wnd16.c
View file @
4964c0f1
...
...
@@ -214,6 +214,38 @@ INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
}
/***********************************************************************
* BeginPaint (USER.39)
*/
HDC16
WINAPI
BeginPaint16
(
HWND16
hwnd
,
LPPAINTSTRUCT16
lps
)
{
PAINTSTRUCT
ps
;
BeginPaint
(
WIN_Handle32
(
hwnd
),
&
ps
);
lps
->
hdc
=
ps
.
hdc
;
lps
->
fErase
=
ps
.
fErase
;
lps
->
rcPaint
.
top
=
ps
.
rcPaint
.
top
;
lps
->
rcPaint
.
left
=
ps
.
rcPaint
.
left
;
lps
->
rcPaint
.
right
=
ps
.
rcPaint
.
right
;
lps
->
rcPaint
.
bottom
=
ps
.
rcPaint
.
bottom
;
lps
->
fRestore
=
ps
.
fRestore
;
lps
->
fIncUpdate
=
ps
.
fIncUpdate
;
return
lps
->
hdc
;
}
/***********************************************************************
* EndPaint (USER.40)
*/
BOOL16
WINAPI
EndPaint16
(
HWND16
hwnd
,
const
PAINTSTRUCT16
*
lps
)
{
PAINTSTRUCT
ps
;
ps
.
hdc
=
lps
->
hdc
;
return
EndPaint
(
WIN_Handle32
(
hwnd
),
&
ps
);
}
/**************************************************************************
* ShowWindow (USER.42)
*/
...
...
windows/painting.c
View file @
4964c0f1
...
...
@@ -279,153 +279,6 @@ copyrgn:
/***********************************************************************
* BeginPaint (USER.39)
*/
HDC16
WINAPI
BeginPaint16
(
HWND16
hwnd
,
LPPAINTSTRUCT16
lps
)
{
PAINTSTRUCT
ps
;
BeginPaint
(
WIN_Handle32
(
hwnd
),
&
ps
);
lps
->
hdc
=
ps
.
hdc
;
lps
->
fErase
=
ps
.
fErase
;
lps
->
rcPaint
.
top
=
ps
.
rcPaint
.
top
;
lps
->
rcPaint
.
left
=
ps
.
rcPaint
.
left
;
lps
->
rcPaint
.
right
=
ps
.
rcPaint
.
right
;
lps
->
rcPaint
.
bottom
=
ps
.
rcPaint
.
bottom
;
lps
->
fRestore
=
ps
.
fRestore
;
lps
->
fIncUpdate
=
ps
.
fIncUpdate
;
return
lps
->
hdc
;
}
/***********************************************************************
* BeginPaint (USER32.@)
*/
HDC
WINAPI
BeginPaint
(
HWND
hwnd
,
PAINTSTRUCT
*
lps
)
{
BOOL
bIcon
;
HRGN
hrgnUpdate
;
RECT
clipRect
,
clientRect
;
HWND
full_handle
;
WND
*
wndPtr
;
if
(
!
(
full_handle
=
WIN_IsCurrentThread
(
hwnd
)))
{
if
(
IsWindow
(
hwnd
))
FIXME
(
"window %x belongs to other thread
\n
"
,
hwnd
);
return
0
;
}
hwnd
=
full_handle
;
bIcon
=
(
IsIconic
(
hwnd
)
&&
GetClassLongA
(
hwnd
,
GCL_HICON
));
if
(
!
(
wndPtr
=
WIN_FindWndPtr
(
hwnd
)))
return
0
;
wndPtr
->
flags
&=
~
WIN_NEEDS_BEGINPAINT
;
/* send WM_NCPAINT and make sure hrgnUpdate is a valid rgn handle */
WIN_UpdateNCRgn
(
wndPtr
,
0
,
UNC_UPDATE
|
UNC_IN_BEGINPAINT
);
/*
* Make sure the window is still a window. All window locks are suspended
* when the WM_NCPAINT is sent.
*/
if
(
!
IsWindow
(
hwnd
))
{
WIN_ReleaseWndPtr
(
wndPtr
);
return
0
;
}
if
(
((
hrgnUpdate
=
wndPtr
->
hrgnUpdate
)
!=
0
)
||
(
wndPtr
->
flags
&
WIN_INTERNAL_PAINT
))
add_paint_count
(
hwnd
,
-
1
);
wndPtr
->
hrgnUpdate
=
0
;
wndPtr
->
flags
&=
~
WIN_INTERNAL_PAINT
;
WIN_ReleaseWndPtr
(
wndPtr
);
HideCaret
(
hwnd
);
TRACE
(
"hrgnUpdate = %04x,
\n
"
,
hrgnUpdate
);
if
(
GetClassLongA
(
hwnd
,
GCL_STYLE
)
&
CS_PARENTDC
)
{
/* Don't clip the output to the update region for CS_PARENTDC window */
if
(
hrgnUpdate
)
DeleteObject
(
hrgnUpdate
);
lps
->
hdc
=
GetDCEx
(
hwnd
,
0
,
DCX_WINDOWPAINT
|
DCX_USESTYLE
|
(
bIcon
?
DCX_WINDOW
:
0
)
);
}
else
{
if
(
hrgnUpdate
)
/* convert to client coordinates */
OffsetRgn
(
hrgnUpdate
,
wndPtr
->
rectWindow
.
left
-
wndPtr
->
rectClient
.
left
,
wndPtr
->
rectWindow
.
top
-
wndPtr
->
rectClient
.
top
);
lps
->
hdc
=
GetDCEx
(
hwnd
,
hrgnUpdate
,
DCX_INTERSECTRGN
|
DCX_WINDOWPAINT
|
DCX_USESTYLE
|
(
bIcon
?
DCX_WINDOW
:
0
)
);
/* ReleaseDC() in EndPaint() will delete the region */
}
TRACE
(
"hdc = %04x
\n
"
,
lps
->
hdc
);
if
(
!
lps
->
hdc
)
{
WARN
(
"GetDCEx() failed in BeginPaint(), hwnd=%04x
\n
"
,
hwnd
);
return
0
;
}
/* It is possible that the clip box is bigger than the window itself,
if CS_PARENTDC flag is set. Windows never return a paint rect bigger
than the window itself, so we need to intersect the cliprect with
the window */
GetClientRect
(
hwnd
,
&
clientRect
);
GetClipBox
(
lps
->
hdc
,
&
clipRect
);
LPtoDP
(
lps
->
hdc
,
(
LPPOINT
)
&
clipRect
,
2
);
/* GetClipBox returns LP */
IntersectRect
(
&
lps
->
rcPaint
,
&
clientRect
,
&
clipRect
);
DPtoLP
(
lps
->
hdc
,
(
LPPOINT
)
&
lps
->
rcPaint
,
2
);
/* we must return LP */
TRACE
(
"box = (%i,%i - %i,%i)
\n
"
,
lps
->
rcPaint
.
left
,
lps
->
rcPaint
.
top
,
lps
->
rcPaint
.
right
,
lps
->
rcPaint
.
bottom
);
if
(
!
(
wndPtr
=
WIN_FindWndPtr
(
hwnd
)))
return
0
;
if
(
wndPtr
->
flags
&
WIN_NEEDS_ERASEBKGND
)
{
wndPtr
->
flags
&=
~
WIN_NEEDS_ERASEBKGND
;
lps
->
fErase
=
!
SendMessageA
(
hwnd
,
(
bIcon
)
?
WM_ICONERASEBKGND
:
WM_ERASEBKGND
,
(
WPARAM16
)
lps
->
hdc
,
0
);
}
else
lps
->
fErase
=
TRUE
;
WIN_ReleaseWndPtr
(
wndPtr
);
return
lps
->
hdc
;
}
/***********************************************************************
* EndPaint (USER.40)
*/
BOOL16
WINAPI
EndPaint16
(
HWND16
hwnd
,
const
PAINTSTRUCT16
*
lps
)
{
ReleaseDC16
(
hwnd
,
lps
->
hdc
);
ShowCaret16
(
hwnd
);
return
TRUE
;
}
/***********************************************************************
* EndPaint (USER32.@)
*/
BOOL
WINAPI
EndPaint
(
HWND
hwnd
,
const
PAINTSTRUCT
*
lps
)
{
ReleaseDC
(
hwnd
,
lps
->
hdc
);
ShowCaret
(
hwnd
);
return
TRUE
;
}
/***********************************************************************
* RDW_ValidateParent [RDW_UpdateRgns() helper]
*
* Validate the portions of parents that are covered by a validated child
...
...
@@ -858,8 +711,6 @@ BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rectUpdate,
{
if
(
!
IntersectRect
(
&
r2
,
&
r
,
rectUpdate
)
)
goto
END
;
OffsetRect
(
&
r2
,
pt
.
x
,
pt
.
y
);
rect2i:
if
(
wndPtr
->
hrgnUpdate
==
0
)
wndPtr
->
hrgnUpdate
=
CreateRectRgnIndirect
(
&
r2
);
else
...
...
@@ -869,14 +720,16 @@ rect2i:
{
if
(
flags
&
RDW_FRAME
)
{
if
(
wndPtr
->
hrgnUpdate
)
DeleteObject
(
wndPtr
->
hrgnUpdate
);
wndPtr
->
hrgnUpdate
=
1
;
if
(
wndPtr
->
hrgnUpdate
)
hRgn
=
1
;
else
wndPtr
->
hrgnUpdate
=
1
;
}
else
{
GETCLIENTRECTW
(
wndPtr
,
r2
);
goto
rect2i
;
if
(
wndPtr
->
hrgnUpdate
==
0
)
wndPtr
->
hrgnUpdate
=
CreateRectRgnIndirect
(
&
r2
);
else
hRgn
=
CreateRectRgnIndirect
(
&
r2
);
}
}
}
...
...
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