/*
 * WIN32 clipboard implementation
 *
 * Copyright 1994 Martin Ayotte
 *	     1996 Alex Korobka
 *	     1999 Noel Borthwick
 *	     2003 Ulrich Czekalla for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * NOTES:
 *    This file contains the implementation for the WIN32 Clipboard API
 * and Wine's internal clipboard cache.
 * The actual contents of the clipboard are held in the clipboard cache.
 * The internal implementation talks to a "clipboard driver" to fill or
 * expose the cache to the native device. (Currently only the X11 and
 * TTY clipboard  driver are available)
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/winbase16.h"
#include "user_private.h"
#include "win.h"

#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/server.h"

WINE_DEFAULT_DEBUG_CHANNEL(clipboard);

#define  CF_REGFORMATBASE  0xC000

typedef struct
{
    HWND hWndOpen;
    HWND hWndOwner;
    HWND hWndViewer;
    UINT seqno;
    UINT flags;
} CLIPBOARDINFO, *LPCLIPBOARDINFO;

/*
 * Indicates if data has changed since open.
 */
static BOOL bCBHasChanged = FALSE;


/**************************************************************************
 *                      CLIPBOARD_SetClipboardOwner
 *
 * Set the global wineserver clipboard owner. The current process will
 * be the owner and <hWnd> will get the render notifications.
 */
static BOOL CLIPBOARD_SetClipboardOwner(HWND hWnd)
{
    BOOL bRet;

    TRACE(" hWnd(%p)\n", hWnd);

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = SET_CB_OWNER;
        req->owner = wine_server_user_handle( hWnd );
        bRet = !wine_server_call_err( req );
    }
    SERVER_END_REQ;

    return bRet;
}


/**************************************************************************
 *                      CLIPBOARD_GetClipboardInfo
 */
static BOOL CLIPBOARD_GetClipboardInfo(LPCLIPBOARDINFO cbInfo)
{
    BOOL bRet;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = 0;

        if (((bRet = !wine_server_call_err( req ))))
        {
            cbInfo->hWndOpen = wine_server_ptr_handle( reply->old_clipboard );
            cbInfo->hWndOwner = wine_server_ptr_handle( reply->old_owner );
            cbInfo->hWndViewer = wine_server_ptr_handle( reply->old_viewer );
            cbInfo->seqno = reply->seqno;
            cbInfo->flags = reply->flags;
        }
    }
    SERVER_END_REQ;

    return bRet;
}


/**************************************************************************
 *	CLIPBOARD_ReleaseOwner
 */
BOOL CLIPBOARD_ReleaseOwner(void)
{
    BOOL bRet = FALSE;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = SET_CB_RELOWNER | SET_CB_SEQNO;

        if (wine_server_call_err( req ))
        {
            ERR("Failed to set clipboard.\n");
        }
        else
        {
            bRet = TRUE;
        }
    }
    SERVER_END_REQ;

    return bRet;
}


/**************************************************************************
 *		CLIPBOARD_OpenClipboard
 */
static BOOL CLIPBOARD_OpenClipboard(HWND hWnd)
{
    BOOL bRet;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = SET_CB_OPEN;
        req->clipboard = wine_server_user_handle( hWnd );
        bRet = !wine_server_call( req );
    }
    SERVER_END_REQ;

    return bRet;
}


/**************************************************************************
 *		CLIPBOARD_CloseClipboard
 */
static BOOL CLIPBOARD_CloseClipboard(void)
{
    BOOL bRet;

    TRACE(" Changed=%d\n", bCBHasChanged);

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = SET_CB_CLOSE;
        if (bCBHasChanged) req->flags |= SET_CB_SEQNO;
        bRet = !wine_server_call_err( req );
    }
    SERVER_END_REQ;

    return bRet;
}


/**************************************************************************
 *                WIN32 Clipboard implementation
 **************************************************************************/

/**************************************************************************
 *		RegisterClipboardFormatW (USER32.@)
 */
UINT WINAPI RegisterClipboardFormatW(LPCWSTR FormatName)
{
    return USER_Driver->pRegisterClipboardFormat(FormatName);
}


/**************************************************************************
 *		RegisterClipboardFormatA (USER32.@)
 */
UINT WINAPI RegisterClipboardFormatA(LPCSTR formatName)
{
    int len;
    LPWSTR wFormat;
    UINT ret;

    len = MultiByteToWideChar(CP_ACP, 0, formatName, -1, NULL, 0);
    wFormat = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, formatName, -1, wFormat, len);

    ret = RegisterClipboardFormatW(wFormat);
    HeapFree(GetProcessHeap(), 0, wFormat);
    return ret;
}


/**************************************************************************
 *		GetClipboardFormatNameW (USER32.@)
 */
INT WINAPI GetClipboardFormatNameW(UINT wFormat, LPWSTR retStr, INT maxlen)
{
    return USER_Driver->pGetClipboardFormatName(wFormat, retStr, maxlen);
}


/**************************************************************************
 *		GetClipboardFormatNameA (USER32.@)
 */
INT WINAPI GetClipboardFormatNameA(UINT wFormat, LPSTR retStr, INT maxlen)
{
    INT ret;
    LPWSTR p = HeapAlloc( GetProcessHeap(), 0, maxlen*sizeof(WCHAR) );
    if(p == NULL) return 0; /* FIXME: is this the correct failure value? */

    ret = GetClipboardFormatNameW( wFormat, p, maxlen );

    if (ret && maxlen > 0 && !WideCharToMultiByte( CP_ACP, 0, p, -1, retStr, maxlen, 0, 0))
        retStr[maxlen-1] = 0;
    HeapFree( GetProcessHeap(), 0, p );
    return ret;
}


/**************************************************************************
 *		OpenClipboard (USER32.@)
 *
 * Note: Netscape uses NULL hWnd to open the clipboard.
 */
BOOL WINAPI OpenClipboard( HWND hWnd )
{
    BOOL bRet;

    TRACE("(%p)...\n", hWnd);

    bRet = CLIPBOARD_OpenClipboard(hWnd);

    TRACE(" returning %i\n", bRet);

    return bRet;
}


/**************************************************************************
 *		CloseClipboard (USER32.@)
 */
BOOL WINAPI CloseClipboard(void)
{
    BOOL bRet = FALSE;

    TRACE("(%d)\n", bCBHasChanged);

    if (CLIPBOARD_CloseClipboard())
    {
        if (bCBHasChanged)
        {
            HWND hWndViewer = GetClipboardViewer();

            USER_Driver->pEndClipboardUpdate();

            if (hWndViewer)
                SendMessageW(hWndViewer, WM_DRAWCLIPBOARD, 0, 0);

            bCBHasChanged = FALSE;
        }

        bRet = TRUE;
    }

    return bRet;
}


/**************************************************************************
 *		EmptyClipboard (USER32.@)
 * Empties and acquires ownership of the clipboard
 */
BOOL WINAPI EmptyClipboard(void)
{
    CLIPBOARDINFO cbinfo;

    TRACE("()\n");

    if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
        ~cbinfo.flags & CB_OPEN)
    {
        WARN("Clipboard not opened by calling task!\n");
        SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
        return FALSE;
    }

    /* Destroy private objects */
    if (cbinfo.hWndOwner)
        SendMessageW(cbinfo.hWndOwner, WM_DESTROYCLIPBOARD, 0, 0);

    /* Tell the driver to acquire the selection. The current owner
     * will be signaled to delete it's own cache. */

    /* Assign ownership of the clipboard to the current client. We do
     * this before acquiring the selection so that when we do acquire the
     * selection and the selection loser gets notified, it can check if
     * it has lost the Wine clipboard ownership. If it did then it knows
     * that a WM_DESTORYCLIPBOARD has already been sent. Otherwise it
     * lost the selection to a X app and it should send the
     * WM_DESTROYCLIPBOARD itself. */
    CLIPBOARD_SetClipboardOwner(cbinfo.hWndOpen);

    /* Acquire the selection. This will notify the previous owner
     * to clear it's cache. */
    USER_Driver->pAcquireClipboard(cbinfo.hWndOpen);

    /* Empty the local cache */
    USER_Driver->pEmptyClipboard(FALSE);

    bCBHasChanged = TRUE;

    return TRUE;
}


/**************************************************************************
 *		GetClipboardOwner (USER32.@)
 *  FIXME: Can't return the owner if the clipboard is owned by an external X-app
 */
HWND WINAPI GetClipboardOwner(void)
{
    HWND hWndOwner = 0;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = 0;
        if (!wine_server_call_err( req )) hWndOwner = wine_server_ptr_handle( reply->old_owner );
    }
    SERVER_END_REQ;

    TRACE(" hWndOwner(%p)\n", hWndOwner);

    return hWndOwner;
}


/**************************************************************************
 *		GetOpenClipboardWindow (USER32.@)
 */
HWND WINAPI GetOpenClipboardWindow(void)
{
    HWND hWndOpen = 0;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = 0;
        if (!wine_server_call_err( req )) hWndOpen = wine_server_ptr_handle( reply->old_clipboard );
    }
    SERVER_END_REQ;

    TRACE(" hWndClipWindow(%p)\n", hWndOpen);

    return hWndOpen;
}


/**************************************************************************
 *		SetClipboardViewer (USER32.@)
 */
HWND WINAPI SetClipboardViewer( HWND hWnd )
{
    HWND hwndPrev = 0;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = SET_CB_VIEWER;
        req->viewer = wine_server_user_handle( hWnd );
        if (!wine_server_call_err( req ))
            hwndPrev = wine_server_ptr_handle( reply->old_viewer );
    }
    SERVER_END_REQ;

    TRACE("(%p): returning %p\n", hWnd, hwndPrev);

    return hwndPrev;
}


/**************************************************************************
 *              GetClipboardViewer (USER32.@)
 */
HWND WINAPI GetClipboardViewer(void)
{
    HWND hWndViewer = 0;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = 0;
        if (!wine_server_call_err( req )) hWndViewer = wine_server_ptr_handle( reply->old_viewer );
    }
    SERVER_END_REQ;

    TRACE(" hWndViewer=%p\n", hWndViewer);

    return hWndViewer;
}


/**************************************************************************
 *              ChangeClipboardChain (USER32.@)
 */
BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext)
{
    BOOL bRet = TRUE;
    HWND hWndViewer = GetClipboardViewer();

    if (hWndViewer)
    {
        if (WIN_GetFullHandle(hWnd) == hWndViewer)
            SetClipboardViewer(WIN_GetFullHandle(hWndNext));
        else
            bRet = !SendMessageW(hWndViewer, WM_CHANGECBCHAIN, (WPARAM)hWnd, (LPARAM)hWndNext);
    }
    else
        ERR("hWndViewer is lost\n");

    return bRet;
}


/**************************************************************************
 *		SetClipboardData (USER.141)
 */
HANDLE16 WINAPI SetClipboardData16(UINT16 wFormat, HANDLE16 hData)
{
    CLIPBOARDINFO cbinfo;
    HANDLE16 hResult = 0;

    TRACE("(%04X, %04x) !\n", wFormat, hData);

    /* If it's not owned, data can only be set if the format doesn't exists
       and its rendering is not delayed */
    if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
        (!(cbinfo.flags & CB_OWNER) && !hData))
    {
        WARN("Clipboard not owned by calling task. Operation failed.\n");
        return 0;
    }

    if (USER_Driver->pSetClipboardData(wFormat, hData, 0, cbinfo.flags & CB_OWNER))
    {
        hResult = hData;
        bCBHasChanged = TRUE;
    }

    return hResult;
}


/**************************************************************************
 *		SetClipboardData (USER32.@)
 */
HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData)
{
    CLIPBOARDINFO cbinfo;
    HANDLE hResult = 0;

    TRACE("(%04X, %p) !\n", wFormat, hData);

    /* If it's not owned, data can only be set if the format isn't
       available and its rendering is not delayed */
    if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
       (!(cbinfo.flags & CB_OWNER) && !hData))
    {
        WARN("Clipboard not owned by calling task. Operation failed.\n");
        return 0;
    }

    if (USER_Driver->pSetClipboardData(wFormat, 0, hData, cbinfo.flags & CB_OWNER))
    {
        hResult = hData;
        bCBHasChanged = TRUE;
    }

    return hResult;
}


/**************************************************************************
 *		CountClipboardFormats (USER32.@)
 */
INT WINAPI CountClipboardFormats(void)
{
    INT count = USER_Driver->pCountClipboardFormats();
    TRACE("returning %d\n", count);
    return count;
}


/**************************************************************************
 *		EnumClipboardFormats (USER32.@)
 */
UINT WINAPI EnumClipboardFormats(UINT wFormat)
{
    CLIPBOARDINFO cbinfo;

    TRACE("(%04X)\n", wFormat);

    if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
        (~cbinfo.flags & CB_OPEN))
    {
        WARN("Clipboard not opened by calling task.\n");
        SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
        return 0;
    }
    return USER_Driver->pEnumClipboardFormats(wFormat);
}


/**************************************************************************
 *		IsClipboardFormatAvailable (USER32.@)
 */
BOOL WINAPI IsClipboardFormatAvailable(UINT wFormat)
{
    BOOL bret = USER_Driver->pIsClipboardFormatAvailable(wFormat);
    TRACE("%04x, returning %d\n", wFormat, bret);
    return bret;
}


/**************************************************************************
 *		GetClipboardData (USER.142)
 */
HANDLE16 WINAPI GetClipboardData16(UINT16 wFormat)
{
    HANDLE16 hData = 0;
    CLIPBOARDINFO cbinfo;

    if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
        (~cbinfo.flags & CB_OPEN))
    {
        WARN("Clipboard not opened by calling task.\n");
        SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
        return 0;
    }

    if (!USER_Driver->pGetClipboardData(wFormat, &hData, NULL)) hData = 0;

    return hData;
}


/**************************************************************************
 *		GetClipboardData (USER32.@)
 */
HANDLE WINAPI GetClipboardData(UINT wFormat)
{
    HANDLE hData = 0;
    CLIPBOARDINFO cbinfo;

    TRACE("%04x\n", wFormat);

    if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
        (~cbinfo.flags & CB_OPEN))
    {
        WARN("Clipboard not opened by calling task.\n");
        SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
        return 0;
    }

    if (!USER_Driver->pGetClipboardData(wFormat, NULL, &hData)) hData = 0;

    TRACE("returning %p\n", hData);
    return hData;
}


/**************************************************************************
 *		GetPriorityClipboardFormat (USER32.@)
 */
INT WINAPI GetPriorityClipboardFormat(UINT *list, INT nCount)
{
    int i;

    TRACE("()\n");

    if(CountClipboardFormats() == 0)
        return 0;

    for (i = 0; i < nCount; i++)
        if (IsClipboardFormatAvailable(list[i]))
            return list[i];

    return -1;
}


/**************************************************************************
 *		GetClipboardSequenceNumber (USER32.@)
 * Supported on Win2k/Win98
 * MSDN: Windows clipboard code keeps a serial number for the clipboard
 * for each window station.  The number is incremented whenever the
 * contents change or are emptied.
 * If you do not have WINSTA_ACCESSCLIPBOARD then the function returns 0
 */
DWORD WINAPI GetClipboardSequenceNumber(VOID)
{
    DWORD seqno = 0;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = 0;
        if (!wine_server_call_err( req )) seqno = reply->seqno;
    }
    SERVER_END_REQ;

    TRACE("returning %x\n", seqno);
    return seqno;
}
