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
7304445a
Commit
7304445a
authored
Sep 06, 2012
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32: Maintain a list of active window surfaces and flush them periodically.
parent
a5ef549c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
70 additions
and
16 deletions
+70
-16
painting.c
dlls/user32/painting.c
+3
-13
win.c
dlls/user32/win.c
+60
-2
win.h
dlls/user32/win.h
+2
-0
winpos.c
dlls/user32/winpos.c
+1
-0
winproc.c
dlls/user32/winproc.c
+4
-1
No files found.
dlls/user32/painting.c
View file @
7304445a
...
...
@@ -801,23 +801,11 @@ void move_window_bits( HWND hwnd, struct window_surface *old_surface,
* update_now
*
* Implementation of RDW_UPDATENOW behavior.
*
* FIXME: Windows uses WM_SYNCPAINT to cut down the number of intertask
* SendMessage() calls. This is a comment inside DefWindowProc() source
* from 16-bit SDK:
*
* This message avoids lots of inter-app message traffic
* by switching to the other task and continuing the
* recursion there.
*
* wParam = flags
* LOWORD(lParam) = hrgnClip
* HIWORD(lParam) = hwndSkip (not used; always NULL)
*
*/
static
void
update_now
(
HWND
hwnd
,
UINT
rdw_flags
)
{
HWND
child
=
0
;
int
count
=
0
;
/* desktop window never gets WM_PAINT, only WM_ERASEBKGND */
if
(
hwnd
==
GetDesktopWindow
())
erase_now
(
hwnd
,
rdw_flags
|
RDW_NOCHILDREN
);
...
...
@@ -834,8 +822,10 @@ static void update_now( HWND hwnd, UINT rdw_flags )
if
(
!
flags
)
break
;
/* nothing more to do */
SendMessageW
(
child
,
WM_PAINT
,
0
,
0
);
count
++
;
if
(
rdw_flags
&
RDW_NOCHILDREN
)
break
;
}
if
(
count
)
flush_window_surfaces
(
FALSE
);
}
...
...
dlls/user32/win.c
View file @
7304445a
...
...
@@ -44,6 +44,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
static
DWORD
process_layout
=
~
0u
;
static
struct
list
window_surfaces
=
LIST_INIT
(
window_surfaces
);
static
CRITICAL_SECTION
surfaces_section
;
static
CRITICAL_SECTION_DEBUG
critsect_debug
=
{
0
,
0
,
&
surfaces_section
,
{
&
critsect_debug
.
ProcessLocksList
,
&
critsect_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": surfaces_section"
)
}
};
static
CRITICAL_SECTION
surfaces_section
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
/**********************************************************************/
/* helper for Get/SetWindowLong */
...
...
@@ -475,6 +486,45 @@ BOOL is_desktop_window( HWND hwnd )
}
/*******************************************************************
* register_window_surface
*
* Register a window surface in the global list, possibly replacing another one.
*/
void
register_window_surface
(
struct
window_surface
*
old
,
struct
window_surface
*
new
)
{
if
(
old
==
new
)
return
;
EnterCriticalSection
(
&
surfaces_section
);
if
(
old
)
list_remove
(
&
old
->
entry
);
if
(
new
)
list_add_tail
(
&
window_surfaces
,
&
new
->
entry
);
LeaveCriticalSection
(
&
surfaces_section
);
}
/*******************************************************************
* flush_window_surfaces
*
* Flush pending output from all window surfaces.
*/
void
flush_window_surfaces
(
BOOL
idle
)
{
static
DWORD
last_idle
;
DWORD
now
;
struct
window_surface
*
surface
;
EnterCriticalSection
(
&
surfaces_section
);
now
=
GetTickCount
();
if
(
idle
)
last_idle
=
now
;
/* if not idle, we only flush if there's evidence that the app never goes idle */
else
if
((
int
)(
now
-
last_idle
)
<
1000
)
goto
done
;
LIST_FOR_EACH_ENTRY
(
surface
,
&
window_surfaces
,
struct
window_surface
,
entry
)
surface
->
funcs
->
flush
(
surface
);
done:
LeaveCriticalSection
(
&
surfaces_section
);
}
/***********************************************************************
* WIN_GetPtr
*
...
...
@@ -863,7 +913,11 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
if
(
icon_title
)
DestroyWindow
(
icon_title
);
if
(
menu
)
DestroyMenu
(
menu
);
if
(
sys_menu
)
DestroyMenu
(
sys_menu
);
if
(
surface
)
window_surface_release
(
surface
);
if
(
surface
)
{
register_window_surface
(
surface
,
NULL
);
window_surface_release
(
surface
);
}
USER_Driver
->
pDestroyWindow
(
hwnd
);
...
...
@@ -917,7 +971,11 @@ static void destroy_thread_window( HWND hwnd )
HeapFree
(
GetProcessHeap
(),
0
,
wndPtr
);
if
(
menu
)
DestroyMenu
(
menu
);
if
(
sys_menu
)
DestroyMenu
(
sys_menu
);
if
(
surface
)
window_surface_release
(
surface
);
if
(
surface
)
{
register_window_surface
(
surface
,
NULL
);
window_surface_release
(
surface
);
}
}
...
...
dlls/user32/win.h
View file @
7304445a
...
...
@@ -80,6 +80,8 @@ typedef struct tagWND
/* Window functions */
extern
HWND
get_hwnd_message_parent
(
void
)
DECLSPEC_HIDDEN
;
extern
BOOL
is_desktop_window
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
void
register_window_surface
(
struct
window_surface
*
old
,
struct
window_surface
*
new
)
DECLSPEC_HIDDEN
;
extern
void
flush_window_surfaces
(
BOOL
idle
)
DECLSPEC_HIDDEN
;
extern
WND
*
WIN_GetPtr
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
HWND
WIN_GetFullHandle
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
HWND
WIN_IsCurrentProcess
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
...
...
dlls/user32/winpos.c
View file @
7304445a
...
...
@@ -2020,6 +2020,7 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
if
(
ret
)
{
TRACE
(
"win %p surface %p -> %p
\n
"
,
hwnd
,
old_surface
,
new_surface
);
register_window_surface
(
old_surface
,
new_surface
);
if
(
old_surface
)
{
if
(
!
IsRectEmpty
(
valid_rects
))
...
...
dlls/user32/winproc.c
View file @
7304445a
...
...
@@ -1123,7 +1123,10 @@ static LRESULT WINAPI StaticWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM
static
DWORD
wait_message
(
DWORD
count
,
CONST
HANDLE
*
handles
,
DWORD
timeout
,
DWORD
mask
,
DWORD
flags
)
{
DWORD
ret
=
USER_Driver
->
pMsgWaitForMultipleObjectsEx
(
count
,
handles
,
timeout
,
mask
,
flags
);
DWORD
ret
;
flush_window_surfaces
(
TRUE
);
ret
=
USER_Driver
->
pMsgWaitForMultipleObjectsEx
(
count
,
handles
,
timeout
,
mask
,
flags
);
if
(
ret
==
WAIT_TIMEOUT
&&
!
count
&&
!
timeout
)
NtYieldExecution
();
return
ret
;
}
...
...
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