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
bc75f2f6
Commit
bc75f2f6
authored
Mar 31, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Return the coordinates information needed to setup the DC parameters
in the get_visible_region request instead of requiring the client to compute it again.
parent
7c342b4c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
85 additions
and
132 deletions
+85
-132
dce.c
dlls/x11drv/dce.c
+41
-115
server_protocol.h
include/wine/server_protocol.h
+6
-1
protocol.def
server/protocol.def
+6
-1
trace.c
server/trace.c
+5
-0
window.c
server/window.c
+27
-15
No files found.
dlls/x11drv/dce.c
View file @
bc75f2f6
...
...
@@ -86,21 +86,33 @@ static void dump_cache(void)
/***********************************************************************
* get_server_visible_region
* update_visible_region
*
* Set the visible region and X11 drawable for the DC associated to
* a given window.
*/
static
HRGN
get_server_visible_region
(
HWND
hwnd
,
UINT
flags
)
static
void
update_visible_region
(
struct
dce
*
dce
)
{
RGNDATA
*
data
;
NTSTATUS
status
;
HRGN
ret
=
0
;
HRGN
vis_rgn
=
0
;
HWND
top
=
0
;
struct
x11drv_escape_set_drawable
escape
;
struct
x11drv_win_data
*
data
;
DWORD
flags
=
dce
->
flags
;
size_t
size
=
256
;
/* don't clip siblings if using parent clip region */
if
(
flags
&
DCX_PARENTCLIP
)
flags
&=
~
DCX_CLIPSIBLINGS
;
/* fetch the visible region from the server */
do
{
if
(
!
(
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
data
)
+
size
-
1
)))
return
0
;
RGNDATA
*
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
data
)
+
size
-
1
);
if
(
!
data
)
return
;
SERVER_START_REQ
(
get_visible_region
)
{
req
->
window
=
hwnd
;
req
->
window
=
dce
->
hwnd
;
req
->
flags
=
flags
;
wine_server_set_reply
(
req
,
data
->
Buffer
,
size
);
if
(
!
(
status
=
wine_server_call
(
req
)))
...
...
@@ -110,7 +122,13 @@ static HRGN get_server_visible_region( HWND hwnd, UINT flags )
data
->
rdh
.
iType
=
RDH_RECTANGLES
;
data
->
rdh
.
nCount
=
reply_size
/
sizeof
(
RECT
);
data
->
rdh
.
nRgnSize
=
reply_size
;
ret
=
ExtCreateRegion
(
NULL
,
size
,
data
);
vis_rgn
=
ExtCreateRegion
(
NULL
,
size
,
data
);
top
=
reply
->
top_win
;
escape
.
org
.
x
=
reply
->
win_org_x
-
reply
->
top_org_x
;
escape
.
org
.
y
=
reply
->
win_org_y
-
reply
->
top_org_y
;
escape
.
drawable_org
.
x
=
reply
->
top_org_x
;
escape
.
drawable_org
.
y
=
reply
->
top_org_y
;
}
else
size
=
reply
->
total_size
;
}
...
...
@@ -118,119 +136,27 @@ static HRGN get_server_visible_region( HWND hwnd, UINT flags )
HeapFree
(
GetProcessHeap
(),
0
,
data
);
}
while
(
status
==
STATUS_BUFFER_OVERFLOW
);
if
(
status
)
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
ret
;
}
if
(
status
||
!
vis_rgn
)
return
;
if
(
dce
->
clip_rgn
)
CombineRgn
(
vis_rgn
,
vis_rgn
,
dce
->
clip_rgn
,
(
flags
&
DCX_INTERSECTRGN
)
?
RGN_AND
:
RGN_DIFF
);
/***********************************************************************
* get_top_clipping_window
*
* Get the top window to clip against (i.e. the top parent that has
* an associated X window).
*/
static
HWND
get_top_clipping_window
(
HWND
hwnd
)
{
HWND
ret
=
GetAncestor
(
hwnd
,
GA_ROOT
);
if
(
!
ret
)
ret
=
GetDesktopWindow
();
return
ret
;
}
/***********************************************************************
* set_drawable
*
* Set the drawable, origin and dimensions for the DC associated to
* a given window.
*/
static
void
set_drawable
(
struct
dce
*
dce
,
BOOL
update_visrgn
)
{
HWND
top
=
get_top_clipping_window
(
dce
->
hwnd
);
struct
x11drv_escape_set_drawable
escape
;
struct
x11drv_win_data
*
data
;
DWORD
flags
=
dce
->
flags
;
escape
.
mode
=
IncludeInferiors
;
/* don't clip siblings if using parent clip region */
if
(
flags
&
DCX_PARENTCLIP
)
flags
&=
~
DCX_CLIPSIBLINGS
;
if
(
top
!=
dce
->
hwnd
||
!
(
data
=
X11DRV_get_win_data
(
dce
->
hwnd
)))
{
POINT
client_offset
;
if
(
flags
&
DCX_WINDOW
)
{
RECT
rect
;
GetWindowRect
(
dce
->
hwnd
,
&
rect
);
escape
.
org
.
x
=
rect
.
left
;
escape
.
org
.
y
=
rect
.
top
;
MapWindowPoints
(
0
,
top
,
&
escape
.
org
,
1
);
escape
.
drawable_org
.
x
=
rect
.
left
-
escape
.
org
.
x
;
escape
.
drawable_org
.
y
=
rect
.
top
-
escape
.
org
.
y
;
}
else
{
escape
.
org
.
x
=
escape
.
org
.
y
=
0
;
escape
.
drawable_org
.
x
=
escape
.
drawable_org
.
y
=
0
;
MapWindowPoints
(
dce
->
hwnd
,
top
,
&
escape
.
org
,
1
);
MapWindowPoints
(
top
,
0
,
&
escape
.
drawable_org
,
1
);
}
/* now make origins relative to the X window and not the client area */
client_offset
=
X11DRV_get_client_area_offset
(
top
);
escape
.
org
.
x
+=
client_offset
.
x
;
escape
.
org
.
y
+=
client_offset
.
y
;
escape
.
drawable_org
.
x
-=
client_offset
.
x
;
escape
.
drawable_org
.
y
-=
client_offset
.
y
;
escape
.
drawable
=
X11DRV_get_whole_window
(
top
);
}
if
(
top
==
dce
->
hwnd
&&
((
data
=
X11DRV_get_win_data
(
dce
->
hwnd
))
!=
NULL
)
&&
IsIconic
(
dce
->
hwnd
)
&&
data
->
icon_window
)
escape
.
drawable
=
data
->
icon_window
;
else
{
if
(
IsIconic
(
dce
->
hwnd
))
{
escape
.
drawable
=
data
->
icon_window
?
data
->
icon_window
:
data
->
whole_window
;
escape
.
org
.
x
=
0
;
escape
.
org
.
y
=
0
;
escape
.
drawable_org
=
escape
.
org
;
MapWindowPoints
(
dce
->
hwnd
,
0
,
&
escape
.
drawable_org
,
1
);
}
else
{
escape
.
drawable
=
data
->
whole_window
;
escape
.
drawable_org
.
x
=
data
->
whole_rect
.
left
;
escape
.
drawable_org
.
y
=
data
->
whole_rect
.
top
;
if
(
flags
&
DCX_WINDOW
)
{
escape
.
org
.
x
=
data
->
window_rect
.
left
-
data
->
whole_rect
.
left
;
escape
.
org
.
y
=
data
->
window_rect
.
top
-
data
->
whole_rect
.
top
;
}
else
{
escape
.
org
.
x
=
data
->
client_rect
.
left
;
escape
.
org
.
y
=
data
->
client_rect
.
top
;
}
}
}
escape
.
drawable
=
X11DRV_get_whole_window
(
top
);
escape
.
code
=
X11DRV_SET_DRAWABLE
;
escape
.
mode
=
IncludeInferiors
;
ExtEscape
(
dce
->
hdc
,
X11DRV_ESCAPE
,
sizeof
(
escape
),
(
LPSTR
)
&
escape
,
0
,
NULL
);
if
(
update_visrgn
)
{
/* need to recompute the visible region */
HRGN
visRgn
=
get_server_visible_region
(
dce
->
hwnd
,
flags
);
if
(
dce
->
clip_rgn
)
CombineRgn
(
visRgn
,
visRgn
,
dce
->
clip_rgn
,
(
flags
&
DCX_INTERSECTRGN
)
?
RGN_AND
:
RGN_DIFF
);
/* map region to DC coordinates */
OffsetRgn
(
visRgn
,
-
(
escape
.
org
.
x
+
escape
.
drawable_org
.
x
),
-
(
escape
.
org
.
y
+
escape
.
drawable_org
.
y
)
);
SelectVisRgn16
(
HDC_16
(
dce
->
hdc
),
HRGN_16
(
visRgn
)
);
DeleteObject
(
visRgn
);
}
/* map region to DC coordinates */
OffsetRgn
(
vis_rgn
,
-
(
escape
.
drawable_org
.
x
+
escape
.
org
.
x
),
-
(
escape
.
drawable_org
.
y
+
escape
.
org
.
y
)
);
SelectVisRgn16
(
HDC_16
(
dce
->
hdc
),
HRGN_16
(
vis_rgn
)
);
DeleteObject
(
vis_rgn
);
}
...
...
@@ -619,7 +545,7 @@ HDC X11DRV_GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if
(
SetHookFlags16
(
HDC_16
(
dce
->
hdc
),
DCHF_VALIDATEVISRGN
))
bUpdateVisRgn
=
TRUE
;
/* DC was dirty */
set_drawable
(
dce
,
bUpdateVisRgn
);
if
(
bUpdateVisRgn
)
update_visible_region
(
dce
);
if
(
!
(
flags
&
DCX_NORESETATTRS
))
{
...
...
@@ -678,7 +604,7 @@ static BOOL16 CALLBACK dc_hook( HDC16 hDC, WORD code, DWORD data, LPARAM lParam
* DC is dirty (usually after SetHookFlags()). This
* means that we have to recompute the visible region.
*/
if
(
dce
->
count
)
set_drawable
(
dce
,
TRUE
);
if
(
dce
->
count
)
update_visible_region
(
dce
);
else
/* non-fatal but shouldn't happen */
WARN
(
"DC is not in use!
\n
"
);
break
;
...
...
include/wine/server_protocol.h
View file @
bc75f2f6
...
...
@@ -2675,6 +2675,11 @@ struct get_visible_region_request
struct
get_visible_region_reply
{
struct
reply_header
__header
;
user_handle_t
top_win
;
int
top_org_x
;
int
top_org_y
;
int
win_org_x
;
int
win_org_y
;
size_t
total_size
;
/* VARARG(region,rectangles); */
};
...
...
@@ -3872,6 +3877,6 @@ union generic_reply
struct
set_mailslot_info_reply
set_mailslot_info_reply
;
};
#define SERVER_PROTOCOL_VERSION 16
5
#define SERVER_PROTOCOL_VERSION 16
6
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/protocol.def
View file @
bc75f2f6
...
...
@@ -1882,8 +1882,13 @@ enum message_type
user_handle_t window; /* handle to the window */
unsigned int flags; /* DCX flags */
@REPLY
user_handle_t top_win; /* top window to clip against */
int top_org_x; /* top window visible rect origin in screen coords */
int top_org_y;
int win_org_x; /* window rect origin in screen coords */
int win_org_y;
size_t total_size; /* total size of the resulting region */
VARARG(region,rectangles); /* list of rectangles for the region */
VARARG(region,rectangles); /* list of rectangles for the region
(in screen coords)
*/
@END
...
...
server/trace.c
View file @
bc75f2f6
...
...
@@ -2268,6 +2268,11 @@ static void dump_get_visible_region_request( const struct get_visible_region_req
static
void
dump_get_visible_region_reply
(
const
struct
get_visible_region_reply
*
req
)
{
fprintf
(
stderr
,
" top_win=%p,"
,
req
->
top_win
);
fprintf
(
stderr
,
" top_org_x=%d,"
,
req
->
top_org_x
);
fprintf
(
stderr
,
" top_org_y=%d,"
,
req
->
top_org_y
);
fprintf
(
stderr
,
" win_org_x=%d,"
,
req
->
win_org_x
);
fprintf
(
stderr
,
" win_org_y=%d,"
,
req
->
win_org_y
);
fprintf
(
stderr
,
" total_size=%d,"
,
req
->
total_size
);
fprintf
(
stderr
,
" region="
);
dump_varargs_rectangles
(
cur_size
);
...
...
server/window.c
View file @
bc75f2f6
...
...
@@ -633,17 +633,22 @@ static struct region *intersect_window_region( struct region *region, struct win
}
/* convert coordinates from client to screen coords */
static
inline
void
client_to_screen
(
struct
window
*
win
,
int
*
x
,
int
*
y
)
{
for
(
;
win
;
win
=
win
->
parent
)
{
*
x
+=
win
->
client_rect
.
left
;
*
y
+=
win
->
client_rect
.
top
;
}
}
/* map the region from window to screen coordinates */
static
inline
void
map_win_region_to_screen
(
struct
window
*
win
,
struct
region
*
region
)
{
int
x
=
win
->
window_rect
.
left
;
int
y
=
win
->
window_rect
.
top
;
for
(
win
=
win
->
parent
;
win
;
win
=
win
->
parent
)
{
x
+=
win
->
client_rect
.
left
;
y
+=
win
->
client_rect
.
top
;
}
client_to_screen
(
win
->
parent
,
&
x
,
&
y
);
offset_region
(
region
,
x
,
y
);
}
...
...
@@ -706,11 +711,10 @@ static inline struct window *get_top_clipping_window( struct window *win )
/* compute the visible region of a window, in window coordinates */
static
struct
region
*
get_visible_region
(
struct
window
*
win
,
unsigned
int
flags
)
static
struct
region
*
get_visible_region
(
struct
window
*
win
,
struct
window
*
top
,
unsigned
int
flags
)
{
struct
region
*
tmp
,
*
region
;
int
offset_x
,
offset_y
;
struct
window
*
top
=
get_top_clipping_window
(
win
);
if
(
!
(
region
=
create_empty_region
()))
return
NULL
;
...
...
@@ -1069,11 +1073,10 @@ static unsigned int get_child_update_flags( struct window *win, unsigned int fla
/* expose a region of a window, looking for the top most parent that needs to be exposed */
/* the region is in window coordinates */
static
void
expose_window
(
struct
window
*
win
,
struct
region
*
region
)
static
void
expose_window
(
struct
window
*
win
,
struct
window
*
top
,
struct
region
*
region
)
{
struct
window
*
parent
,
*
ptr
;
int
offset_x
,
offset_y
;
struct
window
*
top
=
get_top_clipping_window
(
win
);
/* find the top most parent that doesn't clip either siblings or children */
for
(
parent
=
ptr
=
win
;
ptr
!=
top
;
ptr
=
ptr
->
parent
)
...
...
@@ -1107,11 +1110,12 @@ static void set_window_pos( struct window *win, struct window *previous,
const
rectangle_t
old_window_rect
=
win
->
window_rect
;
const
rectangle_t
old_visible_rect
=
win
->
visible_rect
;
const
rectangle_t
old_client_rect
=
win
->
client_rect
;
struct
window
*
top
=
get_top_clipping_window
(
win
);
int
visible
=
(
win
->
style
&
WS_VISIBLE
)
||
(
swp_flags
&
SWP_SHOWWINDOW
);
if
(
win
->
parent
&&
!
is_visible
(
win
->
parent
))
visible
=
0
;
if
(
visible
&&
!
(
old_vis_rgn
=
get_visible_region
(
win
,
DCX_WINDOW
)))
return
;
if
(
visible
&&
!
(
old_vis_rgn
=
get_visible_region
(
win
,
top
,
DCX_WINDOW
)))
return
;
/* set the new window info before invalidating anything */
...
...
@@ -1130,7 +1134,7 @@ static void set_window_pos( struct window *win, struct window *previous,
/* if the window is not visible, everything is easy */
if
(
!
visible
)
return
;
if
(
!
(
new_vis_rgn
=
get_visible_region
(
win
,
DCX_WINDOW
)))
if
(
!
(
new_vis_rgn
=
get_visible_region
(
win
,
top
,
DCX_WINDOW
)))
{
free_region
(
old_vis_rgn
);
clear_error
();
/* ignore error since the window info has been modified already */
...
...
@@ -1144,7 +1148,7 @@ static void set_window_pos( struct window *win, struct window *previous,
offset_region
(
old_vis_rgn
,
old_window_rect
.
left
-
window_rect
->
left
,
old_window_rect
.
top
-
window_rect
->
top
);
if
(
xor_region
(
new_vis_rgn
,
old_vis_rgn
,
new_vis_rgn
))
expose_window
(
win
,
new_vis_rgn
);
expose_window
(
win
,
top
,
new_vis_rgn
);
}
free_region
(
old_vis_rgn
);
...
...
@@ -1580,17 +1584,25 @@ DECL_HANDLER(get_windows_offset)
DECL_HANDLER
(
get_visible_region
)
{
struct
region
*
region
;
struct
window
*
win
=
get_window
(
req
->
window
);
struct
window
*
top
,
*
win
=
get_window
(
req
->
window
);
if
(
!
win
)
return
;
if
((
region
=
get_visible_region
(
win
,
req
->
flags
)))
top
=
get_top_clipping_window
(
win
);
if
((
region
=
get_visible_region
(
win
,
top
,
req
->
flags
)))
{
rectangle_t
*
data
;
map_win_region_to_screen
(
win
,
region
);
data
=
get_region_data_and_free
(
region
,
get_reply_max_size
(),
&
reply
->
total_size
);
if
(
data
)
set_reply_data_ptr
(
data
,
reply
->
total_size
);
}
reply
->
top_win
=
top
->
handle
;
reply
->
top_org_x
=
top
->
visible_rect
.
left
;
reply
->
top_org_y
=
top
->
visible_rect
.
top
;
reply
->
win_org_x
=
(
req
->
flags
&
DCX_WINDOW
)
?
win
->
window_rect
.
left
:
win
->
client_rect
.
left
;
reply
->
win_org_y
=
(
req
->
flags
&
DCX_WINDOW
)
?
win
->
window_rect
.
top
:
win
->
client_rect
.
top
;
client_to_screen
(
top
->
parent
,
&
reply
->
top_org_x
,
&
reply
->
top_org_y
);
client_to_screen
(
win
->
parent
,
&
reply
->
win_org_x
,
&
reply
->
win_org_y
);
}
...
...
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