Module: wine Branch: master Commit: d56ac06260daaa82cfcf7a15d3fe10de574be6d3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d56ac06260daaa82cfcf7a15d3...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Sep 27 20:46:41 2010 +0200
server: Mirror the window region for RTL windows in get/set_window_region and redraw_window.
---
server/protocol.def | 6 +++--- server/region.c | 23 +++++++++++++++++++++++ server/user.h | 10 ++++++++++ server/window.c | 31 ++++++++++++++++++------------- 4 files changed, 54 insertions(+), 16 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def index 687fe6c..ccc87fe 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2405,7 +2405,7 @@ enum coords_relative user_handle_t window; /* handle to the window */ @REPLY data_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 window coords) */ @END
@@ -2413,7 +2413,7 @@ enum coords_relative @REQ(set_window_region) user_handle_t window; /* handle to the window */ int redraw; /* redraw the window? */ - VARARG(region,rectangles); /* list of rectangles for the region */ + VARARG(region,rectangles); /* list of rectangles for the region (in window coords) */ @END
@@ -2449,7 +2449,7 @@ enum coords_relative @REQ(redraw_window) user_handle_t window; /* handle to the window */ unsigned int flags; /* RDW_* flags */ - VARARG(region,rectangles); /* list of rectangles for the region */ + VARARG(region,rectangles); /* list of rectangles for the region (in window coords) */ @END
diff --git a/server/region.c b/server/region.c index 2efbd30..8b85c34 100644 --- a/server/region.c +++ b/server/region.c @@ -711,6 +711,29 @@ void offset_region( struct region *region, int x, int y ) region->extents.bottom += y; }
+/* mirror a region relative to a window client rect */ +void mirror_region( const rectangle_t *client_rect, struct region *region ) +{ + int start, end, i, j; + + for (start = 0; start < region->num_rects; start = end + 1) + { + for (end = start; end < region->num_rects - 1; end++) + if (region->rects[end + 1].top != region->rects[end].top) break; + for (i = start, j = end; i < j; i++, j--) + { + rectangle_t rect = region->rects[j]; + region->rects[i] = region->rects[j]; + region->rects[j] = rect; + mirror_rect( client_rect, ®ion->rects[j] ); + mirror_rect( client_rect, ®ion->rects[i] ); + } + if (i == j) mirror_rect( client_rect, ®ion->rects[i] ); + } + mirror_rect( client_rect, ®ion->extents ); +} + + /* make a copy of a region; returns dst or NULL on error */ struct region *copy_region( struct region *dst, const struct region *src ) { diff --git a/server/user.h b/server/user.h index 1f0d909..6ac0398 100644 --- a/server/user.h +++ b/server/user.h @@ -114,6 +114,7 @@ extern rectangle_t *get_region_data_and_free( struct region *region, data_size_t extern int is_region_empty( const struct region *region ); extern void get_region_extents( const struct region *region, rectangle_t *rect ); extern void offset_region( struct region *region, int x, int y ); +extern void mirror_region( const rectangle_t *client_rect, struct region *region ); extern struct region *copy_region( struct region *dst, const struct region *src ); extern struct region *intersect_region( struct region *dst, const struct region *src1, const struct region *src2 ); @@ -164,4 +165,13 @@ extern void set_process_default_desktop( struct process *process, struct desktop extern void close_process_desktop( struct process *process ); extern void close_thread_desktop( struct thread *thread );
+/* mirror a rectangle respective to the window client area */ +static inline void mirror_rect( const rectangle_t *client_rect, rectangle_t *rect ) +{ + int width = client_rect->right - client_rect->left; + int tmp = rect->left; + rect->left = width - rect->right; + rect->right = width - tmp; +} + #endif /* __WINE_SERVER_USER_H */ diff --git a/server/window.c b/server/window.c index bb66a39..e3dc47a 100644 --- a/server/window.c +++ b/server/window.c @@ -905,16 +905,6 @@ static inline void offset_rect( rectangle_t *rect, int offset_x, int offset_y ) }
-/* mirror a rectangle respective to the window client area */ -static inline void mirror_rect( const rectangle_t *window_rect, rectangle_t *rect ) -{ - int width = window_rect->right - window_rect->left; - int tmp = rect->left; - rect->left = width - rect->right; - rect->right = width - tmp; -} - - /* set the region to the client rect clipped by the window rect, in parent-relative coordinates */ static void set_region_client_rect( struct region *region, struct window *win ) { @@ -2314,15 +2304,28 @@ DECL_HANDLER(get_visible_region) /* get the window region */ DECL_HANDLER(get_window_region) { + rectangle_t *data; struct window *win = get_window( req->window );
if (!win) return; + if (!win->win_region) return;
- if (win->win_region) + if (win->ex_style & WS_EX_LAYOUTRTL) { - rectangle_t *data = get_region_data( win->win_region, get_reply_max_size(), &reply->total_size ); - if (data) set_reply_data_ptr( data, reply->total_size ); + struct region *region = create_empty_region(); + + if (!region) return; + if (!copy_region( region, win->win_region )) + { + free_region( region ); + return; + } + mirror_region( &win->window_rect, region ); + data = get_region_data_and_free( region, get_reply_max_size(), &reply->total_size ); } + else data = get_region_data( win->win_region, get_reply_max_size(), &reply->total_size ); + + if (data) set_reply_data_ptr( data, reply->total_size ); }
@@ -2338,6 +2341,7 @@ DECL_HANDLER(set_window_region) { if (!(region = create_region_from_req_data( get_req_data(), get_req_data_size() ))) return; + if (win->ex_style & WS_EX_LAYOUTRTL) mirror_region( &win->window_rect, region ); } set_window_region( win, region, req->redraw ); } @@ -2458,6 +2462,7 @@ DECL_HANDLER(redraw_window) { if (!(region = create_region_from_req_data( get_req_data(), get_req_data_size() ))) return; + if (win->ex_style & WS_EX_LAYOUTRTL) mirror_region( &win->client_rect, region ); } }