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
db412aaf
Commit
db412aaf
authored
May 31, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added a from_child parameter to the get_update_region request to allow
restarting the search from a given child, in order to avoid looping forever on windows that don't repaint correctly.
parent
ec3cf77d
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
111 additions
and
52 deletions
+111
-52
painting.c
dlls/user/painting.c
+9
-22
server_protocol.h
include/wine/server_protocol.h
+2
-1
protocol.def
server/protocol.def
+1
-0
trace.c
server/trace.c
+1
-0
window.c
server/window.c
+98
-29
No files found.
dlls/user/painting.c
View file @
db412aaf
...
...
@@ -99,8 +99,9 @@ static HRGN get_update_region( HWND hwnd, UINT *flags, HWND *child )
SERVER_START_REQ
(
get_update_region
)
{
req
->
window
=
hwnd
;
req
->
flags
=
*
flags
;
req
->
window
=
hwnd
;
req
->
from_child
=
child
?
*
child
:
0
;
req
->
flags
=
*
flags
;
wine_server_set_reply
(
req
,
data
->
Buffer
,
size
);
if
(
!
(
status
=
wine_server_call
(
req
)))
{
...
...
@@ -135,8 +136,9 @@ static BOOL get_update_flags( HWND hwnd, HWND *child, UINT *flags )
SERVER_START_REQ
(
get_update_region
)
{
req
->
window
=
hwnd
;
req
->
flags
=
*
flags
|
UPDATE_NOREGION
;
req
->
window
=
hwnd
;
req
->
from_child
=
child
?
*
child
:
0
;
req
->
flags
=
*
flags
|
UPDATE_NOREGION
;
if
((
ret
=
!
wine_server_call_err
(
req
)))
{
if
(
child
)
*
child
=
reply
->
child
;
...
...
@@ -279,7 +281,7 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
*/
static
void
erase_now
(
HWND
hwnd
,
UINT
rdw_flags
)
{
HWND
child
;
HWND
child
=
0
;
HRGN
hrgn
;
/* loop while we find a child to repaint */
...
...
@@ -319,7 +321,7 @@ static void erase_now( HWND hwnd, UINT rdw_flags )
*/
static
void
update_now
(
HWND
hwnd
,
UINT
rdw_flags
)
{
HWND
prev
=
0
,
child
;
HWND
child
=
0
;
/* desktop window never gets WM_PAINT, only WM_ERASEBKGND */
if
(
hwnd
==
GetDesktopWindow
())
erase_now
(
hwnd
,
rdw_flags
|
RDW_NOCHILDREN
);
...
...
@@ -335,22 +337,7 @@ static void update_now( HWND hwnd, UINT rdw_flags )
if
(
!
get_update_flags
(
hwnd
,
&
child
,
&
flags
))
break
;
if
(
!
flags
)
break
;
/* nothing more to do */
if
(
child
==
prev
)
/* same window again, didn't get repainted properly */
{
UINT
erase_flags
=
UPDATE_NONCLIENT
|
UPDATE_ERASE
|
UPDATE_NOCHILDREN
;
HRGN
hrgn
;
TRACE
(
"%p not repainted properly, erasing
\n
"
,
child
);
if
((
hrgn
=
send_ncpaint
(
child
,
NULL
,
&
erase_flags
)))
send_erase
(
child
,
erase_flags
,
hrgn
,
NULL
,
NULL
);
prev
=
0
;
}
else
{
prev
=
child
;
SendMessageW
(
child
,
WM_PAINT
,
0
,
0
);
}
SendMessageW
(
child
,
WM_PAINT
,
0
,
0
);
if
(
rdw_flags
&
RDW_NOCHILDREN
)
break
;
}
}
...
...
include/wine/server_protocol.h
View file @
db412aaf
...
...
@@ -2770,6 +2770,7 @@ struct get_update_region_request
{
struct
request_header
__header
;
user_handle_t
window
;
user_handle_t
from_child
;
unsigned
int
flags
;
};
struct
get_update_region_reply
...
...
@@ -3997,6 +3998,6 @@ union generic_reply
struct
set_mailslot_info_reply
set_mailslot_info_reply
;
};
#define SERVER_PROTOCOL_VERSION 17
6
#define SERVER_PROTOCOL_VERSION 17
7
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/protocol.def
View file @
db412aaf
...
...
@@ -1953,6 +1953,7 @@ enum message_type
/* Get the window update region */
@REQ(get_update_region)
user_handle_t window; /* handle to the window */
user_handle_t from_child; /* child to start searching from */
unsigned int flags; /* update flags (see below) */
@REPLY
user_handle_t child; /* child to repaint (or window itself) */
...
...
server/trace.c
View file @
db412aaf
...
...
@@ -2440,6 +2440,7 @@ static void dump_set_window_region_request( const struct set_window_region_reque
static
void
dump_get_update_region_request
(
const
struct
get_update_region_request
*
req
)
{
fprintf
(
stderr
,
" window=%p,"
,
req
->
window
);
fprintf
(
stderr
,
" from_child=%p,"
,
req
->
from_child
);
fprintf
(
stderr
,
" flags=%08x"
,
req
->
flags
);
}
...
...
server/window.c
View file @
db412aaf
...
...
@@ -1046,33 +1046,108 @@ static unsigned int get_update_flags( struct window *win, unsigned int flags )
/* iterate through the children of the given window until we find one with some update flags */
static
unsigned
int
get_child_update_flags
(
struct
window
*
win
,
unsigned
int
flags
,
struct
window
**
child
)
static
unsigned
int
get_child_update_flags
(
struct
window
*
win
,
struct
window
*
from_child
,
unsigned
int
flags
,
struct
window
**
child
)
{
struct
window
*
ptr
;
unsigned
int
ret
=
0
;
/* first make sure we want to iterate children at all */
if
(
win
->
style
&
WS_MINIMIZE
)
return
0
;
/* note: the WS_CLIPCHILDREN test is the opposite of the invalidation case,
* here we only want to repaint children of windows that clip them, others
* need to wait for WM_PAINT to be done in the parent first.
*/
if
(
!
(
flags
&
UPDATE_ALLCHILDREN
)
&&
!
(
win
->
style
&
WS_CLIPCHILDREN
))
return
0
;
LIST_FOR_EACH_ENTRY
(
ptr
,
&
win
->
children
,
struct
window
,
entry
)
{
if
(
from_child
)
/* skip all children until from_child is found */
{
if
(
ptr
==
from_child
)
from_child
=
NULL
;
continue
;
}
if
(
!
(
ptr
->
style
&
WS_VISIBLE
))
continue
;
if
((
ret
=
get_update_flags
(
ptr
,
flags
))
!=
0
)
{
*
child
=
ptr
;
break
;
}
if
(
ptr
->
style
&
WS_MINIMIZE
)
continue
;
/* Note: the WS_CLIPCHILDREN test is the opposite of the invalidation case,
* here we only want to repaint children of windows that clip them, others
* need to wait for WM_PAINT to be done in the parent first.
*/
if
(
!
(
flags
&
UPDATE_NOCHILDREN
)
&&
((
flags
&
UPDATE_ALLCHILDREN
)
||
(
ptr
->
style
&
WS_CLIPCHILDREN
)))
if
((
ret
=
get_child_update_flags
(
ptr
,
NULL
,
flags
,
child
)))
break
;
}
return
ret
;
}
/* iterate through children and siblings of the given window until we find one with some update flags */
static
unsigned
int
get_window_update_flags
(
struct
window
*
win
,
struct
window
*
from_child
,
unsigned
int
flags
,
struct
window
**
child
)
{
unsigned
int
ret
;
struct
window
*
ptr
,
*
from_sibling
=
NULL
;
/* if some parent is not visible start from the next sibling */
if
(
!
is_visible
(
win
))
return
0
;
for
(
ptr
=
from_child
;
ptr
&&
ptr
!=
top_window
;
ptr
=
ptr
->
parent
)
{
if
(
!
(
ptr
->
style
&
WS_VISIBLE
)
||
(
ptr
->
style
&
WS_MINIMIZE
))
from_sibling
=
ptr
;
if
(
ptr
==
win
)
break
;
}
/* non-client painting must be delayed if one of the parents is going to
* be repainted and doesn't clip children */
if
((
flags
&
UPDATE_NONCLIENT
)
&&
!
(
flags
&
(
UPDATE_PAINT
|
UPDATE_INTERNALPAINT
)))
{
for
(
ptr
=
win
->
parent
;
ptr
&&
ptr
!=
top_window
;
ptr
=
ptr
->
parent
)
{
if
(
!
(
ptr
->
style
&
WS_CLIPCHILDREN
)
&&
win_needs_repaint
(
ptr
))
return
0
;
}
if
(
from_child
&&
!
(
flags
&
UPDATE_ALLCHILDREN
))
{
if
((
ret
=
get_child_update_flags
(
ptr
,
flags
,
child
)))
break
;
for
(
ptr
=
from_sibling
?
from_sibling
:
from_child
;
ptr
&&
ptr
!=
top_window
;
ptr
=
ptr
->
parent
)
{
if
(
!
(
ptr
->
style
&
WS_CLIPCHILDREN
)
&&
win_needs_repaint
(
ptr
))
from_sibling
=
ptr
;
if
(
ptr
==
win
)
break
;
}
}
}
return
ret
;
/* check window itself (only if not restarting from a child) */
if
(
!
from_child
)
{
if
((
ret
=
get_update_flags
(
win
,
flags
)))
{
*
child
=
win
;
return
ret
;
}
from_child
=
win
;
}
/* now check children */
if
(
flags
&
UPDATE_NOCHILDREN
)
return
0
;
if
(
!
from_sibling
)
{
if
((
ret
=
get_child_update_flags
(
from_child
,
NULL
,
flags
,
child
)))
return
ret
;
from_sibling
=
from_child
;
}
/* then check siblings and parent siblings */
while
(
from_sibling
->
parent
&&
from_sibling
!=
win
)
{
if
((
ret
=
get_child_update_flags
(
from_sibling
->
parent
,
from_sibling
,
flags
,
child
)))
return
ret
;
from_sibling
=
from_sibling
->
parent
;
}
return
0
;
}
...
...
@@ -1667,35 +1742,29 @@ DECL_HANDLER(get_update_region)
{
rectangle_t
*
data
;
unsigned
int
flags
=
req
->
flags
;
struct
window
*
from_child
=
NULL
;
struct
window
*
win
=
get_window
(
req
->
window
);
reply
->
flags
=
0
;
if
(
!
win
||
!
is_visible
(
win
)
)
return
;
if
(
!
win
)
return
;
if
(
(
flags
&
UPDATE_NONCLIENT
)
&&
!
(
flags
&
(
UPDATE_PAINT
|
UPDATE_INTERNALPAINT
))
)
if
(
req
->
from_child
)
{
/* non-client painting must be delayed if one of the parents is going to
* be repainted and doesn't clip children */
struct
window
*
ptr
;
for
(
ptr
=
win
->
parent
;
ptr
&&
ptr
!=
top_window
;
ptr
=
ptr
->
parent
)
{
if
(
!
(
ptr
->
style
&
WS_CLIPCHILDREN
)
&&
win_needs_repaint
(
ptr
))
return
;
}
}
if
(
!
(
from_child
=
get_window
(
req
->
from_child
)))
return
;
if
(
!
(
reply
->
flags
=
get_update_flags
(
win
,
flags
)))
{
/* if window doesn't need any repaint, check the children */
if
(
!
(
flags
&
UPDATE_NOCHILDREN
)
&&
((
flags
&
UPDATE_ALLCHILDREN
)
||
(
win
->
style
&
WS_CLIPCHILDREN
))
&&
!
(
win
->
style
&
WS_MINIMIZE
))
/* make sure from_child is a child of win */
ptr
=
from_child
;
while
(
ptr
&&
ptr
!=
win
)
ptr
=
ptr
->
parent
;
if
(
!
ptr
)
{
reply
->
flags
=
get_child_update_flags
(
win
,
flags
,
&
win
);
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
}
reply
->
flags
=
get_window_update_flags
(
win
,
from_child
,
flags
,
&
win
);
reply
->
child
=
win
->
handle
;
if
(
flags
&
UPDATE_NOREGION
)
return
;
...
...
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