Allow the client rectangle to be of arbitrary size and dimensions,
regardless of the window rectangle.

diff --git a/server/window.c b/server/window.c
index 122706c..88dfe8f 100644
--- a/server/window.c
+++ b/server/window.c
@@ -645,6 +645,19 @@
 }
 
 
+/* 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 )
+{
+    rectangle_t rect;
+
+    rect.left   = max( win->window_rect.left, win->client_rect.left );
+    rect.top    = max( win->window_rect.top, win->client_rect.top );
+    rect.right  = min( win->window_rect.right, win->client_rect.right );
+    rect.bottom = min( win->window_rect.bottom, win->client_rect.bottom );
+    set_region_rect( region, &rect );
+}
+
+
 /* compute the visible region of a window */
 static struct region *get_visible_region( struct window *win, struct window *top,
                                           unsigned int flags )
@@ -662,11 +675,8 @@
 
     if ((flags & DCX_PARENTCLIP) && win != top && win->parent)
     {
-        rectangle_t rect;
-        rect.left = rect.top = 0;
-        rect.right = win->parent->client_rect.right - win->parent->client_rect.left;
-        rect.bottom = win->parent->client_rect.bottom - win->parent->client_rect.top;
-        set_region_rect( region, &rect );
+        set_region_client_rect( region, win->parent );
+        offset_region( region, -win->parent->client_rect.left, -win->parent->client_rect.top );
         offset_x = win->client_rect.left;
         offset_y = win->client_rect.top;
     }
@@ -679,7 +689,7 @@
     }
     else
     {
-        set_region_rect( region, &win->client_rect );
+        set_region_client_rect( region, win );
         if (win->win_region && !intersect_window_region( region, win )) goto error;
         offset_x = win->client_rect.left;
         offset_y = win->client_rect.top;
@@ -712,7 +722,7 @@
             offset_x += win->client_rect.left;
             offset_y += win->client_rect.top;
             offset_region( region, win->client_rect.left, win->client_rect.top );
-            set_region_rect( tmp, &win->client_rect );
+            set_region_client_rect( tmp, win );
             if (win->win_region && !intersect_window_region( tmp, win ))
             {
                 free_region( tmp );
@@ -748,27 +758,14 @@
 /* and converted from client to window coordinates. Helper for (in)validate_window. */
 static struct region *crop_region_to_win_rect( struct window *win, struct region *region, int frame )
 {
-    rectangle_t rect;
     struct region *tmp = create_empty_region();
 
     if (!tmp) return NULL;
 
     /* get bounding rect in client coords */
-    if (frame)
-    {
-        rect.left   = win->window_rect.left - win->client_rect.left;
-        rect.top    = win->window_rect.top - win->client_rect.top;
-        rect.right  = win->window_rect.right - win->client_rect.left;
-        rect.bottom = win->window_rect.bottom - win->client_rect.top;
-    }
-    else
-    {
-        rect.left   = 0;
-        rect.top    = 0;
-        rect.right  = win->client_rect.right - win->client_rect.left;
-        rect.bottom = win->client_rect.bottom - win->client_rect.top;
-    }
-    set_region_rect( tmp, &rect );
+    if (frame) set_region_rect( tmp, &win->window_rect );
+    else set_region_client_rect( tmp, win );
+    offset_region( tmp, -win->client_rect.left, -win->client_rect.top );
 
     /* intersect specified region with bounding rect */
     if (region && !intersect_region( tmp, region, tmp )) goto done;
@@ -831,8 +828,9 @@
     rect.right  = win->client_rect.right - win->window_rect.left;
     rect.bottom = win->client_rect.bottom - win->window_rect.top;
 
-    if ((tmp = create_region( &rect, 1 )))
+    if ((tmp = create_empty_region()))
     {
+        set_region_rect( tmp, &rect );
         if (intersect_region( tmp, win->update_region, tmp ))
             set_update_region( win, tmp );
         else
@@ -1056,23 +1054,6 @@
 }
 
 
-/* validate that the specified window and client rects are valid */
-static int validate_window_rectangles( const rectangle_t *window_rect, const rectangle_t *client_rect )
-{
-    /* rectangles must be ordered properly */
-    if (window_rect->right < window_rect->left) return 0;
-    if (window_rect->bottom < window_rect->top) return 0;
-    if (client_rect->right < client_rect->left) return 0;
-    if (client_rect->bottom < client_rect->top) return 0;
-    /* client rect must be inside window rect */
-    if (client_rect->left < window_rect->left) return 0;
-    if (client_rect->right > window_rect->right) return 0;
-    if (client_rect->top < window_rect->top) return 0;
-    if (client_rect->bottom > window_rect->bottom) return 0;
-    return 1;
-}
-
-
 /* set the window and client rectangles, updating the update region if necessary */
 static void set_window_pos( struct window *win, struct window *top, struct window *previous,
                             unsigned int swp_flags, const rectangle_t *window_rect,
@@ -1138,18 +1119,16 @@
         memcmp( window_rect, &old_window_rect, sizeof(old_window_rect) ) ||
         memcmp( client_rect, &old_client_rect, sizeof(old_client_rect) ))
     {
-        struct region *tmp;
-
-        /* subtract the valid portion of client rect from the total region */
-        if (!memcmp( client_rect, &old_client_rect, sizeof(old_client_rect) ))
-            tmp = create_region( client_rect, 1 );
-        else if (valid_rects)
-            tmp = create_region( &valid_rects[0], 1 );
-        else
-            tmp = create_empty_region();
+        struct region *tmp = create_empty_region();
 
         if (tmp)
         {
+            /* subtract the valid portion of client rect from the total region */
+            if (!memcmp( client_rect, &old_client_rect, sizeof(old_client_rect) ))
+                set_region_rect( tmp, client_rect );
+            else if (valid_rects)
+                set_region_rect( tmp, &valid_rects[0] );
+
             set_region_rect( new_vis_rgn, window_rect );
             if (subtract_region( tmp, new_vis_rgn, tmp ))
             {
@@ -1479,7 +1458,8 @@
         if (previous == win) flags |= SWP_NOZORDER;  /* nothing to do */
     }
 
-    if (!validate_window_rectangles( &req->window, &req->client ))
+    /* window rectangle must be ordered properly */
+    if (req->window.right < req->window.left || req->window.bottom < req->window.top)
     {
         set_error( STATUS_INVALID_PARAMETER );
         return;