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
f4b14106
Commit
f4b14106
authored
Jun 22, 2001
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Don't rely on X to expose windows covered by a sibling, do it
manually.
parent
624f14e7
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
211 additions
and
46 deletions
+211
-46
winpos.c
dlls/x11drv/winpos.c
+209
-0
event.c
windows/x11drv/event.c
+2
-46
No files found.
dlls/x11drv/winpos.c
View file @
f4b14106
...
...
@@ -169,6 +169,206 @@ static HRGN get_visible_region( WND *win, WND *top, UINT flags, int mode )
/***********************************************************************
* get_covered_region
*
* Compute the portion of 'rgn' that is covered by non-clipped siblings.
* This is the area that is covered from X point of view, but may still need
* to be exposed.
* 'rgn' must be relative to the client area of the parent of 'win'.
*/
static
int
get_covered_region
(
WND
*
win
,
HRGN
rgn
)
{
HRGN
tmp
;
int
ret
;
WND
*
ptr
=
win
;
int
xoffset
=
0
,
yoffset
=
0
;
tmp
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
CombineRgn
(
tmp
,
rgn
,
0
,
RGN_COPY
);
/* to make things easier we actually build the uncovered
* area by removing all siblings and then we subtract that
* from the total region to get the covered area */
for
(;;)
{
if
(
!
(
ptr
->
dwStyle
&
WS_CLIPSIBLINGS
))
{
if
(
clip_children
(
ptr
->
parent
,
ptr
,
tmp
,
FALSE
)
==
NULLREGION
)
break
;
}
if
(
!
(
ptr
=
ptr
->
parent
))
break
;
OffsetRgn
(
tmp
,
ptr
->
rectClient
.
left
,
ptr
->
rectClient
.
top
);
xoffset
+=
ptr
->
rectClient
.
left
;
yoffset
+=
ptr
->
rectClient
.
top
;
}
/* make it relative to the target window again */
OffsetRgn
(
tmp
,
-
xoffset
,
-
yoffset
);
/* now subtract the computed region from the original one */
ret
=
CombineRgn
(
rgn
,
rgn
,
tmp
,
RGN_DIFF
);
DeleteObject
(
tmp
);
return
ret
;
}
/***********************************************************************
* expose_window
*
* Expose a region of a given window.
*/
static
void
expose_window
(
WND
*
win
,
RECT
*
rect
,
HRGN
rgn
,
int
flags
)
{
WND
*
ptr
,
*
top
;
int
xoffset
=
0
,
yoffset
=
0
;
/* find the top most parent that doesn't clip children or siblings and
* invalidate the area on its parent, including all children */
top
=
NULL
;
for
(
ptr
=
win
;
ptr
&&
ptr
->
parent
;
ptr
=
ptr
->
parent
)
{
if
(
!
(
ptr
->
dwStyle
&
WS_CLIPSIBLINGS
))
top
=
ptr
;
if
(
!
(
ptr
->
parent
->
dwStyle
&
WS_CLIPCHILDREN
))
top
=
ptr
;
}
if
(
top
)
{
if
(
top
->
parent
&&
top
->
parent
->
hwndSelf
!=
GetDesktopWindow
())
top
=
top
->
parent
;
flags
&=
~
RDW_FRAME
;
/* parent will invalidate children frame anyway */
flags
|=
RDW_ALLCHILDREN
;
}
else
top
=
win
;
/* make coords relative to top */
for
(
ptr
=
win
;
ptr
!=
top
;
ptr
=
ptr
->
parent
)
{
xoffset
+=
ptr
->
rectClient
.
left
;
yoffset
+=
ptr
->
rectClient
.
top
;
}
if
(
rect
)
{
OffsetRect
(
rect
,
xoffset
,
yoffset
);
RedrawWindow
(
top
->
hwndSelf
,
rect
,
0
,
flags
);
}
else
{
OffsetRgn
(
rgn
,
xoffset
,
yoffset
);
RedrawWindow
(
top
->
hwndSelf
,
NULL
,
rgn
,
flags
);
}
}
/***********************************************************************
* expose_covered_parent_area
*
* Expose the parent area that has been uncovered by moving/hiding a
* given window, but that is still covered by other siblings (the area
* not covered by siblings will be exposed automatically by X).
*/
static
void
expose_covered_parent_area
(
WND
*
win
,
const
RECT
*
old_rect
)
{
int
ret
=
SIMPLEREGION
;
HRGN
hrgn
=
CreateRectRgnIndirect
(
old_rect
);
if
(
win
->
dwStyle
&
WS_VISIBLE
)
{
HRGN
tmp
=
CreateRectRgnIndirect
(
&
win
->
rectWindow
);
ret
=
CombineRgn
(
hrgn
,
hrgn
,
tmp
,
RGN_DIFF
);
DeleteObject
(
tmp
);
}
if
(
ret
!=
NULLREGION
)
{
if
(
get_covered_region
(
win
,
hrgn
)
!=
NULLREGION
)
expose_window
(
win
->
parent
,
NULL
,
hrgn
,
RDW_INVALIDATE
|
RDW_ERASE
|
RDW_ALLCHILDREN
);
}
DeleteObject
(
hrgn
);
}
/***********************************************************************
* expose_covered_window_area
*
* Expose the area of a window that is covered by other siblings.
*/
static
void
expose_covered_window_area
(
WND
*
win
,
const
RECT
*
old_client_rect
,
BOOL
frame
)
{
HRGN
hrgn
;
int
ret
=
SIMPLEREGION
;
if
(
frame
)
hrgn
=
CreateRectRgn
(
win
->
rectWindow
.
left
-
win
->
rectClient
.
left
,
win
->
rectWindow
.
top
-
win
->
rectClient
.
top
,
win
->
rectWindow
.
right
-
win
->
rectWindow
.
left
,
win
->
rectWindow
.
bottom
-
win
->
rectWindow
.
top
);
else
hrgn
=
CreateRectRgn
(
0
,
0
,
win
->
rectClient
.
right
-
win
->
rectClient
.
left
,
win
->
rectClient
.
bottom
-
win
->
rectClient
.
top
);
/* if the client rect didn't move we don't need to repaint it all */
if
(
old_client_rect
->
left
==
win
->
rectClient
.
left
&&
old_client_rect
->
top
==
win
->
rectClient
.
top
)
{
RECT
rc
;
if
(
IntersectRect
(
&
rc
,
old_client_rect
,
&
win
->
rectClient
))
{
HRGN
tmp
;
/* subtract the unchanged client area from the region to expose */
OffsetRect
(
&
rc
,
-
win
->
rectClient
.
left
,
-
win
->
rectClient
.
top
);
if
((
tmp
=
CreateRectRgnIndirect
(
&
rc
)))
{
ret
=
CombineRgn
(
hrgn
,
hrgn
,
tmp
,
RGN_DIFF
);
DeleteObject
(
tmp
);
}
}
}
if
(
ret
!=
NULLREGION
)
{
if
(
get_covered_region
(
win
,
hrgn
)
!=
NULLREGION
)
expose_window
(
win
,
NULL
,
hrgn
,
RDW_INVALIDATE
|
RDW_ERASE
|
RDW_FRAME
|
RDW_ALLCHILDREN
);
}
DeleteObject
(
hrgn
);
}
/***********************************************************************
* X11DRV_Expose
*/
void
X11DRV_Expose
(
HWND
hwnd
,
XExposeEvent
*
event
)
{
RECT
rect
;
struct
x11drv_win_data
*
data
;
int
flags
=
RDW_INVALIDATE
|
RDW_ERASE
;
WND
*
win
;
TRACE
(
"win %x (%lx) %d,%d %dx%d
\n
"
,
hwnd
,
event
->
window
,
event
->
x
,
event
->
y
,
event
->
width
,
event
->
height
);
rect
.
left
=
event
->
x
;
rect
.
top
=
event
->
y
;
rect
.
right
=
rect
.
left
+
event
->
width
;
rect
.
bottom
=
rect
.
top
+
event
->
height
;
if
(
!
(
win
=
WIN_FindWndPtr
(
hwnd
)))
return
;
data
=
win
->
pDriverData
;
if
(
event
->
window
!=
data
->
client_window
)
/* whole window or icon window */
{
flags
|=
RDW_FRAME
;
/* make position relative to client area instead of window */
OffsetRect
(
&
rect
,
-
data
->
client_rect
.
left
,
-
data
->
client_rect
.
top
);
}
expose_window
(
win
,
&
rect
,
0
,
flags
);
WIN_ReleaseWndPtr
(
win
);
}
/***********************************************************************
* X11DRV_GetDC (X11DRV.@)
*
* Set the drawable, origin and dimensions for the DC associated to
...
...
@@ -572,6 +772,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
{
/* if we moved the client area, repaint the whole non-client window */
XClearArea
(
display
,
get_whole_window
(
wndPtr
),
0
,
0
,
0
,
0
,
True
);
winpos
->
flags
|=
SWP_FRAMECHANGED
;
}
if
(
winpos
->
flags
&
SWP_SHOWWINDOW
)
{
...
...
@@ -593,6 +794,14 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
wine_tsx11_unlock
();
}
/* manually expose the areas that X won't expose because they are still covered by something */
if
(
!
(
winpos
->
flags
&
SWP_SHOWWINDOW
))
expose_covered_parent_area
(
wndPtr
,
&
oldWindowRect
);
if
(
wndPtr
->
dwStyle
&
WS_VISIBLE
)
expose_covered_window_area
(
wndPtr
,
&
oldClientRect
,
winpos
->
flags
&
SWP_FRAMECHANGED
);
WIN_ReleaseWndPtr
(
wndPtr
);
if
(
wvrFlags
&
WVR_REDRAW
)
RedrawWindow
(
winpos
->
hwnd
,
NULL
,
0
,
RDW_INVALIDATE
|
RDW_ERASE
);
...
...
windows/x11drv/event.c
View file @
f4b14106
...
...
@@ -96,13 +96,13 @@ static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event );
static
void
EVENT_MotionNotify
(
HWND
hWnd
,
XMotionEvent
*
event
);
static
void
EVENT_FocusIn
(
HWND
hWnd
,
XFocusChangeEvent
*
event
);
static
void
EVENT_FocusOut
(
HWND
hWnd
,
XFocusChangeEvent
*
event
);
static
void
EVENT_Expose
(
HWND
hWnd
,
XExposeEvent
*
event
);
static
void
EVENT_SelectionRequest
(
HWND
hWnd
,
XSelectionRequestEvent
*
event
,
BOOL
bIsMultiple
);
static
void
EVENT_SelectionClear
(
HWND
hWnd
,
XSelectionClearEvent
*
event
);
static
void
EVENT_PropertyNotify
(
XPropertyEvent
*
event
);
static
void
EVENT_ClientMessage
(
HWND
hWnd
,
XClientMessageEvent
*
event
);
static
void
EVENT_MappingNotify
(
XMappingEvent
*
event
);
extern
void
X11DRV_Expose
(
HWND
hwnd
,
XExposeEvent
*
event
);
extern
void
X11DRV_MapNotify
(
HWND
hwnd
,
XMapEvent
*
event
);
extern
void
X11DRV_UnmapNotify
(
HWND
hwnd
,
XUnmapEvent
*
event
);
extern
void
X11DRV_ConfigureNotify
(
HWND
hwnd
,
XConfigureEvent
*
event
);
...
...
@@ -319,7 +319,7 @@ static void EVENT_ProcessEvent( XEvent *event )
break
;
case
Expose
:
EVENT
_Expose
(
hWnd
,
&
event
->
xexpose
);
X11DRV
_Expose
(
hWnd
,
&
event
->
xexpose
);
break
;
case
ConfigureNotify
:
...
...
@@ -388,50 +388,6 @@ WORD X11DRV_EVENT_XStateToKeyState( int state )
}
/***********************************************************************
* EVENT_Expose
*/
static
void
EVENT_Expose
(
HWND
hwnd
,
XExposeEvent
*
event
)
{
RECT
rect
;
struct
x11drv_win_data
*
data
;
int
flags
=
RDW_INVALIDATE
|
RDW_ERASE
;
WND
*
win
;
TRACE
(
"win %x (%lx) %d,%d %dx%d
\n
"
,
hwnd
,
event
->
window
,
event
->
x
,
event
->
y
,
event
->
width
,
event
->
height
);
rect
.
left
=
event
->
x
;
rect
.
top
=
event
->
y
;
rect
.
right
=
rect
.
left
+
event
->
width
;
rect
.
bottom
=
rect
.
top
+
event
->
height
;
if
(
!
(
win
=
WIN_FindWndPtr
(
hwnd
)))
return
;
data
=
win
->
pDriverData
;
if
(
event
->
window
!=
data
->
client_window
)
/* whole window or icon window */
{
flags
|=
RDW_FRAME
;
/* make position relative to client area instead of window */
OffsetRect
(
&
rect
,
-
data
->
client_rect
.
left
,
-
data
->
client_rect
.
top
);
}
/* find the top level parent that doesn't clip children and invalidate the area */
/* on the parent (which will invalidate all the children too) */
while
(
win
->
parent
&&
win
->
parent
->
hwndSelf
!=
GetDesktopWindow
()
&&
!
(
win
->
parent
->
dwStyle
&
WS_CLIPCHILDREN
))
{
OffsetRect
(
&
rect
,
win
->
rectClient
.
left
,
win
->
rectClient
.
top
);
WIN_UpdateWndPtr
(
&
win
,
win
->
parent
);
flags
&=
~
RDW_FRAME
;
/* parent will invalidate children frame anyway */
flags
|=
RDW_ALLCHILDREN
;
/* force invalidating all children of siblings */
}
hwnd
=
win
->
hwndSelf
;
WIN_ReleaseWndPtr
(
win
);
RedrawWindow
(
hwnd
,
&
rect
,
0
,
flags
);
}
/* get the coordinates of a mouse event */
static
void
get_coords
(
HWND
*
hwnd
,
Window
window
,
int
x
,
int
y
,
POINT
*
pt
)
{
...
...
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