/*
 * Window related functions
 *
 * Copyright 1993, 1994, 1995, 1996, 2001 Alexandre Julliard
 * Copyright 1993 David Metcalfe
 * Copyright 1995, 1996 Alex Korobka
 */

#include "config.h"

#include "ts_xlib.h"
#include "ts_xutil.h"

#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"

#include "debugtools.h"
#include "x11drv.h"
#include "win.h"
#include "dce.h"
#include "options.h"

DEFAULT_DEBUG_CHANNEL(win);

extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );

#define HAS_DLGFRAME(style,exStyle) \
((!((style) & WS_THICKFRAME)) && (((style) & WS_DLGFRAME) || ((exStyle) & WS_EX_DLGMODALFRAME)))

/* X context to associate a hwnd to an X window */
XContext winContext = 0;

Atom wmProtocols = None;
Atom wmDeleteWindow = None;
Atom dndProtocol = None;
Atom dndSelection = None;
Atom wmChangeState = None;
Atom kwmDockWindow = None;
Atom _kde_net_wm_system_tray_window_for = None; /* KDE 2 Final */


/***********************************************************************
 *		X11DRV_register_window
 *
 * Associate an X window to a HWND.
 */
void X11DRV_register_window( Display *display, HWND hwnd, Window win )
{
    if (!winContext) winContext = TSXUniqueContext();
    TSXSaveContext( display, win, winContext, (char *)hwnd );
    TSXSetWMProtocols( display, win, &wmDeleteWindow, 1 );
}


/***********************************************************************
 *              set_wm_hint
 *
 * Set a window manager hint.
 */
static void set_wm_hint( Display *display, Window win, int hint, int val )
{
    XWMHints* wm_hints = TSXGetWMHints( display, win );
    if (!wm_hints) wm_hints = TSXAllocWMHints();
    if (wm_hints)
    {
        wm_hints->flags = hint;
        switch( hint )
        {
        case InputHint:
            wm_hints->input = val;
            break;

        case StateHint:
            wm_hints->initial_state = val;
            break;

        case IconPixmapHint:
            wm_hints->icon_pixmap = (Pixmap)val;
            break;

        case IconWindowHint:
            wm_hints->icon_window = (Window)val;
            break;
        }
        TSXSetWMHints( display, win, wm_hints );
        TSXFree(wm_hints);
    }
}


/***********************************************************************
 *              set_icon_hints
 *
 * Set the icon wm hints
 */
static void set_icon_hints( Display *display, WND *wndPtr, XWMHints *hints )
{
    X11DRV_WND_DATA *data = wndPtr->pDriverData;
    HICON hIcon = GetClassLongA( wndPtr->hwndSelf, GCL_HICON );

    if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap );
    if (data->hWMIconMask) DeleteObject( data->hWMIconMask);

    if (!hIcon)
    {
        data->hWMIconBitmap = 0;
        data->hWMIconMask = 0;
        hints->flags &= ~(IconPixmapHint | IconMaskHint);
    }
    else
    {
        HBITMAP hbmOrig;
        RECT rcMask;
        BITMAP bmMask;
        ICONINFO ii;
        HDC hDC;

        GetIconInfo(hIcon, &ii);

        X11DRV_CreateBitmap(ii.hbmMask);
        X11DRV_CreateBitmap(ii.hbmColor);

        GetObjectA(ii.hbmMask, sizeof(bmMask), &bmMask);
        rcMask.top    = 0;
        rcMask.left   = 0;
        rcMask.right  = bmMask.bmWidth;
        rcMask.bottom = bmMask.bmHeight;

        hDC = CreateCompatibleDC(0);
        hbmOrig = SelectObject(hDC, ii.hbmMask);
        InvertRect(hDC, &rcMask);
        SelectObject(hDC, hbmOrig);
        DeleteDC(hDC);

        data->hWMIconBitmap = ii.hbmColor;
        data->hWMIconMask = ii.hbmMask;

        hints->icon_pixmap = X11DRV_BITMAP_Pixmap(data->hWMIconBitmap);
        hints->icon_mask = X11DRV_BITMAP_Pixmap(data->hWMIconMask);
        hints->flags |= IconPixmapHint | IconMaskHint;
    }
}


/***********************************************************************
 *		dock_window
 *
 * Set the X Property of the window that tells the windowmanager we really
 * want to be in the systray
 *
 * KDE: set "KWM_DOCKWINDOW", type "KWM_DOCKWINDOW" to 1 before a window is 
 * 	mapped.
 *
 * all others: to be added ;)
 */
inline static void dock_window( Display *display, Window win )
{
    int data = 1;
    if (kwmDockWindow != None)
        TSXChangeProperty( display, win, kwmDockWindow, kwmDockWindow,
                           32, PropModeReplace, (char*)&data, 1 );
    if (_kde_net_wm_system_tray_window_for != None)
        TSXChangeProperty( display, win, _kde_net_wm_system_tray_window_for, XA_WINDOW,
                           32, PropModeReplace, (char*)&win, 1 );
}


/**********************************************************************
 *		create_desktop
 */
static void create_desktop( Display *display, WND *wndPtr )
{
    X11DRV_WND_DATA *data = wndPtr->pDriverData;

    wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True );
    wmDeleteWindow = TSXInternAtom( display, "WM_DELETE_WINDOW", True );
    dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
    dndSelection = TSXInternAtom( display, "DndSelection" , False );
    wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);
    kwmDockWindow = TSXInternAtom( display, "KWM_DOCKWINDOW", False );
    _kde_net_wm_system_tray_window_for = TSXInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False );

    data->window = root_window;
    if (root_window != DefaultRootWindow(display))
    {
        wndPtr->flags |= WIN_NATIVE;
        X11DRV_create_desktop_thread();
    }
}


/**********************************************************************
 *		CreateWindow   (X11DRV.@)
 */
BOOL X11DRV_CreateWindow( HWND hwnd )
{
    Display *display = thread_display();
    X11DRV_WND_DATA *data;
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    int x = wndPtr->rectWindow.left;
    int y = wndPtr->rectWindow.top;
    int cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
    int cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;

    if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(X11DRV_WND_DATA))))
    {
        WIN_ReleaseWndPtr( wndPtr );
        return FALSE;
    }
    data->window = 0;
    wndPtr->pDriverData = data;

    if (!wndPtr->parent)
    {
        create_desktop( display, wndPtr );
        WIN_ReleaseWndPtr( wndPtr );
        return TRUE;
    }

    /* Create the X window (only for top-level windows, and then only */
    /* when there's no desktop window) */

    if ((root_window == DefaultRootWindow(display))
        && (wndPtr->parent->hwndSelf == GetDesktopWindow()))
    {
        Window    wGroupLeader;
        XWMHints* wm_hints;
        XSetWindowAttributes win_attr;

        /* Create "managed" windows only if a title bar or resizable */
        /* frame is required. */
        if (WIN_WindowNeedsWMBorder(wndPtr->dwStyle, wndPtr->dwExStyle))
        {
            win_attr.event_mask = ExposureMask | KeyPressMask |
                KeyReleaseMask | PointerMotionMask |
                ButtonPressMask | ButtonReleaseMask |
                FocusChangeMask | StructureNotifyMask;
            win_attr.override_redirect = FALSE;
            wndPtr->dwExStyle |= WS_EX_MANAGED;
        }
        else
        {
            win_attr.event_mask = ExposureMask | KeyPressMask |
                KeyReleaseMask | PointerMotionMask |
                ButtonPressMask | ButtonReleaseMask |
                FocusChangeMask;
            win_attr.override_redirect = TRUE;
        }
        wndPtr->flags |= WIN_NATIVE;

        wine_tsx11_lock();

        win_attr.bit_gravity   = (wndPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ? ForgetGravity : NorthWestGravity;
        win_attr.colormap      = X11DRV_PALETTE_PaletteXColormap;
        win_attr.backing_store = NotUseful;
        win_attr.save_under    = ((wndPtr->clsStyle & CS_SAVEBITS) != 0);
        win_attr.cursor        = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) );

        data->hWMIconBitmap = 0;
        data->hWMIconMask = 0;
        data->bit_gravity = win_attr.bit_gravity;

        /* Zero-size X11 window hack.  X doesn't like them, and will crash */
        /* with a BadValue unless we do something ugly like this. */
        /* Zero size window won't be mapped  */
        if (cx <= 0) cx = 1;
        if (cy <= 0) cy = 1;

        data->window = XCreateWindow( display, root_window,
                                        x, y, cx, cy,
                                        0, screen_depth,
                                        InputOutput, visual,
                                        CWEventMask | CWOverrideRedirect |
                                        CWColormap | CWCursor | CWSaveUnder |
                                        CWBackingStore | CWBitGravity,
                                        &win_attr );

        if (win_attr.cursor) XFreeCursor( display, win_attr.cursor );
        wine_tsx11_unlock();

        if(!(wGroupLeader = data->window))
        {
            HeapFree( GetProcessHeap(), 0, data );
            WIN_ReleaseWndPtr( wndPtr );
            return FALSE;
        }

        /* If we are the systray, we need to be managed to be noticed by KWM */
        if (wndPtr->dwExStyle & WS_EX_TRAYWINDOW) dock_window( display, data->window );

        if (wndPtr->dwExStyle & WS_EX_MANAGED)
        {
            XClassHint *class_hints = TSXAllocClassHint();
            XSizeHints* size_hints = TSXAllocSizeHints();

            if (class_hints)
            {
                class_hints->res_name = "wineManaged";
                class_hints->res_class = "Wine";
                TSXSetClassHint( display, data->window, class_hints );
                TSXFree (class_hints);
            }

            if (size_hints)
            {
                size_hints->win_gravity = StaticGravity;
                size_hints->x = x;
                size_hints->y = y;
                size_hints->flags = PWinGravity|PPosition;

                if (HAS_DLGFRAME(wndPtr->dwStyle,wndPtr->dwExStyle))
                {
                    size_hints->min_width = size_hints->max_width = cx;
                    size_hints->min_height = size_hints->max_height = cy;
                    size_hints->flags |= PMinSize | PMaxSize;
                }

                TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), 
                                   size_hints, XA_WM_NORMAL_HINTS );
                TSXFree(size_hints);
            }
        }

        if (wndPtr->owner)  /* Get window owner */
        {
            Window w = X11DRV_WND_FindXWindow( wndPtr->owner );
            if (w != None)
            {
                TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w );
                wGroupLeader = w;
            }
        }

        if ((wm_hints = TSXAllocWMHints()))
        {
            wm_hints->flags = InputHint | StateHint | WindowGroupHint;
            wm_hints->input = True;

            if (wndPtr->dwExStyle & WS_EX_MANAGED)
            {
                set_icon_hints( display, wndPtr, wm_hints );
                wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE)
                    ? IconicState : NormalState;
            }
            else
                wm_hints->initial_state = NormalState;
            wm_hints->window_group = wGroupLeader;

            TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
            TSXFree(wm_hints);
        }
        X11DRV_register_window( display, hwnd, data->window );
        TSXFlush( display );
    }
    WIN_ReleaseWndPtr( wndPtr );
    return TRUE;
}


/***********************************************************************
 *		DestroyWindow   (X11DRV.@)
 */
BOOL X11DRV_DestroyWindow( HWND hwnd )
{
    Display *display = thread_display();
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    X11DRV_WND_DATA *data = wndPtr->pDriverData;
    Window w;

    if (data && (w = data->window))
    {
        XEvent xe;
        wine_tsx11_lock();
        XSync( gdi_display, False );  /* flush any reference to this drawable in GDI queue */
        XDeleteContext( display, w, winContext );
        XDestroyWindow( display, w );
        while( XCheckWindowEvent(display, w, NoEventMask, &xe) );
        wine_tsx11_unlock();

        data->window = None;
        if( data->hWMIconBitmap )
        {
            DeleteObject( data->hWMIconBitmap );
            data->hWMIconBitmap = 0;
        }
        if( data->hWMIconMask )
        {
            DeleteObject( data->hWMIconMask);
            data->hWMIconMask= 0;
        }
    }
    HeapFree( GetProcessHeap(), 0, data );
    wndPtr->pDriverData = NULL;
    WIN_ReleaseWndPtr( wndPtr );
    return TRUE;
}


/*****************************************************************
 *		SetParent   (X11DRV.@)
 */
HWND X11DRV_SetParent( HWND hwnd, HWND parent )
{
    Display *display = thread_display();
    WND *wndPtr;
    WND *pWndParent;
    DWORD dwStyle;
    HWND retvalue;

    if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;

    dwStyle = wndPtr->dwStyle;

    if (!parent) parent = GetDesktopWindow();

    if (!(pWndParent = WIN_FindWndPtr(parent)))
    {
        WIN_ReleaseWndPtr( wndPtr );
        return 0;
    }

    /* Windows hides the window first, then shows it again
     * including the WM_SHOWWINDOW messages and all */
    if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE );

    retvalue = wndPtr->parent->hwndSelf;  /* old parent */
    if (pWndParent != wndPtr->parent)
    {
        if ( X11DRV_WND_GetXWindow(wndPtr) )
        {
            /* Toplevel window needs to be reparented.  Used by Tk 8.0 */
            TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
            ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
        }
        WIN_UnlinkWindow(wndPtr->hwndSelf);
        wndPtr->parent = pWndParent;

        /* Create an X counterpart for reparented top-level windows
	     * when not in the desktop mode. */
        if (parent == GetDesktopWindow())
        {
            if(root_window == DefaultRootWindow(display))
                X11DRV_CreateWindow(wndPtr->hwndSelf);
        }
        else /* a child window */
        {
            if( !( wndPtr->dwStyle & WS_CHILD ) )
            {
                if( wndPtr->wIDmenu != 0)
                {
                    DestroyMenu( (HMENU) wndPtr->wIDmenu );
                    wndPtr->wIDmenu = 0;
                }
            }
        }
        WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
    }
    WIN_ReleaseWndPtr( pWndParent );
    WIN_ReleaseWndPtr( wndPtr );

    /* SetParent additionally needs to make hwnd the topmost window
       in the x-order and send the expected WM_WINDOWPOSCHANGING and
       WM_WINDOWPOSCHANGED notification messages. 
    */
    SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
                  SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|
                  ((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
    /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
     * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */

    return retvalue;
}


/*******************************************************************
 *		EnableWindow   (X11DRV.@)
 */
BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable )
{
    Display *display = thread_display();
    WND *wndPtr;
    BOOL retvalue;
    Window w;

    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;

    retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);

    if (enable && (wndPtr->dwStyle & WS_DISABLED))
    {
        /* Enable window */
        wndPtr->dwStyle &= ~WS_DISABLED;

        if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
            set_wm_hint( display, w, InputHint, TRUE );

        SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
    }
    else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
    {
        SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0 );

        /* Disable window */
        wndPtr->dwStyle |= WS_DISABLED;

        if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
            set_wm_hint( display, w, InputHint, FALSE );

        if (hwnd == GetFocus())
            SetFocus( 0 );  /* A disabled window can't have the focus */

        if (hwnd == GetCapture())
            ReleaseCapture();  /* A disabled window can't capture the mouse */

        SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
    }
    WIN_ReleaseWndPtr(wndPtr);
    return retvalue;
}


/*****************************************************************
 *		SetFocus   (X11DRV.@)
 *
 * Set the X focus.
 * Explicit colormap management seems to work only with OLVWM.
 */
void X11DRV_SetFocus( HWND hwnd )
{
    Display *display = thread_display();
    XWindowAttributes win_attr;
    Window win;
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    WND *w = wndPtr;

    if (!wndPtr) return;

    /* Only mess with the X focus if there's */
    /* no desktop window and if the window is not managed by the WM. */
    if (root_window != DefaultRootWindow(display)) goto done;

    while (w && !((X11DRV_WND_DATA *) w->pDriverData)->window)
        w = w->parent;
    if (!w) w = wndPtr;
    if (w->dwExStyle & WS_EX_MANAGED) goto done;

    if (!hwnd)  /* If setting the focus to 0, uninstall the colormap */
    {
        if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
            TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
    }
    else if ((win = X11DRV_WND_FindXWindow(wndPtr)))
    {
        /* Set X focus and install colormap */
        if (TSXGetWindowAttributes( display, win, &win_attr ) &&
            (win_attr.map_state == IsViewable))
        {
            /* If window is not viewable, don't change anything */
            TSXSetInputFocus( display, win, RevertToParent, CurrentTime );
            if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
                TSXInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
            X11DRV_Synchronize();
        }
    }

 done:
    WIN_ReleaseWndPtr( wndPtr );
}


/*****************************************************************
 *		SetWindowText   (X11DRV.@)
 */
BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text )
{
    Display *display = thread_display();
    UINT count;
    char *buffer;
    static UINT text_cp = (UINT)-1;
    Window win;
    WND *wndPtr = WIN_FindWndPtr( hwnd );

    if (!wndPtr) return FALSE;
    if ((win = X11DRV_WND_GetXWindow(wndPtr)))
    {
        if (text_cp == (UINT)-1)
        {
            text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP);
            TRACE("text_cp = %u\n", text_cp);
        }

        /* allocate new buffer for window text */
        count = WideCharToMultiByte(text_cp, 0, text, -1, NULL, 0, NULL, NULL);
        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WCHAR) )))
        {
            ERR("Not enough memory for window text\n");
            WIN_ReleaseWndPtr( wndPtr );
            return FALSE;
        }
        WideCharToMultiByte(text_cp, 0, text, -1, buffer, count, NULL, NULL);

        TSXStoreName( display, win, buffer );
        TSXSetIconName( display, win, buffer );
        HeapFree( GetProcessHeap(), 0, buffer );
    }
    WIN_ReleaseWndPtr( wndPtr );
    return TRUE;
}


/**********************************************************************
 *		X11DRV_SetWindowIcon
 *
 * hIcon or hIconSm has changed (or is being initialised for the
 * first time). Complete the X11 driver-specific initialisation
 * and set the window hints.
 *
 * This is not entirely correct, may need to create
 * an icon window and set the pixmap as a background
 */
HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small )
{
    Display *display = thread_display();
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    int index = small ? GCL_HICONSM : GCL_HICON;
    HICON old;

    if (!wndPtr) return 0;

    old = GetClassLongW( hwnd, index );
    SetClassLongW( hwnd, index, icon );

    SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE |
                  SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );

    if (wndPtr->dwExStyle & WS_EX_MANAGED)
    {
        Window win = X11DRV_WND_GetXWindow(wndPtr);
        XWMHints* wm_hints = TSXGetWMHints( display, win );

        if (!wm_hints) wm_hints = TSXAllocWMHints();
        if (wm_hints)
        {
            set_icon_hints( display, wndPtr, wm_hints );
            TSXSetWMHints( display, win, wm_hints );
            TSXFree( wm_hints );
        }
    }

    WIN_ReleaseWndPtr( wndPtr );
    return old;
}


/*************************************************************************
 *             fix_caret
 */
static BOOL fix_caret(HWND hWnd, LPRECT lprc, UINT flags)
{
   HWND hCaret = CARET_GetHwnd();

   if( hCaret )
   {
       RECT rc;
       CARET_GetRect( &rc );
       if( hCaret == hWnd ||
          (flags & SW_SCROLLCHILDREN && IsChild(hWnd, hCaret)) )
       {
           POINT pt;
           pt.x = rc.left;
           pt.y = rc.top;
           MapWindowPoints( hCaret, hWnd, (LPPOINT)&rc, 2 );
           if( IntersectRect(lprc, lprc, &rc) )
           {
               HideCaret(0);
               lprc->left = pt.x;
               lprc->top = pt.y;
               return TRUE;
           }
       }
   }
   return FALSE;
}


/*************************************************************************
 *		ScrollWindowEx   (X11DRV.@)
 */
INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
                           const RECT *rect, const RECT *clipRect,
                           HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags )
{
    INT  retVal = NULLREGION;
    BOOL bCaret = FALSE, bOwnRgn = TRUE;
    RECT rc, cliprc;
    WND*   wnd = WIN_FindWndPtr( hwnd );

    if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE ))
    {
        retVal = ERROR;
        goto END;
    }

    GetClientRect(hwnd, &rc);
    if (rect) IntersectRect(&rc, &rc, rect);

    if (clipRect) IntersectRect(&cliprc,&rc,clipRect);
    else cliprc = rc;

    if (!IsRectEmpty(&cliprc) && (dx || dy))
    {
        HDC   hDC;
        BOOL  bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE));
        HRGN  hrgnClip = CreateRectRgnIndirect(&cliprc);
        HRGN  hrgnTemp = CreateRectRgnIndirect(&rc);
        RECT  caretrc;

        TRACE("%04x, %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d) %04x\n",
              (HWND16)hwnd, dx, dy, hrgnUpdate, rcUpdate,
              clipRect?clipRect->left:0, clipRect?clipRect->top:0,
              clipRect?clipRect->right:0, clipRect?clipRect->bottom:0,
              rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags );

        caretrc = rc;
        bCaret = fix_caret(hwnd, &caretrc, flags);

        if( hrgnUpdate ) bOwnRgn = FALSE;
        else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );

        hDC = GetDCEx( hwnd, hrgnClip, DCX_CACHE | DCX_USESTYLE |
                         DCX_KEEPCLIPRGN | DCX_INTERSECTRGN |
                       ((flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0) );
        if (hDC)
        {
            X11DRV_WND_SurfaceCopy(wnd,hDC,dx,dy,&rc,bUpdate);
            if( bUpdate )
            {
                DC* dc;

                if( (dc = DC_GetDCPtr(hDC)) )
                {
                    OffsetRgn( hrgnTemp, dc->DCOrgX, dc->DCOrgY );
                    CombineRgn( hrgnTemp, hrgnTemp, dc->hVisRgn,
                                RGN_AND );
                    OffsetRgn( hrgnTemp, -dc->DCOrgX, -dc->DCOrgY );
                    CombineRgn( hrgnUpdate, hrgnTemp, hrgnClip,
                                RGN_AND );
                    OffsetRgn( hrgnTemp, dx, dy );
                    retVal =
                        CombineRgn( hrgnUpdate, hrgnUpdate, hrgnTemp,
                                    RGN_DIFF );

                    if( rcUpdate ) GetRgnBox( hrgnUpdate, rcUpdate );
                    GDI_ReleaseObj( hDC );
                }
            }
            ReleaseDC(hwnd, hDC);
        }

        if( wnd->hrgnUpdate > 1 )
        {
            /* Takes into account the fact that some damages may have
               occured during the scroll. */
            CombineRgn( hrgnTemp, wnd->hrgnUpdate, 0, RGN_COPY );
            OffsetRgn( hrgnTemp, dx, dy );
            CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND );
            CombineRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, hrgnTemp, RGN_OR );
        }

        if( flags & SW_SCROLLCHILDREN )
        {
            RECT r;
            WND *w;
            for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next))
            {
                r = w->rectWindow;
                if( !rect || IntersectRect(&r, &r, &rc) )
                    SetWindowPos(w->hwndSelf, 0, w->rectWindow.left + dx,
                                 w->rectWindow.top  + dy, 0,0, SWP_NOZORDER |
                                 SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
                                 SWP_DEFERERASE );
            }
        }

        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( bCaret )
        {
            SetCaretPos( caretrc.left + dx, caretrc.top + dy );
            ShowCaret(0);
        }

        if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
        DeleteObject( hrgnClip );
        DeleteObject( hrgnTemp );
    }
END:
    WIN_ReleaseWndPtr(wnd);
    return retVal;
}
