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
06a60621
Commit
06a60621
authored
Jun 15, 2004
by
Ulrich Czekalla
Committed by
Alexandre Julliard
Jun 15, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ScrollDC should take into account overlapped windows. With this change
ScrollWindowEx can be moved out of X11drv.
parent
a98f0dff
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
169 additions
and
87 deletions
+169
-87
user_main.c
dlls/user/user_main.c
+1
-1
scroll.c
dlls/x11drv/scroll.c
+73
-77
x11drv.spec
dlls/x11drv/x11drv.spec
+1
-1
user.h
include/user.h
+1
-1
scroll.c
windows/scroll.c
+93
-7
No files found.
dlls/user/user_main.c
View file @
06a60621
...
...
@@ -110,7 +110,7 @@ static BOOL load_driver(void)
GET_USER_FUNC
(
ForceWindowRaise
);
GET_USER_FUNC
(
MsgWaitForMultipleObjectsEx
);
GET_USER_FUNC
(
ReleaseDC
);
GET_USER_FUNC
(
Scroll
WindowEx
);
GET_USER_FUNC
(
Scroll
DC
);
GET_USER_FUNC
(
SetFocus
);
GET_USER_FUNC
(
SetParent
);
GET_USER_FUNC
(
SetWindowPos
);
...
...
dlls/x11drv/scroll.c
View file @
06a60621
...
...
@@ -38,98 +38,94 @@ WINE_DEFAULT_DEBUG_CHANNEL(scroll);
/*************************************************************************
* ScrollWindowEx (X11DRV.@)
*
* Note: contrary to what the doc says, pixels that are scrolled from the
* outside of clipRect to the inside are NOT painted.
*
* Parameter are the same as in ScrollWindowEx, with the additional
* requirement that rect and clipRect are _valid_ pointers, to
* rectangles _within_ the client are. Moreover, there is something
* to scroll.
* ScrollDC (X11DRV.@)
*/
INT
X11DRV_ScrollWindowEx
(
HWND
hwnd
,
INT
dx
,
INT
dy
,
const
RECT
*
rect
,
const
RECT
*
clipRect
,
HRGN
hrgnUpdate
,
LPRECT
rcUpdate
,
UINT
flags
)
BOOL
WINAPI
X11DRV_ScrollDC
(
HDC
hdc
,
INT
dx
,
INT
dy
,
const
RECT
*
lprcScroll
,
const
RECT
*
lprcClip
,
HRGN
hrgnUpdate
,
LPRECT
lprcUpdate
)
{
INT
retVal
;
BOOL
bOwnRgn
=
TRUE
;
BOOL
bUpdate
=
(
rcUpdate
||
hrgnUpdate
||
flags
&
(
SW_INVALIDATE
|
SW_ERASE
));
HRGN
hrgnTemp
;
HDC
hDC
;
RECT
rc
,
cliprc
;
RECT
rSrc
,
rClipped_src
,
rClip
,
rDst
,
offset
;
INT
code
=
X11DRV_START_EXPOSURES
;
TRACE
(
"%p, %d,%d hrgnUpdate=%p rcUpdate = %p %s %04x
\n
"
,
hwnd
,
dx
,
dy
,
hrgnUpdate
,
rcUpdate
,
wine_dbgstr_rect
(
rect
),
flags
);
TRACE
(
"clipRect = %s
\n
"
,
wine_dbgstr_rect
(
clipRect
));
if
(
hrgnUpdate
||
lprcUpdate
)
ExtEscape
(
hdc
,
X11DRV_ESCAPE
,
sizeof
(
code
),
(
LPSTR
)
&
code
,
0
,
NULL
);
GetClientRect
(
hwnd
,
&
rc
);
if
(
rect
)
IntersectRect
(
&
rc
,
&
rc
,
rect
);
/* compute device clipping region (in device coordinates) */
if
(
clipRect
)
IntersectRect
(
&
cliprc
,
&
rc
,
clipRect
);
else
cliprc
=
rc
;
if
(
lprcScroll
)
rSrc
=
*
lprcScroll
;
else
GetClipBox
(
hdc
,
&
rSrc
);
LPtoDP
(
hdc
,
(
LPPOINT
)
&
rSrc
,
2
);
if
(
hrgnUpdate
)
bOwnRgn
=
FALSE
;
else
if
(
bUpdate
)
hrgnUpdate
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
if
(
lprcClip
)
rClip
=
*
lprcClip
;
else
GetClipBox
(
hdc
,
&
rClip
);
LPtoDP
(
hdc
,
(
LPPOINT
)
&
rClip
,
2
);
hDC
=
GetDCEx
(
hwnd
,
0
,
DCX_CACHE
|
DCX_USESTYLE
);
if
(
hDC
)
{
enum
x11drv_escape_codes
code
=
X11DRV_START_EXPOSURES
;
HRGN
hrgn
=
0
;
IntersectRect
(
&
rClipped_src
,
&
rSrc
,
&
rClip
);
TRACE
(
"rSrc %s rClip %s clipped rSrc %s
\n
"
,
wine_dbgstr_rect
(
&
rSrc
),
wine_dbgstr_rect
(
&
rClip
),
wine_dbgstr_rect
(
&
rClipped_src
));
ExtEscape
(
hDC
,
X11DRV_ESCAPE
,
sizeof
(
code
),
(
LPSTR
)
&
code
,
0
,
NULL
);
ScrollDC
(
hDC
,
dx
,
dy
,
&
rc
,
&
cliprc
,
hrgnUpdate
,
rcUpdate
);
code
=
X11DRV_END_EXPOSURES
;
ExtEscape
(
hDC
,
X11DRV_ESCAPE
,
sizeof
(
code
),
(
LPSTR
)
&
code
,
sizeof
(
hrgn
),
(
LPSTR
)
&
hrgn
);
ReleaseDC
(
hwnd
,
hDC
);
if
(
hrgn
)
{
if
(
bUpdate
)
CombineRgn
(
hrgnUpdate
,
hrgnUpdate
,
hrgn
,
RGN_OR
);
else
RedrawWindow
(
hwnd
,
NULL
,
hrgn
,
RDW_INVALIDATE
|
RDW_ERASE
);
DeleteObject
(
hrgn
);
}
}
rDst
=
rClipped_src
;
SetRect
(
&
offset
,
0
,
0
,
dx
,
dy
);
LPtoDP
(
hdc
,
(
LPPOINT
)
&
offset
,
2
);
OffsetRect
(
&
rDst
,
offset
.
right
-
offset
.
left
,
offset
.
bottom
-
offset
.
top
);
TRACE
(
"rDst before clipping %s
\n
"
,
wine_dbgstr_rect
(
&
rDst
));
IntersectRect
(
&
rDst
,
&
rDst
,
&
rClip
);
TRACE
(
"rDst after clipping %s
\n
"
,
wine_dbgstr_rect
(
&
rDst
));
/* Take into account the fact that some damage may have occurred during the scroll */
hrgnTemp
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
retVal
=
GetUpdateRgn
(
hwnd
,
hrgnTemp
,
FALSE
);
if
(
retVal
!=
NULLREGION
)
if
(
!
IsRectEmpty
(
&
rDst
))
{
HRGN
hrgnClip
=
CreateRectRgnIndirect
(
&
cliprc
);
OffsetRgn
(
hrgnTemp
,
dx
,
dy
);
CombineRgn
(
hrgnTemp
,
hrgnTemp
,
hrgnClip
,
RGN_AND
);
RedrawWindow
(
hwnd
,
NULL
,
hrgnTemp
,
RDW_INVALIDATE
|
RDW_ERASE
);
DeleteObject
(
hrgnClip
);
/* copy bits */
RECT
rDst_lp
=
rDst
,
rSrc_lp
=
rDst
;
OffsetRect
(
&
rSrc_lp
,
offset
.
left
-
offset
.
right
,
offset
.
top
-
offset
.
bottom
);
DPtoLP
(
hdc
,
(
LPPOINT
)
&
rDst_lp
,
2
);
DPtoLP
(
hdc
,
(
LPPOINT
)
&
rSrc_lp
,
2
);
if
(
!
BitBlt
(
hdc
,
rDst_lp
.
left
,
rDst_lp
.
top
,
rDst_lp
.
right
-
rDst_lp
.
left
,
rDst_lp
.
bottom
-
rDst_lp
.
top
,
hdc
,
rSrc_lp
.
left
,
rSrc_lp
.
top
,
SRCCOPY
))
return
FALSE
;
}
DeleteObject
(
hrgnTemp
);
if
(
flags
&
SW_SCROLLCHILDREN
)
/* compute update areas. This is the clipped source or'ed with the unclipped source translated minus the
clipped src translated (rDst) all clipped to rClip */
if
(
hrgnUpdate
||
lprcUpdate
)
{
HWND
*
list
=
WIN_ListChildren
(
hwnd
);
if
(
list
)
HRGN
hrgn
=
hrgnUpdate
,
hrgn2
,
hrgn3
=
0
;
code
=
X11DRV_END_EXPOSURES
;
ExtEscape
(
hdc
,
X11DRV_ESCAPE
,
sizeof
(
code
),
(
LPSTR
)
&
code
,
sizeof
(
hrgn3
),
(
LPSTR
)
&
hrgn3
);
if
(
hrgn
)
SetRectRgn
(
hrgn
,
rClipped_src
.
left
,
rClipped_src
.
top
,
rClipped_src
.
right
,
rClipped_src
.
bottom
);
else
hrgn
=
CreateRectRgn
(
rClipped_src
.
left
,
rClipped_src
.
top
,
rClipped_src
.
right
,
rClipped_src
.
bottom
);
hrgn2
=
CreateRectRgnIndirect
(
&
rSrc
);
OffsetRgn
(
hrgn2
,
offset
.
right
-
offset
.
left
,
offset
.
bottom
-
offset
.
top
);
CombineRgn
(
hrgn
,
hrgn
,
hrgn2
,
RGN_OR
);
SetRectRgn
(
hrgn2
,
rDst
.
left
,
rDst
.
top
,
rDst
.
right
,
rDst
.
bottom
);
CombineRgn
(
hrgn
,
hrgn
,
hrgn2
,
RGN_DIFF
);
SetRectRgn
(
hrgn2
,
rClip
.
left
,
rClip
.
top
,
rClip
.
right
,
rClip
.
bottom
);
CombineRgn
(
hrgn
,
hrgn
,
hrgn2
,
RGN_AND
);
if
(
hrgn3
)
{
int
i
;
RECT
r
,
dummy
;
for
(
i
=
0
;
list
[
i
];
i
++
)
{
GetWindowRect
(
list
[
i
],
&
r
);
MapWindowPoints
(
0
,
hwnd
,
(
POINT
*
)
&
r
,
2
);
if
(
!
rect
||
IntersectRect
(
&
dummy
,
&
r
,
&
rc
))
SetWindowPos
(
list
[
i
],
0
,
r
.
left
+
dx
,
r
.
top
+
dy
,
0
,
0
,
SWP_NOZORDER
|
SWP_NOSIZE
|
SWP_NOACTIVATE
|
SWP_NOREDRAW
|
SWP_DEFERERASE
);
}
HeapFree
(
GetProcessHeap
(),
0
,
list
);
CombineRgn
(
hrgn
,
hrgn
,
hrgn3
,
RGN_OR
);
DeleteObject
(
hrgn3
);
}
}
if
(
flags
&
(
SW_INVALIDATE
|
SW_ERASE
)
)
RedrawWindow
(
hwnd
,
NULL
,
hrgnUpdate
,
RDW_INVALIDATE
|
RDW_ERASE
|
((
flags
&
SW_ERASE
)
?
RDW_ERASENOW
:
0
)
|
((
flags
&
SW_SCROLLCHILDREN
)
?
RDW_ALLCHILDREN
:
0
)
);
if
(
lprcUpdate
)
{
GetRgnBox
(
hrgn
,
lprcUpdate
);
if
(
bOwnRgn
&&
hrgnUpdate
)
DeleteObject
(
hrgnUpdate
);
return
retVal
;
/* Put the lprcUpdate in logical coordinate */
DPtoLP
(
hdc
,
(
LPPOINT
)
lprcUpdate
,
2
);
TRACE
(
"returning lprcUpdate %s
\n
"
,
wine_dbgstr_rect
(
lprcUpdate
));
}
if
(
!
hrgnUpdate
)
DeleteObject
(
hrgn
);
DeleteObject
(
hrgn2
);
}
return
TRUE
;
}
dlls/x11drv/x11drv.spec
View file @
06a60621
...
...
@@ -98,7 +98,7 @@
@ cdecl RegisterClipboardFormat(str) X11DRV_RegisterClipboardFormat
@ cdecl ReleaseDC(long long) X11DRV_ReleaseDC
@ cdecl ResetSelectionOwner(long long) X11DRV_ResetSelectionOwner
@ cdecl Scroll
WindowEx(long long long ptr ptr long ptr long) X11DRV_ScrollWindowEx
@ cdecl Scroll
DC(long long long ptr ptr long ptr) X11DRV_ScrollDC
@ cdecl SetClipboardData(long long long long) X11DRV_SetClipboardData
@ cdecl SetFocus(long) X11DRV_SetFocus
@ cdecl SetParent(long long) X11DRV_SetParent
...
...
include/user.h
View file @
06a60621
...
...
@@ -113,7 +113,7 @@ typedef struct tagUSER_DRIVER {
void
(
*
pForceWindowRaise
)(
HWND
);
DWORD
(
*
pMsgWaitForMultipleObjectsEx
)(
DWORD
,
const
HANDLE
*
,
DWORD
,
DWORD
,
DWORD
);
void
(
*
pReleaseDC
)(
HWND
,
HDC
);
INT
(
*
pScrollWindowEx
)(
HWND
,
INT
,
INT
,
const
RECT
*
,
const
RECT
*
,
HRGN
,
LPRECT
,
UIN
T
);
BOOL
(
*
pScrollDC
)(
HDC
,
INT
,
INT
,
const
RECT
*
,
const
RECT
*
,
HRGN
,
LPREC
T
);
void
(
*
pSetFocus
)(
HWND
);
HWND
(
*
pSetParent
)(
HWND
,
HWND
);
BOOL
(
*
pSetWindowPos
)(
WINDOWPOS
*
);
...
...
windows/scroll.c
View file @
06a60621
...
...
@@ -60,6 +60,93 @@ static HWND fix_caret(HWND hWnd, LPRECT lprc, UINT flags)
return
0
;
}
/*************************************************************************
* scroll_window
*
* Note: contrary to what the doc says, pixels that are scrolled from the
* outside of clipRect to the inside are NOT painted.
*
* Parameter are the same as in ScrollWindowEx, with the additional
* requirement that rect and clipRect are _valid_ pointers, to
* rectangles _within_ the client are. Moreover, there is something
* to scroll.
*/
static
INT
scroll_window
(
HWND
hwnd
,
INT
dx
,
INT
dy
,
const
RECT
*
rect
,
const
RECT
*
clipRect
,
HRGN
hrgnUpdate
,
LPRECT
rcUpdate
,
UINT
flags
)
{
INT
retVal
;
BOOL
bOwnRgn
=
TRUE
;
BOOL
bUpdate
=
(
rcUpdate
||
hrgnUpdate
||
flags
&
(
SW_INVALIDATE
|
SW_ERASE
));
HRGN
hrgnTemp
;
HDC
hDC
;
RECT
rc
,
cliprc
;
TRACE
(
"%p, %d,%d hrgnUpdate=%p rcUpdate = %p %s %04x
\n
"
,
hwnd
,
dx
,
dy
,
hrgnUpdate
,
rcUpdate
,
wine_dbgstr_rect
(
rect
),
flags
);
TRACE
(
"clipRect = %s
\n
"
,
wine_dbgstr_rect
(
clipRect
));
GetClientRect
(
hwnd
,
&
rc
);
if
(
rect
)
IntersectRect
(
&
rc
,
&
rc
,
rect
);
if
(
clipRect
)
IntersectRect
(
&
cliprc
,
&
rc
,
clipRect
);
else
cliprc
=
rc
;
if
(
hrgnUpdate
)
bOwnRgn
=
FALSE
;
else
if
(
bUpdate
)
hrgnUpdate
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
hDC
=
GetDCEx
(
hwnd
,
0
,
DCX_CACHE
|
DCX_USESTYLE
);
if
(
hDC
)
{
ScrollDC
(
hDC
,
dx
,
dy
,
&
rc
,
&
cliprc
,
hrgnUpdate
,
rcUpdate
);
ReleaseDC
(
hwnd
,
hDC
);
if
(
!
bUpdate
)
RedrawWindow
(
hwnd
,
NULL
,
hrgnUpdate
,
RDW_INVALIDATE
|
RDW_ERASE
);
}
/* Take into account the fact that some damage may have occurred during the scroll */
hrgnTemp
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
retVal
=
GetUpdateRgn
(
hwnd
,
hrgnTemp
,
FALSE
);
if
(
retVal
!=
NULLREGION
)
{
HRGN
hrgnClip
=
CreateRectRgnIndirect
(
&
cliprc
);
OffsetRgn
(
hrgnTemp
,
dx
,
dy
);
CombineRgn
(
hrgnTemp
,
hrgnTemp
,
hrgnClip
,
RGN_AND
);
RedrawWindow
(
hwnd
,
NULL
,
hrgnTemp
,
RDW_INVALIDATE
|
RDW_ERASE
);
DeleteObject
(
hrgnClip
);
}
DeleteObject
(
hrgnTemp
);
if
(
flags
&
SW_SCROLLCHILDREN
)
{
HWND
*
list
=
WIN_ListChildren
(
hwnd
);
if
(
list
)
{
int
i
;
RECT
r
,
dummy
;
for
(
i
=
0
;
list
[
i
];
i
++
)
{
GetWindowRect
(
list
[
i
],
&
r
);
MapWindowPoints
(
0
,
hwnd
,
(
POINT
*
)
&
r
,
2
);
if
(
!
rect
||
IntersectRect
(
&
dummy
,
&
r
,
&
rc
))
SetWindowPos
(
list
[
i
],
0
,
r
.
left
+
dx
,
r
.
top
+
dy
,
0
,
0
,
SWP_NOZORDER
|
SWP_NOSIZE
|
SWP_NOACTIVATE
|
SWP_NOREDRAW
|
SWP_DEFERERASE
);
}
HeapFree
(
GetProcessHeap
(),
0
,
list
);
}
}
if
(
flags
&
(
SW_INVALIDATE
|
SW_ERASE
)
)
RedrawWindow
(
hwnd
,
NULL
,
hrgnUpdate
,
RDW_INVALIDATE
|
RDW_ERASE
|
((
flags
&
SW_ERASE
)
?
RDW_ERASENOW
:
0
)
|
((
flags
&
SW_SCROLLCHILDREN
)
?
RDW_ALLCHILDREN
:
0
)
);
if
(
bOwnRgn
&&
hrgnUpdate
)
DeleteObject
(
hrgnUpdate
);
return
retVal
;
}
/*************************************************************************
* ScrollWindow (USER32.@)
...
...
@@ -90,8 +177,10 @@ BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
if
(
lprcClip
)
TRACE
(
"lprcClip = %s
\n
"
,
wine_dbgstr_rect
(
lprcClip
));
if
(
lprcScroll
)
TRACE
(
"lprcScroll = %s
\n
"
,
wine_dbgstr_rect
(
lprcScroll
));
/* compute device clipping region (in device coordinates) */
if
(
USER_Driver
.
pScrollDC
)
return
USER_Driver
.
pScrollDC
(
hdc
,
dx
,
dy
,
lprcScroll
,
lprcClip
,
hrgnUpdate
,
lprcUpdate
);
/* compute device clipping region (in device coordinates) */
if
(
lprcScroll
)
rSrc
=
*
lprcScroll
;
else
GetClipBox
(
hdc
,
&
rSrc
);
LPtoDP
(
hdc
,
(
LPPOINT
)
&
rSrc
,
2
);
...
...
@@ -189,12 +278,9 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy,
RECT
caretrc
=
rc
;
HWND
hwndCaret
=
fix_caret
(
hwnd
,
&
caretrc
,
flags
);
if
(
USER_Driver
.
pScrollWindowEx
)
result
=
USER_Driver
.
pScrollWindowEx
(
hwnd
,
dx
,
dy
,
rect
,
clipRect
,
hrgnUpdate
,
rcUpdate
,
flags
);
else
result
=
ERROR
;
/* FIXME: we should have a fallback implementation */
result
=
scroll_window
(
hwnd
,
dx
,
dy
,
rect
,
clipRect
,
hrgnUpdate
,
rcUpdate
,
flags
);
if
(
hwndCaret
)
{
SetCaretPos
(
caretrc
.
left
+
dx
,
caretrc
.
top
+
dy
);
...
...
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